persistentstorage/centralrepository/common/src/heaprepos.cpp
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // simrepos.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "heaprepos.h"
       
    19 
       
    20 CHeapRepository* CHeapRepository::NewL(TUid aUid)
       
    21 	{
       
    22 	CHeapRepository* repos=new (ELeave) CHeapRepository(aUid);
       
    23 	return repos;
       
    24 	}
       
    25 
       
    26 CHeapRepository::CHeapRepository(TUid aUid)
       
    27 	:iSettings(),iUid(aUid),iSinglePolicies(KGranularity)
       
    28 	{
       
    29 	}
       
    30 
       
    31 CHeapRepository::~CHeapRepository()
       
    32 	{
       
    33 	iSinglePolicies.ResetAndDestroy();
       
    34 	iRangePolicies.Close();
       
    35 	iDeletedSettings.Close();
       
    36 	iSettings.Close();
       
    37 	iRangeMeta.Close();
       
    38 	}
       
    39 
       
    40 /**
       
    41 Stores the repository in-memory content to the related repository file on drive C.
       
    42 If the operation fails, the in-memory content won't match the content of 
       
    43 the repository file (which will be kept as it was before the CommitChangesL() call).
       
    44 In order to keep the consistency, the in-memory repository content is deleted now
       
    45 and restored later, on the next repository operation.
       
    46 */
       
    47 TInt CHeapRepository::CommitChanges(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath)
       
    48 	{
       
    49 	TRAPD(error, DoCommitChangesL(aFs,aPersistVersion,aTargetFilePath));
       
    50 	if (error != KErrNone)
       
    51 		{	
       
    52 		//If the commit fails reset the repository as it is in an inconsistent state
       
    53 		ResetContent();
       
    54 		}
       
    55 	return error;
       
    56 	}	
       
    57 
       
    58 void CHeapRepository::SetMetaDataOnRead(TServerSetting& aSetting, TBool aSingleMetaFound)
       
    59 	{
       
    60 	TInt isMetaFlagSet = aSetting.Meta() & KMetaDefaultValue;
       
    61 	
       
    62 	if(!aSingleMetaFound)
       
    63 		// No single metadata set for this key
       
    64 		{
       
    65 		// First check for a matching "range" default metadata
       
    66 		// setting
       
    67 		TSettingsDefaultMeta* defaultMeta = iRangeMeta.Find(aSetting.Key());
       
    68 		if (defaultMeta)
       
    69 			{
       
    70 			if (isMetaFlagSet)
       
    71 				//sets a default meta data
       
    72 				//also sets the flag back to indicate that it is a default setting from ROM 
       
    73 				//or previous install so it can be replaced later with a new one. 
       
    74 				aSetting.SetMeta(defaultMeta->GetDefaultMetadata() | KMetaDefaultValue);
       
    75 			else
       
    76 				aSetting.SetMeta(defaultMeta->GetDefaultMetadata());
       
    77 			}
       
    78 		else
       
    79 			{
       
    80 			// Range value not found, try for a repository default
       
    81 			if (isMetaFlagSet)	
       
    82 				aSetting.SetMeta(iDefaultMeta | KMetaDefaultValue) ;
       
    83 			else
       
    84 				aSetting.SetMeta(iDefaultMeta) ;
       
    85 			}
       
    86 		}
       
    87 
       
    88 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
       
    89 #ifdef CENTREP_CONV_TOOL
       
    90 	if (aSingleMetaFound && aSetting.IsClean() && !aSetting.IsIndividualMeta())
       
    91 		aSingleMetaFound=EFalse;
       
    92 #endif	
       
    93 	aSetting.SetIndividualMeta(aSingleMetaFound);
       
    94 #endif			
       
    95 	}
       
    96 
       
    97 TInt CHeapRepository::Create(TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool aSingleMetaFound)
       
    98 	{
       
    99 	if(iSettings.Find(aSetting.Key()))
       
   100 		return KErrAlreadyExists;
       
   101 	
       
   102 	SetMetaDataOnRead( aSetting, aSingleMetaFound);
       
   103 	aSetting.SetAccessPolicy(aPolicy);
       
   104 
       
   105 	return iSettings.OrderedInsert(aSetting);
       
   106 	}
       
   107 
       
   108 // Comparison relation to allow single policies to be inserted in order
       
   109 TInt CHeapRepository::CompareKeyIds(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem)
       
   110 	{
       
   111 	if(aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey)
       
   112 		return 0;
       
   113 	return (aSinglePolicy.iLowKey < aSinglePolicyIndexItem.iLowKey)?-1:1;
       
   114 	}
       
   115 
       
   116 // Identity relation to allow single policy for a given key to be found
       
   117 TBool CHeapRepository::SinglePolicyMatchOnKey(const TSettingsAccessPolicy& aSinglePolicy, const TSettingsAccessPolicy& aSinglePolicyIndexItem)
       
   118 	{
       
   119 	return aSinglePolicy.iLowKey==aSinglePolicyIndexItem.iLowKey;
       
   120 	}
       
   121 
       
   122 // returns the read security policy used if there is no per-setting policy at aId
       
   123 const TSecurityPolicy& CHeapRepository::GetFallbackReadAccessPolicy(TUint32 aId)
       
   124 	{
       
   125 	return *(GetFallbackAccessPolicy(aId)->GetReadAccessPolicy());
       
   126 	}
       
   127 
       
   128 // returns the write security policy used if there is no per-setting policy at aId
       
   129 const TSecurityPolicy& CHeapRepository::GetFallbackWriteAccessPolicy(TUint32 aId)
       
   130 	{
       
   131 	return *(GetFallbackAccessPolicy(aId)->GetWriteAccessPolicy());
       
   132 	}
       
   133 
       
   134 // Get pointer to security policy that applies to a given setting
       
   135 TSettingsAccessPolicy* CHeapRepository::GetFallbackAccessPolicy(TUint32 aId
       
   136 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
       
   137 	,TBool aSkipSingle
       
   138 #endif
       
   139 	)
       
   140 	{
       
   141 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
       
   142 	if (!aSkipSingle)
       
   143 		{
       
   144 #endif		
       
   145 		// Check for single policy
       
   146 		TSettingsAccessPolicy policy(aId);
       
   147 		TIdentityRelation<TSettingsAccessPolicy> identity(SinglePolicyMatchOnKey);
       
   148 		TInt index = iSinglePolicies.Find(&policy, identity);
       
   149 		if(KErrNotFound != index)
       
   150 			return iSinglePolicies[index];
       
   151 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS		
       
   152 		}
       
   153 #endif		
       
   154 	
       
   155 	// check if the aId falls into any range specified in the ini file
       
   156 	TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aId);
       
   157 	if(rangePolicy)
       
   158 		return rangePolicy;
       
   159 	
       
   160 	// If no single policy or range policy, return default policy
       
   161 	return &iDefaultPolicy;
       
   162 	}
       
   163 
       
   164 // this function saves idividual meta as well
       
   165 TInt CHeapRepository::ReadSettingSavePolicyL(CIniFileIn& aFile,TServerSetting& aSetting, TSettingsAccessPolicy* &aPolicy, TBool& aSingleMetaFound)
       
   166 	{
       
   167 	TBool singleReadPolicyFound;
       
   168 	TBool singleWritePolicyFound;
       
   169 	TSecurityPolicy singleReadPolicy;
       
   170 	TSecurityPolicy singleWritePolicy;
       
   171 
       
   172 	TInt err=aFile.ReadSettingL(aSetting,singleReadPolicy, singleWritePolicy, singleReadPolicyFound, singleWritePolicyFound, aSingleMetaFound);
       
   173 	if(err!=KErrNone)
       
   174 		return err;
       
   175 	
       
   176 	// Set up single policies
       
   177 	if(!singleReadPolicyFound)
       
   178 		singleReadPolicy=GetDefaultReadAccessPolicy();
       
   179 	if(!singleWritePolicyFound)
       
   180 		singleWritePolicy=GetDefaultWriteAccessPolicy();
       
   181 
       
   182 	aSetting.PushL();
       
   183 	if(singleReadPolicyFound || singleWritePolicyFound)
       
   184 		{
       
   185 		aPolicy=new (ELeave) TSettingsAccessPolicy(singleReadPolicy,singleWritePolicy,aSetting.Key());
       
   186 		CleanupStack::PushL(aPolicy);
       
   187 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS		
       
   188 		//reused single setting high key and mask to indicate whether read or write has been specified
       
   189 		//or they are just a default policy
       
   190 		if (singleReadPolicyFound)
       
   191 			aPolicy->iHighKey=1;
       
   192 		if (singleWritePolicyFound)
       
   193 			aPolicy->iKeyMask=1;
       
   194 #endif		
       
   195 		TLinearOrder<TSettingsAccessPolicy> order(&CHeapRepository::CompareKeyIds);
       
   196 		iSinglePolicies.InsertInOrderL(aPolicy,order);
       
   197 		CleanupStack::Pop(aPolicy);
       
   198 		}
       
   199 	else
       
   200 		{
       
   201 		// check if the aId falls into any range specified in the ini file
       
   202 		// otherwise set policy to default policy
       
   203 		TSettingsAccessPolicy* rangePolicy = iRangePolicies.Find(aSetting.Key());
       
   204 		if(rangePolicy)
       
   205 			aPolicy=rangePolicy;
       
   206 		else
       
   207 			aPolicy=&iDefaultPolicy;
       
   208 		}
       
   209 		
       
   210 	aSetting.Pop();
       
   211 	return err;
       
   212 	}
       
   213 		
       
   214 #ifdef CENTREP_CONV_TOOL
       
   215 void CHeapRepository::DoCommitChangesToIniFileL(RFs& aFs,const TDesC& aOutFileName
       
   216 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
       
   217 	,TUint32 aCreVersion
       
   218 #endif
       
   219 	)
       
   220 	{
       
   221 	CIniFileOut* out = CIniFileOut::NewLC(aFs,aOutFileName);
       
   222 
       
   223 	out->WriteHeaderL();
       
   224 	out->WriteOwnerSectionL(iOwner);
       
   225 	out->WriteTimeStampL(iTimeStamp);
       
   226 	out->WriteMetaDataL(iDefaultMeta, iRangeMeta);
       
   227 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
       
   228 	out->WritePlatSecL(GetDefaultAccessPolicy(), iRangePolicies,aCreVersion);
       
   229 #else
       
   230 	out->WritePlatSecL(GetDefaultReadAccessPolicy(), GetDefaultWriteAccessPolicy(), iRangePolicies);
       
   231 #endif	
       
   232 
       
   233 
       
   234 	out->WriteMainSectionHeaderL();
       
   235 	for(TInt i=0; i<iSettings.Count(); i++)
       
   236 		{
       
   237 		const TServerSetting& setting = iSettings[i];
       
   238 		if (setting.HasAccessPolicy() && (iSinglePolicies.Find(setting.AccessPolicy()) != KErrNotFound))
       
   239 			{
       
   240 			out->WriteSettingL(setting, *setting.AccessPolicy()
       
   241 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS			
       
   242 			,aCreVersion
       
   243 #endif			
       
   244 			);
       
   245 			}
       
   246 		else
       
   247 			{
       
   248 			out->WriteSettingL(setting
       
   249 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS			
       
   250 			,aCreVersion
       
   251 #endif			
       
   252 			);
       
   253 			}
       
   254 		}
       
   255 
       
   256 	out->CommitL();
       
   257 	CleanupStack::PopAndDestroy(out);//out
       
   258 	}
       
   259 #endif
       
   260 
       
   261 void CHeapRepository::DoCommitChangesL(RFs& aFs,TUint8 aPersistVersion,const TDesC& aTargetFilePath) 
       
   262 	{
       
   263 	CCreGenerator::CommitChangesToCreL(aFs,aPersistVersion,*this, aTargetFilePath);
       
   264 	}	
       
   265 
       
   266 /**
       
   267 The method reloads the repository content from a repository file.
       
   268 The current repository must be emptied (or must be empty already) before the call is made.
       
   269 @param aIniFile A reference to CIniFileIn object, which will be used to load
       
   270 				the repository content.
       
   271 @leave System-wide error codes.
       
   272 @leave KErrGeneral It's probably a programmer's error - current CHeapRepository 
       
   273 				   object is partially initialised.
       
   274 @leave KErrCorrupt Corrupted repository file.
       
   275 */
       
   276 void CHeapRepository::ReloadContentL(CIniFileIn& aIniFile)
       
   277 	{
       
   278 	// Preconditions - CHeapRepository object should be an empty one.
       
   279 	if(!IsEmpty())
       
   280 		{
       
   281 		User::Leave(KErrGeneral);
       
   282 		}
       
   283 	TInt err = ReloadContentExceptSettingsL(aIniFile);
       
   284 	if(err == KErrCorrupt)
       
   285 		{
       
   286 		User::Leave(err);
       
   287 		}
       
   288 	CleanupClosePushL(iRangeMeta);
       
   289 	CleanupClosePushL(iRangePolicies);
       
   290 	
       
   291 	// Settings
       
   292 	TServerSetting setting;
       
   293 	TSettingsAccessPolicy* policy;
       
   294 	TBool singleMetaFound;
       
   295 	TCleanupItem tc(SinglePoliciesCleanup, &iSinglePolicies);
       
   296 	CleanupStack::PushL(tc);	
       
   297 	CleanupClosePushL(iSettings);
       
   298 	while((err = ReadSettingSavePolicyL(aIniFile, setting, policy, singleMetaFound)) == KErrNone)
       
   299 		{
       
   300 		setting.PushL();
       
   301 		if(iSettings.IsDefault())
       
   302 			{
       
   303 			setting.SetClean();			
       
   304 			}
       
   305 		User::LeaveIfError(Create(setting, policy, singleMetaFound));
       
   306 		setting.Pop();
       
   307 		}
       
   308 	if(err == KErrNotFound)			
       
   309 		{
       
   310 		err = KErrNone;
       
   311 		}
       
   312 	User::LeaveIfError(err);
       
   313 	CleanupStack::Pop(4,&iRangeMeta);
       
   314 	}
       
   315 
       
   316 /**
       
   317 Resets current repository data - actually all of them, which may be loaded from
       
   318 the related ini file.
       
   319 The iUid data member value is kept as it was at the moment of creation of 
       
   320 CHeapRepository object.
       
   321 */
       
   322 void CHeapRepository::ResetContent()
       
   323 	{
       
   324 	iSettings.Reset();
       
   325 	iOwner = KNullUid;
       
   326 	iTimeStamp = TTime(0);
       
   327 
       
   328 	for (TInt i=0;i<iSinglePolicies.Count();i++)
       
   329 		{
       
   330 		delete iSinglePolicies[i];
       
   331 		}
       
   332 	iSinglePolicies.Reset();
       
   333 	iRangePolicies.Reset();
       
   334 	TSecurityPolicy emptyPolicy=TSecurityPolicy();
       
   335 	iDefaultPolicy = TSettingsAccessPolicy(emptyPolicy,emptyPolicy, KUnspecifiedKey);
       
   336 	iDefaultMeta = 0;
       
   337 	iRangeMeta.Reset();
       
   338 	}
       
   339   
       
   340 void CHeapRepository::CreateRepositoryFromCreFileL(RFs& aFs,const TDesC& aFilePath )
       
   341 	{
       
   342 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
       
   343 	TUint8 dummyVersion;	
       
   344 	CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath,dummyVersion);
       
   345 #else
       
   346 	CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath);
       
   347 #endif	
       
   348 	}
       
   349 
       
   350 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
       
   351 void CHeapRepository::CreateRepositoryFromCreFileL(RFs& aFs,const TDesC& aFilePath,TUint8& aCreVersion)
       
   352 	{	
       
   353 	CCreGenerator::CreateReposFromCreL(aFs,*this, aFilePath,aCreVersion);
       
   354 	}
       
   355 #endif
       
   356 
       
   357 void CHeapRepository::ExternalizeCre(TUint8 aPersistVersion,RWriteStream& aStream) const
       
   358 	{
       
   359 	CCreGenerator::ExternalizeCre(aPersistVersion,*this, aStream);
       
   360 	}
       
   361 
       
   362 
       
   363 void CHeapRepository::InternalizeCreL(RReadStream& aStream)
       
   364 	{
       
   365 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
       
   366 	TUint8 dummyVersion;
       
   367 	CCreGenerator::InternalizeCreL(*this, aStream,dummyVersion);
       
   368 #else
       
   369 	CCreGenerator::InternalizeCreL(*this, aStream);
       
   370 #endif	
       
   371 	}
       
   372 
       
   373 
       
   374 void CHeapRepository::SinglePoliciesCleanup(TAny *aPtr)
       
   375 	{
       
   376 	static_cast<RPointerArray<TSettingsAccessPolicy>*>(aPtr)->ResetAndDestroy();
       
   377 	}
       
   378 
       
   379 TInt CHeapRepository::ReloadContentExceptSettingsL(CIniFileIn& aIniFile)
       
   380 	{
       
   381 	// Look for an "owner" section
       
   382 	TUint32 uidValue(KNullUid.iUid);
       
   383 	TInt err = aIniFile.ReadOwnerSectionL(uidValue);
       
   384 	if(err == KErrCorrupt)
       
   385 		{
       
   386 		return err;
       
   387 		}
       
   388 	iOwner.iUid = uidValue;
       
   389 	// Timestamp
       
   390 	TTime timeStamp (0);
       
   391 	err = aIniFile.ReadTimeStampSectionL(timeStamp);
       
   392 	if(err == KErrCorrupt)
       
   393 		{
       
   394 		return err;
       
   395 		}
       
   396 	iTimeStamp=timeStamp;
       
   397 
       
   398 	// Metadata
       
   399 	err = aIniFile.ReadDefaultMetaSecSectionL(iDefaultMeta, iRangeMeta);
       
   400 	// Even if err == KErrCorrupt, some items might have already been placed in the array
       
   401 	CleanupClosePushL(iRangeMeta);
       
   402 	if(err == KErrCorrupt)
       
   403 		{
       
   404 		CleanupStack::PopAndDestroy(&iRangeMeta);
       
   405 		return err;
       
   406 		}
       
   407 
       
   408 	// Default read/write policies
       
   409 	TBool gotDefaultReadPolicy;
       
   410 	TBool gotDefaultWritePolicy;
       
   411 	TSecurityPolicy defaultReadPolicy;
       
   412 	TSecurityPolicy defaultWritePolicy;
       
   413 	err = aIniFile.ReadPlatSecSectionL(defaultReadPolicy, gotDefaultReadPolicy,
       
   414 									   defaultWritePolicy, gotDefaultWritePolicy,
       
   415 									   iRangePolicies);
       
   416 	// Even if err == KErrCorrupt, some items might have already been placed in the array
       
   417 	CleanupClosePushL(iRangePolicies);	
       
   418 	if(err == KErrCorrupt)
       
   419 		{
       
   420 		CleanupStack::PopAndDestroy(2,&iRangeMeta);
       
   421 		return err;
       
   422 		}
       
   423 
       
   424 	iDefaultPolicy = TSettingsAccessPolicy(defaultReadPolicy,defaultWritePolicy, KUnspecifiedKey);
       
   425 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
       
   426 	if (gotDefaultReadPolicy)
       
   427 		iDefaultPolicy.iHighKey=1;
       
   428 	if (gotDefaultWritePolicy)
       
   429 		iDefaultPolicy.iKeyMask=1;
       
   430 #endif	
       
   431 	CleanupStack::Pop(2,&iRangeMeta);
       
   432 	return KErrNone;
       
   433 	}
       
   434 
       
   435 TBool CHeapRepository::IsEmpty()
       
   436 	{
       
   437 	if(iSettings.Count() != 0 || iRangeMeta.Count() != 0 ||
       
   438 	   iSinglePolicies.Count() != 0 || iRangePolicies.Count() != 0)
       
   439 		{
       
   440 		return EFalse;
       
   441 		}
       
   442 	return ETrue;
       
   443 	}