1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/persistentdata/persistentstorage/centralrepository/common/src/heaprepos.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,443 @@
1.4 +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// simrepos.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "heaprepos.h"
1.22 +
1.23 +CHeapRepository* CHeapRepository::NewL(TUid aUid)
1.24 + {
1.25 + CHeapRepository* repos=new (ELeave) CHeapRepository(aUid);
1.26 + return repos;
1.27 + }
1.28 +
1.29 +CHeapRepository::CHeapRepository(TUid aUid)
1.30 + :iSettings(),iUid(aUid),iSinglePolicies(KGranularity)
1.31 + {
1.32 + }
1.33 +
1.34 +CHeapRepository::~CHeapRepository()
1.35 + {
1.36 + iSinglePolicies.ResetAndDestroy();
1.37 + iRangePolicies.Close();
1.38 + iDeletedSettings.Close();
1.39 + iSettings.Close();
1.40 + iRangeMeta.Close();
1.41 + }
1.42 +
1.43 +/**
1.44 +Stores the repository in-memory content to the related repository file on drive C.
1.45 +If the operation fails, the in-memory content won't match the content of
1.46 +the repository file (which will be kept as it was before the CommitChangesL() call).
1.47 +In order to keep the consistency, the in-memory repository content is deleted now
1.48 +and restored later, on the next repository operation.
1.49 +*/
1.50 +TInt CHeapRepository::CommitChanges(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath)
1.51 + {
1.52 + TRAPD(error, DoCommitChangesL(aFs,aPersistVersion,aTargetFilePath));
1.53 + if (error != KErrNone)
1.54 + {
1.55 + //If the commit fails reset the repository as it is in an inconsistent state
1.56 + ResetContent();
1.57 + }
1.58 + return error;
1.59 + }
1.60 +
1.61 +void CHeapRepository::SetMetaDataOnRead(TServerSetting& aSetting, TBool aSingleMetaFound)
1.62 + {
1.63 + TInt isMetaFlagSet = aSetting.Meta() & KMetaDefaultValue;
1.64 +
1.65 + if(!aSingleMetaFound)
1.66 + // No single metadata set for this key
1.67 + {
1.68 + // First check for a matching "range" default metadata
1.69 + // setting
1.70 + TSettingsDefaultMeta* defaultMeta = iRangeMeta.Find(aSetting.Key());
1.71 + if (defaultMeta)
1.72 + {
1.73 + if (isMetaFlagSet)
1.74 + //sets a default meta data
1.75 + //also sets the flag back to indicate that it is a default setting from ROM
1.76 + //or previous install so it can be replaced later with a new one.
1.77 + aSetting.SetMeta(defaultMeta->GetDefaultMetadata() | KMetaDefaultValue);
1.78 + else
1.79 + aSetting.SetMeta(defaultMeta->GetDefaultMetadata());
1.80 + }
1.81 + else
1.82 + {
1.83 + // Range value not found, try for a repository default
1.84 + if (isMetaFlagSet)
1.85 + aSetting.SetMeta(iDefaultMeta | KMetaDefaultValue) ;
1.86 + else
1.87 + aSetting.SetMeta(iDefaultMeta) ;
1.88 + }
1.89 + }
1.90 +
1.91 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.92 +#ifdef CENTREP_CONV_TOOL
1.93 + if (aSingleMetaFound && aSetting.IsClean() && !aSetting.IsIndividualMeta())
1.94 + aSingleMetaFound=EFalse;
1.95 +#endif
1.96 + aSetting.SetIndividualMeta(aSingleMetaFound);
1.97 +#endif
1.98 + }
1.99 +
1.100 +TInt CHeapRepository::Create(TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool aSingleMetaFound)
1.101 + {
1.102 + if(iSettings.Find(aSetting.Key()))
1.103 + return KErrAlreadyExists;
1.104 +
1.105 + SetMetaDataOnRead( aSetting, aSingleMetaFound);
1.106 + aSetting.SetAccessPolicy(aPolicy);
1.107 +
1.108 + return iSettings.OrderedInsert(aSetting);
1.109 + }
1.110 +
1.111 +// Comparison relation to allow single policies to be inserted in order
1.112 +TInt CHeapRepository::CompareKeyIds(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem)
1.113 + {
1.114 + if(aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey)
1.115 + return 0;
1.116 + return (aSinglePolicy.iLowKey < aSinglePolicyIndexItem.iLowKey)?-1:1;
1.117 + }
1.118 +
1.119 +// Identity relation to allow single policy for a given key to be found
1.120 +TBool CHeapRepository::SinglePolicyMatchOnKey(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem)
1.121 + {
1.122 + return aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey;
1.123 + }
1.124 +
1.125 +// returns the read security policy used if there is no per-setting policy at aId
1.126 +const TSecurityPolicy& CHeapRepository::GetFallbackReadAccessPolicy(TUint32 aId)
1.127 + {
1.128 + return *(GetFallbackAccessPolicy(aId)->GetReadAccessPolicy());
1.129 + }
1.130 +
1.131 +// returns the write security policy used if there is no per-setting policy at aId
1.132 +const TSecurityPolicy& CHeapRepository::GetFallbackWriteAccessPolicy(TUint32 aId)
1.133 + {
1.134 + return *(GetFallbackAccessPolicy(aId)->GetWriteAccessPolicy());
1.135 + }
1.136 +
1.137 +// Get pointer to security policy that applies to a given setting
1.138 +TSettingsAccessPolicy* CHeapRepository::GetFallbackAccessPolicy(TUint32 aId
1.139 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.140 + ,TBool aSkipSingle
1.141 +#endif
1.142 + )
1.143 + {
1.144 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.145 + if (!aSkipSingle)
1.146 + {
1.147 +#endif
1.148 + // Check for single policy
1.149 + TSettingsAccessPolicy policy(aId);
1.150 + TIdentityRelation<TSettingsAccessPolicy> identity(SinglePolicyMatchOnKey);
1.151 + TInt index = iSinglePolicies.Find(&policy, identity);
1.152 + if(KErrNotFound != index)
1.153 + return iSinglePolicies[index];
1.154 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.155 + }
1.156 +#endif
1.157 +
1.158 + // check if the aId falls into any range specified in the ini file
1.159 + TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aId);
1.160 + if(rangePolicy)
1.161 + return rangePolicy;
1.162 +
1.163 + // If no single policy or range policy, return default policy
1.164 + return &iDefaultPolicy;
1.165 + }
1.166 +
1.167 +// this function saves idividual meta as well
1.168 +TInt CHeapRepository::ReadSettingSavePolicyL(CIniFileIn& aFile,TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool& aSingleMetaFound)
1.169 + {
1.170 + TBool singleReadPolicyFound;
1.171 + TBool singleWritePolicyFound;
1.172 + TSecurityPolicy singleReadPolicy;
1.173 + TSecurityPolicy singleWritePolicy;
1.174 +
1.175 + TInt err=aFile.ReadSettingL(aSetting,singleReadPolicy, singleWritePolicy, singleReadPolicyFound, singleWritePolicyFound, aSingleMetaFound);
1.176 + if(err!=KErrNone)
1.177 + return err;
1.178 +
1.179 + // Set up single policies
1.180 + if(!singleReadPolicyFound)
1.181 + singleReadPolicy=GetDefaultReadAccessPolicy();
1.182 + if(!singleWritePolicyFound)
1.183 + singleWritePolicy=GetDefaultWriteAccessPolicy();
1.184 +
1.185 + aSetting.PushL();
1.186 + if(singleReadPolicyFound || singleWritePolicyFound)
1.187 + {
1.188 + aPolicy=new (ELeave) TSettingsAccessPolicy(singleReadPolicy,singleWritePolicy,aSetting.Key());
1.189 + CleanupStack::PushL(aPolicy);
1.190 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.191 + //reused single setting high key and mask to indicate whether read or write has been specified
1.192 + //or they are just a default policy
1.193 + if (singleReadPolicyFound)
1.194 + aPolicy->iHighKey=1;
1.195 + if (singleWritePolicyFound)
1.196 + aPolicy->iKeyMask=1;
1.197 +#endif
1.198 + TLinearOrder<TSettingsAccessPolicy> order(&CHeapRepository::CompareKeyIds);
1.199 + iSinglePolicies.InsertInOrderL(aPolicy,order);
1.200 + CleanupStack::Pop(aPolicy);
1.201 + }
1.202 + else
1.203 + {
1.204 + // check if the aId falls into any range specified in the ini file
1.205 + // otherwise set policy to default policy
1.206 + TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aSetting.Key());
1.207 + if(rangePolicy)
1.208 + aPolicy=rangePolicy;
1.209 + else
1.210 + aPolicy=&iDefaultPolicy;
1.211 + }
1.212 +
1.213 + aSetting.Pop();
1.214 + return err;
1.215 + }
1.216 +
1.217 +#ifdef CENTREP_CONV_TOOL
1.218 +void CHeapRepository::DoCommitChangesToIniFileL(RFs& aFs,const TDesC& aOutFileName
1.219 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.220 + ,TUint32 aCreVersion
1.221 +#endif
1.222 + )
1.223 + {
1.224 + CIniFileOut* out = CIniFileOut::NewLC(aFs,aOutFileName);
1.225 +
1.226 + out->WriteHeaderL();
1.227 + out->WriteOwnerSectionL(iOwner);
1.228 + out->WriteTimeStampL(iTimeStamp);
1.229 + out->WriteMetaDataL(iDefaultMeta, iRangeMeta);
1.230 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.231 + out->WritePlatSecL(GetDefaultAccessPolicy(), iRangePolicies,aCreVersion);
1.232 +#else
1.233 + out->WritePlatSecL(GetDefaultReadAccessPolicy(), GetDefaultWriteAccessPolicy(), iRangePolicies);
1.234 +#endif
1.235 +
1.236 +
1.237 + out->WriteMainSectionHeaderL();
1.238 + for(TInt i=0; i<iSettings.Count(); i++)
1.239 + {
1.240 + const TServerSetting& setting = iSettings[i];
1.241 + if (setting.HasAccessPolicy() && (iSinglePolicies.Find(setting.AccessPolicy()) != KErrNotFound))
1.242 + {
1.243 + out->WriteSettingL(setting, *setting.AccessPolicy()
1.244 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.245 + ,aCreVersion
1.246 +#endif
1.247 + );
1.248 + }
1.249 + else
1.250 + {
1.251 + out->WriteSettingL(setting
1.252 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.253 + ,aCreVersion
1.254 +#endif
1.255 + );
1.256 + }
1.257 + }
1.258 +
1.259 + out->CommitL();
1.260 + CleanupStack::PopAndDestroy(out);//out
1.261 + }
1.262 +#endif
1.263 +
1.264 +void CHeapRepository::DoCommitChangesL(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath)
1.265 + {
1.266 + CCreGenerator::CommitChangesToCreL(aFs,aPersistVersion,*this, aTargetFilePath);
1.267 + }
1.268 +
1.269 +/**
1.270 +The method reloads the repository content from a repository file.
1.271 +The current repository must be emptied (or must be empty already) before the call is made.
1.272 +@param aIniFile A reference to CIniFileIn object, which will be used to load
1.273 + the repository content.
1.274 +@leave System-wide error codes.
1.275 +@leave KErrGeneral It's probably a programmer's error - current CHeapRepository
1.276 + object is partially initialised.
1.277 +@leave KErrCorrupt Corrupted repository file.
1.278 +*/
1.279 +void CHeapRepository::ReloadContentL(CIniFileIn& aIniFile)
1.280 + {
1.281 + // Preconditions - CHeapRepository object should be an empty one.
1.282 + if(!IsEmpty())
1.283 + {
1.284 + User::Leave(KErrGeneral);
1.285 + }
1.286 + TInt err = ReloadContentExceptSettingsL(aIniFile);
1.287 + if(err == KErrCorrupt)
1.288 + {
1.289 + User::Leave(err);
1.290 + }
1.291 + CleanupClosePushL(iRangeMeta);
1.292 + CleanupClosePushL(iRangePolicies);
1.293 +
1.294 + // Settings
1.295 + TServerSetting setting;
1.296 + TSettingsAccessPolicy* policy;
1.297 + TBool singleMetaFound;
1.298 + TCleanupItem tc(SinglePoliciesCleanup, &iSinglePolicies);
1.299 + CleanupStack::PushL(tc);
1.300 + CleanupClosePushL(iSettings);
1.301 + while((err = ReadSettingSavePolicyL(aIniFile, setting, policy, singleMetaFound)) == KErrNone)
1.302 + {
1.303 + setting.PushL();
1.304 + if(iSettings.IsDefault())
1.305 + {
1.306 + setting.SetClean();
1.307 + }
1.308 + User::LeaveIfError(Create(setting, policy, singleMetaFound));
1.309 + setting.Pop();
1.310 + }
1.311 + if(err == KErrNotFound)
1.312 + {
1.313 + err = KErrNone;
1.314 + }
1.315 + User::LeaveIfError(err);
1.316 + CleanupStack::Pop(4,&iRangeMeta);
1.317 + }
1.318 +
1.319 +/**
1.320 +Resets current repository data - actually all of them, which may be loaded from
1.321 +the related ini file.
1.322 +The iUid data member value is kept as it was at the moment of creation of
1.323 +CHeapRepository object.
1.324 +*/
1.325 +void CHeapRepository::ResetContent()
1.326 + {
1.327 + iSettings.Reset();
1.328 + iOwner = KNullUid;
1.329 + iTimeStamp = TTime(0);
1.330 +
1.331 + for (TInt i=0;i<iSinglePolicies.Count();i++)
1.332 + {
1.333 + delete iSinglePolicies[i];
1.334 + }
1.335 + iSinglePolicies.Reset();
1.336 + iRangePolicies.Reset();
1.337 + TSecurityPolicy emptyPolicy=TSecurityPolicy();
1.338 + iDefaultPolicy = TSettingsAccessPolicy(emptyPolicy,emptyPolicy, KUnspecifiedKey);
1.339 + iDefaultMeta = 0;
1.340 + iRangeMeta.Reset();
1.341 + }
1.342 +
1.343 +void CHeapRepository::CreateRepositoryFromCreFileL(RFs& aFs,const TDesC& aFilePath )
1.344 + {
1.345 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.346 + TUint8 dummyVersion;
1.347 + CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath,dummyVersion);
1.348 +#else
1.349 + CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath);
1.350 +#endif
1.351 + }
1.352 +
1.353 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.354 +void CHeapRepository::CreateRepositoryFromCreFileL(RFs& aFs,const TDesC& aFilePath,TUint8& aCreVersion)
1.355 + {
1.356 + CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath,aCreVersion);
1.357 + }
1.358 +#endif
1.359 +
1.360 +void CHeapRepository::ExternalizeCre(TUint8 aPersistVersion,RWriteStream& aStream) const
1.361 + {
1.362 + CCreGenerator::ExternalizeCre(aPersistVersion,*this, aStream);
1.363 + }
1.364 +
1.365 +
1.366 +void CHeapRepository::InternalizeCreL(RReadStream& aStream)
1.367 + {
1.368 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.369 + TUint8 dummyVersion;
1.370 + CCreGenerator::InternalizeCreL(*this, aStream,dummyVersion);
1.371 +#else
1.372 + CCreGenerator::InternalizeCreL(*this, aStream);
1.373 +#endif
1.374 + }
1.375 +
1.376 +
1.377 +void CHeapRepository::SinglePoliciesCleanup(TAny *aPtr)
1.378 + {
1.379 + static_cast<RPointerArray<TSettingsAccessPolicy>*>(aPtr)->ResetAndDestroy();
1.380 + }
1.381 +
1.382 +TInt CHeapRepository::ReloadContentExceptSettingsL(CIniFileIn& aIniFile)
1.383 + {
1.384 + // Look for an "owner" section
1.385 + TUint32 uidValue(KNullUid.iUid);
1.386 + TInt err = aIniFile.ReadOwnerSectionL(uidValue);
1.387 + if(err == KErrCorrupt)
1.388 + {
1.389 + return err;
1.390 + }
1.391 + iOwner.iUid = uidValue;
1.392 + // Timestamp
1.393 + TTime timeStamp (0);
1.394 + err = aIniFile.ReadTimeStampSectionL(timeStamp);
1.395 + if(err == KErrCorrupt)
1.396 + {
1.397 + return err;
1.398 + }
1.399 + iTimeStamp=timeStamp;
1.400 +
1.401 + // Metadata
1.402 + err = aIniFile.ReadDefaultMetaSecSectionL(iDefaultMeta, iRangeMeta);
1.403 + // Even if err == KErrCorrupt, some items might have already been placed in the array
1.404 + CleanupClosePushL(iRangeMeta);
1.405 + if(err == KErrCorrupt)
1.406 + {
1.407 + CleanupStack::PopAndDestroy(&iRangeMeta);
1.408 + return err;
1.409 + }
1.410 +
1.411 + // Default read/write policies
1.412 + TBool gotDefaultReadPolicy;
1.413 + TBool gotDefaultWritePolicy;
1.414 + TSecurityPolicy defaultReadPolicy;
1.415 + TSecurityPolicy defaultWritePolicy;
1.416 + err = aIniFile.ReadPlatSecSectionL(defaultReadPolicy, gotDefaultReadPolicy,
1.417 + defaultWritePolicy, gotDefaultWritePolicy,
1.418 + iRangePolicies);
1.419 + // Even if err == KErrCorrupt, some items might have already been placed in the array
1.420 + CleanupClosePushL(iRangePolicies);
1.421 + if(err == KErrCorrupt)
1.422 + {
1.423 + CleanupStack::PopAndDestroy(2,&iRangeMeta);
1.424 + return err;
1.425 + }
1.426 +
1.427 + iDefaultPolicy = TSettingsAccessPolicy(defaultReadPolicy,defaultWritePolicy, KUnspecifiedKey);
1.428 +#ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
1.429 + if (gotDefaultReadPolicy)
1.430 + iDefaultPolicy.iHighKey=1;
1.431 + if (gotDefaultWritePolicy)
1.432 + iDefaultPolicy.iKeyMask=1;
1.433 +#endif
1.434 + CleanupStack::Pop(2,&iRangeMeta);
1.435 + return KErrNone;
1.436 + }
1.437 +
1.438 +TBool CHeapRepository::IsEmpty()
1.439 + {
1.440 + if(iSettings.Count() != 0 || iRangeMeta.Count() != 0 ||
1.441 + iSinglePolicies.Count() != 0 || iRangePolicies.Count() != 0)
1.442 + {
1.443 + return EFalse;
1.444 + }
1.445 + return ETrue;
1.446 + }