os/persistentdata/persistentstorage/centralrepository/common/src/heaprepos.cpp
changeset 0 bde4ae8d615e
     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 +	}