diff -r 4122176ea935 -r 56f325a607ea kernel/eka/drivers/hcr/hcr_pil.cpp --- a/kernel/eka/drivers/hcr/hcr_pil.cpp Mon Dec 21 16:14:42 2009 +0000 +++ b/kernel/eka/drivers/hcr/hcr_pil.cpp Wed Dec 23 11:43:31 2009 +0000 @@ -23,6 +23,8 @@ #include #include #include +#include + #include #include @@ -35,10 +37,8 @@ #include "hcr_hai.h" #include "hcr_pil.h" - // -- GLOBALS ----------------------------------------------------------------- - GLDEF_C HCR::HCRInternal gHCR; #ifdef HCR_TRACE @@ -53,8 +53,7 @@ aRepos parameter and signals it with the retun value. -@param aRepos The reference to a repository variable - +@param aRepos The reference to a repository variable @return KErrNone if successful, the aRepos parameter references to the file in ROM Image. KErrNotFound if the ROM Image header contains zero or a special value as the repository file address @@ -92,6 +91,18 @@ LOCAL_C TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry); +// -- WINS Specific ---------------------------------------------------------- + +#ifdef __WINS__ + +// Set to ensure Rom Hdr dependency does not break compilation in +// LocateCoreImgRepository() at the end of this file. +// Undef incase it is set in MMP file, avoids compiler warning. +// +#undef HCRTEST_COREIMG_DONTUSE_ROMHDR +#define HCRTEST_COREIMG_DONTUSE_ROMHDR + +#endif // -- FUNCTIONS --------------------------------------------------------------- @@ -101,7 +112,7 @@ Returns 0 when identical. */ TInt CompareSSettingIds(const HCR::TSettingId& a1, const HCR::SSettingId& a2) -{ + { // HCR_FUNC("CompareSSettingIds"); if (a1.iCat > a2.iCat) return (1); // HCR_TRACE_RETURN(1); @@ -118,6 +129,65 @@ return (0); // HCR_TRACE_RETURN(0); } +#ifdef __EPOC32__ +TBool ROMAddressIsInUnpagedSection(const TLinAddr address) + { + HCR_FUNC("ROMAddressIsInUnpagedSection"); + + const TRomHeader& romHdr = Epoc::RomHeader(); + TLinAddr romBase = romHdr.iRomBase; + + HCR_TRACE1("--- address to check if in unpaged ROM section = 0x%8x", address); + HCR_TRACE2("--- iRomSize (0x%8x), iPageableRomStart (0x%8x), ", romHdr.iRomSize, romHdr.iPageableRomStart); + + if ((address < romBase) || (romBase > romBase+romHdr.iRomSize)) + return EFalse; + if (romHdr.iPageableRomStart == 0) + return ETrue; + if (address < romBase+romHdr.iPageableRomStart) + return ETrue; + return EFalse; + } +#endif + + +TInt CompareByCategory(const HCR::TCategoryUid aCatId, const HCR::SSettingId& aSetId) + { + //HCR_FUNC("CompareByCategory"); + if (aCatId > aSetId.iCat) + return (1); // HCR_TRACE_RETURN(1); + if (aCatId < aSetId.iCat) + return (-1); // HCR_TRACE_RETURN(-1); + + // Both Categories and jeys are the same here. + return (0); + } + +/* + * SafeArray TSa class object destructor. It delets the allocated in the heap + * memory and set the instance pointer to NULL. See also TSa class definition + * in hcr_pil.h. + */ +template + HCR::TSa::~TSa() + { + delete[] iSa; + iSa = NULL; + } + +/** + * operator=() changes the memory ownership by + * reinitiazing SafeArray class object with the address to + * already allocated array. + */ +template + HCR::TSa& HCR::TSa::operator=(T* aP) + { + delete[] iSa; + iSa = aP; + return (*this); + } + // -- METHODS ----------------------------------------------------------------- // @@ -193,7 +263,7 @@ if (err == KErrNone) { if (iCoreImgStore == 0) { - err = KErrNoMemory; goto failed; } + err = KErrNoMemory; goto failed; } } else if (err != KErrNotFound) goto failed; @@ -238,7 +308,7 @@ failed: iStatus = (iStatus & EStatMinorMask) | EStatFailed; - HCR_LOG_RETURN(err); + HCR_TRACE_RETURN(err); } @@ -263,16 +333,20 @@ HCR_TRACE0("--- ECoreRepos"); if( iCoreImgStore ) { + NKern::ThreadEnterCS(); delete iCoreImgStore; + NKern::ThreadLeaveCS(); } iCoreImgStore = store; break; case EOverrideRepos: HCR_TRACE0("--- EOverrideRepos"); - if( iCoreImgStore ) + if( iOverrideStore ) { + NKern::ThreadEnterCS(); delete iOverrideStore; + NKern::ThreadLeaveCS(); } iOverrideStore = store; break; @@ -284,7 +358,7 @@ } } - HCR_LOG_RETURN(retVal); + HCR_TRACE_RETURN(retVal); } TInt HCR::HCRInternal::CheckIntegrity() @@ -296,28 +370,30 @@ { err = iVariantStore->CheckIntegrity(); if (err != KErrNone) - HCR_LOGMSG_RETURN("HCR iVariantStore failed integrity check", err); + HCR_TRACEMSG_RETURN("HCR iVariantStore failed integrity check", err); } if (iCoreImgStore) { err = iCoreImgStore->CheckIntegrity(); if (err != KErrNone) - HCR_LOGMSG_RETURN("HCR iCoreImgStore failed integrity check", err); + HCR_TRACEMSG_RETURN("HCR iCoreImgStore failed integrity check", err); } if (iOverrideStore) { err = iOverrideStore->CheckIntegrity(); if (err != KErrNone) - HCR_LOGMSG_RETURN("HCR iOverrideStore failed integrity check", err); + HCR_TRACEMSG_RETURN("HCR iOverrideStore failed integrity check", err); } HCR_TRACE0("=== HCR Repository integrity checks PASSED!"); return KErrNone; } -TInt HCR::HCRInternal::FindSetting(const TSettingId& aId, TSettingType aType, TSettingRef& aSetting) + +TInt HCR::HCRInternal::FindSetting(const TSettingId& aId, TSettingType aType, + TSettingRef& aSetting) { HCR_FUNC("HCRInternal::FindSetting"); TInt err = 0; @@ -329,14 +405,62 @@ ((err = iOverrideStore->FindSetting(aId, aSetting)) == KErrNone)) found = ETrue; if ((err != KErrNone) && (err != KErrNotFound)) - HCR_LOG_RETURN(err); + HCR_TRACE_RETURN(err); if (!found && iCoreImgStore && ((err = iCoreImgStore->FindSetting(aId, aSetting)) == KErrNone)) found = ETrue; if ((err != KErrNone) && (err != KErrNotFound)) - HCR_LOG_RETURN(err); + HCR_TRACE_RETURN(err); + + if (!found && + iVariantStore && + ((err = iVariantStore->FindSetting(aId, aSetting)) == KErrNone)) + found = ETrue; + + if ((err != KErrNone) && (err != KErrNotFound)) + HCR_TRACE_RETURN(err); + + HCR_TRACE3("--- Search results: %d, %d, %x", found, err, aSetting.iSet); + + if (!found || (aSetting.iSet == 0)) + HCR_TRACE_RETURN(KErrNotFound); + + // Setting found at this point in the function + // + + TSettingType type=static_cast(aSetting.iRep->GetType(aSetting)); + if (type & ~aType) + HCR_TRACE_RETURN(KErrArgument); // Wrong setting type + + HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, type); + + return KErrNone; + } + + +TInt HCR::HCRInternal::FindSettingWithType(const TSettingId& aId, TSettingType& aType, + TSettingRef& aSetting) + { + HCR_FUNC("HCRInternal::FindSettingWithType"); + TInt err = 0; + TBool found = EFalse; + + HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore); + + if (iOverrideStore && + ((err = iOverrideStore->FindSetting(aId, aSetting)) == KErrNone)) + found = ETrue; + if ((err != KErrNone) && (err != KErrNotFound)) + HCR_TRACE_RETURN(err); + + if (!found && + iCoreImgStore && + ((err = iCoreImgStore->FindSetting(aId, aSetting)) == KErrNone)) + found = ETrue; + if ((err != KErrNone) && (err != KErrNotFound)) + HCR_TRACE_RETURN(err); if (!found && iVariantStore && @@ -344,39 +468,1049 @@ found = ETrue; if ((err != KErrNone) && (err != KErrNotFound)) - HCR_LOG_RETURN(err); + HCR_TRACE_RETURN(err); HCR_TRACE3("--- Search results: %d, %d, %x", found, err, aSetting.iSet); if (!found || (aSetting.iSet == 0)) - HCR_LOG_RETURN(KErrNotFound); + { + aType = ETypeUndefined; + HCR_TRACE_RETURN(KErrNotFound); + } // Setting found at this point in the function // - TSettingType type=static_cast(aSetting.iRep->GetType(aSetting)); - if (type & ~aType) - HCR_LOG_RETURN(KErrArgument); // Wrong setting type + aType=static_cast(aSetting.iRep->GetType(aSetting)); - HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, type); + HCR_TRACE3("--- Setting found! ID: (%d,%d) Type: %d", aId.iCat, aId.iKey, aType); return KErrNone; } + + +TInt HCR::HCRInternal::GetWordSettings(TInt aNum, const SSettingId aIds[], + TInt32 aValues[], TSettingType aTypes[], TInt aErrors[]) + { + HCR_FUNC("++ HCRInternal::GetWordSettings"); + HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore); -TInt HCR::HCRInternal::FindWordSettings(TInt /*aNum*/, const TSettingId* /*aIds*/, - TInt32* /*aValues*/, TSettingType* /*aTypes*/, TInt* /*aErrors*/) + if(aNum <= 0 || aIds == NULL || aErrors == NULL) + HCR_TRACE_RETURN(KErrArgument); + + TInt err = 0; + //If the user only supplies a single setting then there is no reasons to + //continue with multiple searach and it should be limited by internal + //invocation of FindSettingWithType. + if(aNum == 1) + { + TSettingRef sref(0,0); + TSettingType* pTypes; + + //aTypes array is optional and user may not provided it for us. So we + //need to be sure it's not a null pointer + if(aTypes == NULL) + { + //If this is a null pointer then just create our own element and + //assign it to the pTypes pointer + TSettingType types[1]; + pTypes = types; + } + else + { + //else we use the user supplied array + pTypes = aTypes; + } + + //Let's find this setting + err = HCRSingleton->FindSettingWithType(aIds[0], *pTypes, sref); + + //and analyse the result of operation + + //If setting is not found or it's larger than 4 bytes then store this + //error cause in the user error array + if(err == KErrNotFound || err == KErrArgument) + { + //Indicate the error for the element and set the value to 0 + aErrors[0] = err; + aValues[0] = 0; + return 0; + } + //fatal error here, nothing to do, just exit and return the error code + else if(err == KErrNotReady || err != KErrNone) + { + HCR_TRACE_RETURN(err); + } + else //err == KErrNone + { + //Get the value of the setting + err = sref.iRep->GetValue(sref, reinterpret_cast(aValues[0])); + + //The GetValue can only return either KErrArgument or KErrNone + if(err == KErrArgument) + { + aErrors[0] = KErrArgument; + aValues[0] = 0; + return 0; + } + else //err == KErrNone + { + aErrors[0] = KErrNone; + } + + } + + //This single setting was found so indicate it to the user + return (1); + } + + + //Introducing a SafeArray of pointers to the settings, which is passed to ver- + //sion of GetWordSettings() method declared in TRepository, and implemented + //in TRepositoryCompiled and TRepositoryFile + TSa ids; + + //SafeArray of pointers to the aValues user array elements + TSa values; + + //SafeArray of pointers to the aErrors user array elements + TSa errors; + + //SafeArray of pointers to the aTypes user array elements + TSa types; + + + //Local replacement for the aTypes[] array if it's not provided by user + TSa typesHolder; + + //Allocate the arrays of pointers in the heap + ids = new SSettingId*[aNum]; + values = new TInt32*[aNum]; + errors = new TInt*[aNum]; + types = new TSettingType*[aNum]; + + + //Check all arrays allocations + if(!ids() || !values() || !errors() || !types()) + { + //One of the allocation was unsuccessful + HCR_TRACE_RETURN(KErrNoMemory); + } + + //If the user did not supply the aTypes array for us we need to create one + //for ourself + if(aTypes == NULL) + { + typesHolder = new TSettingType[aNum]; + if(!typesHolder()) + HCR_TRACE_RETURN(KErrNoMemory); + } + + + //Ininialize newly created array of pointers to the user supplied settings + for (TInt index = 0; index < aNum; index++) + { + ids[index] = const_cast(&aIds[index]); + values[index] = const_cast(&aValues[index]); + errors[index] = &aErrors[index]; + + if(aTypes == NULL) + types[index] = &typesHolder[index]; + else + types[index] = &aTypes[index]; + } + + + //nfCount represents a total number of settings which were not found in all + //repositories + TInt nfCount = aNum; + + //nfReposCount represents a number of settings "not found - nf" in the searched + //repository + TInt nfReposCount = 0; + + //It represents a number of setting found in the repository + TInt reposCount = 0; + + + //First step through the Override store and gather all settings we need. + //In the end of this procedure we'll have number of settings not found here + //and found settings data are copied to the user arrays. + if (iOverrideStore) + { + + //Call the sibling method from the TRepositoryFile object + err = iOverrideStore->GetWordSettings(aNum, ids(), + values(), types(), errors()); + + //Analyse the err we've got + if(err != KErrNone && err != KErrNotFound) + { + HCR_TRACE_RETURN(err); + } + else if(err == KErrNone) + { + //Search for number of not found parameters + for(TInt index = 0; index < aNum; index ++) + { + switch(*(errors[index])) + { + //The setting was found or it's found but the type is larger + //than 4 bytes then we just increase a counter of the found + //settings in the repository + case KErrNone: + case KErrArgument: + reposCount ++; + break; + + + //The setting was not found, then re-initialize all the + //arrays of pointers with the pointer to this element. + //nfReposCount depict the counter of not found element and + //index shows the intial element position. + //As nfReposCount is always less or equal to index then we + //can easily make reassignment as nfReposCoun element was + //already analysed. In the end the nfReposCount is increased. + case KErrNotFound: + ids[nfReposCount] = ids[index]; + values[nfReposCount] = values[index]; + types[nfReposCount] = types[index]; + errors[nfReposCount] = errors[index]; + nfReposCount ++; + break; + + + default: + //No any action is needed + break; + } + } + + } + else //err == KErrNotFound + { + //No settings were found in the repository + //reposCount is zero intialized, so nothing to do here + } + + //Update the global counter only if there are some settings were found, + //otherwise it can be situation when we overwrite the nfCount with zero + //when either no any setting presents or no settings were found in the + //repository + if(reposCount > 0) + nfCount = nfReposCount; + } + + //Go through core image and search for the rest of settings + nfReposCount = 0; + reposCount = 0; + + if (iCoreImgStore && nfCount > 0) + { + + err = iCoreImgStore->GetWordSettings(nfCount, ids(), + values(), types(), errors()); + + if (err != KErrNone && err != KErrNotFound) + { + HCR_TRACE_RETURN(err); + } + else if(err == KErrNone) + { + //Search for number of errors + for(TInt index = 0; index < nfCount; index ++) + { + switch(*(errors[index])) + { + //The setting was found or it's found but the type is larger + //than 4 bytes then we just increase a counter of the found + //settings in the repository + case KErrNone: + case KErrArgument: + reposCount ++; + break; + + //The setting was not found, then re-initialize all the + //arrays of pointers with the pointer to this element. + //nfReposCount depict the counter of not found element and + //index shows the intial element position. + //As nfReposCount is always less or equal to index then we + //can easily make reassignment as nfReposCoun element was + //already analysed. In the end the nfReposCount is increased. + case KErrNotFound: + ids[nfReposCount] = ids[index]; + values[nfReposCount] = values[index]; + types[nfReposCount] = types[index]; + errors[nfReposCount] = errors[index]; + nfReposCount ++; + break; + + + default: + //No any action is needed + break; + + } + + } + + } + else //err == KErrNotFound + { + //No settings were found in the repository + //reposCount is zero intialized, so nothing to do here + } + + + //Update the global counter only if there are some settings were found, + //otherwise it can be situation when we overwrite the nfCount with zero + //when either no any setting presents or no settings were found in the + //repository + if(reposCount > 0) + nfCount = nfReposCount; + } + + //let's go through the last Variant store + nfReposCount = 0; + reposCount = 0; + if(iVariantStore && nfCount > 0) + { + err = iVariantStore->GetWordSettings(nfCount, ids(), values(), + types(), errors()); + + if (err != KErrNone && err != KErrNotFound) + { + HCR_TRACE_RETURN(err); + } + else if(err == KErrNone) + { + //Search for number of errors + for(TInt index = 0; index < nfCount; index ++) + { + switch(*(errors[index])) + { + //The setting was found or it's found but the type is larger + //than 4 bytes then we just increase a counter of the found + //settings in the repository + case KErrNone: + case KErrArgument: + reposCount ++; + break; + + //The setting was not found, then re-initialize all the + //arrays of pointers with the pointer to this element. + //nfReposCount depict the counter of not found element and + //index shows the intial element position. + //As nfReposCount is always less or equal to index then we + //can easily make reassignment as nfReposCoun element was + //already analysed. In the end the nfReposCount is increased. + case KErrNotFound: + *values[nfReposCount] = 0; + *types[nfReposCount] = ETypeUndefined; + *errors[nfReposCount] = KErrNotFound; + nfReposCount ++; + break; + + + default: + //No any action is needed + break; + + } + } + + } + else //err == KErrNotFound + { + //No settings were found in the repository + //reposCount is zero intialized, so nothing to do here + } + + //Update the global counter only if there are some settings were found, + //otherwise it can be situation when we overwrite the nfCount with zero + //when either no any setting presents or no settings were found in the + //repository + if(reposCount > 0) + nfCount = nfReposCount; + } + //Return the number of found elements + return (aNum - nfCount); + } + + + + + +TInt HCR::HCRInternal::FindNumSettingsInCategory (TCategoryUid aCatUid) { - HCR_FUNC("HCRInternal::FindWordSettings"); - - return KErrNotSupported; + HCR_FUNC("++ HCRInternal::FindNumSettingsInCategory"); + TInt err = 0; + + HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, iCoreImgStore, iVariantStore); + + //First and last element index within category in the Override store + TInt32 oLowIndex = 0; + TInt32 oHighIndex = 0; + TInt oCount = 0; + + //Find numOverride number of settings within the category in the OverrideStore + //repository + if(iOverrideStore) + { + err = iOverrideStore->FindNumSettingsInCategory(aCatUid, + oLowIndex, oHighIndex); + + if(err == KErrNotFound) + oCount = 0; + else + oCount = oHighIndex - oLowIndex + 1; + + //If CoreImg and Variant store are not activated so just return the + //number of elements found in the Override store + if(!iCoreImgStore && !iVariantStore) + return oCount; + } + + + //First and last element index within category in the CoreImg store + TInt32 cLowIndex = 0; + TInt32 cHighIndex = 0; + TInt32 cLength = 0; + TInt cCount = 0; + + + + //Temproary holder for the found element position + TInt32 elementPos; + //Temproary holder for the low index, which is used to decrease the scope + //of search + TInt32 lowIndex = oLowIndex; + + //Setting data holders + SSettingId setId; + TSettingRef setRef; + + if(iCoreImgStore) + { + //Find numCoreImg number of settings within the category in the CoreImg re- + //pository + err = iCoreImgStore->FindNumSettingsInCategory(aCatUid, + cLowIndex, cHighIndex); + + if(err == KErrNotFound) + cLength = 0; + else + //Calculate the number of elements within category, in CoreImg store + cLength = cHighIndex - cLowIndex + 1; + + if(oCount > 0) + { + //Find all elemnts from CoreImg store which are not redefined in the + //Override store. When element is not found in the Override store + //then cCount is increased. + for(TInt element = 0; element < cLength; element ++) + { + //Find element in the repository by its index + iCoreImgStore->GetSettingRef(cLowIndex + element, setRef); + //and get its id + iCoreImgStore->GetId(setRef, setId); + + //Check either this element is already redefined in the Override + //store + err = iOverrideStore->FindSetting( setId, setRef, + elementPos, lowIndex, oHighIndex); + + if(err == KErrNone) + { + //if the element is found in the Override store, then store the posi- + //tion of this element in lowIndex, to narrow next search procedure + lowIndex = elementPos; + } + else if(err == KErrNotFound) + { + //if element is not found then it means it's not redefined in the + //Override store and this element must be counted in the total number + //of elemnts in all stores + cCount ++; + } + else + { + return err; + } + } + } + else + { + cCount = cLength; + } + + + + //Check if the Variant store is present if it's not then just return the + //result + if(!iVariantStore) + return (oCount + cCount); + + } + + //First and last element index within giving category in the Variant store + TInt32 vLowIndex = 0; + TInt32 vHighIndex = 0; + TInt32 vLength = 0; + TInt vCount = 0; + + if(iVariantStore) + { + //Find numVariant number of settings within the category in the VariantStore + //repository + err = iVariantStore->FindNumSettingsInCategory(aCatUid, vLowIndex, + vHighIndex); + + //Analyze returned error code + + if(err == KErrNotFound) + vLength = 0; + else + //Calculate the number of elements within category, in CoreImg store + vLength = vHighIndex - vLowIndex + 1; + + if(oCount == 0 && cCount == 0) + { + return vLength; + } + + if(oCount > 0 || cCount >0) + { + //Find all elemnts from Variant store which are not redefined either in the + //Override or CoreImg store. These elements are added to the total + //count. + + // Some additional containers. They are needed because we + // must check two stores Override and Variant in this iteration. Making a + // decision of uniqueness of the element is made from the analyse of both + // result. The element is only unique defined in the Variant store if it's + // not redefined either in the Override or Variant store + TSettingRef tmpRef; + //Temproary holder for the found element position + TInt32 elementPos2 = 0; + //Temproary holder for the low index, which is used to decrease the scope + //of search + TInt32 lowIndex2 = cLowIndex; + // This index contains Override low index and will be changed by the position + // of a new found element + lowIndex= oLowIndex; + + TBool isRedefined = EFalse; + + for(TInt element = 0; element < vLength; element ++) + { + //Find the setting in the repository by its index and + iVariantStore->GetSettingRef(vLowIndex + element, setRef); + //get its id + iVariantStore->GetId(setRef, setId); + + if(oCount > 0) + { + //Check either this element is already redefined in the Override store + err = iOverrideStore->FindSetting(setId, tmpRef, + elementPos, lowIndex, oHighIndex); + + if(err == KErrNone) + { + //if the element is found in the Override store, then store the posi- + //tion of this element in lowIndex, to narrow next search procedure + lowIndex = elementPos; + isRedefined = ETrue; + } + else if(err == KErrNotFound) + { + //the element is not presented in the Override store + //nothing to do here + } + else + { + return err; + } + + } + + + if(cCount > 0 && !isRedefined) + { + //Check either this element is already redefined in the CoreImg store + err = iCoreImgStore->FindSetting(setId, tmpRef, + elementPos2, lowIndex2, cHighIndex); + + + if(err == KErrNone) + { + //if the element is found in the Override store, then store the posi- + //tion of this element in lowIndex, to narrow next search procedure + lowIndex2 = elementPos2; + isRedefined = ETrue; + } + else if(err == KErrNotFound) + { + //the element is not presented in the Override store + //nothing to do here + } + else + { + return err; + } + } + + + if(!isRedefined) + vCount ++; + else + isRedefined = EFalse; + + }//for(TInt element = 0; element < vLength; element ++) + + } + else + { + vCount = vLength; + } + } + + //Return the total number of elements found in the category + return (oCount + cCount + vCount); } + +TInt HCR::HCRInternal::FindSettings(TCategoryUid aCatUid, + TInt aMaxNum, TElementId aIds[], + TSettingType aTypes[], TUint16 aLens[]) + { + HCR_FUNC("++ HCRInternal::FindSettings w/o patterns"); + + HCR_TRACE3("--- Repository state: %x, %x, %x", iOverrideStore, + iCoreImgStore, iVariantStore); + + //Error container + TInt err = KErrNone; + + //Total number of found elements + TInt numFound = 0; + //Number of found elements in the Override store + TInt oNumFound = 0; + + //Low and High indexes in the Override store + TInt32 oLoIndex = 0; + TInt32 oHiIndex = 0; + + //Temproary holder for the found element position + TInt32 elementPos = 0; + TInt32 lowIndex = 0; + + + //Tempoary type and length value holders if the + //user does not provide these arrays for us + TSettingType tmpType; + TUint16 tmpLen; + + + //Setting datat holders + TSettingRef setRef; + TSettingId setId; + + + //Find number of elements, low and hingh index in the Override store + if(iOverrideStore) + { + err = iOverrideStore->FindNumSettingsInCategory(aCatUid, oLoIndex, + oHiIndex); + if(err == KErrNone) + { + //If number of elements in the Override Store is larger than aMaxNum or + //CoreImage/Variant stores are not present then write all found + //settings into the user array, return the number of found elements and + //exit + oNumFound = (oHiIndex - oLoIndex + 1); + lowIndex = oLoIndex; + + if(oNumFound < aMaxNum) + { + for(TInt index = 0; index < oNumFound; index ++) + { + //Get setting reference data from the repository + iOverrideStore->GetSettingRef(oLoIndex + index, setRef); + + //Copy the settings data into the user arrays + iOverrideStore->GetSettingInfo(setRef, + aIds[index], + aTypes ? aTypes[index]:tmpType, + aLens ? aLens[index]:tmpLen); + + + } + } + else //oNumFound >= aMaxNum + { + //Copy data to the user array + for(TInt index = 0; index < aMaxNum; index++) + { + //Get setting reference data from the repository + iOverrideStore->GetSettingRef(oLoIndex + index, setRef); + //Copy the settings data into the user arrays + iOverrideStore->GetSettingInfo(setRef, + aIds[index], + aTypes ? aTypes[index]:tmpType, + aLens ? aLens[index]:tmpLen); + + } + return oNumFound; + } + } + else if(err == KErrNotFound) + { + //Nothing to do here, oNumFound is set to zero already + } + else + { + return err; + } + } + + + //Low/High index in the CoreImg + TInt32 cLoIndex = 0; + TInt32 cHiIndex = 0; + TInt cNumFound = 0; + + //Temproary setting reference holder + TSettingRef tmpRef; + + //Temproary holder for the found element position + elementPos = 0; + lowIndex = oLoIndex; + + //Redefined status flag, it's used to flag that the element is found in the + //upper stores + TBool isRedefined = EFalse; + + //User array index + TInt usrArrIndx = 0; + + //If the count is still less than aMaxNum then continue with searching + //settings in the CoreImage store + if(iCoreImgStore) + { + + //Find number of elements and low/high indexes + err = iCoreImgStore->FindNumSettingsInCategory(aCatUid, cLoIndex, + cHiIndex); + + if(err == KErrNone) + { + for(TInt index = 0; index < (cHiIndex - cLoIndex + 1); index ++) + { + //Get the setting data by its index in the repository + iCoreImgStore->GetSettingRef(cLoIndex + index, setRef); + //get setting id + iCoreImgStore->GetId(setRef, setId); + + if(oNumFound > 0) + { + //Check either this element is already redefined in the + err = iOverrideStore->FindSetting(setId, tmpRef, + elementPos, lowIndex, oHiIndex); + + + if(err == KErrNone) + { + lowIndex = elementPos + 1; + isRedefined = ETrue; + } + else if (err == KErrNotFound) + { + //Nothing to do hear, isRedefined flag is EFalse + //all analysis is done later in the code + } + else + { + return err; + } + } + + //Examine the redefined status flag + if(!isRedefined) + { + // If the element was not found then we need to copy to + // the pA array and increase the counter of setting data + // only if we did not reach the aMaxNum of found elements + + usrArrIndx = oNumFound + cNumFound; + if(usrArrIndx < aMaxNum) + { + //Copy the settings data into the user arrays + iCoreImgStore->GetSettingInfo(setRef, + aIds[usrArrIndx], + aTypes ? aTypes[usrArrIndx]:tmpType, + aLens ? aLens[usrArrIndx]:tmpLen); + cNumFound ++; + } + else + { + //All required elements were found! + //As vNumFound was used an index so it's value it runs + //from 0 to X-1, where X - number of found elements. To + //get number of elements found we need increase the last + //counter value by 1. + if(cNumFound != 0) + cNumFound ++; + //It reaches the goal, all required elements are found + //stop here and return the result + break; + } + } + else + //Element is found in other repositories, just reset a flag + isRedefined = EFalse; + } + } + else if (err == KErrNotFound) + { + //cNumFound is already set to zero during the initialization + //Nothing to do here + } + else //any other errors + { + return err; + } + } + + + //Low/High index in the CoreImg + TInt32 vLoIndex = 0; + TInt32 vHiIndex = 0; + TInt vNumFound = 0; + + //Temproary holder for the found element position + TInt32 elementPos2 = 0; + + TInt32 lowIndex2 = cLoIndex; + lowIndex = oLoIndex; + + isRedefined = EFalse; + + + //If the count is still less than aMaxNum then continue with searching + //settings in the CoreImage store + if(iVariantStore) + { + + //Find number of elements and low/high indexes + err = iVariantStore->FindNumSettingsInCategory(aCatUid, vLoIndex, + vHiIndex); + if(err == KErrNone) + { + + for(TInt index = 0; index < (vHiIndex - vLoIndex + 1); index ++) + { + //Get setting reference data by its index in the repository + iVariantStore->GetSettingRef(vLoIndex + index, setRef); + + //and get setting id + iVariantStore->GetId(setRef, setId); + + if(oNumFound > 0) + { + //Check either this element is already redefined in the + err = iOverrideStore->FindSetting(setId, tmpRef, elementPos, + lowIndex, oHiIndex); + + + //Also suppress the error checking due the reason described + //above + if(err == KErrNone) + { + lowIndex = elementPos + 1; + isRedefined = ETrue; + } + else if (err == KErrNotFound) + { + //Element is not found, nothing to proceed here + } + else + { + return err; + } + } + + if(cNumFound > 0 && !isRedefined) + { + //Check either this element is already redefined in the + err = iCoreImgStore->FindSetting(setId, tmpRef, elementPos2, + lowIndex2, cHiIndex); + + if(err == KErrNone) + { + lowIndex2 = elementPos2 + 1; + isRedefined = ETrue; + } + else if (err == KErrNotFound) + { + //Element is not found, nothing to proceed here + } + else + { + return err; + } + } + + if(!isRedefined) + { + usrArrIndx = oNumFound + cNumFound + vNumFound; + if(usrArrIndx < aMaxNum) + { + //Copy the settings data into the user arrays + iVariantStore->GetSettingInfo(setRef, + aIds[usrArrIndx], + aTypes ? aTypes[usrArrIndx]:tmpType, + aLens ? aLens[usrArrIndx]:tmpLen); + + vNumFound ++; + } + else + { + //All required elements were found! + //As vNumFound was used an index so it's value it runs + //from 0 to X-1, where X - number of found elements. To + //get number of elements found we need increase the last + //counter value by 1. + if(vNumFound != 0) + vNumFound ++; + //It reaches the goal, all required elements are found + //stop here and return the result + break; + } + } + else + { + isRedefined = EFalse; + } + } + } + else if (err == KErrNotFound) + { + //oNumFound is already set to zero during the initialization + //Nothing to do here + } + else + { + return err; + } + + } + + //Let's prepare the final data + numFound = oNumFound + cNumFound + vNumFound; + + //Return result to the user + return numFound; + } + + + + + + + +TInt HCR::HCRInternal::FindSettings(TCategoryUid aCat, TInt aMaxNum, + TUint32 aMask, TUint32 aPattern, + TElementId aIds[], TSettingType aTypes[], TUint16 aLens[]) + { + //Holder for errors and number of elements + TInt r = KErrNone; + //Total number of elements within the given category + TInt allInCatFound = 0; + //Number of elements which corresponds to the aMask and aPattern + TInt numFound = 0; + + //Find the number of elements within the category + r = FindNumSettingsInCategory(aCat); + + //Analyse the returned error + //if r < 0 - this is an error return to the user + //if r > 0 - number of found settings + if(r < 0) + { + HCR_TRACE_RETURN(r); + } + else if (r == 0) + //No any elements found for this category + return 0; + else + allInCatFound = r; + + //Result data array holder + TSa pIds; + TSa pTypes; + TSa pLens; + + pIds = new TElementId[allInCatFound]; + pTypes = new TSettingType[allInCatFound]; + pLens = new TUint16[allInCatFound]; + + if(pIds() == NULL || pTypes() == NULL || pLens() == NULL) + //One of the allocation was unsuccessful + HCR_TRACE_RETURN(KErrNoMemory); + + r = FindSettings(aCat, allInCatFound, pIds(), pTypes(), pLens()); + + //Exit if we've got negative result just report error + if(r < 0) + HCR_TRACE_RETURN(r); + + //Somehow we'got less elements than it must be!!! + __NK_ASSERT_DEBUG(r == allInCatFound); + if(r < allInCatFound) + HCR_TRACE_RETURN(KErrGeneral); + + + //Choose the elements which satisfy this condition + //((elementID & aElementMask) == (aPattern & aElementMask)). The total num- + //ber of returned elements should not exceed the aMaxNum + for(TInt index = 0; index < allInCatFound; index++) + { + if(((pIds[index] & aMask) == (aPattern & aMask))) + { + aIds[numFound] = pIds[index]; + + if(aTypes) + aTypes[numFound] = pTypes[index]; + + if(aLens) + aLens[numFound] = pLens[index]; + + numFound ++; + } + else + continue; + + //Check either we already found or not enough elements + //If we did then break the loop + if(numFound == aMaxNum) + break; + } + + return numFound; + } + + // -- METHODS ----------------------------------------------------------------- // // TRepository +HCR::TRepository::~TRepository() + { + HCR_FUNC("~TRepository"); + } TBool HCR::TRepository::IsWordValue(const TSettingRef& aRef) { @@ -419,6 +1553,17 @@ return (aRef.iSet->iLen); } +void HCR::TRepository::GetSettingInfo(const HCR::TSettingRef& aSetRef, + HCR::TElementId& aId, HCR::TSettingType& aType, TUint16& aLen) + { + HCR_FUNC("TRepository::GetSettingInfo"); + + aId = aSetRef.iSet->iId.iKey; + + aType = static_cast(aSetRef.iSet->iType); + + aLen = aSetRef.iSet->iLen; + } // -- METHODS ----------------------------------------------------------------- // @@ -428,6 +1573,8 @@ HCR::TRepository* HCR::TRepositoryCompiled::New(const SRepositoryCompiled* aRepos) { HCR_FUNC("TRepositoryCompiled::New"); + + __NK_ASSERT_ALWAYS(aRepos != 0); return new TRepositoryCompiled(aRepos); } @@ -442,18 +1589,15 @@ HCR_FUNC("~TRepositoryCompiled"); } -TInt HCR::TRepositoryCompiled::Initialise() - { - HCR_FUNC("TRepositoryCompiled::Initialise"); - return KErrNone; - } - TInt HCR::TRepositoryCompiled::CheckIntegrity() { HCR_FUNC("TRepositoryCompiled::CheckIntegrity"); + __NK_ASSERT_ALWAYS(this != 0); + __NK_ASSERT_ALWAYS(iRepos != 0); + if (iRepos->iOrderedSettingList == 0) - HCR_LOGMSG_RETURN("Compiled Repository header missing setting array list", KErrNotFound); + HCR_TRACEMSG_RETURN("Compiled Repository header missing setting array list", KErrNotFound); HCR_TRACE2("Compiled repository 0x%x contains %05d entries", iRepos, iRepos->iHdr->iNumSettings); @@ -462,7 +1606,8 @@ TInt rc=0; for (int i=0; i < iRepos->iHdr->iNumSettings; i++, arr++) { - HCR_TRACE3("Checking entry %05d - (0x%x,%d)", i, arr->iName.iId.iCat, arr->iName.iId.iKey); + __NK_ASSERT_ALWAYS(arr != 0); + HCR_TRACE3("Checking entry %05d - (0x%x,0x%x)", i, arr->iName.iId.iCat, arr->iName.iId.iKey); rc = CompareSSettingIds(prev, arr->iName.iId); // Check for duplicates that reside next to each other if ((i > 0) && (rc == 0)) @@ -479,9 +1624,12 @@ { HCR_FUNC("TRepositoryCompiled::FindSetting"); + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(iRepos->iHdr != 0); + if ((iRepos->iHdr->iNumSettings == 0) || (iRepos->iOrderedSettingList == 0)) - HCR_LOG_RETURN(KErrNotFound); + HCR_TRACE_RETURN(KErrNotFound); SSettingC* arr = iRepos->iOrderedSettingList; int low = 0; @@ -509,12 +1657,372 @@ aSetting.iSet = 0; return KErrNotFound; } + + + + +TInt HCR::TRepositoryCompiled::FindSetting(const TSettingId& aId, + TSettingRef& aSetting, TInt32& aPosition, TInt32 aLow, TInt32 aHigh) + { + HCR_FUNC("TRepositoryCompiled::FindSetting within the given range"); + + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(iRepos->iHdr != 0); + + if ((iRepos->iHdr->iNumSettings == 0) || + (iRepos->iOrderedSettingList == 0)) + HCR_TRACE_RETURN(KErrNotFound); + + SSettingC* arr = iRepos->iOrderedSettingList; + TInt32 low = aLow; + TInt32 high = aHigh; + TInt32 mid; + TInt32 com; + + while (low<=high) + { + mid = (low+high) >> 1; + com = CompareSSettingIds(aId, arr[mid].iName.iId); + if (com < 0) + high = mid-1; + else if (com > 0) + low = mid+1; + else + { + aSetting.iRep = this; + aSetting.iSet = &((arr[mid]).iName); + aPosition = mid; + return KErrNone; + } + } + + aSetting.iRep = 0; + aSetting.iSet = 0; + aPosition = 0; + return KErrNotFound; + } + + + +TInt HCR::TRepositoryCompiled::GetWordSettings(TInt aNum, + SSettingId* aIds[], TInt32* aValues[], TSettingType* aTypes[], + TInt* aErrors[]) + { + HCR_FUNC("TRepositoryCompiled::GetWordSettings"); + + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(iRepos->iHdr != 0); + + if ((iRepos->iHdr->iNumSettings == 0) || + (iRepos->iOrderedSettingList == 0)) + HCR_TRACE_RETURN(KErrNotFound); + + TInt err = KErrNone; + + TInt32 rMaxIndex = 0; + TInt32 rMinIndex = 0; + TInt32 uFirstIndex = 0; + TInt32 uLastIndex = 0; + TInt32 rIndex = 0; + TInt32 uIndex = 0; + + TSettingRef settingRef(NULL, NULL); + SSettingC* pSetting = NULL; + + + //Find position index within the repository for the first and last setting + //from user supplied array aIds[] + uIndex = 0; + TBool isRedefined = EFalse; + err = KErrNotFound; + uFirstIndex = 0; + while(!isRedefined && uIndex < aNum) + { + //Find first setting from user array. The importance here is that we + //should get value of first setting index in the repository in rMinIndex. + //This time the scope of search is whole repository. + err = this->FindSetting(*aIds[uIndex],settingRef, rMinIndex, + 0, iRepos->iHdr->iNumSettings); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + //Copy type only if user provided aTypes array + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //the next one from aIds[] array + uIndex ++; + continue; + } + //fatal error here, nothing to do, just exit and return the error code + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else // err == KErrNone + { + //Get the value and type + pSetting = (SSettingC*) settingRef.iSet; + //again copy the type value into the user array if it's provided + if(aTypes) + *aTypes[uIndex] = static_cast(settingRef.iSet->iType); + + //Check for the found type is this word size? If it's not then + //indicate error for this setting + if(*aTypes[uIndex] > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + //Break the loop by setting the redefined status + isRedefined = ETrue; + } + } + + //At this point we should find at least one element from the user array, + //store this index in the local variable, it is used later in the code. + //Please be noticed we've also got rMinIndex - first setting index in the + //repository. + if(err == KErrNone) + uFirstIndex = uIndex; + //if we did not find any elements at all just return KErrNotFound + else + return KErrNotFound; + + + + //Now lets find the last setting + uIndex = aNum - 1; + isRedefined = EFalse; + err = KErrNotFound; + while(!isRedefined && uIndex > uFirstIndex) + { + //Find the last setting from user array. The importance here is that we + //should get value of first setting index in the repository in + //rMinIndex. This time the scope of search is whole repository. + err = this->FindSetting(*aIds[uIndex],settingRef, rMaxIndex, + rMinIndex, iRepos->iHdr->iNumSettings); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //previous one, as we are moving in reverse direction + uIndex --; + continue; + } + //fatal error here, nothing to do, just exit and return the error code + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else //err == KErrNone + { + pSetting = (SSettingC*) settingRef.iSet; + if(aTypes) + *aTypes[uIndex] = static_cast(settingRef.iSet->iType); + + //Check for the found type is this word size? If it's not then indicate + //error for this setting + if(*aTypes[uIndex] > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + isRedefined = ETrue; + } + } + + //At this point we found the last setting, store it's user array index in + //the local variable, it is used later in the code. Please be noticed + //we've also got rMaxIndex - last setting index in the repository. + if(err == KErrNone) + uLastIndex = uIndex; + else + //if we are here we did not find any other elements than was found + //in previous iteration then just stop here + return KErrNotFound; + + //The scope of user array settings in the repository is found. + //Let's find all other settings from user array. Bare in mind the low + //bound for the repository index is increased each iteration to optimize the + //search time. + for(uIndex = uFirstIndex + 1; uIndex < uLastIndex; uIndex ++) + { + err = this->FindSetting(*aIds[uIndex],settingRef, rIndex, + rMinIndex, rMaxIndex); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //another one + continue; + } + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else //err == KErrNone + { + + pSetting = (SSettingC*) settingRef.iSet; + if(aTypes) + *aTypes[uIndex] = static_cast(settingRef.iSet->iType); + + //Check for the found type is this word size? If it's not then indicate + //error for this setting + if(*aTypes[uIndex] > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + rMinIndex = rIndex + 1; + + } + + } + + return KErrNone; + } + + + + + +TInt HCR::TRepositoryCompiled::FindNumSettingsInCategory(TCategoryUid aCatUid, + TInt32& aFirst, TInt32& aLast) + { + HCR_FUNC("TRepositoryCompiled::FindNumSettingsInCategory"); + + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(iRepos->iHdr != 0); + + if ((iRepos->iHdr->iNumSettings == 0) || (iRepos->iOrderedSettingList == 0)) + HCR_TRACE_RETURN(KErrNotFound); + + SSettingC* arr = iRepos->iOrderedSettingList; + int low = 0; + int high = iRepos->iHdr->iNumSettings-1; + int mid = 0; + int com = 0; + + //Let's find any setting within the category, mid will store the setting + //index in the repository + while (low<=high) + { + mid = (low+high) >> 1; + com = CompareByCategory(aCatUid, arr[mid].iName.iId); + if (com < 0) + high = mid-1; + else if (com > 0) + low = mid+1; + else + { + break; + } + } + + // If no one setting with the given category was found the return error + // to the user + if(low > high) + { + aFirst = 0; + aLast = 0; + return KErrNotFound; + } + + //Search the first element within the category + low = mid; + while(low > 0 && arr[low].iName.iId.iCat == aCatUid) + { + low --; + } + //Check the boundary conditions, there are two cases when we exit the loop + //either we found an element which category is not one we are looking for or + //we reach the beggining of the repository. If we reach the beggining of the + //repository we don't really know is it because this is last elment or it + //has required aCatUid, so we check these two conditions below + if(low == 0 && arr[low].iName.iId.iCat == aCatUid) + aFirst = low; + //We finish the loop either reaching the setting which category id is not + //what we need or this is first setting in the repository again with another + //category, so in both case we throw this element from the account. + else + aFirst = low + 1; + + //Search the last element within the category + high = mid; + while(high < iRepos->iHdr->iNumSettings && arr[high].iName.iId.iCat == aCatUid) + { + high ++; + } + + //Same situation as above, boundary conditions + if(high == (iRepos->iHdr->iNumSettings -1) && arr[high].iName.iId.iCat == aCatUid) + aLast = high; + else + aLast = high -1; + + + return KErrNone; + } + + + +void HCR::TRepositoryCompiled::GetSettingRef(TInt32 aIndex, + HCR::TSettingRef& aRef) + { + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(iRepos->iHdr != 0); + __NK_ASSERT_DEBUG(aIndex >=0 && aIndex < iRepos->iHdr->iNumSettings); + + if ((iRepos->iHdr->iNumSettings == 0) || (iRepos->iOrderedSettingList == 0)) + { + aRef.iRep = NULL; + aRef.iSet = NULL; + } + + //Get the pointer to the repository data + SSettingC* arr = iRepos->iOrderedSettingList; + + aRef.iRep = this; + aRef.iSet = &(arr[aIndex].iName); + } + + TInt HCR::TRepositoryCompiled::GetValue(const TSettingRef& aRef, UValueWord& aValue) { HCR_FUNC("TRepositoryCompiled::GetValue"); if (!IsWordValue(aRef)) - HCR_LOG_RETURN(KErrArgument); + HCR_TRACE_RETURN(KErrArgument); SSettingC* sptr = (SSettingC*)(aRef.iSet); aValue = sptr->iValue.iLit; @@ -525,7 +2033,7 @@ { HCR_FUNC("TRepositoryCompiled::GetLargeValue"); if (!IsLargeValue(aRef)) - HCR_LOG_RETURN(KErrArgument); + HCR_TRACE_RETURN(KErrArgument); SSettingC* sptr = (SSettingC*)(aRef.iSet); aValue = sptr->iValue.iPtr; @@ -541,6 +2049,8 @@ HCR::TRepository* HCR::TRepositoryFile::New(const SRepositoryFile* aRepos) { HCR_FUNC("TRepositoryFile::New"); + + __NK_ASSERT_ALWAYS(aRepos != 0); return new TRepositoryFile(aRepos); } @@ -552,27 +2062,32 @@ HCR::TRepositoryFile::~TRepositoryFile() { - HCR_FUNC("~TRepositoryFile"); - - } - -TInt HCR::TRepositoryFile::Initialise() - { - HCR_FUNC("TRepositoryFile::Initialise"); - + HCR_FUNC("~TRepositoryFile"); - return KErrNone; +#ifdef __WINS__ + // On target hardware the iRepos pointer always points to a file in the Core + // rom image and hence is not memory allocated on kernel heap. Hence it does + // not need to be freeded. + // When running under the emulator the file repositories are loaded into + // allocated memory which needs to be freed here. + + delete const_cast(iRepos); + iRepos = 0; +#endif // __WINS__ + } TInt HCR::TRepositoryFile::CheckIntegrity() { HCR_FUNC("TRepositoryFile::CheckIntegrity"); + __NK_ASSERT_ALWAYS(this != 0); + __NK_ASSERT_ALWAYS(iRepos != 0); if ((*((TUint32*)&(iRepos->iHdr)) != 0x66524348) || (iRepos->iHdr.iFormatVersion != 0x0001)) - HCR_LOGMSG_RETURN("File Repository header describes an unsupported repository type", KErrCorrupt); - + HCR_TRACEMSG_RETURN("File Repository header describes an unsupported repository type", KErrCorrupt); + HCR_TRACE2("File repository 0x%x contains %05d entries", iRepos, iRepos->iHdr.iNumSettings); SSettingF* arr = (SSettingF*) (iRepos+1); @@ -580,7 +2095,8 @@ TInt rc=0; for (int i=0; i < iRepos->iHdr.iNumSettings; i++, arr++) { - HCR_TRACE3("Checking entry %05d - (0x%x,%d)", i, arr->iName.iId.iCat, arr->iName.iId.iKey); + __NK_ASSERT_ALWAYS(arr != 0); + HCR_TRACE3("Checking entry %05d - (0x%x,0x%x)", i, arr->iName.iId.iCat, arr->iName.iId.iKey); rc = CompareSSettingIds(prev, arr->iName.iId); // Check for duplicates that reside next to each other if ((i > 0) && (rc == 0)) @@ -596,9 +2112,11 @@ TInt HCR::TRepositoryFile::FindSetting(const TSettingId& aId, TSettingRef& aSetting) { HCR_FUNC("TRepositoryFile::FindSetting"); - + + __NK_ASSERT_DEBUG(iRepos != 0); + if (iRepos->iHdr.iNumSettings == 0) - HCR_LOG_RETURN(KErrNotFound); + HCR_TRACE_RETURN(KErrNotFound); SSettingF* arr = (SSettingF*) (iRepos+1); int low = 0; @@ -627,35 +2145,392 @@ return KErrNotFound; } + +TInt HCR::TRepositoryFile::FindSetting (const TSettingId& aId, + TSettingRef& aSetting, TInt32& aPosition, TInt32 aLow, TInt32 aHigh) + { + HCR_FUNC("TRepositoryFile::FindSetting within the given range"); + + + __NK_ASSERT_DEBUG(iRepos != 0); + + if (iRepos->iHdr.iNumSettings == 0) + HCR_TRACE_RETURN(KErrNotFound); + + SSettingF* arr = (SSettingF*) (iRepos+1); + TInt32 low = aLow; + TInt32 high = aHigh; + TInt32 mid; + TInt32 com; + + while (low<=high) + { + mid = (low+high) >> 1; + com = CompareSSettingIds(aId, arr[mid].iName.iId); + if (com < 0) + high = mid-1; + else if (com > 0) + low = mid+1; + else + { + aSetting.iRep = this; + aSetting.iSet = &((arr[mid]).iName); + aPosition = mid; + return KErrNone; + } + } + + aSetting.iRep = 0; + aSetting.iSet = 0; + aPosition = 0; + return KErrNotFound; + } + + + + +TInt HCR::TRepositoryFile::GetWordSettings(TInt aNum, + SSettingId* aIds[], TInt32* aValues[], TSettingType* aTypes[], + TInt* aErrors[]) + { + HCR_FUNC("TRepositoryFile::GetWordSettings"); + + + __NK_ASSERT_DEBUG(iRepos != 0); + + if (iRepos->iHdr.iNumSettings == 0) + return KErrNotFound; + + TInt err = KErrNone; + + TInt32 rMaxIndex = 0; + TInt32 rMinIndex = 0; + TInt32 uFirstIndex = 0; + TInt32 uLastIndex = 0; + TInt32 rIndex = 0; + TInt32 uIndex = 0; + + TSettingRef settingRef(NULL, NULL); + SSettingF* pSetting = NULL; + + //Find position index within the repository for the first and last setting + //from user supplied array aIds[] + uIndex = 0; + TBool isRedefined = EFalse; + err = KErrNotFound; + uFirstIndex = 0; + while(!isRedefined && uIndex < aNum) + { + //Find first setting from user array. The importance here is that we + //should get value of first setting index in the repository in rMinIndex. + //This time the scope of search is whole repository. + err = this->FindSetting(*aIds[uIndex],settingRef, rMinIndex, + 0, iRepos->iHdr.iNumSettings); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + //Copy type only if user provided aTypes array + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //the next one from aIds[] array + uIndex ++; + continue; + } + //fatal error here, nothing to do, just exit and return the error code + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else // err == KErrNone + { + //Get the value and type + pSetting = (SSettingF*) settingRef.iSet; + //again copy the type value into the user array if it's provided + if(aTypes) + *aTypes[uIndex] = static_cast(settingRef.iSet->iType); + + //Check for the found type is this word size? If it's not then + //indicate error for this setting + if(*aTypes[uIndex] > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + //Break the loop by setting the redefined status + isRedefined = ETrue; + } + } + + //At this point we should find at least one element, store this index in the + //local variable, this is used later in the code. Please be noticed we've + //also got rMinIndex - first setting index in the repository. + if(err == KErrNone) + uFirstIndex = uIndex; + else + //if we are hear it means we did not find any user settings at all + //we can't do any thing and just return KErrNotFound to indicate + //this fact + return KErrNotFound; + + + + //Now lets find the last setting + uIndex = aNum - 1; + isRedefined = EFalse; + err = KErrNotFound; + + while(!isRedefined && uIndex > uFirstIndex) + { + //Find the last setting from user array. The importance here is that we + //should get value of first setting index in the repository in + //rMinIndex. This time the scope of search is whole repository. + err = this->FindSetting(*aIds[uIndex],settingRef, rMaxIndex, + rMinIndex, iRepos->iHdr.iNumSettings); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //previous one + uIndex --; + continue; + } + //fatal error here, nothing to do, just exit and return the error code + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else //err == KErrNone + { + pSetting = (SSettingF*) settingRef.iSet; + if(aTypes) + *aTypes[uIndex] = static_cast(settingRef.iSet->iType); + + //Check for the found type is this word size? If it's not then indicate + //error for this setting + if(*aTypes[uIndex] > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + isRedefined = ETrue; + } + } + + //At this point we found the last setting, store it's user array index in + //the local variable, this is used later in the code. Please be noticed + //we've also got rMaxIndex - last setting index in the repository. + if(err == KErrNone) + uLastIndex = uIndex; + else + //if we are here we did not find any other elements than was found + //in previous iteration then just stop here + return KErrNotFound; + + //The scope of user array settings in the repository is found. + //Let's find all other settings from user array. Bare in mind the low + //bound for the repository index is increased each iteration to optimize the + //search time. + for(uIndex = uFirstIndex + 1; uIndex < uLastIndex; uIndex ++) + { + err = this->FindSetting(*aIds[uIndex],settingRef, rIndex, + rMinIndex, rMaxIndex); + if(err == KErrNotFound) + { + *aErrors[uIndex] = err; + *aValues[uIndex] = 0; + if(aTypes) + *aTypes[uIndex] = ETypeUndefined; + + //As FindSetting did not find the element, let's challenge with + //another one + continue; + } + else if(err == KErrNotReady || err != KErrNone) + { + return err; + } + else //err == KErrNone + { + + pSetting = (SSettingF*) settingRef.iSet; + + TSettingType type = static_cast(settingRef.iSet->iType); + if(aTypes != NULL) + *aTypes[uIndex] = type; + + //Check for the found type is this word size? If it's not then indicate + //error for this setting + if(type > ETypeLinAddr) + { + *aErrors[uIndex] = KErrArgument; + *aValues[uIndex] = 0; + } + else + { + *aErrors[uIndex] = KErrNone; + *aValues[uIndex] = pSetting->iValue.iLit.iInt32; + } + + rMinIndex = rIndex + 1; + } + + } + + return KErrNone; + } + + + +void HCR::TRepositoryFile::GetSettingRef(TInt32 aIndex, + HCR::TSettingRef& aSetRef) + { + __NK_ASSERT_DEBUG(iRepos != 0); + __NK_ASSERT_DEBUG(aIndex >= 0 && aIndex < iRepos->iHdr.iNumSettings); + + if (iRepos->iHdr.iNumSettings == 0) + { + aSetRef.iRep = NULL; + aSetRef.iSet = NULL; + } + + SSettingF* arr = (SSettingF*)(iRepos + 1); + + aSetRef.iRep = this; + aSetRef.iSet = &(arr[aIndex].iName); + } + + + + +TInt HCR::TRepositoryFile::FindNumSettingsInCategory(TCategoryUid aCatUid, + TInt32& aFirst, TInt32& aLast) + { + HCR_FUNC("TRepositoryFile::FindNumSettingsInCategory"); + + __NK_ASSERT_DEBUG(iRepos != 0); + + if (iRepos->iHdr.iNumSettings == 0) + HCR_TRACE_RETURN(KErrNotFound); + + SSettingF* arr = (SSettingF*) (iRepos+1); + TInt32 low = 0; + TInt32 high = iRepos->iHdr.iNumSettings-1; + TInt32 mid = 0; + TInt32 com = 0; + + + //Let's find any setting within the category, mid will store the setting + //index in the repository + while (low<=high) + { + mid = (low+high) >> 1; + com = CompareByCategory(aCatUid, arr[mid].iName.iId); + if (com < 0) + high = mid-1; + else if (com > 0) + low = mid+1; + else + { + break; + } + } + + // If no one setting with the given category was found the return error + // to the user + if(low > high) + { + aFirst = 0; + aLast = 0; + return KErrNotFound; + } + + //Search the first element within the category + low = mid; + while(low > 0 && arr[low].iName.iId.iCat == aCatUid) + { + low --; + } + //Check the boundary conditions, there are two cases when we exit the loop + //either we found an element which category is not one we are looking for or + //we reach the beggining of the repository. If we reach the beggining of the + //repository we don't really know is it because this is last elment or it + //has required aCatUid, so we check these two conditions below + if(low == 0 && arr[low].iName.iId.iCat == aCatUid) + aFirst = low; + //We finish the loop either reaching the setting which category id is not + //what we need or this is first setting in the repository again with another + //category, so in both case we throw this element from the account. + else + aFirst = low + 1; + + + //Search the last element within the category + high = mid; + while(high < iRepos->iHdr.iNumSettings && arr[high].iName.iId.iCat == aCatUid) + { + high ++; + } + //Same situation as above, boundary conditions + if(high == (iRepos->iHdr.iNumSettings - 1) && arr[high].iName.iId.iCat == aCatUid) + aLast = high; + else + aLast = high -1; + + return KErrNone; + } + + + + TInt HCR::TRepositoryFile::GetValue(const TSettingRef& aRef, UValueWord& aValue) { HCR_FUNC("TRepositoryFile::GetValue"); if (!IsWordValue(aRef)) - HCR_LOG_RETURN(KErrArgument); + HCR_TRACE_RETURN(KErrArgument); SSettingF* sptr = (SSettingF*)(aRef.iSet); aValue = sptr->iValue.iLit; return KErrNone; } + TInt HCR::TRepositoryFile::GetLargeValue(const TSettingRef& aRef, UValueLarge& aValue) { HCR_FUNC("TRepositoryFile::GetLargeValue"); if (!IsLargeValue(aRef)) - HCR_LOG_RETURN(KErrArgument); + HCR_TRACE_RETURN(KErrArgument); SSettingF* sptr = (SSettingF*)(aRef.iSet); TRepositoryFile *rptr = (TRepositoryFile *)(aRef.iRep); aValue.iData = (TUint8*) rptr->iRepos; aValue.iData += rptr->iRepos->iLSDfirstByteOffset+sptr->iValue.iOffset; + return KErrNone; } - // -- FUNCTIONS --------------------------------------------------------------- #ifndef HCRTEST_NO_KEXT_ENTRY_POINT @@ -669,21 +2544,24 @@ HCR::MVariant* varPtr = CreateHCRVariant(); if (varPtr==0) - HCR_LOG_RETURN(KErrNoMemory); - + HCR_TRACE_RETURN(KErrNoMemory); + + //Call of the "placement" new operator, which constructs the HCR object on + //the global memory address defined by gHCR and initialized with the same + //data given by constructor below new(&gHCR) HCR::HCRInternal(varPtr); TInt err = HCRSingleton->Initialise(); if (err != KErrNone) - HCR_LOG_RETURN(err); + HCR_TRACE_RETURN(err); return err; } #endif // HCRTEST_NO_KEXT_ENTRY_POINT // -- Implementation of local functions - +#ifndef __WINS__ TInt SearchEntryInTRomDir(const TRomDir* aActDir, const TPtrC aFileName, TRomEntry* &aEntry) { HCR_FUNC("SearchEntryInTRomDir"); @@ -702,10 +2580,11 @@ TBool found = EFalse; while( !found ) { - HCR_TRACE0("Begin of loop..."); TInt nameLength = (aEntry->iNameLength)<<1; - HCR_HEX_DUMP_ABS((TUint8 *)aEntry, sizeof(TRomEntry)+(nameLength - 2) ); + // Uncommnet to get dump of ROM data when debugging.... + // HCR_TRACE0("Begin of loop..."); + // HCR_HEX_DUMP_ABS((TUint8 *)aEntry, sizeof(TRomEntry)+(nameLength - 2) ); const TText* entryName = &aEntry->iName[0]; HCR_TRACE1("--- entryName length: %d", nameLength); TBuf<512> newEntryName( nameLength); @@ -751,6 +2630,9 @@ HCR_TRACE_RETURN(retVal); } +#endif // !__WINS__ + + TInt SearchCoreImgRepository(HCR::TRepository*& aRepos, const TText * aFileName) { HCR_FUNC("SearchCoreImgRepository(TRepository*& aRepos, TText & aFileName)"); @@ -775,6 +2657,178 @@ origFileName.Append((const TText*)aFileName, nameLen); HCR_TRACE2("--- origFileName: %S (%d)", &origFileName, origFileName.Length()); + +#ifdef __WINS__ + TBuf wholeFilePath; + void* reposBuf = 0; + +#ifdef __VC32__ + +#ifdef _DEBUG + // - wins udeb version + wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UDEB\\"); +#else + // - wins urel version + wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINS\\UREL\\"); +#endif + +#else + +#ifdef _DEBUG + // - winscw udeb version + wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UDEB\\"); +#else + // - winscw urel version + wholeFilePath.Copy((const TText*)"\\EPOC32\\RELEASE\\WINSCW\\UREL\\"); +#endif + +#endif + + for( TInt j = 0; j < nameLen; ++j) + { + wholeFilePath.Append( origFileName[j] ); + } + + HCR_TRACE3("--- epoc emulator file path: %S (%d/%d)", &wholeFilePath, wholeFilePath.Length(), wholeFilePath.Size()); + + TInt length = wholeFilePath.Length(); + + NKern::ThreadEnterCS(); + TCHAR* chFilePath = new TCHAR[length+1]; + NKern::ThreadLeaveCS(); + + for(int loop=0;loop(reposBuf)); + NKern::ThreadLeaveCS(); + + if (aRepos == NULL) + { + retVal = KErrNoMemory; + } + + HCR_TRACE_RETURN(retVal); + +#else TBuf<512> fileNameBuf; for( TInt i = 0; i != nameLen; ++i) @@ -813,7 +2867,7 @@ // Not found root directory for this hardware variant HCR_TRACE_RETURN(retVal); } - + TRomDir* romDir = (TRomDir*)rootDirInfo->iAddressLin; HCR_TRACE3("--- romDir: 0x%08x (files:0x%08x, entries:0x%08x)", romDir, romDir->FileCount(), romDir->EntryCount() ); @@ -852,7 +2906,18 @@ // Repository file found retVal = KErrNone; HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin); +#ifdef __EPOC32__ + // HCR design requires the core image file repository to be in the + // unpaged portion of the core ROM image. This check will Fault the + // kernel startup if this is not found to be the case, perhaps due + // to mis-configured obey files. + // Skipped on emulator builds as Epoc class in platform.h not + // defined. Hence support for core images not supported. + __NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)entry->iAddressLin)); +#endif + NKern::ThreadEnterCS(); aRepos = HCR::TRepositoryFile::New(reinterpret_cast(entry->iAddressLin)); + NKern::ThreadLeaveCS(); if (aRepos == NULL) retVal = KErrNoMemory; @@ -880,7 +2945,18 @@ // Repository file found retVal = KErrNone; HCR_TRACE1("--- Repository address: 0x%08x ", entry->iAddressLin); +#ifdef __EPOC32__ + // HCR design requires the core image file repository to be in the + // unpaged portion of the core ROM image. This check will Fault the + // kernel startup if this is not found to be the case, perhaps due + // to mis-configured obey files. + // Skipped on emulator builds as Epoc class in platform.h not + // defined. Hence support for core images not supported. + __NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)entry->iAddressLin)); +#endif + NKern::ThreadEnterCS(); aRepos = HCR::TRepositoryFile::New(reinterpret_cast(entry->iAddressLin)); + NKern::ThreadLeaveCS(); if (aRepos == NULL) retVal = KErrNoMemory; } @@ -888,19 +2964,18 @@ } HCR_TRACE_RETURN(retVal); +#endif //ifdef __WINS__ } TInt LocateCoreImgRepository(HCR::TRepository*& aRepos) { HCR_FUNC("LocateCoreImgRepository"); -#ifdef __WINS__ - aRepos = 0; // To avoid warning on WINS - return KErrNotFound; -#else - #ifdef HCRTEST_COREIMG_DONTUSE_ROMHDR - + + // Use this testing more on Emulator platform + // and on hardware when ROM Header is not to be used or not implemented + const TText8* hcrfile = (const TText8*) "hcr.dat"; TInt retVal = SearchCoreImgRepository(aRepos, hcrfile); if (retVal != KErrNone) @@ -913,7 +2988,18 @@ if(romHeader.iHcrFileAddress != 0) { +#ifdef __EPOC32__ + // HCR design requires the core image file repository to be in the + // unpaged portion of the core ROM image. This check will Fault the + // kernel startup if this is not found to be the case, perhaps due + // to mis-configured obey files. + // Skipped on emulator builds as Epoc class in platform.h not + // defined. Hence support for core images not supported. + __NK_ASSERT_ALWAYS(ROMAddressIsInUnpagedSection((TLinAddr)romHeader.iHcrFileAddress)); +#endif + NKern::ThreadEnterCS(); aRepos = HCR::TRepositoryFile::New(reinterpret_cast(romHeader.iHcrFileAddress)); + NKern::ThreadLeaveCS(); if (aRepos == 0) return KErrNoMemory; } @@ -921,7 +3007,8 @@ return KErrNotFound; #endif // HCRTEST_COREIMG_DONTUSE_ROMHDR + + return KErrNone; -#endif // __WINS__ }