kernel/eka/drivers/hcr/hcr_pil.cpp
changeset 0 a41df078684a
child 4 56f325a607ea
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 <nkern/nkern.h>
       
    27 #include <kernel/kernel.h>
       
    28 
       
    29 #include <e32rom.h>
       
    30 #include <plat_priv.h>
       
    31 
       
    32 #include <kernel/kernboot.h>
       
    33 
       
    34 
       
    35 #include "hcr_hai.h"
       
    36 #include "hcr_pil.h"
       
    37 
       
    38 
       
    39 // -- GLOBALS -----------------------------------------------------------------
       
    40 
       
    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     
       
    58 @return	KErrNone 		if successful, the aRepos parameter references to the file in ROM Image.
       
    59         KErrNotFound 	if the ROM Image header contains zero or a special value as the repository file address
       
    60 
       
    61 
       
    62 */    
       
    63 LOCAL_C TInt LocateCoreImgRepository(HCR::TRepository*& aRepos);
       
    64 
       
    65 /**
       
    66 This method transfer the value of aFileName to ROM Image conform file name string. 
       
    67 Retrive the variant dependent ROM Root directory address.
       
    68 Search the file in \sys\bin directory and if it doesn't exists there it try to find it in \sys\Data.
       
    69 
       
    70 
       
    71 @param 	aRepos     			The reference to a repository variable.
       
    72 				aFileName			  The name of the new repository file without path. '\0' terminated c-style string.
       
    73     
       
    74 @return	KErrNone 			if successful
       
    75         KErrNotFound 		if file not found in \sys\bin or \sys\Data
       
    76 
       
    77 
       
    78 */    
       
    79 LOCAL_C TInt SearchCoreImgRepository(HCR::TRepository* & aRepos, const TText * aFileName);
       
    80 
       
    81 /**
       
    82 Scanning a given directory for the given entry name. The entry name can be sub-directory or file.
       
    83 
       
    84 @param 	aActDir     		Pointer to curretn directory in the ROM Image directory tree
       
    85 		aFileName			File to be search
       
    86 		aEntry				If the file found this referenced to proper directory entry
       
    87     
       
    88 @return	 KErrNone		 			if the entry found
       
    89          KErrNotFound					if the entry not found
       
    90 */    
       
    91 
       
    92 LOCAL_C TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry);
       
    93 
       
    94 
       
    95 
       
    96 // -- FUNCTIONS ---------------------------------------------------------------
       
    97 
       
    98 /**
       
    99  Returns 1 when a1 > a2
       
   100  Returns -1 when a1 < a2
       
   101  Returns 0 when identical.
       
   102  */
       
   103 TInt CompareSSettingIds(const HCR::TSettingId& a1, const HCR::SSettingId& a2)    
       
   104 {
       
   105     // HCR_FUNC("CompareSSettingIds");
       
   106     if (a1.iCat > a2.iCat)
       
   107         return (1); // HCR_TRACE_RETURN(1);
       
   108     if (a1.iCat < a2.iCat)
       
   109         return (-1); // HCR_TRACE_RETURN(-1);
       
   110     
       
   111     // Categories are the same at this point, check keys.
       
   112     if (a1.iKey > a2.iKey)
       
   113         return (1); // HCR_TRACE_RETURN(1);
       
   114     if (a1.iKey < a2.iKey)
       
   115         return (-1); // HCR_TRACE_RETURN(-1);
       
   116    
       
   117     // Both Categories and jeys are the same here.
       
   118     return (0); // HCR_TRACE_RETURN(0);
       
   119     }
       
   120 
       
   121 
       
   122 // -- METHODS -----------------------------------------------------------------
       
   123 //
       
   124 // HCRInternal
       
   125 
       
   126 HCR::HCRInternal::HCRInternal()
       
   127    : iStatus(EStatConstructed), iVariant(0), iVariantStore(0), iCoreImgStore(0), iOverrideStore(0)
       
   128     {
       
   129     HCR_FUNC("HCRInternal(Defualt)");
       
   130     }
       
   131 
       
   132 HCR::HCRInternal::HCRInternal(HCR::MVariant* aVar)
       
   133    : iVariant(aVar), iVariantStore(0), iCoreImgStore(0), iOverrideStore(0)
       
   134     {
       
   135     HCR_FUNC("HCRInternal");
       
   136     }
       
   137     
       
   138 HCR::HCRInternal::~HCRInternal()
       
   139     {
       
   140     HCR_FUNC("~HCRInternal");
       
   141     }
       
   142    
       
   143 TUint32 HCR::HCRInternal::GetStatus()
       
   144     {
       
   145     HCR_FUNC("GetStatus");
       
   146     return iStatus;
       
   147     }
       
   148   
       
   149     
       
   150 TInt HCR::HCRInternal::Initialise()
       
   151     {
       
   152     HCR_FUNC("HCRInternal::Initialise");
       
   153     
       
   154     TAny* store = 0; 
       
   155     TInt err = 0;
       
   156 	
       
   157 	// Variant PSL object must exist before PIL initalised.
       
   158 	if (iVariant == 0) {
       
   159  			err = KErrGeneral; goto failed; }
       
   160 
       
   161 	// Inform the PSL that we are initialising, give them an opportunity to do
       
   162 	// initialisation work too.
       
   163     err = iVariant->Initialise(); 
       
   164     if (err != KErrNone)
       
   165     	goto failed;
       
   166    
       
   167     iStatus = EStatVariantInitialised;
       
   168     
       
   169     // Ask the PSL for the address of the SRepositoryCompiled object. PSL 
       
   170     // can return KErrNotSupported & NULL if compiled repository not 
       
   171 	// used/support by PSL.
       
   172     err = iVariant->GetCompiledRepositoryAddress(store);
       
   173     if (err == KErrNone)
       
   174         {
       
   175         if (store == 0) { // Programming error in PSL, ptr/rc mismatch
       
   176  			err = KErrArgument; goto failed; }
       
   177         	
       
   178         iVariantStore = TRepositoryCompiled::New(reinterpret_cast<const HCR::SRepositoryCompiled *>(store));
       
   179         if (iVariantStore == 0) { 
       
   180 			err = KErrNoMemory; goto failed; }
       
   181 
       
   182         }
       
   183     else if (err != KErrNotSupported)
       
   184     	goto failed;       
       
   185   
       
   186         
       
   187     // Ask the PSL if it wants the PIL not to search for the Core Image 
       
   188 	// SRepositoryFile settings.
       
   189     iCoreImgStore = 0;
       
   190     if (!iVariant->IgnoreCoreImgRepository())
       
   191     	{
       
   192     	err = LocateCoreImgRepository(iCoreImgStore);
       
   193     	if (err == KErrNone)
       
   194      	   {
       
   195         	if (iCoreImgStore == 0) {
       
   196 				err = KErrNoMemory; goto failed; }
       
   197         	}
       
   198     	else if (err != KErrNotFound)
       
   199     		goto failed;
       
   200 		}       
       
   201   
       
   202         
       
   203     // Ask the PSL for the address of the SRepositoryFile object. PSL 
       
   204     // can return KErrNotSupported & NULL if a local media based file 
       
   205 	// repository is not used/support by PSL.  
       
   206     store = 0;
       
   207     err = iVariant->GetOverrideRepositoryAddress(store);
       
   208     if (err == KErrNone)
       
   209         {
       
   210         if (store == 0) { // Programming error in PSL, ptr/rc mismatch
       
   211  			err = KErrArgument; goto failed; }       
       
   212         
       
   213         iOverrideStore = TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(store));
       
   214         if (iOverrideStore == 0) {
       
   215 			err = KErrNoMemory; goto failed; }
       
   216 			
       
   217         }
       
   218     else if (err != KErrNotSupported)
       
   219     	goto failed;       
       
   220 
       
   221 	iStatus = EStatInitialised;
       
   222 	
       
   223     // Sanity check here to ensure we have atleast one repository to use and run
       
   224     // sanity check on their contents to look for ordering issues and duplicates.
       
   225 	HCR_TRACE3("=== HCR Ready: compiled:%x, coreimg:%x, override:%x", iVariantStore, iCoreImgStore, iOverrideStore);
       
   226     if ((iVariantStore == 0) && (iCoreImgStore == 0) && (iOverrideStore == 0)) {
       
   227  		err = KErrArgument; goto failed; }
       
   228 
       
   229 
       
   230 #ifdef _DEBUG
       
   231 	err = CheckIntegrity();
       
   232 	if (err != KErrNone)
       
   233 		goto failed;	
       
   234 #endif
       
   235 
       
   236 	iStatus = EStatReady;
       
   237 	return KErrNone;
       
   238 
       
   239 failed:
       
   240     iStatus = (iStatus & EStatMinorMask) | EStatFailed;
       
   241 	HCR_LOG_RETURN(err);
       
   242     }
       
   243 
       
   244 
       
   245 TInt HCR::HCRInternal::SwitchRepository(const TText * aFileName, const TReposId aId)
       
   246 	{
       
   247 	HCR_FUNC("HCRInternal::SwitchRepository");
       
   248 	
       
   249 	TInt retVal = KErrNone;
       
   250 	TRepository* store = NULL;
       
   251 
       
   252 	if( aFileName != NULL)
       
   253 		{
       
   254 		retVal = SearchCoreImgRepository(store, aFileName);
       
   255 		HCR_TRACE2("--- SearchCoreImgRepository()->%d (0x%08x)", retVal, retVal);
       
   256 		}
       
   257 		
       
   258 	if( retVal == KErrNone )
       
   259 		{
       
   260 		switch(aId)
       
   261 			{
       
   262 			case ECoreRepos:
       
   263 			    HCR_TRACE0("--- ECoreRepos");
       
   264 				if( iCoreImgStore )
       
   265 					{
       
   266 					delete iCoreImgStore;
       
   267 					}
       
   268 				iCoreImgStore = store;
       
   269 				break;
       
   270 				
       
   271 			case EOverrideRepos:
       
   272 			    HCR_TRACE0("--- EOverrideRepos");
       
   273 				if( iCoreImgStore )
       
   274     				{
       
   275 					delete iOverrideStore;
       
   276 					}
       
   277 				iOverrideStore = store;
       
   278 				break;
       
   279 		
       
   280 			default:
       
   281 			    HCR_TRACE0("--- default:");
       
   282 				retVal = KErrNotSupported;
       
   283 				break;		
       
   284 			}
       
   285 		}
       
   286 
       
   287 	HCR_LOG_RETURN(retVal);
       
   288     }
       
   289 
       
   290 TInt HCR::HCRInternal::CheckIntegrity()
       
   291 	{
       
   292 	HCR_FUNC("HCRInternal::CheckIntegrity");
       
   293 	
       
   294 	TInt err = KErrNone;
       
   295 	if (iVariantStore)
       
   296 		{
       
   297 		err = iVariantStore->CheckIntegrity();
       
   298 		if (err != KErrNone)
       
   299 			HCR_LOGMSG_RETURN("HCR iVariantStore failed integrity check", err);
       
   300 		}
       
   301 
       
   302 	if (iCoreImgStore)
       
   303 		{
       
   304 		err = iCoreImgStore->CheckIntegrity();
       
   305 		if (err != KErrNone)
       
   306 			HCR_LOGMSG_RETURN("HCR iCoreImgStore failed integrity check", err);
       
   307 		}	
       
   308 	
       
   309 	if (iOverrideStore)
       
   310 		{
       
   311 		err = iOverrideStore->CheckIntegrity();
       
   312 		if (err != KErrNone)
       
   313 			HCR_LOGMSG_RETURN("HCR iOverrideStore failed integrity check", err);
       
   314 		}
       
   315 
       
   316 	HCR_TRACE0("=== HCR Repository integrity checks PASSED!");
       
   317 	return KErrNone;	
       
   318 	}
       
   319 
       
   320 TInt HCR::HCRInternal::FindSetting(const TSettingId& aId, TSettingType aType, TSettingRef& aSetting)
       
   321     {
       
   322     HCR_FUNC("HCRInternal::FindSetting");
       
   323     TInt err = 0;
       
   324     TBool found = EFalse;
       
   325     
       
   326     HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore);
       
   327     
       
   328     if (iOverrideStore && 
       
   329         ((err = iOverrideStore->FindSetting(aId, aSetting)) == KErrNone))
       
   330         found = ETrue;
       
   331     if ((err != KErrNone) && (err != KErrNotFound))
       
   332         HCR_LOG_RETURN(err);
       
   333         
       
   334     if (!found &&
       
   335         iCoreImgStore &&
       
   336         ((err = iCoreImgStore->FindSetting(aId, aSetting)) == KErrNone))
       
   337         found = ETrue;
       
   338     if ((err != KErrNone) && (err != KErrNotFound))
       
   339         HCR_LOG_RETURN(err);
       
   340 
       
   341     if (!found &&
       
   342         iVariantStore &&
       
   343         ((err = iVariantStore->FindSetting(aId, aSetting)) == KErrNone))
       
   344         found = ETrue;
       
   345         
       
   346     if ((err != KErrNone) && (err != KErrNotFound))
       
   347         HCR_LOG_RETURN(err);
       
   348 
       
   349     HCR_TRACE3("--- Search results: %d, %d, %x", found, err, aSetting.iSet);
       
   350     
       
   351     if (!found || (aSetting.iSet == 0))
       
   352         HCR_LOG_RETURN(KErrNotFound);
       
   353 
       
   354     // Setting found at this point in the function
       
   355     //
       
   356     
       
   357     TSettingType type=static_cast<TSettingType>(aSetting.iRep->GetType(aSetting)); 
       
   358     if (type & ~aType)
       
   359         HCR_LOG_RETURN(KErrArgument); // Wrong setting type
       
   360     
       
   361     HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, type);
       
   362     
       
   363     return KErrNone;
       
   364     }
       
   365     
       
   366 TInt HCR::HCRInternal::FindWordSettings(TInt /*aNum*/, const TSettingId* /*aIds*/, 
       
   367                         TInt32* /*aValues*/, TSettingType* /*aTypes*/, TInt* /*aErrors*/)
       
   368     {
       
   369     HCR_FUNC("HCRInternal::FindWordSettings");
       
   370 
       
   371     return KErrNotSupported;
       
   372     }
       
   373 
       
   374 
       
   375 
       
   376 // -- METHODS -----------------------------------------------------------------
       
   377 //
       
   378 // TRepository
       
   379 
       
   380 
       
   381 TBool HCR::TRepository::IsWordValue(const TSettingRef& aRef)
       
   382     {
       
   383     HCR_FUNC("TRepository::IsWordValue");
       
   384     return ((aRef.iSet->iType & KMaskWordTypes) != 0);
       
   385     }
       
   386 
       
   387 TBool HCR::TRepository::IsLargeValue(const TSettingRef& aRef)
       
   388     {
       
   389     HCR_FUNC("TRepository::IsLargeValue");
       
   390     return ((aRef.iSet->iType & KMaskLargeTypes) != 0);
       
   391     }
       
   392 
       
   393 void HCR::TRepository::GetId(const TSettingRef& aRef, TCategoryUid& aCat, TElementId& aKey)
       
   394     {
       
   395     HCR_FUNC("TRepository::GetId1");
       
   396     aCat = aRef.iSet->iId.iCat;
       
   397     aKey = aRef.iSet->iId.iKey;
       
   398     }
       
   399 
       
   400 void HCR::TRepository::GetId(const TSettingRef& aRef, SSettingId& aId)
       
   401     {
       
   402     HCR_FUNC("TRepository::GetId2");
       
   403     aId = aRef.iSet->iId;
       
   404     }
       
   405 
       
   406 TInt32 HCR::TRepository::GetType(const TSettingRef& aRef)
       
   407     {
       
   408     HCR_FUNC("TRepository::GetType");
       
   409     return (aRef.iSet->iType);
       
   410     }
       
   411 
       
   412 TUint16 HCR::TRepository::GetLength(const TSettingRef& aRef)
       
   413     {
       
   414     HCR_FUNC("TRepository::GetLength");
       
   415     
       
   416 	// Assume large value, will be caught when value retreived if not correct.
       
   417 	// Saves some CPU cycles...
       
   418 	// if (IsLargeValue(aRef))
       
   419     return (aRef.iSet->iLen);
       
   420     }
       
   421 
       
   422 
       
   423 // -- METHODS -----------------------------------------------------------------
       
   424 //
       
   425 // TRepositoryCompiled
       
   426 
       
   427 
       
   428 HCR::TRepository* HCR::TRepositoryCompiled::New(const SRepositoryCompiled* aRepos)
       
   429     {
       
   430     HCR_FUNC("TRepositoryCompiled::New");
       
   431     return new TRepositoryCompiled(aRepos);
       
   432     }
       
   433 
       
   434 HCR::TRepositoryCompiled::TRepositoryCompiled(const SRepositoryCompiled* aRepos)
       
   435  : iRepos(aRepos)
       
   436     {
       
   437     HCR_FUNC("TRepositoryCompiled");
       
   438     }
       
   439     
       
   440 HCR::TRepositoryCompiled::~TRepositoryCompiled()
       
   441     {
       
   442     HCR_FUNC("~TRepositoryCompiled");
       
   443     }
       
   444         
       
   445 TInt HCR::TRepositoryCompiled::Initialise()
       
   446     {
       
   447     HCR_FUNC("TRepositoryCompiled::Initialise");
       
   448     return KErrNone;
       
   449     }
       
   450     
       
   451 TInt HCR::TRepositoryCompiled::CheckIntegrity()
       
   452     {
       
   453     HCR_FUNC("TRepositoryCompiled::CheckIntegrity");
       
   454     
       
   455 	if (iRepos->iOrderedSettingList == 0)
       
   456         HCR_LOGMSG_RETURN("Compiled Repository header missing setting array list", KErrNotFound);
       
   457     
       
   458 	HCR_TRACE2("Compiled repository 0x%x contains %05d entries", iRepos, iRepos->iHdr->iNumSettings);
       
   459 
       
   460     SSettingC* arr = iRepos->iOrderedSettingList;
       
   461     TSettingId prev(0,0);
       
   462     TInt rc=0;
       
   463     for (int i=0; i < iRepos->iHdr->iNumSettings; i++, arr++)
       
   464     	{
       
   465     	HCR_TRACE3("Checking entry %05d - (0x%x,%d)", i, arr->iName.iId.iCat,  arr->iName.iId.iKey);
       
   466     	rc = CompareSSettingIds(prev, arr->iName.iId);
       
   467 		// Check for duplicates that reside next to each other
       
   468     	if ((i > 0) && (rc == 0))
       
   469     		HCR_TRACE_RETURN (KErrAlreadyExists);
       
   470     	// Check that the entries are in ascending order	
       
   471     	if (rc != -1)
       
   472     		HCR_TRACE_RETURN (KErrCorrupt);
       
   473     	prev = arr->iName.iId;
       
   474 		}
       
   475     return KErrNone; 
       
   476     }
       
   477     
       
   478 TInt HCR::TRepositoryCompiled::FindSetting(const TSettingId& aId, TSettingRef& aSetting)
       
   479     {
       
   480     HCR_FUNC("TRepositoryCompiled::FindSetting");
       
   481     
       
   482     if ((iRepos->iHdr->iNumSettings == 0) || 
       
   483         (iRepos->iOrderedSettingList == 0))
       
   484         HCR_LOG_RETURN(KErrNotFound);
       
   485     
       
   486     SSettingC* arr = iRepos->iOrderedSettingList;
       
   487     int low = 0;
       
   488     int high = iRepos->iHdr->iNumSettings-1;
       
   489     int mid;
       
   490     int com;
       
   491     
       
   492     while (low<=high)
       
   493         {
       
   494         mid = (low+high) >> 1;
       
   495         com = CompareSSettingIds(aId, arr[mid].iName.iId);
       
   496         if (com < 0)
       
   497             high = mid-1;
       
   498         else if (com > 0)
       
   499             low = mid+1;
       
   500         else
       
   501             {
       
   502             aSetting.iRep = this;
       
   503             aSetting.iSet = &((arr[mid]).iName);
       
   504             return KErrNone;
       
   505             }    
       
   506         } 
       
   507         
       
   508     aSetting.iRep = 0;
       
   509 	aSetting.iSet = 0; 
       
   510     return KErrNotFound;
       
   511     }
       
   512     
       
   513 TInt HCR::TRepositoryCompiled::GetValue(const TSettingRef& aRef, UValueWord& aValue)
       
   514     {
       
   515     HCR_FUNC("TRepositoryCompiled::GetValue");
       
   516     if (!IsWordValue(aRef))
       
   517         HCR_LOG_RETURN(KErrArgument);
       
   518         
       
   519 	SSettingC* sptr = (SSettingC*)(aRef.iSet);
       
   520     aValue = sptr->iValue.iLit;
       
   521 	return KErrNone;
       
   522     }
       
   523 
       
   524 TInt HCR::TRepositoryCompiled::GetLargeValue(const TSettingRef& aRef, UValueLarge& aValue)
       
   525     {
       
   526     HCR_FUNC("TRepositoryCompiled::GetLargeValue");
       
   527     if (!IsLargeValue(aRef))
       
   528         HCR_LOG_RETURN(KErrArgument);
       
   529 
       
   530 	SSettingC* sptr = (SSettingC*)(aRef.iSet);
       
   531     aValue = sptr->iValue.iPtr;
       
   532     return KErrNone;
       
   533     }
       
   534 
       
   535 
       
   536 // -- METHODS -----------------------------------------------------------------
       
   537 //
       
   538 // TRepositoryFile
       
   539 
       
   540 
       
   541 HCR::TRepository* HCR::TRepositoryFile::New(const SRepositoryFile* aRepos)
       
   542     {
       
   543     HCR_FUNC("TRepositoryFile::New");
       
   544     return new TRepositoryFile(aRepos);
       
   545     }
       
   546 
       
   547 HCR::TRepositoryFile::TRepositoryFile(const SRepositoryFile* aRepos)
       
   548  : iRepos(aRepos)
       
   549     {
       
   550     HCR_FUNC("TRepositoryFile");
       
   551     }
       
   552 
       
   553 HCR::TRepositoryFile::~TRepositoryFile()
       
   554     {
       
   555     HCR_FUNC("~TRepositoryFile");
       
   556     
       
   557     }
       
   558         
       
   559 TInt HCR::TRepositoryFile::Initialise()
       
   560     {
       
   561     HCR_FUNC("TRepositoryFile::Initialise");
       
   562     
       
   563 	
       
   564     return KErrNone;
       
   565     }
       
   566     
       
   567 TInt HCR::TRepositoryFile::CheckIntegrity()
       
   568     {
       
   569     HCR_FUNC("TRepositoryFile::CheckIntegrity");
       
   570     
       
   571     
       
   572 	if ((*((TUint32*)&(iRepos->iHdr)) != 0x66524348) || 
       
   573 		(iRepos->iHdr.iFormatVersion != 0x0001))
       
   574         HCR_LOGMSG_RETURN("File Repository header describes an unsupported repository type", KErrCorrupt);
       
   575     
       
   576     HCR_TRACE2("File repository 0x%x contains %05d entries", iRepos, iRepos->iHdr.iNumSettings);
       
   577     
       
   578     SSettingF* arr = (SSettingF*) (iRepos+1);
       
   579     TSettingId prev(0,0);
       
   580     TInt rc=0;
       
   581     for (int i=0; i < iRepos->iHdr.iNumSettings; i++, arr++)
       
   582     	{
       
   583     	HCR_TRACE3("Checking entry %05d - (0x%x,%d)", i, arr->iName.iId.iCat,  arr->iName.iId.iKey);
       
   584     	rc = CompareSSettingIds(prev, arr->iName.iId);
       
   585 	   	// Check for duplicates that reside next to each other
       
   586     	if ((i > 0) && (rc == 0))
       
   587     		HCR_TRACE_RETURN (KErrAlreadyExists);
       
   588     	// Check that the entries are in ascending order	
       
   589     	if (rc != -1)
       
   590     		HCR_TRACE_RETURN (KErrCorrupt);
       
   591     	prev = arr->iName.iId;
       
   592 		}
       
   593     return KErrNone; 
       
   594     }
       
   595 
       
   596 TInt HCR::TRepositoryFile::FindSetting(const TSettingId& aId, TSettingRef& aSetting)
       
   597     {
       
   598     HCR_FUNC("TRepositoryFile::FindSetting");
       
   599     
       
   600     if (iRepos->iHdr.iNumSettings == 0)
       
   601         HCR_LOG_RETURN(KErrNotFound);
       
   602     
       
   603     SSettingF* arr = (SSettingF*) (iRepos+1);
       
   604     int low = 0;
       
   605     int high = iRepos->iHdr.iNumSettings-1;
       
   606     int mid;
       
   607     int com;
       
   608     
       
   609     while (low<=high)
       
   610         {
       
   611         mid = (low+high) >> 1;
       
   612         com = CompareSSettingIds(aId, arr[mid].iName.iId);
       
   613         if (com < 0)
       
   614             high = mid-1;
       
   615         else if (com > 0)
       
   616             low = mid+1;
       
   617         else
       
   618             {
       
   619             aSetting.iRep = this;
       
   620             aSetting.iSet = &((arr[mid]).iName);
       
   621             return KErrNone;
       
   622             }    
       
   623         } 
       
   624         
       
   625     aSetting.iRep = 0;
       
   626 	aSetting.iSet = 0; 
       
   627     return KErrNotFound;
       
   628     }
       
   629 
       
   630 TInt HCR::TRepositoryFile::GetValue(const TSettingRef& aRef, UValueWord& aValue)
       
   631     {
       
   632     HCR_FUNC("TRepositoryFile::GetValue");
       
   633 
       
   634     if (!IsWordValue(aRef))
       
   635         HCR_LOG_RETURN(KErrArgument);
       
   636         
       
   637 	SSettingF* sptr = (SSettingF*)(aRef.iSet);
       
   638     aValue = sptr->iValue.iLit;
       
   639 	return KErrNone;
       
   640     }
       
   641 
       
   642 TInt HCR::TRepositoryFile::GetLargeValue(const TSettingRef& aRef, UValueLarge& aValue)
       
   643     {
       
   644     HCR_FUNC("TRepositoryFile::GetLargeValue");
       
   645 
       
   646     if (!IsLargeValue(aRef))
       
   647         HCR_LOG_RETURN(KErrArgument);
       
   648 
       
   649 	SSettingF* sptr = (SSettingF*)(aRef.iSet);
       
   650 	TRepositoryFile *rptr = (TRepositoryFile *)(aRef.iRep);
       
   651 	
       
   652     aValue.iData = (TUint8*) rptr->iRepos;
       
   653 	aValue.iData += rptr->iRepos->iLSDfirstByteOffset+sptr->iValue.iOffset;
       
   654     return KErrNone;
       
   655     }
       
   656 
       
   657 
       
   658 
       
   659 // -- FUNCTIONS ---------------------------------------------------------------
       
   660 
       
   661 #ifndef HCRTEST_NO_KEXT_ENTRY_POINT
       
   662 #ifndef __WINS__
       
   663 DECLARE_EXTENSION_WITH_PRIORITY(KExtensionMaximumPriority)
       
   664 #else
       
   665 DECLARE_STANDARD_EXTENSION()
       
   666 #endif // __WINS__
       
   667 	{
       
   668 	HCR_FUNC("InitExtension");
       
   669 
       
   670 	HCR::MVariant* varPtr = CreateHCRVariant();
       
   671 	if (varPtr==0)
       
   672 		HCR_LOG_RETURN(KErrNoMemory);
       
   673 
       
   674 	new(&gHCR) HCR::HCRInternal(varPtr);
       
   675 
       
   676 	TInt err = HCRSingleton->Initialise();
       
   677 
       
   678 	if (err != KErrNone)
       
   679 		HCR_LOG_RETURN(err);
       
   680 
       
   681 	return err;
       
   682 	}
       
   683 #endif // HCRTEST_NO_KEXT_ENTRY_POINT
       
   684 
       
   685 // -- Implementation of local functions
       
   686 
       
   687 TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry)
       
   688 	{
       
   689 	HCR_FUNC("SearchEntryInTRomDir");
       
   690 	TInt retVal = KErrNotFound;
       
   691 	HCR_TRACE2("--- aFileName: %S (%d)", &aFileName, aFileName.Length());
       
   692 	
       
   693 	if( aActDir == 0)
       
   694 		{
       
   695 		HCR_TRACE_RETURN(retVal);
       
   696 		}
       
   697 	
       
   698 	TInt dirSize = aActDir->iSize;
       
   699 	aEntry = (TRomEntry*)&aActDir->iEntry;
       
   700 	HCR_TRACE3("--- dirSize: 0x%08x (%d), aEntry: 0x%08x", dirSize, dirSize, aEntry);
       
   701 	
       
   702 	TBool found = EFalse;
       
   703 	while( !found )
       
   704 		{
       
   705 		HCR_TRACE0("Begin of loop...");
       
   706 		TInt nameLength = (aEntry->iNameLength)<<1;
       
   707 		
       
   708 		HCR_HEX_DUMP_ABS((TUint8 *)aEntry, sizeof(TRomEntry)+(nameLength - 2) );
       
   709 		const TText* entryName = &aEntry->iName[0];
       
   710 		HCR_TRACE1("--- entryName length: %d", nameLength);
       
   711 		TBuf<512> newEntryName( nameLength);
       
   712 		for( TInt i = 0; i != nameLength; ++i)
       
   713 			{
       
   714 			newEntryName[i] = (unsigned char)('A' <= entryName[i] && 'Z' >= entryName[i]? entryName[i]+('a'-'A'): entryName[i]);
       
   715 			}		
       
   716 				
       
   717 		HCR_TRACE6("--- aFileName: %S (%d/%d), newEntryName: %S (%d/%d)", &aFileName, aFileName.Length(), aFileName.Size(), &newEntryName, newEntryName.Length(), newEntryName.Size());
       
   718 		TInt r = aFileName.Compare(newEntryName);
       
   719 		HCR_TRACE1("--- result of CompareFileNames: 0x%08x", r);
       
   720 		
       
   721 		if ( r == 0)
       
   722 			{
       
   723 			found = ETrue;
       
   724 			HCR_TRACE1("--- aEntry: 0x%08x", aEntry);
       
   725 			}
       
   726 		else
       
   727 			{
       
   728 		
       
   729 			TInt entrySize = sizeof(TRomEntry) + (nameLength - 2);
       
   730 			HCR_TRACE2("--- entrySize: 0x%08x, (%d)", entrySize, entrySize);
       
   731 			
       
   732 			// The entrySize must be aligned to 4 bytes boundary
       
   733 			entrySize = ((entrySize&0x03) == 0 ? entrySize : ((entrySize&0xfffffffc) + 4));
       
   734 			HCR_TRACE2("--- entrySize: 0x%08x, (%d)", entrySize, entrySize);
       
   735 			
       
   736 			aEntry = (TRomEntry*)((char *)aEntry + entrySize);
       
   737 			dirSize -= entrySize;
       
   738 			HCR_TRACE2("--- aEntry: 0x%08x, dirSize:%d", aEntry, dirSize);
       
   739 			if( dirSize <= 0)
       
   740 				{
       
   741 				break;
       
   742 				}
       
   743 			}
       
   744 		}
       
   745 		
       
   746 	if( found)
       
   747 		{
       
   748 		retVal = KErrNone;
       
   749 		}
       
   750 		
       
   751 	HCR_TRACE_RETURN(retVal);		
       
   752 	}
       
   753 	
       
   754 TInt SearchCoreImgRepository(HCR::TRepository*& aRepos, const TText * aFileName)
       
   755     {
       
   756     HCR_FUNC("SearchCoreImgRepository(TRepository*& aRepos, TText & aFileName)");
       
   757     
       
   758     TInt retVal = KErrNotFound;
       
   759 
       
   760 	// Convert aFileName to directory entry style Unicode 
       
   761 	const TText* p = aFileName;
       
   762 	
       
   763 	if( *p == 0)
       
   764 		{
       
   765 		// Empty file name -> return with KErrNotFound!
       
   766 		HCR_TRACE_RETURN(retVal);
       
   767 		}
       
   768 		
       
   769 	while( *(++p)) {};					// Search the end of file name string.
       
   770 	TInt nameLen=(TInt)(p-aFileName);	
       
   771 	
       
   772 	HCR_TRACE2("--- aFileName: %s (%d)", aFileName, nameLen );
       
   773 	
       
   774 	TBuf<256> origFileName;
       
   775 	origFileName.Append((const TText*)aFileName, nameLen);
       
   776 	HCR_TRACE2("--- origFileName: %S (%d)", &origFileName, origFileName.Length());
       
   777 	
       
   778 	
       
   779 	TBuf<512> fileNameBuf;
       
   780 	for( TInt i = 0; i != nameLen; ++i)
       
   781 		{
       
   782 		fileNameBuf.Append( 'A' <= origFileName[i] && 'Z' >= origFileName[i]? origFileName[i]+('a'-'A'): origFileName[i]);
       
   783 		fileNameBuf.Append(TChar(0));
       
   784 		}
       
   785 
       
   786 	TPtrC fileName(fileNameBuf);
       
   787 	HCR_TRACE3("--- fileName: %S (%d/%d)", &fileName, fileName.Length(), fileName.Size());
       
   788 
       
   789     // Locate ROM Root directory
       
   790     TSuperPage& superpage = Kern::SuperPage();
       
   791    	TRomRootDirectoryList* romRootDirAddress = (TRomRootDirectoryList*)superpage.iRootDirList;
       
   792  
       
   793     HCR_TRACE3("--- Superpage: 0x%08x, ROM root dir list: 0x%08x (Num of root dirs:%d)", &superpage, romRootDirAddress, romRootDirAddress->iNumRootDirs );
       
   794 
       
   795 	// Search the root directory which is match to the current hardware variant
       
   796     TUint hardwareVariant 	   = superpage.iActiveVariant;
       
   797     TInt variantIndex;
       
   798     TRootDirInfo* rootDirInfo = 0;
       
   799     
       
   800     for(variantIndex = 0; variantIndex < romRootDirAddress->iNumRootDirs; ++variantIndex )
       
   801 	    {
       
   802 	    HCR_TRACE3("--- variantIndex:%d, current hardware variant: 0x%08x, root dir hardware variant:0x%08x", variantIndex, hardwareVariant, romRootDirAddress->iRootDir[variantIndex].iHardwareVariant);
       
   803 	    
       
   804     	if( romRootDirAddress->iRootDir[variantIndex].iHardwareVariant == hardwareVariant)
       
   805 	    	{
       
   806 	    	rootDirInfo = &romRootDirAddress->iRootDir[variantIndex]; 
       
   807 	    	break;
       
   808 	    	}
       
   809 	    }
       
   810     
       
   811     if( rootDirInfo == 0 )
       
   812 	    {
       
   813 	    // Not found root directory for this hardware variant
       
   814 	    HCR_TRACE_RETURN(retVal);
       
   815 	    }
       
   816 	    
       
   817 	TRomDir* romDir = (TRomDir*)rootDirInfo->iAddressLin;
       
   818 
       
   819 	HCR_TRACE3("--- romDir: 0x%08x (files:0x%08x, entries:0x%08x)", romDir, romDir->FileCount(), romDir->EntryCount() );
       
   820 	TRomEntry* entry = (TRomEntry*)&romDir->iEntry;
       
   821 	
       
   822 	// We are searching in \sys\bin\ and \sys\Data\ directory only	
       
   823 	TPtrC level1DirName((const TText*)"s\0y\0s\0", 6);		// Unicode, because the entry names are unicode too.
       
   824 	TPtrC level2Dir1Name((const TText*)"b\0i\0n\0", 6);
       
   825 	TPtrC level2Dir2Name((const TText*)"d\0a\0t\0a\0", 8);		// Originally \sys\Data however we search all entry in lower case
       
   826 	
       
   827 	TInt r = SearchEntryInTRomDir(romDir, level1DirName, entry);
       
   828 	HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
       
   829 
       
   830 	if( r == KErrNone)
       
   831 		{
       
   832 		// \sys directory found.
       
   833 		romDir = (TRomDir*)entry->iAddressLin;
       
   834 		HCR_TRACE1("--- romDir: 0x%08x ", romDir);
       
   835 		
       
   836 		TRomDir* parentDir = romDir;
       
   837 		// Search in \sys\bin directory
       
   838 		r = SearchEntryInTRomDir(romDir, level2Dir1Name, entry);
       
   839 	
       
   840 		HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
       
   841 		if( r == KErrNone)
       
   842 			{
       
   843 			// \sys\bin directory found
       
   844 			romDir = (TRomDir*)entry->iAddressLin;
       
   845 			HCR_TRACE1("--- romDir: 0x%08x ", romDir);
       
   846 			// Search the repository file
       
   847 			r = SearchEntryInTRomDir(romDir, fileName, entry);
       
   848 			
       
   849 			HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
       
   850 			if( r == KErrNone)
       
   851 				{
       
   852 				// Repository file found
       
   853 				retVal = KErrNone;				
       
   854 				HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin);
       
   855 				aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(entry->iAddressLin));	
       
   856 				if (aRepos == NULL)
       
   857                         retVal = KErrNoMemory;					
       
   858                         
       
   859                 HCR_TRACE_RETURN(retVal);
       
   860 				}
       
   861 			}
       
   862 
       
   863 		// \sys\bin directory or repository file in \sys\bin directory not found.    
       
   864 		// Search \sys\Data directory
       
   865 		romDir = parentDir;
       
   866 		r = SearchEntryInTRomDir(romDir, level2Dir2Name, entry);
       
   867 		HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
       
   868 		if( r == KErrNone)
       
   869 			{
       
   870 			// \sys\Data directory found
       
   871 			romDir = (TRomDir*)entry->iAddressLin;
       
   872 			HCR_TRACE1("--- romDir: 0x%08x ", romDir);
       
   873 			
       
   874 			// Search repository file
       
   875 			r = SearchEntryInTRomDir(romDir, fileName, entry);
       
   876 			
       
   877 			HCR_TRACE1("--- result of SearchEntryInTRomDir: 0x%08x", r);
       
   878 			if( r == KErrNone)
       
   879 				{
       
   880 				// Repository file found    
       
   881 				retVal = KErrNone;				
       
   882 				HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin);
       
   883 				aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(entry->iAddressLin));
       
   884 				if (aRepos == NULL)
       
   885                     retVal = KErrNoMemory;					
       
   886 				}
       
   887 			}
       
   888 		}
       
   889 	
       
   890     HCR_TRACE_RETURN(retVal);
       
   891     }
       
   892 
       
   893 TInt LocateCoreImgRepository(HCR::TRepository*& aRepos)
       
   894     {
       
   895     HCR_FUNC("LocateCoreImgRepository");
       
   896 
       
   897 #ifdef __WINS__
       
   898     aRepos = 0;                     // To avoid warning on WINS
       
   899     return KErrNotFound;
       
   900 #else
       
   901 
       
   902 #ifdef HCRTEST_COREIMG_DONTUSE_ROMHDR
       
   903 
       
   904 	const TText8* hcrfile = (const TText8*) "hcr.dat";
       
   905 	TInt retVal = SearchCoreImgRepository(aRepos, hcrfile);
       
   906 	if (retVal != KErrNone)
       
   907 		return retVal;
       
   908 	
       
   909 #else
       
   910 
       
   911 	const TRomHeader& romHeader = Epoc::RomHeader(); 	// 0x80000000;
       
   912 	HCR_TRACE2("--- ROM Header: 0x%08x, HCR file address: 0x%08x", &romHeader, romHeader.iHcrFileAddress);
       
   913 	
       
   914 	if(romHeader.iHcrFileAddress != 0)
       
   915 			{
       
   916 			aRepos = HCR::TRepositoryFile::New(reinterpret_cast<const HCR::SRepositoryFile *>(romHeader.iHcrFileAddress));
       
   917 			if (aRepos == 0)
       
   918 				return KErrNoMemory;
       
   919 			}
       
   920 	else
       
   921 		return KErrNotFound;
       
   922 		
       
   923 #endif // HCRTEST_COREIMG_DONTUSE_ROMHDR
       
   924 	return KErrNone;
       
   925 #endif // __WINS__
       
   926     }
       
   927