os/kernelhwsrv/kernel/eka/drivers/hcr/hcr_pil.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Hardware Configuration Respoitory Platform Independent Layer (PIL)
    15 //
    16 
    17 
    18 // -- INCLUDES ----------------------------------------------------------------
    19 
    20 
    21 #include "hcr_debug.h"
    22 
    23 #include <e32def.h>
    24 #include <e32err.h>
    25 #include <e32des8.h>
    26 #include <e32cmn.h>
    27 
    28 #include <nkern/nkern.h>
    29 #include <kernel/kernel.h>
    30 
    31 #include <e32rom.h>
    32 #include <plat_priv.h>
    33 
    34 #include <kernel/kernboot.h>
    35 
    36 
    37 #include "hcr_hai.h"
    38 #include "hcr_pil.h"
    39 
    40 // -- GLOBALS -----------------------------------------------------------------
    41 
    42 GLDEF_C HCR::HCRInternal gHCR;
    43 
    44 #ifdef HCR_TRACE
    45 GLDEF_C TBuf<81> gTraceBuffer;
    46 #endif
    47 
    48 
    49 // -- Local functions prototypes
    50 /**
    51 Retrive Repository file address stored in the iHcrFileAddress field of ROM Image header.
    52 If this filed is zero or it is equal with a special value then it keeps the original vaule of 
    53 aRepos parameter and signals it with the retun value.
    54 
    55 
    56 @param aRepos     		The reference to a repository variable    
    57 @return	KErrNone 		if successful, the aRepos parameter references to the file in ROM Image.
    58         KErrNotFound 	if the ROM Image header contains zero or a special value as the repository file address
    59 
    60 
    61 */    
    62 LOCAL_C TInt LocateCoreImgRepository(HCR::TRepository*& aRepos);
    63 
    64 /**
    65 This method transfer the value of aFileName to ROM Image conform file name string. 
    66 Retrive the variant dependent ROM Root directory address.
    67 Search the file in \sys\bin directory and if it doesn't exists there it try to find it in \sys\Data.
    68 
    69 
    70 @param 	aRepos     			The reference to a repository variable.
    71 				aFileName			  The name of the new repository file without path. '\0' terminated c-style string.
    72     
    73 @return	KErrNone 			if successful
    74         KErrNotFound 		if file not found in \sys\bin or \sys\Data
    75 
    76 
    77 */    
    78 LOCAL_C TInt SearchCoreImgRepository(HCR::TRepository* & aRepos, const TText * aFileName);
    79 
    80 /**
    81 Scanning a given directory for the given entry name. The entry name can be sub-directory or file.
    82 
    83 @param 	aActDir     		Pointer to curretn directory in the ROM Image directory tree
    84 		aFileName			File to be search
    85 		aEntry				If the file found this referenced to proper directory entry
    86     
    87 @return	 KErrNone		 			if the entry found
    88          KErrNotFound					if the entry not found
    89 */    
    90 
    91 LOCAL_C TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry);
    92 
    93 
    94 // -- WINS Specific ----------------------------------------------------------
    95 
    96 #ifdef __WINS__
    97 
    98 // Set to ensure Rom Hdr dependency does not break compilation in 
    99 // LocateCoreImgRepository() at the end of this file.
   100 // Undef incase it is set in MMP file, avoids compiler warning.
   101 //
   102 #undef HCRTEST_COREIMG_DONTUSE_ROMHDR
   103 #define HCRTEST_COREIMG_DONTUSE_ROMHDR
   104 
   105 #endif
   106 
   107 // -- FUNCTIONS ---------------------------------------------------------------
   108 
   109 /**
   110  Returns 1 when a1 > a2
   111  Returns -1 when a1 < a2
   112  Returns 0 when identical.
   113  */
   114 TInt CompareSSettingIds(const HCR::TSettingId& a1, const HCR::SSettingId& a2)    
   115 	{
   116     // HCR_FUNC("CompareSSettingIds");
   117     if (a1.iCat > a2.iCat)
   118         return (1); // HCR_TRACE_RETURN(1);
   119     if (a1.iCat < a2.iCat)
   120         return (-1); // HCR_TRACE_RETURN(-1);
   121     
   122     // Categories are the same at this point, check keys.
   123     if (a1.iKey > a2.iKey)
   124         return (1); // HCR_TRACE_RETURN(1);
   125     if (a1.iKey < a2.iKey)
   126         return (-1); // HCR_TRACE_RETURN(-1);
   127    
   128     // Both Categories and jeys are the same here.
   129     return (0); // HCR_TRACE_RETURN(0);
   130     }
   131 
   132 #ifdef __EPOC32__
   133 TBool ROMAddressIsInUnpagedSection(const TLinAddr address)
   134 	{
   135     HCR_FUNC("ROMAddressIsInUnpagedSection");
   136 	
   137 	const TRomHeader& romHdr = Epoc::RomHeader();
   138 	TLinAddr romBase = romHdr.iRomBase;
   139 
   140 	HCR_TRACE1("--- address to check if in unpaged ROM section = 0x%8x", address);
   141 	HCR_TRACE2("--- iRomSize (0x%8x), iPageableRomStart (0x%8x), ", romHdr.iRomSize, romHdr.iPageableRomStart);
   142 
   143 	if ((address < romBase) || (romBase > romBase+romHdr.iRomSize))
   144 		return EFalse;
   145 	if (romHdr.iPageableRomStart == 0)
   146 		return ETrue;
   147 	if (address < romBase+romHdr.iPageableRomStart)
   148 		return ETrue;
   149 	return EFalse;
   150 	}
   151 #endif
   152 
   153 
   154 TInt CompareByCategory(const HCR::TCategoryUid aCatId, const HCR::SSettingId& aSetId)    
   155     {
   156     //HCR_FUNC("CompareByCategory");
   157     if (aCatId > aSetId.iCat)
   158         return (1); // HCR_TRACE_RETURN(1);
   159     if (aCatId < aSetId.iCat)
   160         return (-1); // HCR_TRACE_RETURN(-1);
   161     
   162     // Both Categories and jeys are the same here.
   163     return (0); 
   164     }
   165 
   166 /*
   167  * SafeArray TSa class object destructor. It delets the allocated in the heap
   168  * memory and set the instance pointer to NULL. See also TSa class definition
   169  * in hcr_pil.h.
   170  */
   171 template<typename T>
   172     HCR::TSa<T>::~TSa()
   173     {
   174     delete[] iSa;
   175     iSa = NULL;
   176     }
   177 
   178 /**
   179  * operator=() changes the memory ownership by   
   180  * reinitiazing SafeArray class object with the address to   
   181  * already allocated array.
   182  */
   183 template<typename T>
   184    HCR::TSa<T>& HCR::TSa<T>::operator=(T* aP)
   185     {
   186     delete[] iSa;
   187     iSa = aP; 
   188     return (*this);
   189     }
   190 
   191 
   192 // -- METHODS -----------------------------------------------------------------
   193 //
   194 // HCRInternal
   195 
   196 HCR::HCRInternal::HCRInternal()
   197    : iStatus(EStatConstructed), iVariant(0), iVariantStore(0), iCoreImgStore(0), iOverrideStore(0)
   198     {
   199     HCR_FUNC("HCRInternal(Defualt)");
   200     }
   201 
   202 HCR::HCRInternal::HCRInternal(HCR::MVariant* aVar)
   203    : iVariant(aVar), iVariantStore(0), iCoreImgStore(0), iOverrideStore(0)
   204     {
   205     HCR_FUNC("HCRInternal");
   206     }
   207     
   208 HCR::HCRInternal::~HCRInternal()
   209     {
   210     HCR_FUNC("~HCRInternal");
   211     
   212     if (iVariant)
   213 		{
   214 		delete iVariant;
   215     	iVariant =0;
   216     	}
   217     if (iVariantStore)
   218 		{
   219 		delete iVariantStore;
   220     	iVariantStore =0;
   221     	}
   222     if (iCoreImgStore)
   223 		{
   224 		delete iCoreImgStore;
   225     	iCoreImgStore =0;
   226     	}
   227     if (iOverrideStore)
   228 		{
   229 		delete iOverrideStore;
   230     	iOverrideStore =0;
   231     	}
   232     }
   233    
   234 TUint32 HCR::HCRInternal::GetStatus()
   235     {
   236     HCR_FUNC("GetStatus");
   237     return iStatus;
   238     }
   239   
   240     
   241 TInt HCR::HCRInternal::Initialise()
   242     {
   243     HCR_FUNC("HCRInternal::Initialise");
   244     
   245     TAny* store = 0; 
   246     TInt err = 0;
   247 	
   248 	// Variant PSL object must exist before PIL initalised.
   249 	if (iVariant == 0) {
   250  			err = KErrGeneral; goto failed; }
   251 
   252 	// Inform the PSL that we are initialising, give them an opportunity to do
   253 	// initialisation work too.
   254     err = iVariant->Initialise(); 
   255     if (err != KErrNone)
   256     	goto failed;
   257    
   258     iStatus = EStatVariantInitialised;
   259     
   260     // Ask the PSL for the address of the SRepositoryCompiled object. PSL 
   261     // can return KErrNotSupported & NULL if compiled repository not 
   262 	// used/support by PSL.
   263     err = iVariant->GetCompiledRepositoryAddress(store);
   264     if (err == KErrNone)
   265         {
   266         if (store == 0) { // Programming error in PSL, ptr/rc mismatch
   267  			err = KErrArgument; goto failed; }
   268         	
   269         iVariantStore = TRepositoryCompiled::New(reinterpret_cast<const HCR::SRepositoryCompiled *>(store));
   270         if (iVariantStore == 0) { 
   271 			err = KErrNoMemory; goto failed; }
   272 
   273         }
   274     else if (err != KErrNotSupported)
   275     	goto failed;       
   276   
   277         
   278     // Ask the PSL if it wants the PIL not to search for the Core Image 
   279 	// SRepositoryFile settings.
   280     iCoreImgStore = 0;
   281     if (!iVariant->IgnoreCoreImgRepository())
   282     	{
   283     	err = LocateCoreImgRepository(iCoreImgStore);
   284     	if (err == KErrNone)
   285      	   {
   286         	if (iCoreImgStore == 0) {
   287 				err = KErrNoMemory; goto failed; }	
   288         	}
   289     	else if (err != KErrNotFound)
   290     		goto failed;
   291 		}       
   292   
   293         
   294     // Ask the PSL for the address of the SRepositoryFile object. PSL 
   295     // can return KErrNotSupported & NULL if a local media based file 
   296 	// repository is not used/support by PSL.  
   297     store = 0;
   298     err = iVariant->GetOverrideRepositoryAddress(store);
   299     if (err == KErrNone)
   300         {
   301         if (store == 0) { // Programming error in PSL, ptr/rc mismatch
   302  			err = KErrArgument; goto failed; }       
   303         
   304         iOverrideStore = TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(store));
   305         if (iOverrideStore == 0) {
   306 			err = KErrNoMemory; goto failed; }
   307 			
   308         }
   309     else if (err != KErrNotSupported)
   310     	goto failed;       
   311 
   312 	iStatus = EStatInitialised;
   313 	
   314     // Sanity check here to ensure we have atleast one repository to use and run
   315     // sanity check on their contents to look for ordering issues and duplicates.
   316 	HCR_TRACE3("=== HCR Ready: compiled:%x, coreimg:%x, override:%x", iVariantStore, iCoreImgStore, iOverrideStore);
   317     if ((iVariantStore == 0) && (iCoreImgStore == 0) && (iOverrideStore == 0)) {
   318  		err = KErrArgument; goto failed; }
   319 
   320 
   321 #ifdef _DEBUG
   322 	err = CheckIntegrity();
   323 	if (err != KErrNone)
   324 		goto failed;	
   325 #endif
   326 
   327 	iStatus = EStatReady;
   328 	return KErrNone;
   329 
   330 failed:
   331     iStatus = (iStatus & EStatMinorMask) | EStatFailed;
   332 	HCR_TRACE_RETURN(err);
   333     }
   334 
   335 
   336 TInt HCR::HCRInternal::SwitchRepository(const TText * aFileName, const TReposId aId)
   337 	{
   338 	HCR_FUNC("HCRInternal::SwitchRepository");
   339 	
   340 	TInt retVal = KErrNone;
   341 	TRepository* store = NULL;
   342 
   343 	if( aFileName != NULL)
   344 		{
   345 		retVal = SearchCoreImgRepository(store, aFileName);
   346 		HCR_TRACE2("--- SearchCoreImgRepository()->%d (0x%08x)", retVal, retVal);
   347 		}
   348 		
   349 	if( retVal == KErrNone )
   350 		{
   351 		switch(aId)
   352 			{
   353 			case ECoreRepos:
   354 			    HCR_TRACE0("--- ECoreRepos");
   355 				if( iCoreImgStore )
   356 					{
   357 					NKern::ThreadEnterCS();
   358 					delete iCoreImgStore;
   359 					NKern::ThreadLeaveCS();
   360 					}
   361 				iCoreImgStore = store;
   362 				break;
   363 				
   364 			case EOverrideRepos:
   365 			    HCR_TRACE0("--- EOverrideRepos");
   366 				if( iOverrideStore )
   367     				{
   368 	    			NKern::ThreadEnterCS();
   369 					delete iOverrideStore;
   370 					NKern::ThreadLeaveCS();
   371 					}
   372 				iOverrideStore = store;
   373 				break;
   374 		
   375 			default:
   376 			    HCR_TRACE0("--- default:");
   377 				retVal = KErrNotSupported;
   378 				break;		
   379 			}
   380 		}
   381 
   382 	HCR_TRACE_RETURN(retVal);
   383     }
   384 
   385 TInt HCR::HCRInternal::CheckIntegrity()
   386 	{
   387 	HCR_FUNC("HCRInternal::CheckIntegrity");
   388 	
   389 	TInt err = KErrNone;
   390 	if (iVariantStore)
   391 		{
   392 		err = iVariantStore->CheckIntegrity();
   393 		if (err != KErrNone)
   394 			HCR_TRACEMSG_RETURN("HCR iVariantStore failed integrity check", err);
   395 		}
   396 
   397 	if (iCoreImgStore)
   398 		{
   399 		err = iCoreImgStore->CheckIntegrity();
   400 		if (err != KErrNone)
   401 			HCR_TRACEMSG_RETURN("HCR iCoreImgStore failed integrity check", err);
   402 		}	
   403 	
   404 	if (iOverrideStore)
   405 		{
   406 		err = iOverrideStore->CheckIntegrity();
   407 		if (err != KErrNone)
   408 			HCR_TRACEMSG_RETURN("HCR iOverrideStore failed integrity check", err);
   409 		}
   410 
   411 	HCR_TRACE0("=== HCR Repository integrity checks PASSED!");
   412 	return KErrNone;	
   413 	}
   414 
   415 
   416 TInt HCR::HCRInternal::FindSetting(const TSettingId& aId, TSettingType aType, 
   417         TSettingRef& aSetting)
   418     {
   419     HCR_FUNC("HCRInternal::FindSetting");
   420     TInt err = KErrNone;
   421     TBool found = EFalse;
   422     
   423     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore);
   424     
   425     if (iOverrideStore && 
   426         ((err = iOverrideStore->FindSetting(aId, aSetting)) == KErrNone))
   427         found = ETrue;
   428     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   429         
   430     if (!found &&
   431         iCoreImgStore &&
   432         ((err = iCoreImgStore->FindSetting(aId, aSetting)) == KErrNone))
   433         found = ETrue;
   434     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   435 
   436     if (!found &&
   437         iVariantStore &&
   438         ((err = iVariantStore->FindSetting(aId, aSetting)) == KErrNone))
   439         found = ETrue;
   440     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   441 
   442     HCR_TRACE3("--- Search results: %d, %d, %x", found, err, aSetting.iSet);
   443     
   444     if (!found)
   445         HCR_TRACE_RETURN(KErrNotFound);
   446 
   447     // aSetting should now point to the found setting
   448     __NK_ASSERT_DEBUG(aSetting.iSet != 0);
   449 
   450     // Setting found at this point in the function
   451     //
   452     
   453     TSettingType type=static_cast<TSettingType>(aSetting.iRep->GetType(aSetting)); 
   454     if (type & ~aType)
   455         HCR_TRACE_RETURN(KErrArgument); // Wrong setting type
   456     
   457     HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, type);
   458     
   459     return err;
   460     }
   461 
   462 
   463 TInt HCR::HCRInternal::FindSettingWithType(const TSettingId& aId, TSettingType& aType, 
   464       TSettingRef& aSetting)
   465     {
   466     HCR_FUNC("HCRInternal::FindSettingWithType");
   467     TInt err = KErrNone;
   468     TBool found = EFalse;
   469     
   470     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore);
   471     
   472     if (iOverrideStore && 
   473         ((err = iOverrideStore->FindSetting(aId, aSetting)) == KErrNone))
   474         found = ETrue;
   475     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   476 
   477     if (!found &&
   478         iCoreImgStore &&
   479         ((err = iCoreImgStore->FindSetting(aId, aSetting)) == KErrNone))
   480         found = ETrue;
   481     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   482 
   483     if (!found &&
   484         iVariantStore &&
   485         ((err = iVariantStore->FindSetting(aId, aSetting)) == KErrNone))
   486         found = ETrue;
   487     __NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
   488 
   489     HCR_TRACE3("--- Search results: %d, %d, %x", found, err, aSetting.iSet);
   490     
   491     if (!found)
   492         {
   493         aType = ETypeUndefined;
   494         HCR_TRACE_RETURN(KErrNotFound);
   495         }
   496 
   497     // aSetting should now point to the found setting
   498     __NK_ASSERT_DEBUG(aSetting.iSet != 0);
   499 
   500     // Setting found at this point in the function
   501     //
   502     
   503     aType=static_cast<TSettingType>(aSetting.iRep->GetType(aSetting)); 
   504     
   505     HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, aType);
   506     
   507     return err;
   508     }
   509 
   510 
   511 TInt HCR::HCRInternal::GetWordSettings(TInt aNum, const SSettingId aIds[], 
   512         TInt32 aValues[], TSettingType aTypes[], TInt aErrors[])
   513     {
   514     HCR_FUNC("++ HCRInternal::GetWordSettings");
   515     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore);
   516     
   517     if(aNum <= 0 || aIds == NULL || aErrors == NULL)
   518         HCR_TRACE_RETURN(KErrArgument);
   519     
   520     TInt err = 0;
   521     //If the user only supplies a single setting then there is no reasons to 
   522     //continue with multiple searach and it should be limited by internal 
   523     //invocation of FindSettingWithType.
   524     if(aNum == 1)
   525         {
   526         TSettingRef sref(0,0);
   527         TSettingType* pTypes;
   528                 
   529         //aTypes array is optional and user may not provided it for us. So we
   530         //need to be sure it's not a null pointer
   531         if(aTypes == NULL)
   532             {
   533             //If this is a null pointer then just create our own element and 
   534             //assign it to the pTypes pointer
   535             TSettingType types[1];
   536             pTypes = types;
   537             }
   538         else
   539             {
   540             //else we use the user supplied array
   541             pTypes = aTypes;
   542             }
   543                 
   544         //Let's find this setting
   545         err = HCRSingleton->FindSettingWithType(aIds[0], *pTypes, sref);
   546         
   547         //and analyse the result of operation
   548         
   549         //If setting is not found or it's larger than 4 bytes then store this
   550         //error cause in the user error array 
   551         if(err == KErrNotFound || err == KErrArgument)
   552             {
   553             //Indicate the error for the element and set the value to 0
   554             aErrors[0] = err;
   555             aValues[0] = 0;
   556             return 0;
   557             }
   558         //fatal error here, nothing to do, just exit and return the error code
   559         else if(err == KErrNotReady || err != KErrNone)
   560             {
   561             HCR_TRACE_RETURN(err);
   562             }
   563         else //err == KErrNone
   564             {
   565             //Get the value of the setting
   566             err = sref.iRep->GetValue(sref, reinterpret_cast<UValueWord&>(aValues[0]));
   567 
   568             //The GetValue can only return either KErrArgument or KErrNone
   569             if(err == KErrArgument)
   570                 {
   571                 aErrors[0] = KErrArgument;
   572                 aValues[0] = 0;
   573                 return 0;
   574                 }
   575             else //err == KErrNone
   576                 {
   577                 aErrors[0] = KErrNone;
   578                 }
   579             
   580             }
   581         
   582         //This single setting was found so indicate it to the user
   583         return (1);
   584         }
   585 
   586     
   587     //Introducing a SafeArray of pointers to the settings, which is passed to ver- 
   588     //sion of GetWordSettings() method declared in TRepository, and implemented 
   589     //in TRepositoryCompiled and TRepositoryFile
   590     TSa<SSettingId*> ids;
   591 
   592     //SafeArray of pointers to the aValues user array elements 
   593     TSa<TInt32*> values;
   594     
   595     //SafeArray of pointers to the aErrors user array elements 
   596     TSa<TInt*> errors;
   597     
   598     //SafeArray of pointers to the aTypes user array elements
   599     TSa<TSettingType*> types;
   600     
   601     
   602     //Local replacement for the aTypes[] array if it's not provided by user
   603     TSa<TSettingType> typesHolder;
   604     
   605     //Allocate the arrays of pointers in the  heap
   606     ids = new SSettingId*[aNum];
   607     values = new TInt32*[aNum];
   608     errors = new TInt*[aNum];
   609     types  = new TSettingType*[aNum];
   610 
   611 
   612     //Check all arrays allocations
   613     if(!ids() || !values() || !errors() || !types())
   614         {
   615         //One of the allocation was unsuccessful 
   616         HCR_TRACE_RETURN(KErrNoMemory);
   617         }
   618     
   619     //If the user did not supply the aTypes array for us we need to create one 
   620     //for ourself
   621     if(aTypes == NULL)
   622         {
   623         typesHolder = new TSettingType[aNum];
   624         if(!typesHolder())
   625             HCR_TRACE_RETURN(KErrNoMemory);
   626         }
   627     
   628        
   629     //Ininialize newly created array of pointers to the user supplied settings 
   630     for (TInt index = 0; index < aNum; index++)
   631         {
   632         ids[index] = const_cast<SSettingId*>(&aIds[index]);
   633         values[index] = const_cast<TInt32*>(&aValues[index]);
   634         errors[index] = &aErrors[index];
   635        
   636         if(aTypes == NULL)
   637             types[index] = &typesHolder[index];
   638         else
   639             types[index] = &aTypes[index];
   640         }
   641     
   642     
   643     //nfCount represents a total number of settings which were not found in all
   644     //repositories
   645     TInt nfCount = aNum;
   646     
   647     //nfReposCount represents a number of settings "not found - nf" in the searched
   648     //repository
   649     TInt nfReposCount   = 0;
   650 
   651     //It represents a number of setting found in the repository
   652     TInt reposCount   = 0;
   653     
   654     
   655     //First step through the Override store and gather all settings we need.
   656     //In the end of this procedure we'll have number of settings not found here
   657     //and found settings data are copied to the user arrays.
   658     if (iOverrideStore)
   659         {
   660 
   661         //Call the sibling method from the TRepositoryFile object
   662         err = iOverrideStore->GetWordSettings(aNum, ids(),
   663                 values(), types(), errors());
   664 
   665         //Analyse the err we've got 
   666         if(err != KErrNone && err != KErrNotFound)
   667             {
   668             HCR_TRACE_RETURN(err);
   669             }
   670         else if(err == KErrNone)
   671             {
   672             //Search for number of not found parameters
   673             for(TInt index = 0; index < aNum; index ++)
   674                 {
   675                 switch(*(errors[index]))
   676                     {
   677                     //The setting was found or it's found but the type is larger
   678                     //than 4 bytes then we just increase a counter of the found
   679                     //settings in the repository
   680                     case KErrNone:
   681                     case KErrArgument:
   682                         reposCount ++;
   683                         break;
   684 
   685 
   686                     //The setting was not found, then re-initialize all the 
   687                     //arrays of pointers with the pointer to this element. 
   688                     //nfReposCount depict the counter of not found element and
   689                     //index shows the intial element position.
   690                     //As nfReposCount is always less or equal to index then we
   691                     //can easily make reassignment as nfReposCoun element was
   692                     //already analysed. In the end the nfReposCount is increased.
   693                     case KErrNotFound:
   694                         ids[nfReposCount]        = ids[index];
   695                         values[nfReposCount]     = values[index];
   696                         types[nfReposCount]      = types[index];
   697                         errors[nfReposCount]     = errors[index];                  
   698                         nfReposCount ++;
   699                         break;
   700 
   701 
   702                     default:
   703                         //No any action is needed
   704                         break;
   705                     }
   706                 }
   707 
   708             }
   709         else //err == KErrNotFound
   710             {
   711             //No settings were found in the repository
   712             //reposCount is zero intialized, so nothing to do here
   713             }
   714         
   715         //Update the global counter only if there are some settings were found,
   716         //otherwise it can be situation when we overwrite the nfCount with zero
   717         //when either no any setting presents or no settings were found in the
   718         //repository
   719         if(reposCount > 0)
   720             nfCount = nfReposCount;
   721         }
   722     
   723     //Go through core image and search for the rest of settings
   724     nfReposCount = 0;
   725     reposCount = 0;
   726     
   727     if (iCoreImgStore && nfCount > 0)
   728         {
   729 
   730         err = iCoreImgStore->GetWordSettings(nfCount, ids(),
   731                                                 values(), types(), errors());
   732 
   733         if (err != KErrNone && err != KErrNotFound)
   734             {
   735             HCR_TRACE_RETURN(err);
   736             }
   737         else if(err == KErrNone)
   738             {
   739             //Search for number of errors
   740             for(TInt index = 0; index < nfCount; index ++)
   741                 {
   742                 switch(*(errors[index]))
   743                     {
   744                     //The setting was found or it's found but the type is larger
   745                     //than 4 bytes then we just increase a counter of the found
   746                     //settings in the repository
   747                     case KErrNone:
   748                     case KErrArgument:
   749                         reposCount ++;
   750                         break;
   751 
   752                     //The setting was not found, then re-initialize all the 
   753                     //arrays of pointers with the pointer to this element. 
   754                     //nfReposCount depict the counter of not found element and
   755                     //index shows the intial element position.
   756                     //As nfReposCount is always less or equal to index then we
   757                     //can easily make reassignment as nfReposCoun element was
   758                     //already analysed. In the end the nfReposCount is increased.
   759                     case KErrNotFound:
   760                         ids[nfReposCount]        = ids[index];
   761                         values[nfReposCount]     = values[index];
   762                         types[nfReposCount]      = types[index];
   763                         errors[nfReposCount]     = errors[index];                  
   764                         nfReposCount ++;
   765                         break;
   766 
   767 
   768                     default:
   769                         //No any action is needed
   770                         break;
   771 
   772                     }
   773 
   774                 }
   775 
   776             }
   777         else //err == KErrNotFound 
   778             {
   779             //No settings were found in the repository
   780             //reposCount is zero intialized, so nothing to do here
   781             }
   782 
   783 
   784         //Update the global counter only if there are some settings were found,
   785         //otherwise it can be situation when we overwrite the nfCount with zero
   786         //when either no any setting presents or no settings were found in the
   787         //repository 
   788         if(reposCount > 0)
   789             nfCount = nfReposCount;
   790         }
   791     
   792     //let's go through the last Variant store
   793     nfReposCount = 0;
   794     reposCount = 0;
   795     if(iVariantStore && nfCount > 0)
   796         {
   797         err = iVariantStore->GetWordSettings(nfCount, ids(), values(), 
   798                 types(), errors());
   799 
   800         if (err != KErrNone && err != KErrNotFound)
   801             {
   802             HCR_TRACE_RETURN(err);
   803             }
   804         else if(err == KErrNone)
   805             {
   806             //Search for number of errors
   807             for(TInt index = 0; index < nfCount; index ++)
   808                 {
   809                 switch(*(errors[index]))
   810                     {
   811                     //The setting was found or it's found but the type is larger
   812                     //than 4 bytes then we just increase a counter of the found
   813                     //settings in the repository
   814                     case KErrNone:
   815                     case KErrArgument:
   816                         reposCount ++;
   817                         break;
   818 
   819                     //The setting was not found, then re-initialize all the 
   820                     //arrays of pointers with the pointer to this element. 
   821                     //nfReposCount depict the counter of not found element and
   822                     //index shows the intial element position.
   823                     //As nfReposCount is always less or equal to index then we
   824                     //can easily make reassignment as nfReposCoun element was
   825                     //already analysed. In the end the nfReposCount is increased.
   826                     case KErrNotFound:
   827                         *values[nfReposCount]     = 0;
   828                         *types[nfReposCount]      = ETypeUndefined;
   829                         *errors[nfReposCount]     = KErrNotFound;
   830                         nfReposCount ++;
   831                         break;
   832 
   833 
   834                     default:
   835                         //No any action is needed
   836                         break;
   837 
   838                     }
   839                 }
   840             
   841             }
   842         else //err == KErrNotFound
   843             {
   844             //No settings were found in the repository
   845             //reposCount is zero intialized, so nothing to do here
   846             }
   847         
   848         //Update the global counter only if there are some settings were found,
   849         //otherwise it can be situation when we overwrite the nfCount with zero
   850         //when either no any setting presents or no settings were found in the
   851         //repository
   852         if(reposCount > 0)
   853             nfCount = nfReposCount;
   854         }
   855     //Return the number of found elements
   856     return (aNum - nfCount);
   857     }
   858 
   859 
   860 
   861 
   862 
   863 TInt HCR::HCRInternal::FindNumSettingsInCategory (TCategoryUid aCatUid)
   864     {
   865     HCR_FUNC("++ HCRInternal::FindNumSettingsInCategory");
   866     TInt err = 0;
   867 
   868     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore);
   869 
   870     //First and last element index within category in the Override store
   871     TInt32 oLowIndex = 0;
   872     TInt32 oHighIndex = 0;
   873     TInt oCount = 0;
   874 
   875     //Find numOverride number of settings within the category in the OverrideStore 
   876     //repository
   877     if(iOverrideStore)
   878         {
   879         err = iOverrideStore->FindNumSettingsInCategory(aCatUid, 
   880                 oLowIndex, oHighIndex);
   881        
   882         if(err == KErrNotFound)
   883             oCount = 0;
   884         else
   885             oCount = oHighIndex - oLowIndex + 1;
   886 
   887         //If CoreImg and Variant store are not activated so just return the
   888         //number of elements found in the Override store
   889         if(!iCoreImgStore && !iVariantStore)
   890             return oCount;
   891         }
   892 
   893 
   894     //First and last element index within category in the CoreImg store
   895     TInt32 cLowIndex = 0;
   896     TInt32 cHighIndex = 0;
   897     TInt32 cLength = 0;
   898     TInt   cCount = 0;
   899 
   900         
   901     
   902     //Temproary holder for the found element position
   903     TInt32 elementPos;
   904     //Temproary holder for the low index, which is used to decrease the scope
   905     //of search
   906     TInt32 lowIndex = oLowIndex;
   907     
   908     //Setting data holders
   909     SSettingId setId;
   910     TSettingRef setRef;
   911     
   912     if(iCoreImgStore)
   913         {
   914         //Find numCoreImg number of settings within the category in the CoreImg re-
   915         //pository
   916         err = iCoreImgStore->FindNumSettingsInCategory(aCatUid, 
   917                 cLowIndex, cHighIndex);
   918 
   919         if(err == KErrNotFound)
   920             cLength = 0;
   921         else
   922             //Calculate the number of elements within category, in CoreImg store
   923             cLength = cHighIndex - cLowIndex + 1;
   924 
   925         if(oCount > 0)
   926             {
   927             //Find all elemnts from CoreImg store which are not redefined in the 
   928             //Override store. When element is not found in the Override store 
   929             //then cCount is increased.
   930             for(TInt element = 0; element < cLength; element ++)
   931                 {
   932                 //Find element in the repository by its index
   933                 iCoreImgStore->GetSettingRef(cLowIndex + element, setRef);
   934                 //and get its id
   935                 iCoreImgStore->GetId(setRef, setId);
   936                 
   937                 //Check either this element is already redefined in the Override
   938                 //store
   939                 err = iOverrideStore->FindSetting( setId, setRef, 
   940                         elementPos, lowIndex, oHighIndex);
   941 
   942                 if(err == KErrNone)
   943                     {
   944                     //if the element is found in the Override store, then store the posi-
   945                     //tion of this element in lowIndex, to narrow next search procedure
   946                     lowIndex = elementPos;
   947                     }
   948                 else //err == KErrNotFound
   949                     {
   950                     //if element is not found then it means it's not redefined in the 
   951                     //Override store and this element must be counted in the total number
   952                     //of elemnts in all stores
   953                     cCount ++;
   954                     
   955                     //FindSetting can only return KErrNotFound, let's assert 
   956                     //we've only got KErrNotFound
   957                     __NK_ASSERT_DEBUG(err == KErrNotFound);
   958                     
   959                     }
   960                 
   961                 }
   962             }
   963         else
   964             {
   965             cCount = cLength;
   966             }
   967 
   968         }
   969 
   970     //First and last element index within giving category in the Variant store
   971     TInt32 vLowIndex  = 0;
   972     TInt32 vHighIndex = 0;
   973     TInt32 vLength = 0;
   974     TInt vCount = 0;
   975 
   976     if(iVariantStore)
   977         {
   978         //Find numVariant number of settings within the category in the VariantStore
   979         //repository
   980         err = iVariantStore->FindNumSettingsInCategory(aCatUid, vLowIndex, 
   981                 vHighIndex);
   982 
   983         //Analyze returned error code
   984 
   985         if(err == KErrNotFound)
   986             vLength = 0;
   987         else
   988             //Calculate the number of elements within category, in CoreImg store
   989             vLength = vHighIndex - vLowIndex + 1;
   990 
   991 
   992         if(oCount > 0 || cCount >0)
   993             {
   994             //Find all elemnts from Variant store which are not redefined either in the 
   995             //Override or CoreImg store. These elements are added to the total 
   996             //count.
   997             
   998             // Some additional containers. They are needed because we  
   999             // must check two stores Override and Variant in this iteration. Making a 
  1000             // decision of uniqueness of the element is made from the analyse of both  
  1001             // result. The element is only unique defined in the Variant store if it's  
  1002             // not redefined either in the Override or Variant store
  1003             TSettingRef tmpRef;
  1004             //Temproary holder for the found element position
  1005             TInt32 elementPos2 = 0;
  1006             //Temproary holder for the low index, which is used to decrease the scope
  1007             //of search
  1008             TInt32 lowIndex2 = cLowIndex;
  1009             // This index contains Override low index and will be changed by the position
  1010             // of a new found element 
  1011             lowIndex= oLowIndex;
  1012 
  1013             TBool isRedefined = EFalse;
  1014             
  1015             for(TInt element = 0; element < vLength; element ++)
  1016                 {
  1017                 //Find the setting in the repository by its index and
  1018                 iVariantStore->GetSettingRef(vLowIndex + element, setRef);
  1019                 //get its id
  1020                 iVariantStore->GetId(setRef, setId);
  1021 
  1022                 if(oCount > 0)
  1023                     {
  1024                     //Check either this element is already redefined in the Override store 
  1025                     err = iOverrideStore->FindSetting(setId, tmpRef, 
  1026                             elementPos, lowIndex, oHighIndex);
  1027 
  1028                     if(err == KErrNone)
  1029                         {
  1030                         //if the element is found in the Override store, then store the posi-
  1031                         //tion of this element in lowIndex, to narrow next search procedure
  1032                         lowIndex = elementPos;
  1033                         isRedefined = ETrue;
  1034                         }
  1035                     else //err == KErrNotFound
  1036                         {
  1037                         //the element is not presented in the Override store
  1038                         //nothing to do here
  1039 
  1040                         //FindSetting can only return KErrNotFound, let's assert 
  1041                         //we've only got KErrNotFound
  1042                         __NK_ASSERT_DEBUG(err == KErrNotFound);
  1043                         }
  1044                     
  1045 
  1046                     }
  1047 
  1048 
  1049                 if(cCount > 0 && !isRedefined)
  1050                     {
  1051                     //Check either this element is already redefined in the CoreImg store
  1052                     err = iCoreImgStore->FindSetting(setId, tmpRef, 
  1053                             elementPos2, lowIndex2, cHighIndex);
  1054 
  1055 
  1056                     if(err == KErrNone)
  1057                         {
  1058                         //if the element is found in the Override store, then store the posi-
  1059                         //tion of this element in lowIndex, to narrow next search procedure
  1060                         lowIndex2 = elementPos2;
  1061                         isRedefined = ETrue;
  1062                         }
  1063                     else //err == KErrNotFound
  1064                         {
  1065                         //the element is not presented in the Override store
  1066                         //nothing to do here
  1067 
  1068                         //FindSetting can only return KErrNotFound, let's assert 
  1069                         //we've only got KErrNotFound
  1070                         __NK_ASSERT_DEBUG(err == KErrNotFound);
  1071                         }
  1072                     
  1073                     }
  1074                 
  1075 
  1076                 if(!isRedefined)
  1077                     vCount ++;
  1078                 else
  1079                     isRedefined = EFalse;
  1080 
  1081                 }//for(TInt element = 0; element < vLength; element ++)
  1082 
  1083             }
  1084         else
  1085             {
  1086             vCount = vLength;
  1087             }
  1088         }
  1089 
  1090     //Return the total number of elements found in the category
  1091     return (oCount + cCount + vCount);
  1092     }
  1093 
  1094 
  1095 
  1096 
  1097 TInt HCR::HCRInternal::FindSettings(TCategoryUid aCatUid, 
  1098         TInt aMaxNum, TElementId aIds[],  
  1099         TSettingType aTypes[], TUint16 aLens[])
  1100     {
  1101     HCR_FUNC("++ HCRInternal::FindSettings w/o patterns");
  1102    
  1103     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, 
  1104             iCoreImgStore, iVariantStore);
  1105    
  1106     //Error container
  1107     TInt err = KErrNone;
  1108     
  1109     //Number of found elements in the Override store
  1110     TInt oNumFound = 0;
  1111 
  1112     //Low and High indexes in the Override store
  1113     TInt32 oLoIndex = 0;
  1114     TInt32 oHiIndex = 0;
  1115 
  1116     //Temproary holder for the found element position
  1117     TInt32 elementPos = 0;
  1118     TInt32 lowIndex = 0;
  1119     
  1120 
  1121     //Tempoary type and length value holders if the
  1122     //user does not provide these arrays for us
  1123     TSettingType tmpType;
  1124     TUint16 tmpLen;
  1125 
  1126         
  1127     //Setting datat holders
  1128     TSettingRef setRef;
  1129     TSettingId  setId;
  1130 
  1131     
  1132     //Find number of elements, low and hingh index in the Override store
  1133     if(iOverrideStore)
  1134         {
  1135         err = iOverrideStore->FindNumSettingsInCategory(aCatUid, oLoIndex,
  1136                 oHiIndex);
  1137         if(err == KErrNone)
  1138             {
  1139             //If number of elements in the Override Store is larger than aMaxNum or 
  1140             //CoreImage/Variant stores are not present then write all found 
  1141             //settings into the user array, return the number of found elements and
  1142             //exit
  1143             oNumFound = (oHiIndex - oLoIndex + 1);
  1144             lowIndex = oLoIndex;
  1145        
  1146             if(oNumFound < aMaxNum)
  1147                 {
  1148                 for(TInt index = 0; index < oNumFound; index ++)
  1149                     {
  1150                     //Get setting reference data from the repository
  1151                     iOverrideStore->GetSettingRef(oLoIndex + index, setRef);
  1152 
  1153                     //Copy the settings data into the user arrays
  1154                     iOverrideStore->GetSettingInfo(setRef, 
  1155                             aIds[index], 
  1156                             aTypes ? aTypes[index]:tmpType,
  1157                             aLens ? aLens[index]:tmpLen);
  1158 
  1159                     
  1160                     }
  1161                 }
  1162             else //oNumFound >= aMaxNum
  1163                 {
  1164                 //Copy data to the user array
  1165                 for(TInt index = 0; index < aMaxNum; index++)
  1166                     {
  1167                     //Get setting reference data from the repository
  1168                     iOverrideStore->GetSettingRef(oLoIndex + index, setRef);
  1169                     //Copy the settings data into the user arrays
  1170                     iOverrideStore->GetSettingInfo(setRef, 
  1171                             aIds[index], 
  1172                             aTypes ? aTypes[index]:tmpType,
  1173                             aLens  ? aLens[index]:tmpLen);
  1174 
  1175                     }
  1176                 return aMaxNum;
  1177                 }
  1178             }
  1179         else // err == KErrNotFound
  1180             {
  1181             //Nothing to do here, oNumFound is set to zero already
  1182 
  1183             //FindNumSettingsInCategory can only return KErrNotFound, let's  
  1184             //assert we've only got KErrNotFound
  1185             __NK_ASSERT_DEBUG(err == KErrNotFound);
  1186             }
  1187 
  1188         }
  1189 
  1190    
  1191     //Low/High index in the CoreImg
  1192     TInt32 cLoIndex = 0;
  1193     TInt32 cHiIndex = 0;
  1194     TInt cNumFound = 0;
  1195     
  1196     //Temproary setting reference holder
  1197     TSettingRef tmpRef;
  1198 
  1199     //Temproary holder for the found element position
  1200     elementPos = 0;
  1201     lowIndex = oLoIndex;
  1202 
  1203     //Redefined status flag, it's used to flag that the element is found in the 
  1204     //upper stores
  1205     TBool isRedefined = EFalse;
  1206     
  1207     //User array index
  1208     TInt usrArrIndx = 0;
  1209 
  1210     //If the count is still less than aMaxNum then continue with searching 
  1211     //settings in the CoreImage store
  1212     if(iCoreImgStore)
  1213         {
  1214 
  1215         //Find number of elements and low/high indexes
  1216         err = iCoreImgStore->FindNumSettingsInCategory(aCatUid, cLoIndex,
  1217                 cHiIndex);
  1218 
  1219         if(err == KErrNone)
  1220             {
  1221             for(TInt index = 0; index < (cHiIndex - cLoIndex + 1); index ++)
  1222                 {
  1223                 //Get the setting data by its index in the repository
  1224                 iCoreImgStore->GetSettingRef(cLoIndex + index, setRef);
  1225                 //get setting id
  1226                 iCoreImgStore->GetId(setRef, setId);
  1227                 
  1228                 if(oNumFound > 0)
  1229                     {
  1230                     //Check either this element is already redefined in the 
  1231                     err = iOverrideStore->FindSetting(setId, tmpRef, 
  1232                             elementPos, lowIndex, oHiIndex);
  1233 
  1234                     
  1235                     if(err == KErrNone)
  1236                         {
  1237                         lowIndex = elementPos + 1;
  1238                         isRedefined = ETrue;
  1239                         }
  1240                     else //err == KErrNotFound
  1241                         {
  1242                         //Nothing to do hear, isRedefined flag is EFalse
  1243                         //all analysis is done later in the code
  1244 
  1245                         //FindSetting can only return KErrNotFound, let's assert 
  1246                         //we've only got KErrNotFound
  1247                         __NK_ASSERT_DEBUG(err == KErrNotFound);
  1248                         }
  1249                     
  1250                     }
  1251 
  1252                 //Examine the redefined status flag
  1253                 if(!isRedefined)
  1254                     {
  1255                     // If the element was not found then we need to copy to 
  1256                     // the pA array and increase the counter of setting data 
  1257                     // only if we did not reach the aMaxNum of found elements
  1258                     
  1259                     usrArrIndx = oNumFound + cNumFound;
  1260                     if(usrArrIndx < aMaxNum)
  1261                         {
  1262                         //Copy the settings data into the user arrays
  1263                         iCoreImgStore->GetSettingInfo(setRef, 
  1264                                  aIds[usrArrIndx], 
  1265                                  aTypes ? aTypes[usrArrIndx]:tmpType,
  1266                                  aLens ? aLens[usrArrIndx]:tmpLen);
  1267                         cNumFound ++;
  1268                         }
  1269                     else
  1270                         {
  1271                         //It reaches the goal, all required elements are found
  1272                         //stop here and return the result
  1273                         break;
  1274                         }
  1275                     }
  1276                 else
  1277                     //Element is found in other repositories, just reset a flag
  1278                     isRedefined = EFalse;
  1279                 }
  1280             }
  1281         else //err == KErrNotFound
  1282             {
  1283             //cNumFound is already set to zero during the initialization
  1284             //Nothing to do here
  1285 
  1286             //FindNumSettingsInCategory can only return KErrNotFound, let's  
  1287             //assert we've only got KErrNotFound
  1288             __NK_ASSERT_DEBUG(err == KErrNotFound);
  1289             }
  1290         
  1291         }
  1292 
  1293     
  1294     //Low/High index in the CoreImg
  1295     TInt32 vLoIndex = 0;
  1296     TInt32 vHiIndex = 0;
  1297     TInt vNumFound = 0;
  1298 
  1299     //Temproary holder for the found element position
  1300     TInt32 elementPos2 = 0;
  1301     
  1302     TInt32 lowIndex2 = cLoIndex;
  1303     lowIndex  = oLoIndex;
  1304 
  1305     isRedefined = EFalse;
  1306     
  1307 
  1308     //If the count is still less than aMaxNum then continue with searching 
  1309     //settings in the CoreImage store
  1310     if(iVariantStore)
  1311         {
  1312 
  1313         //Find number of elements and low/high indexes
  1314         err = iVariantStore->FindNumSettingsInCategory(aCatUid, vLoIndex,
  1315                 vHiIndex);
  1316         if(err == KErrNone)
  1317             {
  1318 
  1319             for(TInt index = 0; index < (vHiIndex - vLoIndex + 1); index ++)
  1320                 {
  1321                 //Get setting reference data by its index in the repository
  1322                 iVariantStore->GetSettingRef(vLoIndex + index, setRef);
  1323                 
  1324                 //and get setting id
  1325                 iVariantStore->GetId(setRef, setId);
  1326                 
  1327                 if(oNumFound > 0)
  1328                     {
  1329                     //Check either this element is already redefined in the 
  1330                     err = iOverrideStore->FindSetting(setId, tmpRef, elementPos,  
  1331                             lowIndex, oHiIndex);
  1332                     
  1333                 
  1334                     //Also suppress the error checking due the reason described 
  1335                     //above
  1336                     if(err == KErrNone)
  1337                         {
  1338                         lowIndex = elementPos + 1;
  1339                         isRedefined = ETrue;
  1340                         }
  1341                     else //err == KErrNotFound
  1342                         {
  1343                         //Element is not found, nothing to proceed here
  1344 
  1345                         //FindSetting can only return KErrNotFound, let's assert 
  1346                         //we've only got KErrNotFound
  1347                         __NK_ASSERT_DEBUG(err == KErrNotFound);
  1348                         }
  1349                     
  1350                     }
  1351 
  1352                 if(cNumFound > 0 && !isRedefined)
  1353                     {
  1354                     //Check either this element is already redefined in the 
  1355                     err = iCoreImgStore->FindSetting(setId, tmpRef, elementPos2,  
  1356                             lowIndex2, cHiIndex);
  1357 
  1358                     if(err == KErrNone)
  1359                         {
  1360                         lowIndex2 = elementPos2 + 1;
  1361                         isRedefined = ETrue;
  1362                         }
  1363                     else //err == KErrNotFound
  1364                         {
  1365                         //Element is not found, nothing to proceed here
  1366 
  1367                         //FindSetting can only return KErrNotFound, let's assert 
  1368                         //we've only got KErrNotFound
  1369                         __NK_ASSERT_DEBUG(err == KErrNotFound);
  1370                         }
  1371                     
  1372                     }
  1373                
  1374                 if(!isRedefined)
  1375                     {
  1376                     usrArrIndx = oNumFound + cNumFound + vNumFound;
  1377                     if(usrArrIndx < aMaxNum)
  1378                         {
  1379                         //Copy the settings data into the user arrays
  1380                         iVariantStore->GetSettingInfo(setRef, 
  1381                                  aIds[usrArrIndx], 
  1382                                  aTypes ? aTypes[usrArrIndx]:tmpType,
  1383                                  aLens ? aLens[usrArrIndx]:tmpLen);
  1384 
  1385                         vNumFound ++;
  1386                         }
  1387                     else
  1388                         {
  1389                         //It reaches the goal, all required elements are found
  1390                         //stop here and return the result
  1391                         break;
  1392                         }
  1393                     }
  1394                 else
  1395                     {
  1396                     isRedefined = EFalse;
  1397                     }
  1398                 }
  1399             }
  1400         else //err == KErrNotFound
  1401             {
  1402             //oNumFound is already set to zero during the initialization
  1403             //Nothing to do here
  1404 
  1405             //FindNumSettingsInCategory can only return KErrNotFound, let's  
  1406             //assert we've only got KErrNotFound
  1407             __NK_ASSERT_DEBUG(err == KErrNotFound);
  1408             }
  1409                 
  1410         }
  1411     
  1412     //Let's prepare the final data
  1413     return (oNumFound + cNumFound + vNumFound);
  1414     }
  1415 
  1416 
  1417 
  1418 
  1419 
  1420 
  1421 
  1422 TInt HCR::HCRInternal::FindSettings(TCategoryUid aCat, TInt aMaxNum,
  1423                 TUint32 aMask, TUint32 aPattern, 
  1424                 TElementId aIds[], TSettingType aTypes[], TUint16 aLens[])
  1425     {
  1426     //Holder for errors and number of elements
  1427     TInt r = KErrNone;
  1428     //Total number of elements within the given category
  1429     TInt allInCatFound = 0;
  1430     //Number of elements which corresponds to the aMask and aPattern
  1431     TInt numFound = 0;
  1432     
  1433     //Find the number of elements within the category
  1434     r = FindNumSettingsInCategory(aCat);
  1435     
  1436     //We don't expect any errors here
  1437     __NK_ASSERT_DEBUG(r >= 0);
  1438     
  1439     if (r == 0)
  1440         //No any elements found for this category 
  1441         return 0;
  1442     else
  1443         allInCatFound = r;
  1444     
  1445     //Result data array holder
  1446     TSa<TElementId> pIds; 
  1447     TSa<TSettingType> pTypes;
  1448     TSa<TUint16> pLens;
  1449     
  1450     pIds = new TElementId[allInCatFound];
  1451     pTypes = new TSettingType[allInCatFound];
  1452     pLens = new TUint16[allInCatFound];
  1453 
  1454     if(pIds() == NULL || pTypes() == NULL || pLens() == NULL)
  1455         //One of the allocation was unsuccessful 
  1456         HCR_TRACE_RETURN(KErrNoMemory);
  1457     
  1458     r = FindSettings(aCat, allInCatFound, pIds(), pTypes(), pLens());
  1459     
  1460     //We don't expect any errors here
  1461     __NK_ASSERT_DEBUG(r >= 0);
  1462     
  1463     //Check either we've got less elements than it must be
  1464     __NK_ASSERT_DEBUG(r == allInCatFound);
  1465     
  1466     //Choose the elements which satisfy this condition
  1467     //((elementID & aElementMask) == (aPattern & aElementMask)). The total num-
  1468     //ber of returned elements should not exceed the aMaxNum
  1469     for(TInt index = 0; index < allInCatFound; index++)
  1470         {
  1471             if(((pIds[index] & aMask) == (aPattern & aMask)))
  1472                 {
  1473                 aIds[numFound] = pIds[index];
  1474 
  1475                 if(aTypes)
  1476                     aTypes[numFound] = pTypes[index];
  1477 
  1478                 if(aLens)
  1479                     aLens[numFound] = pLens[index];
  1480 
  1481                 numFound ++;
  1482                 }
  1483             else
  1484                 continue;
  1485             
  1486             //Check either we already found  or not enough elements
  1487             //If we did then break the loop
  1488             if(numFound == aMaxNum)
  1489                 break;
  1490         }
  1491     
  1492     return numFound;
  1493     }
  1494 
  1495 
  1496 // -- METHODS -----------------------------------------------------------------
  1497 //
  1498 // TRepository
  1499 
  1500 HCR::TRepository::~TRepository()
  1501 	{
  1502     HCR_FUNC("~TRepository");
  1503 	}
  1504 
  1505 TBool HCR::TRepository::IsWordValue(const TSettingRef& aRef)
  1506     {
  1507     HCR_FUNC("TRepository::IsWordValue");
  1508     return ((aRef.iSet->iType & KMaskWordTypes) != 0);
  1509     }
  1510 
  1511 TBool HCR::TRepository::IsLargeValue(const TSettingRef& aRef)
  1512     {
  1513     HCR_FUNC("TRepository::IsLargeValue");
  1514     return ((aRef.iSet->iType & KMaskLargeTypes) != 0);
  1515     }
  1516 
  1517 void HCR::TRepository::GetId(const TSettingRef& aRef, SSettingId& aId)
  1518     {
  1519     HCR_FUNC("TRepository::GetId2");
  1520     aId = aRef.iSet->iId;
  1521     }
  1522 
  1523 TInt32 HCR::TRepository::GetType(const TSettingRef& aRef)
  1524     {
  1525     HCR_FUNC("TRepository::GetType");
  1526     return (aRef.iSet->iType);
  1527     }
  1528 
  1529 TUint16 HCR::TRepository::GetLength(const TSettingRef& aRef)
  1530     {
  1531     HCR_FUNC("TRepository::GetLength");
  1532     
  1533 	// Assume large value, will be caught when value retreived if not correct.
  1534 	// Saves some CPU cycles...
  1535 	// if (IsLargeValue(aRef))
  1536     return (aRef.iSet->iLen);
  1537     }
  1538 
  1539 void HCR::TRepository::GetSettingInfo(const HCR::TSettingRef& aSetRef, 
  1540                HCR::TElementId& aId, HCR::TSettingType& aType, TUint16& aLen)
  1541     {
  1542     HCR_FUNC("TRepository::GetSettingInfo");
  1543 
  1544     aId = aSetRef.iSet->iId.iKey;
  1545    
  1546     aType = static_cast<TSettingType>(aSetRef.iSet->iType);
  1547 
  1548     aLen = aSetRef.iSet->iLen;
  1549     }
  1550 
  1551 // -- METHODS -----------------------------------------------------------------
  1552 //
  1553 // TRepositoryCompiled
  1554 
  1555 
  1556 HCR::TRepository* HCR::TRepositoryCompiled::New(const SRepositoryCompiled* aRepos)
  1557     {
  1558     HCR_FUNC("TRepositoryCompiled::New");
  1559     
  1560     __NK_ASSERT_ALWAYS(aRepos != 0);
  1561     return new TRepositoryCompiled(aRepos);
  1562     }
  1563 
  1564 HCR::TRepositoryCompiled::TRepositoryCompiled(const SRepositoryCompiled* aRepos)
  1565  : iRepos(aRepos)
  1566     {
  1567     HCR_FUNC("TRepositoryCompiled");
  1568     }
  1569     
  1570 HCR::TRepositoryCompiled::~TRepositoryCompiled()
  1571     {
  1572     HCR_FUNC("~TRepositoryCompiled");
  1573     }
  1574         
  1575 TInt HCR::TRepositoryCompiled::CheckIntegrity()
  1576     {
  1577     HCR_FUNC("TRepositoryCompiled::CheckIntegrity");
  1578     
  1579     __NK_ASSERT_ALWAYS(this != 0);   
  1580     __NK_ASSERT_ALWAYS(iRepos != 0);
  1581 
  1582 	if (iRepos->iOrderedSettingList == 0)
  1583         HCR_TRACEMSG_RETURN("Compiled Repository header missing setting array list", KErrNotFound);
  1584     
  1585 	HCR_TRACE2("Compiled repository 0x%x contains %05d entries", iRepos, iRepos->iHdr->iNumSettings);
  1586 
  1587     SSettingC* arr = iRepos->iOrderedSettingList;
  1588     TSettingId prev(0,0);
  1589     TInt rc=0;
  1590     for (int i=0; i < iRepos->iHdr->iNumSettings; i++, arr++)
  1591     	{
  1592     	__NK_ASSERT_ALWAYS(arr != 0);
  1593     	HCR_TRACE3("Checking entry %05d - (0x%x,0x%x)", i, arr->iName.iId.iCat,  arr->iName.iId.iKey);
  1594     	rc = CompareSSettingIds(prev, arr->iName.iId);
  1595 		// Check for duplicates that reside next to each other
  1596     	if ((i > 0) && (rc == 0))
  1597     		HCR_TRACE_RETURN (KErrAlreadyExists);
  1598     	// Check that the entries are in ascending order	
  1599     	if (rc != -1)
  1600     		HCR_TRACE_RETURN (KErrCorrupt);
  1601     	prev = arr->iName.iId;
  1602 		}
  1603     return KErrNone; 
  1604     }
  1605     
  1606 TInt HCR::TRepositoryCompiled::FindSetting(const TSettingId& aId, TSettingRef& aSetting)
  1607     {
  1608     HCR_FUNC("TRepositoryCompiled::FindSetting");
  1609     
  1610     __NK_ASSERT_DEBUG(iRepos != 0);
  1611     __NK_ASSERT_DEBUG(iRepos->iHdr != 0);
  1612     
  1613     if ((iRepos->iHdr->iNumSettings == 0) || 
  1614         (iRepos->iOrderedSettingList == 0))
  1615         HCR_TRACE_RETURN(KErrNotFound);
  1616     
  1617     SSettingC* arr = iRepos->iOrderedSettingList;
  1618     int low = 0;
  1619     int high = iRepos->iHdr->iNumSettings-1;
  1620     int mid;
  1621     int com;
  1622     
  1623     while (low<=high)
  1624         {
  1625         mid = (low+high) >> 1;
  1626         com = CompareSSettingIds(aId, arr[mid].iName.iId);
  1627         if (com < 0)
  1628             high = mid-1;
  1629         else if (com > 0)
  1630             low = mid+1;
  1631         else
  1632             {
  1633             aSetting.iRep = this;
  1634             aSetting.iSet = &((arr[mid]).iName);
  1635             return KErrNone;
  1636             }    
  1637         } 
  1638         
  1639     aSetting.iRep = 0;
  1640 	aSetting.iSet = 0; 
  1641     return KErrNotFound;
  1642     }
  1643 
  1644 
  1645 
  1646 
  1647 TInt HCR::TRepositoryCompiled::FindSetting(const TSettingId& aId, 
  1648        TSettingRef& aSetting,  TInt32& aPosition,  TInt32 aLow, TInt32 aHigh)
  1649     {
  1650     HCR_FUNC("TRepositoryCompiled::FindSetting within the given range");
  1651     
  1652     
  1653     __NK_ASSERT_DEBUG(iRepos != 0);
  1654     __NK_ASSERT_DEBUG(iRepos->iHdr != 0);
  1655 	__NK_ASSERT_DEBUG(iRepos->iOrderedSettingList != 0);
  1656 	__NK_ASSERT_DEBUG(iRepos->iHdr->iNumSettings != 0);
  1657     
  1658     SSettingC* arr = iRepos->iOrderedSettingList;
  1659     TInt32 low = aLow;
  1660     TInt32 high = aHigh;
  1661     TInt32 mid;
  1662     TInt32 com;
  1663     
  1664     while (low<=high)
  1665         {
  1666         mid = (low+high) >> 1;
  1667         com = CompareSSettingIds(aId, arr[mid].iName.iId);
  1668         if (com < 0)
  1669             high = mid-1;
  1670         else if (com > 0)
  1671             low = mid+1;
  1672         else
  1673             {
  1674             aSetting.iRep = this;
  1675             aSetting.iSet = &((arr[mid]).iName);
  1676             aPosition = mid;
  1677             return KErrNone;
  1678             }    
  1679         } 
  1680         
  1681     aSetting.iRep = 0;
  1682     aSetting.iSet = 0;
  1683     aPosition = 0;
  1684     return KErrNotFound;
  1685     }
  1686     
  1687 
  1688 
  1689 TInt HCR::TRepositoryCompiled::GetWordSettings(TInt aNum,   
  1690        SSettingId* aIds[], TInt32* aValues[], TSettingType* aTypes[],
  1691         TInt* aErrors[])
  1692     {
  1693     HCR_FUNC("TRepositoryCompiled::GetWordSettings");
  1694     
  1695     __NK_ASSERT_DEBUG(iRepos != 0);
  1696     __NK_ASSERT_DEBUG(iRepos->iHdr != 0);
  1697 	__NK_ASSERT_DEBUG(aIds != NULL);
  1698 	__NK_ASSERT_DEBUG(aValues != NULL);
  1699 	__NK_ASSERT_DEBUG(aTypes != NULL);
  1700 	__NK_ASSERT_DEBUG(aErrors != NULL);
  1701     
  1702     if ((iRepos->iHdr->iNumSettings == 0) || 
  1703         (iRepos->iOrderedSettingList == 0))
  1704         HCR_TRACE_RETURN(KErrNotFound);
  1705  
  1706     TInt err = KErrNone;
  1707         
  1708     TInt32 rMaxIndex = 0;
  1709     TInt32 rMinIndex = 0;
  1710     TInt32 uFirstIndex = 0;
  1711     TInt32 uLastIndex = 0;
  1712     TInt32 rIndex = 0;
  1713     TInt32 uIndex = 0;
  1714     
  1715     TSettingRef settingRef(NULL, NULL);
  1716     SSettingC* pSetting = NULL;
  1717 
  1718 
  1719     //Find position index within the repository for the first and last setting
  1720     //from user supplied array aIds[]
  1721     uIndex = 0;
  1722     TBool isRedefined = EFalse;
  1723     err = KErrNotFound;
  1724     uFirstIndex = 0;
  1725     while(!isRedefined && uIndex < aNum)
  1726         {
  1727         //Find first setting from user array. The importance here is that we   
  1728         //should get value of first setting index in the repository in rMinIndex.
  1729         //This time the  scope of search is whole repository.
  1730         err = this->FindSetting(*aIds[uIndex],settingRef, rMinIndex, 
  1731                 0, iRepos->iHdr->iNumSettings);
  1732 
  1733 		__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  1734 
  1735         if(err == KErrNotFound)
  1736             {
  1737             *aErrors[uIndex] = err;
  1738             *aValues[uIndex] = 0;
  1739             *aTypes[uIndex] = ETypeUndefined;
  1740             
  1741             //As FindSetting did not find the element, let's challenge with 
  1742             //the next one from aIds[] array
  1743             uIndex ++;
  1744             continue;
  1745             }
  1746         else // err == KErrNone
  1747             {
  1748             //Get the value and type
  1749             pSetting = (SSettingC*) settingRef.iSet;
  1750             
  1751 			*aTypes[uIndex] = static_cast<TSettingType>(settingRef.iSet->iType); 
  1752 
  1753 			//Check for the found type is this word size? If it's not then 
  1754 			//indicate error for this setting
  1755 			if(*aTypes[uIndex] > ETypeLinAddr)
  1756 				{
  1757 				*aErrors[uIndex] = KErrArgument;
  1758 				*aValues[uIndex] = 0;
  1759 				}
  1760 			else
  1761 				{
  1762 				*aErrors[uIndex] = KErrNone;
  1763 				*aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  1764 				}
  1765 				
  1766             //Break the loop by setting the redefined status
  1767             isRedefined = ETrue;
  1768             }
  1769         }
  1770     
  1771     //At this point we should find at least one element from the user array,   
  1772     //store this index in the local variable, it is used later in the code.   
  1773     //Please be noticed we've also got rMinIndex - first setting index in the
  1774     //repository.
  1775     if(err == KErrNone)
  1776         uFirstIndex = uIndex;
  1777     //if we did not find any elements at all just return KErrNotFound
  1778     else
  1779         return KErrNotFound;
  1780 
  1781     
  1782     
  1783     //Now lets find the last setting
  1784     uIndex = aNum - 1;
  1785     isRedefined = EFalse;
  1786     err = KErrNotFound;
  1787     while(!isRedefined && uIndex > uFirstIndex)
  1788         {
  1789         //Find the last setting from user array. The importance here is that we   
  1790         //should get value of first setting index in the repository in 
  1791         //rMinIndex. This time the  scope of search is whole repository.
  1792         err = this->FindSetting(*aIds[uIndex],settingRef, rMaxIndex, 
  1793                 rMinIndex, iRepos->iHdr->iNumSettings);
  1794 
  1795 		__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  1796 
  1797         if(err == KErrNotFound)
  1798             {
  1799             *aErrors[uIndex] = err;
  1800             *aValues[uIndex] = 0;
  1801             *aTypes[uIndex] = ETypeUndefined;
  1802             
  1803             //As FindSetting did not find the element, let's challenge with 
  1804             //previous one, as we are moving in reverse direction
  1805             uIndex --;
  1806             continue;
  1807             }
  1808         else //err == KErrNone
  1809             {
  1810             pSetting = (SSettingC*) settingRef.iSet;
  1811             *aTypes[uIndex] = static_cast<TSettingType>(settingRef.iSet->iType); 
  1812             
  1813 			//Check for the found type is this word size? If it's not then indicate
  1814 			//error for this setting
  1815 			if(*aTypes[uIndex] > ETypeLinAddr)
  1816 				{
  1817 				*aErrors[uIndex] = KErrArgument;
  1818 				*aValues[uIndex] = 0;
  1819 				}
  1820 			else
  1821 				{
  1822 				*aErrors[uIndex] = KErrNone;
  1823 				*aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  1824 				}
  1825 				
  1826             isRedefined = ETrue;
  1827             }
  1828         }
  1829 
  1830     //At this point we found the last setting, store it's user array index in   
  1831     //the local variable, it is used later in the code. Please be noticed   
  1832     //we've also got rMaxIndex - last setting index in the repository.
  1833     if(err == KErrNone)
  1834         uLastIndex = uIndex;
  1835     else
  1836         //if we are here we did not find any other elements than was found
  1837         //in previous iteration then just stop here
  1838         return KErrNotFound;
  1839     
  1840     //The scope of user array settings in the repository is found. 
  1841     //Let's find all other settings from user array. Bare in mind the low
  1842     //bound for the repository index is increased each iteration to optimize the
  1843     //search time.
  1844     for(uIndex = uFirstIndex + 1; uIndex < uLastIndex; uIndex ++)
  1845         {
  1846         err = this->FindSetting(*aIds[uIndex],settingRef, rIndex, 
  1847                 rMinIndex, rMaxIndex);
  1848 
  1849 		__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  1850 
  1851         if(err == KErrNotFound)
  1852             {
  1853             *aErrors[uIndex] = err;
  1854             *aValues[uIndex] = 0;
  1855             *aTypes[uIndex] = ETypeUndefined;
  1856 
  1857             //As FindSetting did not find the element, let's challenge with 
  1858             //another one
  1859             continue;
  1860             }
  1861         else //err == KErrNone
  1862             {
  1863 
  1864             pSetting = (SSettingC*) settingRef.iSet;
  1865             *aTypes[uIndex] = static_cast<TSettingType>(settingRef.iSet->iType); 
  1866 
  1867 			//Check for the found type is this word size? If it's not then indicate
  1868 			//error for this setting
  1869 			if(*aTypes[uIndex] > ETypeLinAddr)
  1870 				{
  1871 				*aErrors[uIndex] = KErrArgument;
  1872 				*aValues[uIndex] = 0;
  1873 				}
  1874 			else
  1875 				{
  1876 				*aErrors[uIndex] = KErrNone;
  1877 				*aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  1878 				}
  1879 				
  1880             rMinIndex = rIndex + 1;
  1881 
  1882             }
  1883 
  1884         }
  1885 
  1886     return KErrNone;
  1887     }
  1888 
  1889 
  1890 
  1891 
  1892 
  1893 TInt HCR::TRepositoryCompiled::FindNumSettingsInCategory(TCategoryUid aCatUid,
  1894         TInt32& aFirst, TInt32& aLast)
  1895     {
  1896     HCR_FUNC("TRepositoryCompiled::FindNumSettingsInCategory");
  1897 
  1898     __NK_ASSERT_DEBUG(iRepos != 0);
  1899     __NK_ASSERT_DEBUG(iRepos->iHdr != 0);
  1900 	__NK_ASSERT_DEBUG(iRepos->iOrderedSettingList != 0);
  1901     
  1902     if(iRepos->iHdr->iNumSettings == 0)
  1903         {
  1904         aFirst = 0;
  1905         aLast = 0;
  1906         HCR_TRACE_RETURN(KErrNotFound);
  1907         }
  1908 
  1909     SSettingC* arr = iRepos->iOrderedSettingList;
  1910     int low = 0;
  1911     int high = iRepos->iHdr->iNumSettings-1;
  1912     int mid = 0;
  1913     int com = 0;
  1914 
  1915     //Let's find any setting within the category, mid will store the setting 
  1916     //index in the repository
  1917     while (low<=high)
  1918         {
  1919         mid = (low+high) >> 1;
  1920         com = CompareByCategory(aCatUid, arr[mid].iName.iId);
  1921         if (com < 0)
  1922             high = mid-1;
  1923         else if (com > 0)
  1924             low = mid+1;
  1925         else
  1926             {
  1927             break;
  1928             }    
  1929         } 
  1930 
  1931     // If no one setting with the given category was found the return error  
  1932     // to the user
  1933     if(low > high)
  1934         {
  1935         aFirst = 0;
  1936         aLast  = 0;
  1937         return KErrNotFound;
  1938         }
  1939 
  1940     //Search the first element within the category
  1941     low = mid;
  1942     while(low >= 0 && arr[low].iName.iId.iCat == aCatUid)
  1943         {
  1944         if(low > 0)
  1945             low --;
  1946         else
  1947             break;
  1948         }
  1949     //Check the boundary conditions, there are two cases when we exit the loop
  1950     //either we found an element which category is not one we are looking for or
  1951     //we reach the beggining of the repository. If we reach the beggining of the
  1952     //repository we don't really know is it because this is last elment or it
  1953     //has required aCatUid, so we check these two conditions below
  1954     if(arr[low].iName.iId.iCat == aCatUid)
  1955         aFirst = low;
  1956 
  1957     //We finish the loop either reaching the setting which category id is not
  1958     //what we need or this is first setting in the repository again with another
  1959     //category, so in both case we throw this element from the account.
  1960     else
  1961         aFirst = low + 1;
  1962 
  1963     //Search the last element within the category
  1964     high = mid;
  1965     while(high <= iRepos->iHdr->iNumSettings - 1 && arr[high].iName.iId.iCat == aCatUid)
  1966         {
  1967         if(high < iRepos->iHdr->iNumSettings - 1)
  1968             high ++;
  1969         else
  1970             break;
  1971         }
  1972 
  1973     //Same situation as above, boundary conditions
  1974     if(arr[high].iName.iId.iCat == aCatUid)
  1975         aLast = high;
  1976     else
  1977         aLast = high -1;
  1978 
  1979 
  1980     return KErrNone;
  1981     }
  1982 
  1983 
  1984 
  1985 void HCR::TRepositoryCompiled::GetSettingRef(TInt32 aIndex, 
  1986         HCR::TSettingRef& aRef)
  1987     {
  1988     __NK_ASSERT_DEBUG(iRepos != 0);
  1989     __NK_ASSERT_DEBUG(iRepos->iHdr != 0);
  1990     __NK_ASSERT_DEBUG(iRepos->iHdr->iNumSettings != 0 && iRepos->iOrderedSettingList != 0);
  1991     __NK_ASSERT_DEBUG(aIndex >=0 && aIndex < iRepos->iHdr->iNumSettings);
  1992     
  1993 
  1994     //Get the pointer to the repository data
  1995     SSettingC* arr = iRepos->iOrderedSettingList;
  1996         
  1997     aRef.iRep = this;
  1998     aRef.iSet = &(arr[aIndex].iName);
  1999     }
  2000 
  2001 
  2002 TInt HCR::TRepositoryCompiled::GetValue(const TSettingRef& aRef, UValueWord& aValue)
  2003     {
  2004     HCR_FUNC("TRepositoryCompiled::GetValue");
  2005     if (!IsWordValue(aRef))
  2006         HCR_TRACE_RETURN(KErrArgument);
  2007         
  2008 	SSettingC* sptr = (SSettingC*)(aRef.iSet);
  2009     aValue = sptr->iValue.iLit;
  2010 	return KErrNone;
  2011     }
  2012 
  2013 TInt HCR::TRepositoryCompiled::GetLargeValue(const TSettingRef& aRef, UValueLarge& aValue)
  2014     {
  2015     HCR_FUNC("TRepositoryCompiled::GetLargeValue");
  2016     if (!IsLargeValue(aRef))
  2017         HCR_TRACE_RETURN(KErrArgument);
  2018 
  2019 	SSettingC* sptr = (SSettingC*)(aRef.iSet);
  2020     aValue = sptr->iValue.iPtr;
  2021     return KErrNone;
  2022     }
  2023 
  2024 
  2025 // -- METHODS -----------------------------------------------------------------
  2026 //
  2027 // TRepositoryFile
  2028 
  2029 
  2030 HCR::TRepository* HCR::TRepositoryFile::New(const SRepositoryFile* aRepos)
  2031     {
  2032     HCR_FUNC("TRepositoryFile::New");
  2033 
  2034     __NK_ASSERT_ALWAYS(aRepos != 0);
  2035     return new TRepositoryFile(aRepos);
  2036     }
  2037 
  2038 HCR::TRepositoryFile::TRepositoryFile(const SRepositoryFile* aRepos)
  2039  : iRepos(aRepos)
  2040     {
  2041     HCR_FUNC("TRepositoryFile");
  2042     }
  2043 
  2044 HCR::TRepositoryFile::~TRepositoryFile()
  2045     {
  2046     HCR_FUNC("~TRepositoryFile"); 
  2047 	
  2048 #ifdef __WINS__
  2049 	// On target hardware the iRepos pointer always points to a file in the Core
  2050 	// rom image and hence is not memory allocated on kernel heap. Hence it does
  2051 	// not need to be freeded. 
  2052 	// When running under the emulator the file repositories are loaded into
  2053 	// allocated memory which needs to be freed here.
  2054 
  2055 	delete const_cast<SRepositoryFile*>(iRepos);
  2056 	iRepos = 0;
  2057 #endif // __WINS__
  2058 
  2059     }
  2060     
  2061 TInt HCR::TRepositoryFile::CheckIntegrity()
  2062     {
  2063     HCR_FUNC("TRepositoryFile::CheckIntegrity");
  2064     
  2065     __NK_ASSERT_ALWAYS(this != 0);   
  2066     __NK_ASSERT_ALWAYS(iRepos != 0);
  2067     
  2068 	if ((*((TUint32*)&(iRepos->iHdr)) != 0x66524348) || 
  2069 		(iRepos->iHdr.iFormatVersion != 0x0001))
  2070         HCR_TRACEMSG_RETURN("File Repository header describes an unsupported repository type", KErrCorrupt); 
  2071 	
  2072     HCR_TRACE2("File repository 0x%x contains %05d entries", iRepos, iRepos->iHdr.iNumSettings);
  2073     
  2074     SSettingF* arr = (SSettingF*) (iRepos+1);
  2075     TSettingId prev(0,0);
  2076     TInt rc=0;
  2077     for (int i=0; i < iRepos->iHdr.iNumSettings; i++, arr++)
  2078     	{
  2079     	__NK_ASSERT_ALWAYS(arr != 0);
  2080     	HCR_TRACE3("Checking entry %05d - (0x%x,0x%x)", i, arr->iName.iId.iCat,  arr->iName.iId.iKey);
  2081     	rc = CompareSSettingIds(prev, arr->iName.iId);
  2082 	   	// Check for duplicates that reside next to each other
  2083     	if ((i > 0) && (rc == 0))
  2084     		HCR_TRACE_RETURN (KErrAlreadyExists);
  2085     	// Check that the entries are in ascending order	
  2086     	if (rc != -1)
  2087     		HCR_TRACE_RETURN (KErrCorrupt);
  2088     	prev = arr->iName.iId;
  2089 		}
  2090     return KErrNone; 
  2091     }
  2092 
  2093 TInt HCR::TRepositoryFile::FindSetting(const TSettingId& aId, TSettingRef& aSetting)
  2094     {
  2095     HCR_FUNC("TRepositoryFile::FindSetting");
  2096  
  2097     __NK_ASSERT_DEBUG(iRepos != 0);
  2098    
  2099     if (iRepos->iHdr.iNumSettings == 0)
  2100         HCR_TRACE_RETURN(KErrNotFound);
  2101     
  2102     SSettingF* arr = (SSettingF*) (iRepos+1);
  2103     int low = 0;
  2104     int high = iRepos->iHdr.iNumSettings-1;
  2105     int mid;
  2106     int com;
  2107     
  2108     while (low<=high)
  2109         {
  2110         mid = (low+high) >> 1;
  2111         com = CompareSSettingIds(aId, arr[mid].iName.iId);
  2112         if (com < 0)
  2113             high = mid-1;
  2114         else if (com > 0)
  2115             low = mid+1;
  2116         else
  2117             {
  2118             aSetting.iRep = this;
  2119             aSetting.iSet = &((arr[mid]).iName);
  2120             return KErrNone;
  2121             }    
  2122         } 
  2123         
  2124     aSetting.iRep = 0;
  2125 	aSetting.iSet = 0; 
  2126     return KErrNotFound;
  2127     }
  2128 
  2129 
  2130 TInt HCR::TRepositoryFile::FindSetting (const TSettingId& aId,
  2131         TSettingRef& aSetting, TInt32& aPosition, TInt32 aLow, TInt32 aHigh)
  2132     {
  2133     HCR_FUNC("TRepositoryFile::FindSetting within the given range");
  2134 
  2135 
  2136     __NK_ASSERT_DEBUG(iRepos != 0);
  2137     __NK_ASSERT_DEBUG(iRepos->iHdr.iNumSettings != 0);
  2138 
  2139     SSettingF* arr = (SSettingF*) (iRepos+1);
  2140     TInt32 low = aLow;
  2141     TInt32 high = aHigh;
  2142     TInt32 mid;
  2143     TInt32 com;
  2144 
  2145     while (low<=high)
  2146         {
  2147         mid = (low+high) >> 1;
  2148         com = CompareSSettingIds(aId, arr[mid].iName.iId);
  2149         if (com < 0)
  2150             high = mid-1;
  2151         else if (com > 0)
  2152             low = mid+1;
  2153         else
  2154             {
  2155             aSetting.iRep = this;
  2156             aSetting.iSet = &((arr[mid]).iName);
  2157             aPosition = mid;
  2158             return KErrNone;
  2159             }    
  2160         } 
  2161 
  2162     aSetting.iRep = 0;
  2163     aSetting.iSet = 0; 
  2164     aPosition = 0;
  2165     return KErrNotFound;
  2166     }
  2167 
  2168 
  2169 
  2170 
  2171 TInt HCR::TRepositoryFile::GetWordSettings(TInt aNum,   
  2172         SSettingId* aIds[], TInt32* aValues[], TSettingType* aTypes[],
  2173         TInt* aErrors[])
  2174     {
  2175     HCR_FUNC("TRepositoryFile::GetWordSettings");
  2176 
  2177 
  2178     __NK_ASSERT_DEBUG(iRepos != 0);
  2179 	__NK_ASSERT_DEBUG(aIds != NULL);
  2180 	__NK_ASSERT_DEBUG(aValues != NULL);
  2181 	__NK_ASSERT_DEBUG(aTypes != NULL);
  2182 	__NK_ASSERT_DEBUG(aErrors != NULL);
  2183    
  2184     if (iRepos->iHdr.iNumSettings == 0)
  2185         return KErrNotFound;
  2186 
  2187     TInt err = KErrNone;
  2188 
  2189     TInt32 rMaxIndex = 0;
  2190     TInt32 rMinIndex = 0;
  2191     TInt32 uFirstIndex = 0;
  2192     TInt32 uLastIndex = 0;
  2193     TInt32 rIndex = 0;
  2194     TInt32 uIndex = 0;
  2195 
  2196     TSettingRef settingRef(NULL, NULL);
  2197     SSettingF* pSetting = NULL;
  2198 
  2199     //Find position index within the repository for the first and last setting
  2200     //from user supplied array aIds[]
  2201         uIndex = 0;
  2202         TBool isRedefined = EFalse;
  2203         err = KErrNotFound;
  2204         uFirstIndex = 0;
  2205         while(!isRedefined && uIndex < aNum)
  2206             {
  2207             //Find first setting from user array. The importance here is that we   
  2208             //should get value of first setting index in the repository in rMinIndex.
  2209             //This time the  scope of search is whole repository.
  2210             err = this->FindSetting(*aIds[uIndex],settingRef, rMinIndex, 
  2211                     0, iRepos->iHdr.iNumSettings);
  2212 
  2213 			__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  2214 
  2215             if(err == KErrNotFound)
  2216                 {
  2217                 *aErrors[uIndex] = err;
  2218                 *aValues[uIndex] = 0;
  2219                 *aTypes[uIndex] = ETypeUndefined;
  2220                 
  2221                 //As FindSetting did not find the element, let's challenge with 
  2222                 //the next one from aIds[] array
  2223                 uIndex ++;
  2224                 continue;
  2225                 }
  2226             else // err == KErrNone
  2227                 {
  2228                 //Get the value and type
  2229                 pSetting = (SSettingF*) settingRef.iSet;
  2230                 //again copy the type value into the user array if it's provided
  2231                 *aTypes[uIndex] = static_cast<TSettingType>(settingRef.iSet->iType); 
  2232             
  2233 				//Check for the found type is this word size? If it's not then 
  2234 				//indicate error for this setting
  2235 				if(*aTypes[uIndex] > ETypeLinAddr)
  2236 					{
  2237 					*aErrors[uIndex] = KErrArgument;
  2238 					*aValues[uIndex] = 0;
  2239 					}
  2240 				else
  2241 					{
  2242 					*aErrors[uIndex] = KErrNone;
  2243 					*aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  2244 					}
  2245 					
  2246                 //Break the loop by setting the redefined status
  2247                 isRedefined = ETrue;
  2248                 }
  2249             }
  2250         
  2251         //At this point we should find at least one element, store this index in the  
  2252         //local variable, this is used later in the code. Please be noticed we've  
  2253         //also got rMinIndex - first setting index in the repository. 
  2254         if(err == KErrNone)
  2255             uFirstIndex = uIndex;
  2256         else
  2257             //if we are hear it means we did not find any user settings at all
  2258             //we can't do any thing and just return KErrNotFound to indicate
  2259             //this fact
  2260             return KErrNotFound;
  2261 
  2262         
  2263         
  2264         //Now lets find the last setting
  2265         uIndex = aNum - 1;
  2266         isRedefined = EFalse;
  2267         err = KErrNotFound;
  2268         
  2269         while(!isRedefined && uIndex > uFirstIndex)
  2270             {
  2271             //Find the last setting from user array. The importance here is that we   
  2272             //should get value of first setting index in the repository in 
  2273             //rMinIndex. This time the  scope of search is whole repository.
  2274             err = this->FindSetting(*aIds[uIndex],settingRef, rMaxIndex, 
  2275                     rMinIndex, iRepos->iHdr.iNumSettings);
  2276 
  2277 			__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  2278 			
  2279             if(err == KErrNotFound)
  2280                 {
  2281                 *aErrors[uIndex] = err;
  2282                 *aValues[uIndex] = 0;
  2283                 *aTypes[uIndex] = ETypeUndefined;
  2284                 
  2285                 //As FindSetting did not find the element, let's challenge with 
  2286                 //previous one
  2287                 uIndex --;
  2288                 continue;
  2289                 }
  2290             else //err == KErrNone
  2291                 {
  2292                 pSetting = (SSettingF*) settingRef.iSet;
  2293                 *aTypes[uIndex] = static_cast<TSettingType>(settingRef.iSet->iType); 
  2294 
  2295 				//Check for the found type is this word size? If it's not then indicate
  2296 				//error for this setting
  2297 				if(*aTypes[uIndex] > ETypeLinAddr)
  2298 					{
  2299 					*aErrors[uIndex] = KErrArgument;
  2300 					*aValues[uIndex] = 0;
  2301 					}
  2302 				else
  2303 					{
  2304 					*aErrors[uIndex] = KErrNone;
  2305 					*aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  2306 					}
  2307 					
  2308                 isRedefined = ETrue;
  2309                 }
  2310             }
  2311 
  2312         //At this point we found the last setting, store it's user array index in   
  2313         //the local variable, this is used later in the code. Please be noticed   
  2314         //we've also got rMaxIndex - last setting index in the repository.
  2315         if(err == KErrNone)
  2316             uLastIndex = uIndex;
  2317         else
  2318             //if we are here we did not find any other elements than was found
  2319             //in previous iteration then just stop here
  2320             return KErrNotFound;  
  2321         
  2322         //The scope of user array settings in the repository is found. 
  2323         //Let's find all other settings from user array. Bare in mind the low
  2324         //bound for the repository index is increased each iteration to optimize the
  2325         //search time.
  2326         for(uIndex = uFirstIndex + 1; uIndex < uLastIndex; uIndex ++)
  2327             {
  2328             err = this->FindSetting(*aIds[uIndex],settingRef, rIndex, 
  2329                     rMinIndex, rMaxIndex);
  2330 
  2331 			__NK_ASSERT_DEBUG(err == KErrNotFound || err == KErrNone);
  2332 
  2333             if(err == KErrNotFound)
  2334                 {
  2335                 *aErrors[uIndex] = err;
  2336                 *aValues[uIndex] = 0;
  2337                 *aTypes[uIndex] = ETypeUndefined;
  2338 
  2339                 //As FindSetting did not find the element, let's challenge with 
  2340                 //another one
  2341                 continue;
  2342                 }
  2343             else //err == KErrNone
  2344                 {
  2345 
  2346                 pSetting = (SSettingF*) settingRef.iSet;
  2347                 
  2348                 TSettingType type = static_cast<TSettingType>(settingRef.iSet->iType); 
  2349                 *aTypes[uIndex] = type; 
  2350 
  2351                 //Check for the found type is this word size? If it's not then indicate
  2352                 //error for this setting
  2353                 if(type > ETypeLinAddr)
  2354                     {
  2355                     *aErrors[uIndex] = KErrArgument;
  2356                     *aValues[uIndex] = 0;
  2357                     }
  2358                 else
  2359                     {
  2360                     *aErrors[uIndex] = KErrNone;
  2361                     *aValues[uIndex] = pSetting->iValue.iLit.iInt32;
  2362                     }
  2363 
  2364                 rMinIndex = rIndex + 1;
  2365                 }
  2366 
  2367             }
  2368 
  2369         return KErrNone;
  2370     }
  2371 
  2372 
  2373 
  2374 void HCR::TRepositoryFile::GetSettingRef(TInt32 aIndex, 
  2375          HCR::TSettingRef& aSetRef)
  2376     {
  2377     __NK_ASSERT_DEBUG(iRepos != 0);
  2378     __NK_ASSERT_DEBUG(iRepos->iHdr.iNumSettings != 0);
  2379     __NK_ASSERT_DEBUG(aIndex >= 0 && aIndex < iRepos->iHdr.iNumSettings);
  2380 
  2381     SSettingF* arr = (SSettingF*)(iRepos + 1);
  2382     
  2383     aSetRef.iRep = this;
  2384     aSetRef.iSet = &(arr[aIndex].iName);
  2385     }
  2386 
  2387 
  2388 
  2389 
  2390 TInt HCR::TRepositoryFile::FindNumSettingsInCategory(TCategoryUid aCatUid,
  2391         TInt32& aFirst, TInt32& aLast)
  2392     {
  2393     HCR_FUNC("TRepositoryFile::FindNumSettingsInCategory");
  2394 
  2395     __NK_ASSERT_DEBUG(iRepos != 0);
  2396     
  2397     if(iRepos->iHdr.iNumSettings == 0)
  2398         {
  2399         aFirst = 0;
  2400         aLast = 0;
  2401         HCR_TRACE_RETURN(KErrNotFound);
  2402         }
  2403     
  2404     SSettingF* arr = (SSettingF*) (iRepos+1);
  2405     TInt32 low = 0;
  2406     TInt32 high = iRepos->iHdr.iNumSettings-1;
  2407     TInt32 mid = 0;
  2408     TInt32 com = 0;
  2409 
  2410 
  2411     //Let's find any setting within the category, mid will store the setting 
  2412     //index in the repository
  2413     while (low<=high)
  2414         {
  2415         mid = (low+high) >> 1;
  2416         com = CompareByCategory(aCatUid, arr[mid].iName.iId);
  2417         if (com < 0)
  2418             high = mid-1;
  2419         else if (com > 0)
  2420             low = mid+1;
  2421         else
  2422             {
  2423             break;
  2424             }    
  2425         } 
  2426 
  2427     // If no one setting with the given category was found the return error  
  2428     // to the user
  2429     if(low > high)
  2430         {
  2431         aFirst = 0;
  2432         aLast  = 0;
  2433         return KErrNotFound;
  2434         }
  2435 
  2436     //Search the first element within the category
  2437     low = mid;
  2438     while(low >= 0 && arr[low].iName.iId.iCat == aCatUid)
  2439         {
  2440         if(low > 0)
  2441             low --;
  2442         else
  2443             break;
  2444         }
  2445 
  2446     //Check the boundary conditions, there are two cases when we exit the loop
  2447     //either we found an element which category is not one we are looking for or
  2448     //we reach the beggining of the repository. If we reach the beggining of the
  2449     //repository we don't really know is it because this is last elment or it
  2450     //has required aCatUid, so we check these two conditions below
  2451     if(arr[low].iName.iId.iCat == aCatUid)
  2452         aFirst = low;
  2453         
  2454     //We finish the loop either reaching the setting which category id is not
  2455     //what we need or this is first setting in the repository again with another
  2456     //category, so in both case we throw this element from the account.
  2457     else
  2458         aFirst = low + 1;
  2459 
  2460 
  2461     //Search the last element within the category
  2462     high = mid;
  2463     while(high <= iRepos->iHdr.iNumSettings - 1 && arr[high].iName.iId.iCat == aCatUid)
  2464         {
  2465         if(high < iRepos->iHdr.iNumSettings - 1)
  2466             high ++;
  2467         else
  2468             break;
  2469         }
  2470 
  2471     //Same situation as above, boundary conditions
  2472     if(arr[high].iName.iId.iCat == aCatUid)
  2473         aLast = high;
  2474     else
  2475         aLast = high - 1;
  2476 
  2477     return KErrNone;
  2478     }
  2479 
  2480 
  2481 
  2482 
  2483 TInt HCR::TRepositoryFile::GetValue(const TSettingRef& aRef, UValueWord& aValue)
  2484     {
  2485     HCR_FUNC("TRepositoryFile::GetValue");
  2486 
  2487     if (!IsWordValue(aRef))
  2488         HCR_TRACE_RETURN(KErrArgument);
  2489         
  2490 	SSettingF* sptr = (SSettingF*)(aRef.iSet);
  2491     aValue = sptr->iValue.iLit;
  2492 	return KErrNone;
  2493     }
  2494 
  2495 
  2496 TInt HCR::TRepositoryFile::GetLargeValue(const TSettingRef& aRef, UValueLarge& aValue)
  2497     {
  2498     HCR_FUNC("TRepositoryFile::GetLargeValue");
  2499 
  2500     if (!IsLargeValue(aRef))
  2501         HCR_TRACE_RETURN(KErrArgument);
  2502 
  2503 	SSettingF* sptr = (SSettingF*)(aRef.iSet);
  2504 	TRepositoryFile *rptr = (TRepositoryFile *)(aRef.iRep);
  2505 	
  2506     aValue.iData = (TUint8*) rptr->iRepos;
  2507 	aValue.iData += rptr->iRepos->iLSDfirstByteOffset+sptr->iValue.iOffset;
  2508 	
  2509     return KErrNone;
  2510     }
  2511 
  2512 
  2513 // -- FUNCTIONS ---------------------------------------------------------------
  2514 
  2515 #ifndef HCRTEST_NO_KEXT_ENTRY_POINT
  2516 #ifndef __WINS__
  2517 DECLARE_EXTENSION_WITH_PRIORITY(KExtensionMaximumPriority)
  2518 #else
  2519 DECLARE_STANDARD_EXTENSION()
  2520 #endif // __WINS__
  2521 	{
  2522 	HCR_FUNC("InitExtension");
  2523 
  2524 	HCR::MVariant* varPtr = CreateHCRVariant();
  2525 	if (varPtr==0)
  2526 		HCR_TRACE_RETURN(KErrNoMemory);
  2527 
  2528 	//Call of the "placement" new operator, which constructs the HCR object on 
  2529 	//the global memory address defined by gHCR and initialized with the same
  2530 	//data given by constructor below
  2531 	new(&gHCR) HCR::HCRInternal(varPtr);
  2532 
  2533 	TInt err = HCRSingleton->Initialise();
  2534 
  2535 	if (err != KErrNone)
  2536 		HCR_TRACE_RETURN(err);
  2537 
  2538 	return err;
  2539 	}
  2540 #endif // HCRTEST_NO_KEXT_ENTRY_POINT
  2541 
  2542 // -- Implementation of local functions
  2543 #ifndef __WINS__
  2544 TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry)
  2545 	{
  2546 	HCR_FUNC("SearchEntryInTRomDir");
  2547 	TInt retVal = KErrNotFound;
  2548 	HCR_TRACE2("--- aFileName: %S (%d)", &aFileName, aFileName.Length());
  2549 	
  2550 	if( aActDir == 0)
  2551 		{
  2552 		HCR_TRACE_RETURN(retVal);
  2553 		}
  2554 	
  2555 	TInt dirSize = aActDir->iSize;
  2556 	aEntry = (TRomEntry*)&aActDir->iEntry;
  2557 	HCR_TRACE3("--- dirSize: 0x%08x (%d), aEntry: 0x%08x", dirSize, dirSize, aEntry);
  2558 	
  2559 	TBool found = EFalse;
  2560 	while( !found )
  2561 		{
  2562 		TInt nameLength = (aEntry->iNameLength)<<1;
  2563 		
  2564 		// Uncommnet to get dump of ROM data when debugging....
  2565 		// HCR_TRACE0("Begin of loop...");
  2566 		// HCR_HEX_DUMP_ABS((TUint8 *)aEntry, sizeof(TRomEntry)+(nameLength - 2) );
  2567 		const TText* entryName = &aEntry->iName[0];
  2568 		HCR_TRACE1("--- entryName length: %d", nameLength);
  2569 		TBuf<512> newEntryName( nameLength);
  2570 		for( TInt i = 0; i != nameLength; ++i)
  2571 			{
  2572 			newEntryName[i] = (unsigned char)('A' <= entryName[i] && 'Z' >= entryName[i]? entryName[i]+('a'-'A'): entryName[i]);
  2573 			}		
  2574 				
  2575 		HCR_TRACE6("--- aFileName: %S (%d/%d), newEntryName: %S (%d/%d)", &aFileName, aFileName.Length(), aFileName.Size(), &newEntryName, newEntryName.Length(), newEntryName.Size());
  2576 		TInt r = aFileName.Compare(newEntryName);
  2577 		HCR_TRACE1("--- result of CompareFileNames: 0x%08x", r);
  2578 		
  2579 		if ( r == 0)
  2580 			{
  2581 			found = ETrue;
  2582 			HCR_TRACE1("--- aEntry: 0x%08x", aEntry);
  2583 			}
  2584 		else
  2585 			{
  2586 		
  2587 			TInt entrySize = sizeof(TRomEntry) + (nameLength - 2);
  2588 			HCR_TRACE2("--- entrySize: 0x%08x, (%d)", entrySize, entrySize);
  2589 			
  2590 			// The entrySize must be aligned to 4 bytes boundary
  2591 			entrySize = ((entrySize&0x03) == 0 ? entrySize : ((entrySize&0xfffffffc) + 4));
  2592 			HCR_TRACE2("--- entrySize: 0x%08x, (%d)", entrySize, entrySize);
  2593 			
  2594 			aEntry = (TRomEntry*)((char *)aEntry + entrySize);
  2595 			dirSize -= entrySize;
  2596 			HCR_TRACE2("--- aEntry: 0x%08x, dirSize:%d", aEntry, dirSize);
  2597 			if( dirSize <= 0)
  2598 				{
  2599 				break;
  2600 				}
  2601 			}
  2602 		}
  2603 		
  2604 	if( found)
  2605 		{
  2606 		retVal = KErrNone;
  2607 		}
  2608 		
  2609 	HCR_TRACE_RETURN(retVal);		
  2610 	}
  2611 	
  2612 #endif // !__WINS__
  2613 
  2614 
  2615 TInt SearchCoreImgRepository(HCR::TRepository*& aRepos, const TText * aFileName)
  2616     {
  2617     HCR_FUNC("SearchCoreImgRepository(TRepository*& aRepos, TText & aFileName)");
  2618     
  2619     TInt retVal = KErrNotFound;
  2620 
  2621 	// Convert aFileName to directory entry style Unicode 
  2622 	const TText* p = aFileName;
  2623 	
  2624 	if( *p == 0)
  2625 		{
  2626 		// Empty file name -> return with KErrNotFound!
  2627 		HCR_TRACE_RETURN(retVal);
  2628 		}
  2629 		
  2630 	while( *(++p)) {};					// Search the end of file name string.
  2631 	TInt nameLen=(TInt)(p-aFileName);	
  2632 	
  2633 	HCR_TRACE2("--- aFileName: %s (%d)", aFileName, nameLen );
  2634 	
  2635 	TBuf<256> origFileName;
  2636 	origFileName.Append((const TText*)aFileName, nameLen);
  2637 	HCR_TRACE2("--- origFileName: %S (%d)", &origFileName, origFileName.Length());
  2638 	
  2639 
  2640 #ifdef __WINS__
  2641     TBuf<KMaxFileName> wholeFilePath; 
  2642 	void* reposBuf = 0;
  2643     
  2644 #ifdef __VC32__
  2645 	
  2646 #ifdef _DEBUG
  2647 	// - wins udeb version
  2648     wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UDEB\\");
  2649 #else
  2650     // - wins urel version
  2651     wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UREL\\");
  2652 #endif
  2653 
  2654 #else
  2655 
  2656 #ifdef _DEBUG
  2657     // - winscw udeb version
  2658     wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UDEB\\");
  2659 #else
  2660     // - winscw urel version
  2661     wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UREL\\");
  2662 #endif
  2663     
  2664 #endif    
  2665     
  2666     for( TInt j = 0; j < nameLen; ++j)
  2667           {
  2668           wholeFilePath.Append( origFileName[j] );
  2669           }
  2670     
  2671     HCR_TRACE3("--- epoc emulator file path: %S (%d/%d)", &wholeFilePath, wholeFilePath.Length(), wholeFilePath.Size());
  2672     
  2673     TInt length = wholeFilePath.Length();
  2674     
  2675     NKern::ThreadEnterCS();
  2676     TCHAR* chFilePath = new TCHAR[length+1];
  2677     NKern::ThreadLeaveCS();
  2678     
  2679     for(int loop=0;loop<length;++loop) 
  2680         {
  2681         chFilePath[loop] = wholeFilePath[loop];
  2682         }
  2683     chFilePath[length] = '\0';
  2684     
  2685     //try to locate file
  2686     WIN32_FIND_DATAW wfd;
  2687     HANDLE hFile = FindFirstFile(chFilePath, &wfd);
  2688     TBool foundFile = EFalse;
  2689     if (hFile == INVALID_HANDLE_VALUE)
  2690         {
  2691         HCR_TRACE0("--- file not found in \\sys\\bin; try \\sys\\data");
  2692         
  2693 #ifdef __VC32__
  2694     
  2695 #ifdef _DEBUG
  2696         // - wins udeb version
  2697         wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UDEB\\Z\\sys\\data\\");
  2698 #else
  2699         // - wins urel version
  2700         wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UREL\\Z\\sys\\data\\");
  2701 #endif
  2702 
  2703 #else
  2704 
  2705 #ifdef _DEBUG
  2706         // - winscw udeb version
  2707         wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UDEB\\Z\\sys\\data\\");
  2708 #else
  2709         // - winscw urel version
  2710         wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UREL\\Z\\sys\\data\\");
  2711 #endif
  2712     
  2713 #endif  
  2714         
  2715         for( TInt i = 0; i < nameLen; ++i)
  2716             {
  2717             wholeFilePath.Append( origFileName[i] );
  2718             }
  2719             
  2720         HCR_TRACE3("--- epoc emulator file path: %S (%d/%d)", &wholeFilePath, wholeFilePath.Length(), wholeFilePath.Size());
  2721             
  2722         length = wholeFilePath.Length();
  2723         
  2724         NKern::ThreadEnterCS();
  2725         delete[] chFilePath;
  2726         chFilePath = new TCHAR[length+1];
  2727         NKern::ThreadLeaveCS();
  2728         
  2729         for(int loop=0;loop<length;++loop) 
  2730             {
  2731             chFilePath[loop] = wholeFilePath[loop];
  2732             }
  2733         chFilePath[length] = '\0';
  2734         
  2735         hFile = FindFirstFile(chFilePath, &wfd);
  2736         
  2737         if (hFile == INVALID_HANDLE_VALUE)
  2738             {
  2739             HCR_TRACE0("--- file not found in \\sys\\data");
  2740             }
  2741         else
  2742             {
  2743             HCR_TRACE0("--- file found in \\sys\\data");
  2744             foundFile = ETrue;        
  2745             }
  2746         }
  2747     else
  2748         {
  2749         HCR_TRACE0("--- file found in \\sys\\bin");
  2750         foundFile = ETrue;
  2751         }
  2752     
  2753     if(!foundFile)
  2754         {
  2755         // No file found; release memory and return
  2756         NKern::ThreadEnterCS();
  2757         delete[] chFilePath;
  2758         NKern::ThreadLeaveCS();
  2759         
  2760         HCR_TRACE_RETURN(KErrNotFound);
  2761         }
  2762         
  2763 
  2764     __NK_ASSERT_ALWAYS(wfd.nFileSizeHigh==0);
  2765             
  2766     DWORD num_read = 0;    
  2767     retVal = KErrNone;
  2768     
  2769     NKern::ThreadEnterCS();
  2770     reposBuf = new BYTE[wfd.nFileSizeLow];
  2771     NKern::ThreadLeaveCS();
  2772     
  2773     if(reposBuf == NULL)
  2774 		{
  2775         HCR_TRACEMSG_RETURN("--- Error allocating memory for reading file", KErrNoMemory);
  2776 		}
  2777     else
  2778         {
  2779         hFile = CreateFile(chFilePath, GENERIC_READ,          // open for reading
  2780                 FILE_SHARE_READ,       // share for reading
  2781                 NULL,                  // default security
  2782                 OPEN_EXISTING,         // existing file only
  2783                 FILE_ATTRIBUTE_NORMAL, // normal file
  2784                 NULL); 
  2785         
  2786         BOOL read = ReadFile(hFile, reposBuf, wfd.nFileSizeLow, &num_read, NULL);
  2787         if(!read) 
  2788             {
  2789             retVal = GetLastError();  
  2790             HCR_TRACE1("--- Error reading file %d", GetLastError());
  2791             }
  2792         }
  2793 
  2794     CloseHandle(hFile);
  2795     NKern::ThreadEnterCS();
  2796     delete[] chFilePath;
  2797     NKern::ThreadLeaveCS();
  2798     
  2799     NKern::ThreadEnterCS();
  2800     aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(reposBuf)); 
  2801     NKern::ThreadLeaveCS();
  2802     
  2803     if (aRepos == NULL)
  2804         {
  2805         retVal = KErrNoMemory;
  2806         }
  2807     
  2808     HCR_TRACE_RETURN(retVal);
  2809     
  2810 #else
  2811 	
  2812 	TBuf<512> fileNameBuf;
  2813 	for( TInt i = 0; i != nameLen; ++i)
  2814 		{
  2815 		fileNameBuf.Append( 'A' <= origFileName[i] && 'Z' >= origFileName[i]? origFileName[i]+('a'-'A'): origFileName[i]);
  2816 		fileNameBuf.Append(TChar(0));
  2817 		}
  2818 
  2819 	TPtrC fileName(fileNameBuf);
  2820 	HCR_TRACE3("--- fileName: %S (%d/%d)", &fileName, fileName.Length(), fileName.Size());
  2821 
  2822     // Locate ROM Root directory
  2823     TSuperPage& superpage = Kern::SuperPage();
  2824    	TRomRootDirectoryList* romRootDirAddress = (TRomRootDirectoryList*)superpage.iRootDirList;
  2825  
  2826     HCR_TRACE3("--- Superpage: 0x%08x, ROM root dir list: 0x%08x (Num of root dirs:%d)", &superpage, romRootDirAddress, romRootDirAddress->iNumRootDirs );
  2827 
  2828 	// Search the root directory which is match to the current hardware variant
  2829     TUint hardwareVariant 	   = superpage.iActiveVariant;
  2830     TInt variantIndex;
  2831     TRootDirInfo* rootDirInfo = 0;
  2832     
  2833     for(variantIndex = 0; variantIndex < romRootDirAddress->iNumRootDirs; ++variantIndex )
  2834 	    {
  2835 	    HCR_TRACE3("--- variantIndex:%d, current hardware variant: 0x%08x, root dir hardware variant:0x%08x", variantIndex, hardwareVariant, romRootDirAddress->iRootDir[variantIndex].iHardwareVariant);
  2836 	    
  2837     	if( romRootDirAddress->iRootDir[variantIndex].iHardwareVariant == hardwareVariant)
  2838 	    	{
  2839 	    	rootDirInfo = &romRootDirAddress->iRootDir[variantIndex]; 
  2840 	    	break;
  2841 	    	}
  2842 	    }
  2843     
  2844     if( rootDirInfo == 0 )
  2845 	    {
  2846 	    // Not found root directory for this hardware variant
  2847 	    HCR_TRACE_RETURN(retVal);
  2848 	    }
  2849     
  2850 	TRomDir* romDir = (TRomDir*)rootDirInfo->iAddressLin;
  2851 
  2852 	HCR_TRACE3("--- romDir: 0x%08x (files:0x%08x, entries:0x%08x)", romDir, romDir->FileCount(), romDir->EntryCount() );
  2853 	TRomEntry* entry = (TRomEntry*)&romDir->iEntry;
  2854 	
  2855 	// We are searching in \sys\bin\ and \sys\Data\ directory only	
  2856 	TPtrC level1DirName((const TText*)"s\0y\0s\0", 6);		// Unicode, because the entry names are unicode too.
  2857 	TPtrC level2Dir1Name((const TText*)"b\0i\0n\0", 6);
  2858 	TPtrC level2Dir2Name((const TText*)"d\0a\0t\0a\0", 8);		// Originally \sys\Data however we search all entry in lower case
  2859 	
  2860 	TInt r = SearchEntryInTRomDir(romDir, level1DirName, entry);
  2861 	HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
  2862 
  2863 	if( r == KErrNone)
  2864 		{
  2865 		// \sys directory found.
  2866 		romDir = (TRomDir*)entry->iAddressLin;
  2867 		HCR_TRACE1("--- romDir: 0x%08x ", romDir);
  2868 		
  2869 		TRomDir* parentDir = romDir;
  2870 		// Search in \sys\bin directory
  2871 		r = SearchEntryInTRomDir(romDir, level2Dir1Name, entry);
  2872 	
  2873 		HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
  2874 		if( r == KErrNone)
  2875 			{
  2876 			// \sys\bin directory found
  2877 			romDir = (TRomDir*)entry->iAddressLin;
  2878 			HCR_TRACE1("--- romDir: 0x%08x ", romDir);
  2879 			// Search the repository file
  2880 			r = SearchEntryInTRomDir(romDir, fileName, entry);
  2881 			
  2882 			HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
  2883 			if( r == KErrNone)
  2884 				{
  2885 				// Repository file found
  2886 				retVal = KErrNone;				
  2887 				HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin);
  2888 #ifdef __EPOC32__
  2889 			// HCR design requires the core image file repository to be in the
  2890 			// unpaged portion of the core ROM image. This check will Fault the
  2891 			// kernel startup if this is not found to be the case, perhaps due 
  2892 			// to mis-configured obey files.
  2893 			// Skipped on emulator builds as Epoc class in platform.h not
  2894 			// defined. Hence support for core images not supported. 
  2895 			__NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)entry->iAddressLin));   
  2896 #endif
  2897 				NKern::ThreadEnterCS();
  2898 				aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(entry->iAddressLin));	
  2899 				NKern::ThreadLeaveCS();
  2900 				if (aRepos == NULL)
  2901                         retVal = KErrNoMemory;					
  2902                         
  2903                 HCR_TRACE_RETURN(retVal);
  2904 				}
  2905 			}
  2906 
  2907 		// \sys\bin directory or repository file in \sys\bin directory not found.    
  2908 		// Search \sys\Data directory
  2909 		romDir = parentDir;
  2910 		r = SearchEntryInTRomDir(romDir, level2Dir2Name, entry);
  2911 		HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
  2912 		if( r == KErrNone)
  2913 			{
  2914 			// \sys\Data directory found
  2915 			romDir = (TRomDir*)entry->iAddressLin;
  2916 			HCR_TRACE1("--- romDir: 0x%08x ", romDir);
  2917 			
  2918 			// Search repository file
  2919 			r = SearchEntryInTRomDir(romDir, fileName, entry);
  2920 			
  2921 			HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
  2922 			if( r == KErrNone)
  2923 				{
  2924 				// Repository file found    
  2925 				retVal = KErrNone;				
  2926 				HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin);
  2927 #ifdef __EPOC32__
  2928 			// HCR design requires the core image file repository to be in the
  2929 			// unpaged portion of the core ROM image. This check will Fault the
  2930 			// kernel startup if this is not found to be the case, perhaps due 
  2931 			// to mis-configured obey files.
  2932 			// Skipped on emulator builds as Epoc class in platform.h not
  2933 			// defined. Hence support for core images not supported. 
  2934 			__NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)entry->iAddressLin));   
  2935 #endif
  2936 				NKern::ThreadEnterCS();
  2937 				aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(entry->iAddressLin));
  2938 				NKern::ThreadLeaveCS();
  2939 				if (aRepos == NULL)
  2940                     retVal = KErrNoMemory;					
  2941 				}
  2942 			}
  2943 		}
  2944 	
  2945     HCR_TRACE_RETURN(retVal);
  2946 #endif //ifdef __WINS__
  2947     }
  2948 
  2949 TInt LocateCoreImgRepository(HCR::TRepository*& aRepos)
  2950     {
  2951     HCR_FUNC("LocateCoreImgRepository");
  2952 
  2953 #ifdef HCRTEST_COREIMG_DONTUSE_ROMHDR
  2954     
  2955     // Use this testing more on Emulator platform
  2956     // and on hardware when ROM Header is not to be used or not implemented
  2957     
  2958 	const TText8* hcrfile = (const TText8*) "hcr.dat";
  2959 	TInt retVal = SearchCoreImgRepository(aRepos, hcrfile);
  2960 	if (retVal != KErrNone)
  2961 		return retVal;
  2962 	
  2963 #else
  2964 
  2965 	const TRomHeader& romHeader = Epoc::RomHeader(); 	// 0x80000000;
  2966 	HCR_TRACE2("--- ROM Header: 0x%08x, HCR file address: 0x%08x", &romHeader, romHeader.iHcrFileAddress);
  2967 	
  2968 	if(romHeader.iHcrFileAddress != 0)
  2969 			{
  2970 #ifdef __EPOC32__
  2971 			// HCR design requires the core image file repository to be in the
  2972 			// unpaged portion of the core ROM image. This check will Fault the
  2973 			// kernel startup if this is not found to be the case, perhaps due 
  2974 			// to mis-configured obey files.
  2975 			// Skipped on emulator builds as Epoc class in platform.h not
  2976 			// defined. Hence support for core images not supported. 
  2977 			__NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)romHeader.iHcrFileAddress));   
  2978 #endif
  2979 			NKern::ThreadEnterCS();
  2980 			aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(romHeader.iHcrFileAddress));
  2981 			NKern::ThreadLeaveCS();
  2982 			if (aRepos == 0)
  2983 				return KErrNoMemory;
  2984 			}
  2985 	else
  2986 		return KErrNotFound;
  2987 		
  2988 #endif // HCRTEST_COREIMG_DONTUSE_ROMHDR
  2989 
  2990 
  2991 	return KErrNone;
  2992     }
  2993