sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // simrepos.cpp sl@0: // sl@0: // sl@0: sl@0: #include "heaprepos.h" sl@0: sl@0: CHeapRepository* CHeapRepository::NewL(TUid aUid) sl@0: { sl@0: CHeapRepository* repos=new (ELeave) CHeapRepository(aUid); sl@0: return repos; sl@0: } sl@0: sl@0: CHeapRepository::CHeapRepository(TUid aUid) sl@0: :iSettings(),iUid(aUid),iSinglePolicies(KGranularity) sl@0: { sl@0: } sl@0: sl@0: CHeapRepository::~CHeapRepository() sl@0: { sl@0: iSinglePolicies.ResetAndDestroy(); sl@0: iRangePolicies.Close(); sl@0: iDeletedSettings.Close(); sl@0: iSettings.Close(); sl@0: iRangeMeta.Close(); sl@0: } sl@0: sl@0: /** sl@0: Stores the repository in-memory content to the related repository file on drive C. sl@0: If the operation fails, the in-memory content won't match the content of sl@0: the repository file (which will be kept as it was before the CommitChangesL() call). sl@0: In order to keep the consistency, the in-memory repository content is deleted now sl@0: and restored later, on the next repository operation. sl@0: */ sl@0: TInt CHeapRepository::CommitChanges(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath) sl@0: { sl@0: TRAPD(error, DoCommitChangesL(aFs,aPersistVersion,aTargetFilePath)); sl@0: if (error != KErrNone) sl@0: { sl@0: //If the commit fails reset the repository as it is in an inconsistent state sl@0: ResetContent(); sl@0: } sl@0: return error; sl@0: } sl@0: sl@0: void CHeapRepository::SetMetaDataOnRead(TServerSetting& aSetting, TBool aSingleMetaFound) sl@0: { sl@0: TInt isMetaFlagSet = aSetting.Meta() & KMetaDefaultValue; sl@0: sl@0: if(!aSingleMetaFound) sl@0: // No single metadata set for this key sl@0: { sl@0: // First check for a matching "range" default metadata sl@0: // setting sl@0: TSettingsDefaultMeta* defaultMeta = iRangeMeta.Find(aSetting.Key()); sl@0: if (defaultMeta) sl@0: { sl@0: if (isMetaFlagSet) sl@0: //sets a default meta data sl@0: //also sets the flag back to indicate that it is a default setting from ROM sl@0: //or previous install so it can be replaced later with a new one. sl@0: aSetting.SetMeta(defaultMeta->GetDefaultMetadata() | KMetaDefaultValue); sl@0: else sl@0: aSetting.SetMeta(defaultMeta->GetDefaultMetadata()); sl@0: } sl@0: else sl@0: { sl@0: // Range value not found, try for a repository default sl@0: if (isMetaFlagSet) sl@0: aSetting.SetMeta(iDefaultMeta | KMetaDefaultValue) ; sl@0: else sl@0: aSetting.SetMeta(iDefaultMeta) ; sl@0: } sl@0: } sl@0: sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: #ifdef CENTREP_CONV_TOOL sl@0: if (aSingleMetaFound && aSetting.IsClean() && !aSetting.IsIndividualMeta()) sl@0: aSingleMetaFound=EFalse; sl@0: #endif sl@0: aSetting.SetIndividualMeta(aSingleMetaFound); sl@0: #endif sl@0: } sl@0: sl@0: TInt CHeapRepository::Create(TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool aSingleMetaFound) sl@0: { sl@0: if(iSettings.Find(aSetting.Key())) sl@0: return KErrAlreadyExists; sl@0: sl@0: SetMetaDataOnRead( aSetting, aSingleMetaFound); sl@0: aSetting.SetAccessPolicy(aPolicy); sl@0: sl@0: return iSettings.OrderedInsert(aSetting); sl@0: } sl@0: sl@0: // Comparison relation to allow single policies to be inserted in order sl@0: TInt CHeapRepository::CompareKeyIds(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem) sl@0: { sl@0: if(aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey) sl@0: return 0; sl@0: return (aSinglePolicy.iLowKey < aSinglePolicyIndexItem.iLowKey)?-1:1; sl@0: } sl@0: sl@0: // Identity relation to allow single policy for a given key to be found sl@0: TBool CHeapRepository::SinglePolicyMatchOnKey(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem) sl@0: { sl@0: return aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey; sl@0: } sl@0: sl@0: // returns the read security policy used if there is no per-setting policy at aId sl@0: const TSecurityPolicy& CHeapRepository::GetFallbackReadAccessPolicy(TUint32 aId) sl@0: { sl@0: return *(GetFallbackAccessPolicy(aId)->GetReadAccessPolicy()); sl@0: } sl@0: sl@0: // returns the write security policy used if there is no per-setting policy at aId sl@0: const TSecurityPolicy& CHeapRepository::GetFallbackWriteAccessPolicy(TUint32 aId) sl@0: { sl@0: return *(GetFallbackAccessPolicy(aId)->GetWriteAccessPolicy()); sl@0: } sl@0: sl@0: // Get pointer to security policy that applies to a given setting sl@0: TSettingsAccessPolicy* CHeapRepository::GetFallbackAccessPolicy(TUint32 aId sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: ,TBool aSkipSingle sl@0: #endif sl@0: ) sl@0: { sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: if (!aSkipSingle) sl@0: { sl@0: #endif sl@0: // Check for single policy sl@0: TSettingsAccessPolicy policy(aId); sl@0: TIdentityRelation identity(SinglePolicyMatchOnKey); sl@0: TInt index = iSinglePolicies.Find(&policy, identity); sl@0: if(KErrNotFound != index) sl@0: return iSinglePolicies[index]; sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: } sl@0: #endif sl@0: sl@0: // check if the aId falls into any range specified in the ini file sl@0: TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aId); sl@0: if(rangePolicy) sl@0: return rangePolicy; sl@0: sl@0: // If no single policy or range policy, return default policy sl@0: return &iDefaultPolicy; sl@0: } sl@0: sl@0: // this function saves idividual meta as well sl@0: TInt CHeapRepository::ReadSettingSavePolicyL(CIniFileIn& aFile,TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool& aSingleMetaFound) sl@0: { sl@0: TBool singleReadPolicyFound; sl@0: TBool singleWritePolicyFound; sl@0: TSecurityPolicy singleReadPolicy; sl@0: TSecurityPolicy singleWritePolicy; sl@0: sl@0: TInt err=aFile.ReadSettingL(aSetting,singleReadPolicy, singleWritePolicy, singleReadPolicyFound, singleWritePolicyFound, aSingleMetaFound); sl@0: if(err!=KErrNone) sl@0: return err; sl@0: sl@0: // Set up single policies sl@0: if(!singleReadPolicyFound) sl@0: singleReadPolicy=GetDefaultReadAccessPolicy(); sl@0: if(!singleWritePolicyFound) sl@0: singleWritePolicy=GetDefaultWriteAccessPolicy(); sl@0: sl@0: aSetting.PushL(); sl@0: if(singleReadPolicyFound || singleWritePolicyFound) sl@0: { sl@0: aPolicy=new (ELeave) TSettingsAccessPolicy(singleReadPolicy,singleWritePolicy,aSetting.Key()); sl@0: CleanupStack::PushL(aPolicy); sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: //reused single setting high key and mask to indicate whether read or write has been specified sl@0: //or they are just a default policy sl@0: if (singleReadPolicyFound) sl@0: aPolicy->iHighKey=1; sl@0: if (singleWritePolicyFound) sl@0: aPolicy->iKeyMask=1; sl@0: #endif sl@0: TLinearOrder order(&CHeapRepository::CompareKeyIds); sl@0: iSinglePolicies.InsertInOrderL(aPolicy,order); sl@0: CleanupStack::Pop(aPolicy); sl@0: } sl@0: else sl@0: { sl@0: // check if the aId falls into any range specified in the ini file sl@0: // otherwise set policy to default policy sl@0: TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aSetting.Key()); sl@0: if(rangePolicy) sl@0: aPolicy=rangePolicy; sl@0: else sl@0: aPolicy=&iDefaultPolicy; sl@0: } sl@0: sl@0: aSetting.Pop(); sl@0: return err; sl@0: } sl@0: sl@0: #ifdef CENTREP_CONV_TOOL sl@0: void CHeapRepository::DoCommitChangesToIniFileL(RFs& aFs,const TDesC& aOutFileName sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: ,TUint32 aCreVersion sl@0: #endif sl@0: ) sl@0: { sl@0: CIniFileOut* out = CIniFileOut::NewLC(aFs,aOutFileName); sl@0: sl@0: out->WriteHeaderL(); sl@0: out->WriteOwnerSectionL(iOwner); sl@0: out->WriteTimeStampL(iTimeStamp); sl@0: out->WriteMetaDataL(iDefaultMeta, iRangeMeta); sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: out->WritePlatSecL(GetDefaultAccessPolicy(), iRangePolicies,aCreVersion); sl@0: #else sl@0: out->WritePlatSecL(GetDefaultReadAccessPolicy(), GetDefaultWriteAccessPolicy(), iRangePolicies); sl@0: #endif sl@0: sl@0: sl@0: out->WriteMainSectionHeaderL(); sl@0: for(TInt i=0; iWriteSettingL(setting, *setting.AccessPolicy() sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: ,aCreVersion sl@0: #endif sl@0: ); sl@0: } sl@0: else sl@0: { sl@0: out->WriteSettingL(setting sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: ,aCreVersion sl@0: #endif sl@0: ); sl@0: } sl@0: } sl@0: sl@0: out->CommitL(); sl@0: CleanupStack::PopAndDestroy(out);//out sl@0: } sl@0: #endif sl@0: sl@0: void CHeapRepository::DoCommitChangesL(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath) sl@0: { sl@0: CCreGenerator::CommitChangesToCreL(aFs,aPersistVersion,*this, aTargetFilePath); sl@0: } sl@0: sl@0: /** sl@0: The method reloads the repository content from a repository file. sl@0: The current repository must be emptied (or must be empty already) before the call is made. sl@0: @param aIniFile A reference to CIniFileIn object, which will be used to load sl@0: the repository content. sl@0: @leave System-wide error codes. sl@0: @leave KErrGeneral It's probably a programmer's error - current CHeapRepository sl@0: object is partially initialised. sl@0: @leave KErrCorrupt Corrupted repository file. sl@0: */ sl@0: void CHeapRepository::ReloadContentL(CIniFileIn& aIniFile) sl@0: { sl@0: // Preconditions - CHeapRepository object should be an empty one. sl@0: if(!IsEmpty()) sl@0: { sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: TInt err = ReloadContentExceptSettingsL(aIniFile); sl@0: if(err == KErrCorrupt) sl@0: { sl@0: User::Leave(err); sl@0: } sl@0: CleanupClosePushL(iRangeMeta); sl@0: CleanupClosePushL(iRangePolicies); sl@0: sl@0: // Settings sl@0: TServerSetting setting; sl@0: TSettingsAccessPolicy* policy; sl@0: TBool singleMetaFound; sl@0: TCleanupItem tc(SinglePoliciesCleanup, &iSinglePolicies); sl@0: CleanupStack::PushL(tc); sl@0: CleanupClosePushL(iSettings); sl@0: while((err = ReadSettingSavePolicyL(aIniFile, setting, policy, singleMetaFound)) == KErrNone) sl@0: { sl@0: setting.PushL(); sl@0: if(iSettings.IsDefault()) sl@0: { sl@0: setting.SetClean(); sl@0: } sl@0: User::LeaveIfError(Create(setting, policy, singleMetaFound)); sl@0: setting.Pop(); sl@0: } sl@0: if(err == KErrNotFound) sl@0: { sl@0: err = KErrNone; sl@0: } sl@0: User::LeaveIfError(err); sl@0: CleanupStack::Pop(4,&iRangeMeta); sl@0: } sl@0: sl@0: /** sl@0: Resets current repository data - actually all of them, which may be loaded from sl@0: the related ini file. sl@0: The iUid data member value is kept as it was at the moment of creation of sl@0: CHeapRepository object. sl@0: */ sl@0: void CHeapRepository::ResetContent() sl@0: { sl@0: iSettings.Reset(); sl@0: iOwner = KNullUid; sl@0: iTimeStamp = TTime(0); sl@0: sl@0: for (TInt i=0;i*>(aPtr)->ResetAndDestroy(); sl@0: } sl@0: sl@0: TInt CHeapRepository::ReloadContentExceptSettingsL(CIniFileIn& aIniFile) sl@0: { sl@0: // Look for an "owner" section sl@0: TUint32 uidValue(KNullUid.iUid); sl@0: TInt err = aIniFile.ReadOwnerSectionL(uidValue); sl@0: if(err == KErrCorrupt) sl@0: { sl@0: return err; sl@0: } sl@0: iOwner.iUid = uidValue; sl@0: // Timestamp sl@0: TTime timeStamp (0); sl@0: err = aIniFile.ReadTimeStampSectionL(timeStamp); sl@0: if(err == KErrCorrupt) sl@0: { sl@0: return err; sl@0: } sl@0: iTimeStamp=timeStamp; sl@0: sl@0: // Metadata sl@0: err = aIniFile.ReadDefaultMetaSecSectionL(iDefaultMeta, iRangeMeta); sl@0: // Even if err == KErrCorrupt, some items might have already been placed in the array sl@0: CleanupClosePushL(iRangeMeta); sl@0: if(err == KErrCorrupt) sl@0: { sl@0: CleanupStack::PopAndDestroy(&iRangeMeta); sl@0: return err; sl@0: } sl@0: sl@0: // Default read/write policies sl@0: TBool gotDefaultReadPolicy; sl@0: TBool gotDefaultWritePolicy; sl@0: TSecurityPolicy defaultReadPolicy; sl@0: TSecurityPolicy defaultWritePolicy; sl@0: err = aIniFile.ReadPlatSecSectionL(defaultReadPolicy, gotDefaultReadPolicy, sl@0: defaultWritePolicy, gotDefaultWritePolicy, sl@0: iRangePolicies); sl@0: // Even if err == KErrCorrupt, some items might have already been placed in the array sl@0: CleanupClosePushL(iRangePolicies); sl@0: if(err == KErrCorrupt) sl@0: { sl@0: CleanupStack::PopAndDestroy(2,&iRangeMeta); sl@0: return err; sl@0: } sl@0: sl@0: iDefaultPolicy = TSettingsAccessPolicy(defaultReadPolicy,defaultWritePolicy, KUnspecifiedKey); sl@0: #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS sl@0: if (gotDefaultReadPolicy) sl@0: iDefaultPolicy.iHighKey=1; sl@0: if (gotDefaultWritePolicy) sl@0: iDefaultPolicy.iKeyMask=1; sl@0: #endif sl@0: CleanupStack::Pop(2,&iRangeMeta); sl@0: return KErrNone; sl@0: } sl@0: sl@0: TBool CHeapRepository::IsEmpty() sl@0: { sl@0: if(iSettings.Count() != 0 || iRangeMeta.Count() != 0 || sl@0: iSinglePolicies.Count() != 0 || iRangePolicies.Count() != 0) sl@0: { sl@0: return EFalse; sl@0: } sl@0: return ETrue; sl@0: }