os/persistentdata/persistentstorage/centralrepository/cenrepsrv/srvrepos_noc.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2004-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 //
    15 
    16 #include "panic.h"
    17 #include "shrepos.h"
    18 #include "srvrepos_noc.h"
    19 #include "srvres.h"
    20 #include "cachemgr.h"
    21 #include "sessnotf.h"
    22 #include "srvPerf.h"
    23 #include "srvreqs.h" 
    24 #include "rstrepos.h"
    25 #ifdef SYMBIAN_BAFL_SYSUTIL
    26 #include <bafl/sysutil.h>
    27 #endif
    28 #include <e32def_private.h>
    29 
    30 
    31 void CServerRepository::OpenL(TUid aUid, MObserver& aObserver, TBool aFailIfNotFound)
    32 	{
    33 	iNotifier = &aObserver;
    34 	
    35 	TServerResources::iObserver->iObservers.ReserveL(1);
    36 	
    37 	TServerResources::iObserver->AddSharedRepositoryInfoL(aUid);
    38 	
    39 	TRAPD( err, iRepository = TServerResources::iObserver->AccessL(aUid, aFailIfNotFound) );
    40 	
    41 	//store uid
    42 	iUid = aUid;
    43 	
    44 	if (err == KErrNone)
    45 	    {
    46         TRAP( err, TServerResources::iObserver->AddObserverL(aUid, this) );
    47 	    }
    48 	    
    49 	if (err != KErrNone)
    50         {
    51         TServerResources::iObserver->RemoveSharedRepositoryInfo(aUid);
    52         User::Leave(err);
    53         }
    54 	}
    55 
    56 void CServerRepository::Close()
    57 	{
    58 	iRepository = NULL;
    59 
    60 	TInt index = TServerResources::iObserver->FindOpenRepository(iUid);
    61 	
    62 	if (index>=0)
    63 		{
    64 		iRepository = TServerResources::iObserver->GetOpenRepository(index);
    65 		}
    66 	// cancel to ensure any read/write locks are released and transaction settings cleaned up
    67 
    68     CancelTransaction();
    69 
    70 	
    71 	TServerResources::iObserver->RemoveObserver(iUid, this, index);
    72 	
    73 	iNotifier = NULL;			
    74 	}
    75 	
    76 /**
    77 Notify about all changed keys stored in the specified reference to the
    78 CRestoredRepository.
    79 
    80 @param aRstRepos The reference to CRestoredRepository which holds the list 
    81 of the changed keys.
    82 */	
    83 void CServerRepository::RestoreNotify(const CRestoredRepository& aRstRepos)
    84 	{
    85 	const RArray<TUint32>& keys = aRstRepos.ChangedKeys();
    86 	TInt count=keys.Count();
    87 	for(TInt i = 0; i < count; i++)
    88 		{
    89 		 iRepository->Notify(keys[i]);
    90 		}
    91 	}
    92 	
    93 /**
    94 Attempt to reset a single key to it's value in the file in the given location. Routine
    95 attempts to find a .cre file first. If ( and only if ) a cre file doesn't exist the 
    96 routine attempts to find a txt file. In the presence of multi rofs, it needs to perform
    97 merging of all the rom keyspaces first before doing a reset, hence we are not able to perform
    98 the reading line by line for efficiency purpose.
    99 */
   100 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
   101 void CServerRepository::ResetFromIniFileL(TUint32 aId, 
   102 										  CIniFileIn::TIniFileOpenMode aIniFileOpenMode,
   103 										  TBool& aKeyFound)
   104 	{
   105 	aKeyFound=EFalse;
   106 
   107 	CSharedRepository* rep=NULL;
   108 	// Attempt to reset key to the aLocation if exist
   109 	//dont fail if repository not found
   110 	TServerResources::iObserver->LoadRepositoryLC(iRepository->Uid(),EFalse,rep,aIniFileOpenMode);
   111 	
   112 	if (rep)
   113 		{
   114 		TServerSetting* s = rep->GetSettings().Find(aId);					
   115 		if(s)
   116 			{
   117 			aKeyFound=ETrue;
   118 			// Mark the setting as default again
   119 			s->SetClean();
   120 			iRepository->ResetAndPersistL(*s);
   121 			s->SetAccessPolicy(GetFallbackAccessPolicy(aId));
   122 			}
   123 		}
   124 	CleanupStack::PopAndDestroy(rep);
   125 	}
   126 #else
   127 /**
   128 Attempt to reset a single key to it's value in the file in the given location. Routine
   129 attempts to find a .cre file first. If ( and only if ) a cre file doesn't exist the 
   130 routine attempts to find a txt file.
   131 Note that it would be possible to use LoadRepositoryLC here but for the txt file
   132 that would take longer. This is because in LoadRepositoryLC the txt file is 
   133 completely processed. The Reset specific txt file opening code below is quicker because 
   134 it is just attempting to find the reset key.
   135 */
   136 void CServerRepository::ResetFromIniFileL(TUint32 aId, 
   137 										  TCentRepLocation aLocation,
   138 										  TBool& aKeyFound)
   139 	{
   140 	aKeyFound=EFalse;
   141 
   142 	// Attempt to reset key to value in cre file if it exists
   143 	
   144 	// Attempt to create a temporary repository from the cre file in aLocation
   145 	CSharedRepository* rep = CSharedRepository::NewL(iRepository->Uid());
   146 	CleanupStack::PushL(rep);
   147 	TInt err = rep->CreateRepositoryFromCreFileL(aLocation);
   148 
   149 	// Search for aId in the temporary repository
   150 	if (err!=KErrNotFound)
   151 		{		
   152 		// Note that for all errors except KErrNotFound code leaves and doesn't
   153 		// attempt to look for txt file. This is intentional. Code does not 
   154 		// attempt to support coexisting cre and txt files.
   155 		User::LeaveIfError(err);
   156 		
   157 		// Search for aId in the temporary repository
   158 		TServerSetting* s = rep->GetSettings().Find(aId);					
   159 		if(s)
   160 			{
   161 			aKeyFound=ETrue;
   162 			// Mark the setting as default again
   163 			s->SetClean();
   164 			iRepository->ResetAndPersistL(*s);
   165 			s->SetAccessPolicy(GetFallbackAccessPolicy(aId));
   166 			}
   167 			
   168 		CleanupStack::PopAndDestroy(rep);
   169 		return;
   170 		}
   171 	else
   172 		{
   173 		CleanupStack::PopAndDestroy(rep);
   174 		}
   175 		
   176 	HBufC* fileName(NULL);	
   177 	TServerResources::CreateRepositoryFileNameLC(fileName,iRepository->Uid(),aLocation,EIni);
   178 	
   179 	CIniFileIn* inputFile = 0;
   180 	TInt r = CIniFileIn::NewLC(TServerResources::iFs,inputFile,*fileName);
   181 	if(r==KErrNone)
   182 		{
   183 		//we don't want to read this stuff again... just skip over to get to settings!
   184 		inputFile->SkipOwnerSectionL() ;
   185 		inputFile->SkipTimeStampSectionL() ;
   186 		inputFile->SkipDefaultMetaSectionL() ;
   187 		inputFile->SkipPlatSecSectionL();
   188 		
   189 		// Find start of Main section
   190 		inputFile->FindMainSectionL();
   191 	
   192 		TServerSetting s;
   193 		TBool singleMetaFound=EFalse;
   194 		TBool singleReadPolicyFound=EFalse;
   195 		TBool singleWritePolicyFound=EFalse;
   196 		TSecurityPolicy singleReadPolicy;
   197 		TSecurityPolicy singleWritePolicy;
   198 
   199 		// Note that calling CIniFile::ReadSettingL causes the single policy ( if it exists ) to be read from the
   200 		// file being reset to, but doesn't update the single policy array, which is not required in the reset case. 
   201 		while((r=inputFile->ReadSettingL(s,singleReadPolicy, singleWritePolicy, singleReadPolicyFound, singleWritePolicyFound, singleMetaFound)) == KErrNone)
   202 			{	
   203 			iRepository->SetMetaDataOnRead( s, singleMetaFound);			
   204 			if(s.Key()==aId)
   205 				{
   206 				// Mark the setting as default again
   207 				s.SetClean();
   208 				iRepository->ResetAndPersistL(s);
   209 				s.SetAccessPolicy(GetFallbackAccessPolicy(aId));
   210 				aKeyFound = ETrue;
   211 				break;
   212 				}
   213 			s.Reset();
   214 			}
   215 
   216 	
   217 		}
   218 	CleanupStack::PopAndDestroy(inputFile);	 // inputFile
   219 	CleanupStack::PopAndDestroy(fileName);	 // filename
   220 	}
   221 
   222 #endif	
   223 
   224 TInt CServerRepository::ResetL(TUint32 aId)
   225 	{
   226 	// not yet supported in transactions
   227 	ASSERT(!IsInTransaction());
   228 
   229 	// if setting has not changed, there nothing to do
   230 	TServerSetting *targetSetting = GetSetting(aId) ;
   231 
   232 	if (targetSetting)
   233 		{
   234 		if ((targetSetting->Meta() & KMetaDefaultValue))
   235 			{
   236 			return KErrNone;
   237 			}
   238 		}
   239 
   240 	TInt error = KErrNone;
   241 	TBool keyReset = EFalse;
   242 
   243 	// Check for default value in any installed file first
   244 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS
   245 	ResetFromIniFileL(aId, CIniFileIn::EInstallOnly, keyReset);
   246 #else
   247 	ResetFromIniFileL(aId, EInstall, keyReset);
   248 #endif	
   249 	if (keyReset)
   250 		return KErrNone;
   251 
   252 	// Either we couldn't find a matching key or
   253 	// there wasn't an installed file - try for a ROM
   254 	// file
   255 #ifdef SYMBIAN_CENTREP_SUPPORT_MULTIROFS	
   256 	ResetFromIniFileL(aId, CIniFileIn::ERomOnly, keyReset);
   257 #else
   258 	ResetFromIniFileL(aId, ERom, keyReset);
   259 #endif	
   260 	if (keyReset)
   261 		return KErrNone;
   262 	
   263 	// No default value found in install or ROM file
   264 	// delete the key!
   265 	error = iRepository->DeleteAndPersist(aId);
   266 
   267 	return error ;
   268 	}
   269 
   270 
   271 void CServerRepository::CacheRomVersionL(const TDesC& aFilename,TDesC8& aVersion)
   272 	{
   273 
   274 	RFile file;
   275 	TInt err = KErrNone; 
   276 	_LIT(KTmpPersistedRomVersionFile, "_:\\private\\10202be9\\romversion\\romversion_info.tmp");	
   277 	TBuf<KMaxFileName> tmpPersistedRomVersionFileName;
   278 	
   279 	tmpPersistedRomVersionFileName.Copy(KTmpPersistedRomVersionFile);
   280 	tmpPersistedRomVersionFileName[0] = RFs::GetSystemDriveChar();
   281 	
   282 	//Create a new empty tmp file.
   283     err = file.Replace( TServerResources::iFs, tmpPersistedRomVersionFileName,
   284 	                     EFileWrite | EFileStreamText );
   285 	if (err != KErrNone)
   286 	       {
   287 	       file.Close();
   288 	       User::Leave(err);
   289 	       }
   290 
   291     err = file.Write(aVersion);
   292 	if (err != KErrNone)
   293 		{                                                                                                  
   294 	       file.Close();
   295 	       User::Leave(err);
   296 	    }
   297 	    
   298     file.Close();
   299     
   300 	User::LeaveIfError(TServerResources::iFs.Replace(tmpPersistedRomVersionFileName,aFilename));
   301 
   302 	}
   303 
   304 #ifdef SYMBIAN_BAFL_SYSUTIL
   305 void CServerRepository::CheckROMReflashL()
   306 	{
   307 	TInt err=KErrNone;
   308 
   309 	TBuf16<KSysUtilVersionTextLength> version;
   310 	TBuf8<KSysUtilVersionTextLength*2> persistedCopyOfRomVersion;
   311 	_LIT(KPersistedRomVersionFile, "_:\\private\\10202be9\\romversion\\romversion_info.txt");	
   312 	TBuf<KMaxFileName> persistedRomVersionFileName;
   313 	persistedRomVersionFileName.Copy(KPersistedRomVersionFile);
   314 	persistedRomVersionFileName[0] = RFs::GetSystemDriveChar();
   315 		
   316 	TBuf8<KSysUtilVersionTextLength*2> eightBitVersion;
   317 
   318 	
   319 	if ((err = SysUtil::GetSWVersion(version)) == KErrNone )
   320 		{
   321 		eightBitVersion.Copy(version);//Converts to 8bit
   322 		err = TServerResources::GetTextFromFile(persistedRomVersionFileName,persistedCopyOfRomVersion);		
   323         if(err == KErrNone)
   324         	{
   325         	if(eightBitVersion == persistedCopyOfRomVersion)//No rom update has occurred do nothing
   326         		{
   327         		return;
   328         		}
   329         	else //rom update detected process persists files.
   330         		{
   331         		//Call function with flag set to true causing Reflash merging activity.
   332         		ProcessPersistsRepositoriesL(ECenRepReflash);
   333         		}
   334         	}
   335 
   336 		//create the persisted rom version file
   337 		//if the persists files are successfully processed
   338 		//if the persists file doesnt exist
   339 		//if the persists file is corrupt
   340 		//if the persists file is corrupt in such a way that its contents are too large.
   341 		if (err == KErrNone || err == KErrNotFound || err == KErrPathNotFound || err == KErrCorrupt || err == KErrTooBig)
   342 			{
   343 			CServerRepository::CacheRomVersionL(persistedRomVersionFileName,eightBitVersion);
   344 			}
   345 		else
   346 			{
   347 			User::Leave(err);
   348 			}
   349 		}
   350 	else
   351 		{
   352 		User::Leave(err);
   353 		}
   354 	}
   355 #endif
   356 
   357 void CServerRepository::RFSAllRepositoriesL()
   358 	{
   359 	ProcessPersistsRepositoriesL(ECenRepReset);	
   360 	}
   361 	
   362 void CServerRepository::ProcessPersistsRepositoriesL(TPersistedRepActions aRomFlashOrReset)
   363 	{
   364 	// Read contents of persist directory to get a list of repositories
   365 	TPtr dataDirectory = TServerResources::iDataDirectory->Des();
   366 	RDir persistDir;
   367     CleanupClosePushL(persistDir);
   368 
   369 	User::LeaveIfError(persistDir.Open(TServerResources::iFs, dataDirectory, KEntryAttNormal));
   370 
   371     TEntryArray dirEntries;
   372     TInt readError = KErrNone;
   373     
   374 	while (readError != KErrEof)  
   375 		{
   376 	    readError = persistDir.Read(dirEntries);
   377     
   378 	    if(readError != KErrNone && readError != KErrEof) 
   379 	    	{
   380 	    	User::Leave(readError);
   381 	    	}
   382 	    else
   383 	    	{
   384 	    	const TInt dirCount = dirEntries.Count();   
   385 	    	for (TInt i=0; i<dirCount; i++)
   386 	    		{
   387 				// Attempt to extract a repository UID from directory entry
   388 				TUid uid;
   389 				if (!TServerResources::GetUid(const_cast<TEntry&>(dirEntries[i]), uid))
   390 					{
   391 					CSessionNotifier notifier;
   392 	
   393 					// Create shared repository
   394 					CServerRepository *repository = new(ELeave) CServerRepository;
   395 					CleanupStack::PushL(repository);
   396 	
   397 					repository->OpenL(uid, notifier);
   398 			
   399 					//Handle ROM re-flash
   400 					TInt err = KErrNone;
   401 					if(aRomFlashOrReset==ECenRepReflash)
   402 						{
   403 						TRAP(err, repository->HandleReflashofRepositoryL());
   404 						}
   405 					else if(aRomFlashOrReset==ECenRepReset)
   406 						{
   407 						// Restore settings
   408 						TRAP(err,repository->RFSRepositoryL());	
   409 						}
   410 					if(err != KErrNone)
   411 					  {
   412 					  if(err == KErrNoMemory)
   413 					    {
   414                         repository->Close();
   415 					    User::LeaveNoMemory();
   416 					    }
   417 				      else
   418 					    {//Dont stop processing the rest of the persisted repositories becos one has a problem.
   419 					     __CENTREP_TRACE1("CENTREP: CServerRepository::ProcessPersistsRepositoriesL - Error = %d", err);
   420 					    }
   421 				      }
   422 	
   423 					// delete repository.
   424 					repository->Close();
   425 					CleanupStack::PopAndDestroy(repository);
   426 					}
   427 	    		}
   428 	    	}
   429 		}
   430 	
   431 	CleanupStack::PopAndDestroy(&persistDir);
   432 	}
   433 
   434 TInt CServerRepository::RFSRepositoryL()
   435 	{
   436 	// for each key in combined ROM/Install restore
   437 	TUid uid = iRepository->Uid();
   438 
   439 	CSharedRepository* defaultRepository = 0;
   440 	TInt err=KErrNone;
   441 	
   442 	//Determine if ROM and Install files exist
   443   	TBool romExists=TServerResources::RomFileExistsL(uid);
   444   	TBool installExists=TServerResources::InstallFileExistsL(uid);
   445   		
   446 	if(romExists)
   447 		{
   448 		// Create a rep using the ROM file
   449 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, defaultRepository, CIniFileIn::ERomOnly);
   450 		
   451 		if(installExists)
   452 			{			
   453 			CSharedRepository *installRep = 0;
   454 			// Create install rep for merging
   455 			TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, installRep, CIniFileIn::EInstallOnly);
   456 		
   457 			// If install and ROM exist create a merged rep to Reset against
   458 			defaultRepository->MergeL(*installRep, ESWIUpgradeMerge);
   459 		
   460 			//pop and destroy install repository as this has now been 
   461 			//merged with repository
   462 			CleanupStack::PopAndDestroy(installRep);
   463 			}		
   464 		}
   465 		
   466 	else if(installExists)
   467 		{		
   468 		// Reset against install repository if only the install file exists
   469 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, defaultRepository, CIniFileIn::EInstallOnly);		
   470 		}
   471 	else
   472 		{
   473         // The repository must exist in the ROM or install directory (or both). 
   474         ASSERT(romExists || installExists);
   475 		// Reset against empty repository if neither ROM or install file are found
   476 		defaultRepository = CSharedRepository::NewL(uid);
   477 		CleanupStack::PushL(defaultRepository);
   478 		}
   479 
   480 	for(TInt i = 0; i < iRepository->GetSettings().Count(); i++)
   481 		{
   482 		// setting in persists
   483 		TServerSetting* persistedSetting = &iRepository->GetSettings()[i];
   484 
   485 		// If the clean is set on setting in the persist, nothing to do			
   486 		if (persistedSetting->Meta() & KMetaDefaultValue)
   487 			{
   488 			continue;
   489 			}
   490 
   491 		TUint32 key = persistedSetting->Key();		
   492 		// setting in ROM/install
   493 		TServerSetting* defaultSetting = defaultRepository->GetSettings().Find(key);
   494 
   495 		if (defaultSetting)
   496 			{
   497 			if ((defaultSetting->Meta() & KMetaRfsValue))
   498 				{
   499 				iRepository->ResetNoPersistL(*defaultSetting);
   500 				}
   501 			//remove from Reset repository
   502 			defaultRepository->GetSettings().Remove(key);
   503 			}
   504 		else
   505 			{
   506 			// if setting has no default value (i.e. doesn't exist in any default file but RFS meta is 
   507 			// set (using pre-set default range meta),  delete the setting 
   508 			if ((persistedSetting->Meta() & KMetaRfsValue))			
   509 				{
   510 				iRepository->DeleteNoPersist(key);				
   511 				}
   512 			}
   513 		}
   514 	// search for remaining items in default file, because previous loop has already removed all items 
   515 	// from the persists file
   516 	for(TInt i = 0; i < defaultRepository->GetSettings().Count(); i++)
   517 		{
   518 		TServerSetting* defaultSetting = &defaultRepository->GetSettings()[i];
   519 
   520 		if ((defaultSetting->Meta() & KMetaRfsValue) != KMetaRfsValue)
   521 			{
   522 			continue;
   523 			}
   524 		iRepository->ResetNoPersistL(*defaultSetting);
   525 		}
   526 
   527 	// Persist settings
   528 	iRepository->CommitChangesL();
   529 
   530 	CleanupStack::PopAndDestroy(defaultRepository);
   531 
   532 	return err;
   533 	}
   534 
   535 	
   536 TInt CServerRepository::HandleReflashofRepositoryL()
   537 	{
   538 	// for each key in persists repository
   539 	TUid uid = iRepository->Uid();
   540 
   541 	CSharedRepository* defaultRepository = 0;
   542 	
   543 	//Determine if ROM and Install files exist
   544   	TBool romExists=TServerResources::RomFileExistsL(uid);
   545 	TBool installExists=TServerResources::InstallFileExistsL(uid);
   546  
   547 	if(romExists)
   548 		{
   549 		// Create a rep using the ROM file
   550 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, defaultRepository, CIniFileIn::ERomOnly);
   551 
   552 		if(installExists)//Then create a merged repository of rom and install settings
   553 			{		
   554 			CSharedRepository *installRep = 0;
   555 			// Create install rep for merging
   556 			TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, installRep, CIniFileIn::EInstallOnly);
   557 		
   558 			// If install and ROM exist create a merged rep to Reset against
   559 			defaultRepository->MergeL(*installRep, ESWIUpgradeMerge);
   560 		
   561 			//pop and destroy install repository as this has now been 
   562 			//merged with the rom repository
   563 			CleanupStack::PopAndDestroy(installRep);
   564 			}		
   565 		}		
   566 	else if(installExists)//There was no ROM repository just an install repository
   567 		{			
   568 		// Reset against install repository if only the install file exists
   569 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, defaultRepository, CIniFileIn::EInstallOnly);		
   570 		}
   571 	else //If rom file and install files have been removed for this repository
   572 		{//then remove the persists file.
   573 			TServerResources::DeleteCentrepFileL(uid, EPersists, ECre);
   574 			TServerResources::DeleteCentrepFileL(uid, EPersists, EIni);
   575 			return KErrNone;
   576 		}
   577 
   578 	// Merge rom and/or install with persists repository
   579 	iRepository->MergeL(*defaultRepository, ERomFlash);
   580 
   581 	// Persist settings
   582 	iRepository->CommitChangesL();
   583 
   584 	CleanupStack::PopAndDestroy(defaultRepository);
   585 
   586 	return KErrNone;
   587 	}
   588 
   589 
   590 TInt CServerRepository::ResetAllL()
   591 	{
   592 	// not yet supported in transactions
   593 	ASSERT(!IsInTransaction());
   594 	// fail all sessions' transactions first
   595 	iRepository->FailAllTransactions(/*aExcludeTransactor*/NULL);
   596 
   597 	TUid uid = iRepository->Uid();
   598 
   599 	// Reset
   600  	 	
   601 	// Create a rep using the ROM file
   602 	CSharedRepository* rep = 0;
   603   	TBool romExists=TServerResources::RomFileExistsL(uid);
   604 	if(romExists)
   605 		{
   606 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, rep, CIniFileIn::ERomOnly);
   607 		}
   608 		
   609 	// Create install rep for merging
   610 	CSharedRepository *installRep = 0;
   611 	TBool installExists=TServerResources::InstallFileExistsL(uid);
   612 	if(installExists)
   613 		{			
   614 		TServerResources::iObserver->LoadRepositoryLC(uid, ETrue, installRep, CIniFileIn::EInstallOnly);
   615 		}
   616 		
   617 	TInt err=KErrNone;
   618 	if(	romExists && installExists)
   619 		{
   620 		// If install and ROM exist create a merged rep to Reset against
   621 		rep->MergeL(*installRep, ESWIUpgradeMerge);
   622 		err=iRepository->ResetAllNoPersistL(*rep);
   623 		CleanupStack::PopAndDestroy(installRep);
   624 		CleanupStack::PopAndDestroy(rep);
   625 		}
   626 	else if(romExists)
   627 		{
   628 		// Reset against ROM
   629 		err=iRepository->ResetAllNoPersistL(*rep);
   630 		CleanupStack::PopAndDestroy(rep);
   631 		}
   632 	else if(installExists)
   633 		{
   634 		// Reset against install
   635 		err=iRepository->ResetAllNoPersistL(*installRep);
   636 		CleanupStack::PopAndDestroy(installRep);
   637 		}
   638 	else
   639 		{
   640 		// Reset against empty repository
   641 		rep = CSharedRepository::NewL(uid);
   642 		CleanupStack::PushL(rep);
   643 		err=iRepository->ResetAllNoPersistL(*rep);
   644 		CleanupStack::PopAndDestroy(rep);
   645 		}
   646 	
   647 	return err;
   648 	}
   649 
   650 // Handle install directory file update. 
   651 void CServerRepository::HandleSWIUpdateL(TUid aUid, TTime aModified, CSessionNotifier &aNotifier)
   652 	{		
   653 	// A file create or update has just occurred in the SWI directory. 
   654 	// Need to check if this is a new install. 
   655 	
   656 	if(TServerResources::PersistsFileExistsL(aUid) ||
   657 	   TServerResources::RomFileExistsL(aUid))
   658 		{	
   659 		// Create a rep using the ROM or persists file
   660 		OpenL(aUid, aNotifier);
   661 		if(iRepository->IsTransactionActive())			
   662 			{
   663 			// Fail transactions on any currently open session
   664 			iRepository->FailAllTransactions(NULL);
   665 			}
   666 			
   667 		// Create install rep for merging
   668  		CSharedRepository *installRep = 0;
   669  		TRAPD( err, TServerResources::iObserver->LoadRepositoryLC(aUid, ETrue, installRep, CIniFileIn::EInstallOnly); CleanupStack::Pop(installRep) );
   670 	
   671 		if (err == KErrNone)
   672             {
   673             // Perform merge
   674             TRAP( err, iRepository->HandleUpdateMergeL(aModified, *installRep) );
   675             }
   676         if (installRep!=NULL)
   677             {
   678             delete installRep;
   679             }
   680         Close();
   681         User::LeaveIfError(err);
   682 		}
   683 	else	// No ROM or persists
   684 		{
   685 		// Create install rep for persisting
   686 		OpenL(aUid, aNotifier);
   687 		TRAPD(err, iRepository->CommitChangesL());
   688 	    Close();
   689 	    User::LeaveIfError(err);
   690 		}
   691 	}
   692 
   693 
   694 // Handle install directory file delete 
   695 void CServerRepository::HandleSWIDeleteL(TUid aUid, CSessionNotifier &aNotifier)
   696 	{			
   697 	// A file delete has just occurred in the SWI directory. If there is no ROM file
   698 	// this is a complete uninstall, so delete persists file.Otherwise, do downgrade
   699 	// merge.
   700 	
   701 	if(TServerResources::RomFileExistsL(aUid))		// ROM file, this is a downgrade uninstall
   702 		{
   703 		if(!TServerResources::PersistsFileExistsL(aUid))
   704 			{
   705 			// If we are downgrading the ROM, there should be a persists file because the
   706 			// original upgrade should have created one.
   707 			// However if there isn't a persists file, there's nothing to do, so just return
   708 			return;
   709 			}
   710 			
   711 		// Create a rep using the persists file
   712 		OpenL(aUid, aNotifier);
   713 		if(iRepository->IsTransactionActive())			
   714 			{
   715 			// Fail transactions on any currently open session
   716 			iRepository->FailAllTransactions(NULL);
   717 			}
   718 		
   719 		// Create ROM rep for merging
   720 	 	CSharedRepository *romRep = 0;
   721 		TRAPD( err, TServerResources::iObserver->LoadRepositoryLC(aUid, ETrue, romRep, CIniFileIn::ERomOnly); CleanupStack::Pop(romRep) );
   722 
   723 		if (err == KErrNone)
   724 		    {
   725             // Perform merge
   726             TRAP( err, iRepository->HandleDeleteMergeL(*romRep) );
   727 		    }
   728 		if (romRep!=NULL)
   729 		    {
   730             delete romRep;
   731 		    }
   732 		Close();
   733 		User::LeaveIfError(err);
   734 		}
   735 	else											// No ROM file, this is a complete uninstall
   736 		{		
   737 		if(TServerResources::PersistsFileExistsL(aUid))
   738 			{
   739 		 	TServerResources::DeleteCentrepFileL(aUid, EPersists, ECre);
   740 		 	
   741 			// Check if the repository was open
   742 			TInt i = TServerResources::iObserver->FindOpenRepository(aUid);
   743 
   744 			// If repository is open, fail all transactions 
   745 			if(i>KErrNotFound)			   					  
   746 				{
   747 				OpenL(aUid, aNotifier);
   748 				if(iRepository->IsTransactionActive())			
   749 					{
   750 					// Fail transactions on any currently open session
   751 					iRepository->FailAllTransactions(NULL);
   752 					}
   753 				iRepository->ResetContent();
   754 				Close();				
   755 				}
   756 			}
   757 		}
   758 	}
   759 
   760 void CServerRepository::StoreRepositoryContentsL(CStreamStore& aStore, TStreamId & aSettingStreamId, TStreamId & aDeletedSettingsStreamId) const
   761 	{
   762 	StoreRepositorySettingValuesL(aStore, aSettingStreamId); // Stores current repository setting values
   763 	
   764 	RStoreWriteStream outStream;
   765 	aDeletedSettingsStreamId = outStream.CreateLC(aStore); // Creates the write for settings stream
   766 	iRepository->WriteDeletedSettingsStream(outStream) ;
   767 	outStream.CommitL(); // Commits the stream
   768 	CleanupStack::PopAndDestroy(&outStream); // Performs cleanup on the write stream object
   769 	}
   770 
   771 void CServerRepository::StoreRepositorySettingValuesL(CStreamStore& aStore, TStreamId & aSettingStreamId) const
   772 	{
   773 	RStoreWriteStream outStream;
   774 	aSettingStreamId = outStream.CreateLC(aStore); // Creates the write stream
   775 	iRepository->WriteBackupStream(outStream); // Only care about repository contents.
   776 	outStream.CommitL(); // Commits the stream
   777 	CleanupStack::PopAndDestroy(&outStream); // Performs cleanup on the write stream object
   778 	}
   779 	
   780 void CServerRepository::RestoreRepositoryContentsL(CStreamStore& aStore, TStreamId aSettingStreamId, TStreamId aDeletedSettingsStreamId, CRestoredRepository& aRstRepos)
   781 	{
   782 	RestoreRepositorySettingValuesL(aStore, aSettingStreamId, aRstRepos);
   783 	
   784 	RStoreReadStream inStream;
   785 	// If the backup contains a list of deleted settings read them in and apply them.
   786 	if (aDeletedSettingsStreamId != KNullStreamId)
   787 		{
   788 		inStream.OpenLC(aStore, aDeletedSettingsStreamId); // Creates read stream for deleted settings (if available)
   789 
   790 		TCardinality numDeletedSettings ;
   791 		inStream >> numDeletedSettings ;
   792 		
   793 		for (TInt i = 0; i < numDeletedSettings; i++)
   794 			{
   795 			TUint32 settingToDelete ;
   796 			inStream >> settingToDelete ;
   797 			TInt err = iRepository->DeleteNoPersist(settingToDelete) ; 
   798 			// Add the deleted key to the restored repository if it has existed before being deleted.
   799 			// If it has not existed before being deleted, we do not add it to the list because nothing 
   800 			// has changed.
   801 			if(err == KErrNone)
   802 				{
   803 				aRstRepos.AddKeyL(settingToDelete);
   804 				}
   805 			}
   806 		CleanupStack::PopAndDestroy(&inStream);            // Perform cleanup on the read stream object		
   807 		}
   808 	return;
   809 	}
   810 
   811 void CServerRepository::RestoreRepositorySettingValuesL(CStreamStore& aStore, TStreamId aSettingStreamId, CRestoredRepository& aRstRepos)
   812 	{
   813 	RStoreReadStream inStream;
   814 	inStream.OpenLC(aStore, aSettingStreamId); // Creates the write stream
   815 	iRepository->InternalizeL(inStream, aRstRepos); // Only care about repository contents.
   816 	CleanupStack::PopAndDestroy(&inStream);    // Perform cleanup on the read stream object
   817 	}
   818 
   819 static void CancelTransactionCleanupOperation(TAny* aRepository)
   820 	{
   821 	static_cast<CServerRepository*>(aRepository)->CancelTransaction();
   822 	}
   823 
   824 // So CancelTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
   825 void CServerRepository::CleanupCancelTransactionPushL()
   826 	{
   827 	CleanupStack::PushL(TCleanupItem(CancelTransactionCleanupOperation, this));
   828 	}
   829 
   830 /**
   831 @internalTechnology
   832 Check the range of security policies against RMessage
   833 @return
   834 	KErrNone if read access policies of all settings in array pass,
   835 	KErrPermissionDenied if any single policy fails.
   836 */
   837 TInt CServerRepository::CheckPermissions(RSettingPointerArray& aSettings, const TClientRequest& aMessage, const char* aDiagnostic, TBool aReadPolicy,TUint32& aErrId)
   838 	{
   839 	TInt error = KErrNone;
   840 	TInt numSettings = aSettings.Count();
   841 	for (TInt i = 0; i < numSettings; i++)
   842 		{
   843 		ASSERT(aSettings[i]);
   844 		const TServerSetting& setting = *aSettings[i];
   845 		if (aReadPolicy)
   846 			{
   847 			if (!aMessage.CheckPolicy(GetReadAccessPolicy(setting),aDiagnostic))
   848 				{
   849 				aErrId=setting.Key();	
   850 				error = KErrPermissionDenied;
   851 				break;
   852 				}
   853 			}
   854 		else
   855 			{
   856 			if (!aMessage.CheckPolicy(GetWriteAccessPolicy(setting),aDiagnostic))
   857 				{
   858 				aErrId=setting.Key();			
   859 				error = KErrPermissionDenied;
   860 				break;
   861 				}			
   862 			}
   863 		}
   864 	return error;
   865 	}
   866 
   867 TInt CServerRepository::TransactionDeleteRangeL(const TClientRequest& aMessage, TUint32& aErrorKey)
   868 	{
   869 	// all write operations now done in a transaction
   870 	ASSERT(IsInActiveReadWriteTransaction());
   871 	TInt error = KErrNone;
   872 	aErrorKey = KUnspecifiedKey;
   873 		
   874 	TUint32 partialKey = aMessage.Int0();
   875 	TUint32 keyMask = aMessage.Int1();
   876 	
   877 	RSettingPointerArray settingsToDelete;
   878 	CleanupClosePushL(settingsToDelete);	
   879 	error = FindSettings(partialKey, keyMask, settingsToDelete);
   880 	if (error==KErrNoMemory)
   881 		User::LeaveNoMemory();
   882 	
   883 	//perform write security check first
   884 	error=CheckPermissions(settingsToDelete,aMessage,__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::DeleteRangeL - Attempt made to delete a setting"),EFalse,aErrorKey);
   885 	
   886 	if (error==KErrNone)
   887 		{
   888 		TRAP(error,DeleteSettingsRangeL(settingsToDelete,partialKey,aErrorKey));
   889 		if (error==KErrNoMemory)
   890 			User::LeaveNoMemory();
   891 		}
   892 	CleanupStack::PopAndDestroy(&settingsToDelete);
   893 
   894 	if ((error != KErrNone) && (error != KErrNotFound))
   895 		{
   896 		FailTransaction(error, aErrorKey);
   897 		}
   898 	return error;
   899 	}
   900 
   901 TInt CServerRepository::TransactionMoveL(const TClientRequest& aMessage, TUint32& aErrorKey)	
   902 	{
   903 	// all write operations now done in a transaction
   904 	ASSERT(IsInActiveReadWriteTransaction());	
   905 	//read the source and target partial key
   906 	TKeyFilter sourceKeyIdentifier;
   907 	TPckg<TKeyFilter> pSource(sourceKeyIdentifier);
   908 	aMessage.Read(0, pSource);
   909 
   910 	TKeyFilter targetKeyIdentifier;
   911 	TPckg<TKeyFilter> pTarget(targetKeyIdentifier);
   912 	aMessage.Read(1, pTarget);
   913 
   914 	TUint32 sourceToTarget = (sourceKeyIdentifier.iPartialId & sourceKeyIdentifier.iIdMask) ^ (targetKeyIdentifier.iPartialId & targetKeyIdentifier.iIdMask);
   915 	if (sourceToTarget==0)
   916 		{
   917 		return KErrNone;
   918 		}
   919 	
   920 	//Need to get the list of source settings to perform some security policy check
   921 	RSettingPointerArray sourceSettings;
   922 	CleanupClosePushL(sourceSettings);
   923 	TInt error=FindSettings(sourceKeyIdentifier.iPartialId & sourceKeyIdentifier.iIdMask, sourceKeyIdentifier.iIdMask, sourceSettings);
   924 	
   925 	//dont fail transaction if source settings is empty
   926 	if ((error == KErrNone) && (sourceSettings.Count() == 0))
   927 		{
   928 		error = KErrNotFound;
   929 		aErrorKey = sourceKeyIdentifier.iPartialId;
   930 		CleanupStack::PopAndDestroy(&sourceSettings);
   931 		TPckg<TUint32> p(aErrorKey);
   932 		aMessage.WriteL(2, p);		
   933 		return error;
   934 
   935 		}
   936 	if (error!=KErrNone)
   937 		{
   938 		aErrorKey = sourceKeyIdentifier.iPartialId;
   939 		CleanupStack::PopAndDestroy(&sourceSettings);
   940 		return error;				
   941 		}	
   942 		
   943 	//Now validate against the security policy before doing the settings move
   944 	error=CheckMovePermissions(sourceSettings,aMessage,sourceToTarget,aErrorKey);
   945 	if (error!=KErrNone)
   946 		{
   947 		CleanupStack::PopAndDestroy(&sourceSettings);
   948 		return error;		
   949 		}	
   950 	
   951 	error =MoveL(sourceKeyIdentifier.iPartialId,targetKeyIdentifier.iPartialId,sourceKeyIdentifier.iIdMask,aErrorKey, sourceSettings);
   952 	CleanupStack::PopAndDestroy(&sourceSettings);
   953 	return error;	
   954 	}
   955 
   956 void CServerRepository::LoadIniRepL(CIniFileIn::TIniFileOpenMode aMode)
   957 	{
   958 	if (iIniRep == NULL)
   959 		{
   960 	 	CSharedRepository *rep = NULL;
   961 		TServerResources::iObserver->LoadRepositoryLC(iUid, ETrue, rep, aMode);
   962 		CleanupStack::Pop();
   963 		iIniRep = rep;
   964 		}
   965 	}
   966 
   967 TBool CServerRepository::GetMetaFromIni(TUint32 aKey, TUint32& aMeta)
   968 	{
   969 	// Note: cannot use iRepository even if 
   970 	// iRepository->iSettings.IsDefault() is true.
   971 	// The flag is not updated on TransactionCommit.
   972 	if (iIniRep == NULL)
   973 		{
   974 		TInt err;
   975 		TRAP(err, LoadIniRepL(CIniFileIn::EInstallOnly));
   976 		if (err != KErrNone)
   977 			{
   978 			TRAP(err,LoadIniRepL(CIniFileIn::ERomOnly));
   979 			}
   980 		if (err != KErrNone)
   981 			{
   982 			return EFalse;
   983 			}
   984 		}
   985 
   986 	ASSERT(iIniRep);
   987 	TServerSetting* s = iIniRep->GetSettings().Find(aKey);					
   988 	if (s)
   989 		{
   990 		aMeta = s->Meta();
   991 		return ETrue;
   992 		}
   993 
   994 	return EFalse;
   995 	}
   996 
   997 void CServerRepository::RestoreInstallRepositoryL(TUid aUid, CStreamStore& aStore, TStreamId& aSettingStreamId, CRestoredRepository& aRstRepos)
   998 	{
   999 	iRepository = CSharedRepository::NewL(aUid);
  1000 	CleanupStack::PushL(iRepository);
  1001 	iUid = aUid;
  1002 	RestoreRepositorySettingValuesL(aStore, aSettingStreamId, aRstRepos);
  1003 	CommitChangesL(EInstall);
  1004 	CleanupStack::PopAndDestroy(iRepository);
  1005 	iRepository = NULL;
  1006 	}
  1007 
  1008 void CServerRepository::BackupInstallRepositoryL(TUid aUid, CStreamStore& aStore, TStreamId& aSettingStreamId)
  1009 	{
  1010 	TServerResources::iObserver->LoadRepositoryLC(aUid, EFalse, iRepository, CIniFileIn::EInstallOnly);
  1011 	iUid = aUid;
  1012 	StoreRepositorySettingValuesL(aStore, aSettingStreamId);	
  1013 	CleanupStack::PopAndDestroy(iRepository);
  1014 	iRepository = NULL;
  1015 	}
  1016 
  1017 TInt CServerRepository::CheckAccessPolicyBeforeMoving(const TClientRequest& aMessage, const TServerSetting* aSourceSetting, 
  1018 				TUint32 aSourceKey, const TServerSetting* aTargetSetting, TUint32 aTargetKey, TUint32& aErrorKey)
  1019 	{
  1020 	TInt error = KErrNone;
  1021 	
  1022 	if (aTargetSetting && !aTargetSetting->IsDeleted())
  1023 		{
  1024 		error=KErrAlreadyExists;
  1025 		aErrorKey=aTargetKey;
  1026 		}
  1027 
  1028 	if (!aMessage.CheckPolicy(GetReadAccessPolicy(*aSourceSetting),
  1029 		__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to read a setting")))
  1030 		{
  1031 		error = KErrPermissionDenied;
  1032 		aErrorKey = aSourceKey;
  1033 		}
  1034 	else if (!aMessage.CheckPolicy(GetWriteAccessPolicy(*aSourceSetting),
  1035 		__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to delete a setting")))
  1036 		{
  1037 		error = KErrPermissionDenied;
  1038 		aErrorKey = aSourceKey;
  1039 		}
  1040 	else if (error == KErrAlreadyExists)
  1041 		{
  1042 		// set error to KErrPermissionDenied in preference to KErrAlreadyExists
  1043 		if (!aMessage.CheckPolicy(GetWriteAccessPolicy(*aTargetSetting),
  1044 			__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to create a setting")))
  1045 			{
  1046 			error = KErrPermissionDenied;
  1047 			aErrorKey = aTargetKey;
  1048 			}
  1049 		}
  1050 	else if (!aMessage.CheckPolicy(GetFallbackWriteAccessPolicy(aTargetKey),
  1051 			__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to create a setting")))
  1052 		{
  1053 		error = KErrPermissionDenied;
  1054 		aErrorKey = aTargetKey;
  1055 		}
  1056 	return error;
  1057 	}