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