applayerpluginsandutils/bookmarksupport/test/cenrepsrv/srvrepos.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerpluginsandutils/bookmarksupport/test/cenrepsrv/srvrepos.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,1026 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "panic.h"
+#include "shrepos.h"
+#include "srvrepos.h"
+#include "srvres.h"
+#include "cachemgr.h"
+#include "sessnotf.h"
+#include "srvPerf.h"
+
+#define TRAP_UNIFIED(_unifiedLeave, _function)	\
+	{ \
+	TInt _returnValue = 0; \
+	TRAP(_unifiedLeave, _returnValue = _function);	\
+	TInt& __rref = _unifiedLeave; \
+	__rref = _unifiedLeave | _returnValue; \
+	}
+
+RPointerArray<CSharedRepository> CServerRepository::iOpenRepositories;
+
+CServerRepository::~CServerRepository()
+	{
+	if(iOpenRepositories.Count()==0)
+		iOpenRepositories.Reset();
+	}
+	
+TInt CServerRepository::ReadIniFileL(CSharedRepository*& aRepository, TCentRepLocation aLocation)
+	{
+	TInt r=KErrNone;
+	CIniFileIn* inifile = 0;
+
+	HBufC* fileName(NULL);
+    //allocates memory on the heap
+    TServerResources::CreateRepositoryFileNameLC(fileName,aRepository->iUid,aLocation,EIni);		
+	r = CIniFileIn::NewLC(inifile,fileName,aLocation);
+	if(r==KErrNone)
+		{			
+		r=ReadSettingsL(inifile, aRepository);		
+		if(r==KErrCorrupt)
+			{
+			// File is corrupt, if it's not the ROM file, delete it
+			if(fileName && aLocation != ERom)
+				User::LeaveIfError(TServerResources::iFs.Delete(*fileName));
+			// Delete any repository settings that may have been read in
+			aRepository->iSettings.Reset();
+			}
+		}
+
+	CleanupStack::PopAndDestroy(inifile); // inifile	 
+	CleanupStack::PopAndDestroy(fileName);	// filename
+	return r;
+	}
+	
+TInt CServerRepository::CreateRepositoryL(CSharedRepository*& aRepository, TCentRepLocation aLocation)
+	{
+	aRepository->iSettings.SetIsDefault(aLocation!=EPersists);
+    TInt err(KErrNotFound);
+    
+	err = aRepository->CreateRepositoryFromCreFileL(aLocation);
+	if(err==KErrNotFound)
+		{
+		err = ReadIniFileL(aRepository,aLocation);
+		}
+	return( err);
+	}
+	
+/**
+In order to create a repository this routine looks for a .cre or .txt file. 
+Txt and cre files can co-exist in install and ROM but not in persists location.
+If a persists txt file exists, the first write to the repository will cause a
+cre file to be created and the txt file to be deleted.
+If both files exist in the same location, the .cre is picked up first. 
+If the .cre file is not found,a .txt file from the same location is tried.
+Otherwise if the .cre file is corrupted,it tries a .cre file from a next location. 
+
+Note:
+If a cre file exists at a particular location, even if the cre file is corrupt a txt 
+file will not be searched for in the same location. 
+*/
+
+TInt CServerRepository::CreateRepositoryL(CSharedRepository*& aRepository, CIniFileIn::TIniFileOpenMode aIniFileOpenMode)
+    {
+    TInt err(KErrNotFound);
+    
+    switch (aIniFileOpenMode)
+	    {
+	    case CIniFileIn::EAuto:
+	        {
+	        // Look in persists dir	 
+	        err=CreateRepositoryL(aRepository, EPersists);		
+	        				
+			if(err==KErrNone)
+				{
+				return err;
+				}
+			 
+	        // No persists file - look in ROM dir	 
+	        // Do this before looking in the install dir, because if there is
+	        // a ROM file, an install file and no persists file then this
+	        // repository is being opened after a SW install but before the 
+	        // merge. In this case the install file shouldn't be opened
+	        // until after the merge.
+	        err=CreateRepositoryL(aRepository, ERom);		
+	        				
+			if(err==KErrNone)
+				{
+				break;
+				}
+			else if(err==KErrNotFound)
+				{				
+			     // Look in install directory only if there was no ROM or persists file	            
+				err=CreateRepositoryL(aRepository, EInstall);
+				if(err==KErrNone)
+					{
+					TTime installFileTimeStamp=TServerResources::CentrepFileTimeStampL(aRepository->iUid, EInstall);
+					aRepository->SetInstallTime(installFileTimeStamp);
+					}
+				}
+	        break;
+	        }
+	        
+	    case CIniFileIn::EInstallOnly:
+	        {
+	    	err=CreateRepositoryL(aRepository, EInstall);		
+	        break;
+	        }
+
+	    case CIniFileIn::ERomOnly:
+	        {
+	    	err=CreateRepositoryL(aRepository, ERom);		
+	        break;
+	        }
+	    }
+
+	return err;
+	}
+	
+TInt CServerRepository::ReadSettingsL(CIniFileIn *aIniFile, CSharedRepository* aRep)
+	{	
+	return aRep->ReloadContentL(*aIniFile);
+	}
+
+void CServerRepository::LoadRepositoryLC(TUid aUid, TBool aFailIfNotFound, CSharedRepository*& aRepository, CIniFileIn::TIniFileOpenMode aIniFileOpenMode)
+	{
+	// Calculate the amount of memory this repository will take in the heap
+	// by checking the heap size before and after the internalization
+	RHeap& myHeap = User::Heap();
+	TInt firstSize = myHeap.Size();
+	TInt biggestBlock;
+	TInt firstAvail = myHeap.Available(biggestBlock);
+	
+	aRepository = new CSharedRepository(aUid);
+#ifdef CACHE_OOM_TESTABILITY
+	if ((aRepository==NULL)&&!iTrapOOMOnOpen)	
+		{
+		User::Leave(KErrNoMemory);
+		}
+#endif	
+	if ((aRepository==NULL)&&TServerResources::iCacheManager->Enabled())
+		{
+		// If cache enabled, try recovery by releasing the cache
+		TServerResources::iCacheManager->FlushCache();
+		// retry
+		aRepository = new CSharedRepository(aUid);
+		}
+	// If still no memory, return error
+	if (aRepository==NULL)
+		{
+		User::Leave(KErrNoMemory);
+		}
+	else // successfully created the object, so push it into the cleanup stack
+		{
+		CleanupStack::PushL(aRepository);
+		}
+		
+	// Now that we have enough memory for the object and constructed it properly
+	// we try to load it. We trap all errors, either from leaving functions or error code
+	// returning functions and unify them (in all cases only one of these codes will
+	// contain a valid value and the other will be 0, and for our purposes we treat
+	// all errors the same no matter if they're thrown or returned)
+
+	TInt unifiedErrorCode;
+	TRAP_UNIFIED(unifiedErrorCode, CreateRepositoryL(aRepository, aIniFileOpenMode));
+	
+	switch(unifiedErrorCode)
+		{
+		case KErrNoMemory:
+			{
+			if (TServerResources::iCacheManager->Enabled()) // cache enabled
+				{
+#ifdef CACHE_OOM_TESTABILITY
+				if (!iTrapOOMOnOpen)	
+					{
+					User::Leave(KErrNoMemory);
+					}
+#endif	
+				// Flush cache
+				TServerResources::iCacheManager->FlushCache();
+
+				firstSize = myHeap.Size();
+				firstAvail = myHeap.Available(biggestBlock);
+	
+				//retry
+				TRAP_UNIFIED(unifiedErrorCode, CreateRepositoryL(aRepository, aIniFileOpenMode));
+				}
+			}
+			break;
+		case KErrNotFound:
+		case KErrPathNotFound:		
+			{
+			if (!aFailIfNotFound) // backup open
+				{
+				// override error condition and continue normally
+				unifiedErrorCode = KErrNone;
+				}
+			}
+			break;
+		}
+
+	// If unhandled, leave
+	User::LeaveIfError(unifiedErrorCode);
+
+	// Otherwise, finalize calulations
+	TInt lastSize = myHeap.Size();
+	TInt lastAvail = myHeap.Available(biggestBlock);
+
+	TInt calcSize = (lastSize - lastAvail) - (firstSize - firstAvail);
+	// record repository size for cache algorithm purposes
+	aRepository->SetSize(calcSize);
+	}
+
+void CServerRepository::OpenL(TUid aUid, MObserver& aObserver, TBool aFailIfNotFound)
+	{
+	TInt i = FindRepository(aUid);
+	if(i!=KErrNotFound)
+		{
+		CSharedRepository* rep = iOpenRepositories[i];
+		rep->AddObserverL(aObserver);
+		iRepository = rep;
+		
+		// find the item in the cache and remove it because it's in-use again
+		TServerResources::iCacheManager->RemoveIdleRepository(iRepository);
+		}
+	else
+		{
+		CSharedRepository* rep = NULL;
+		
+		// For memory usage testing purposes
+		RECORD_HEAP_SIZE(EMemLcnRepositoryOpen, aUid.iUid);
+		// Various error conditions are handled in this function 
+		LoadRepositoryLC(aUid, aFailIfNotFound, rep, CIniFileIn::EAuto);
+		// For memory usage testing purposes
+		RECORD_HEAP_SIZE(EMemLcnRepositoryOpen, aUid.iUid);
+				
+		rep->AddObserverL(aObserver);
+		iOpenRepositories.AppendL(rep);
+		iRepository = rep;
+
+		// Add owner mapping to list - Will fail if an entry already exists
+		// with this Repository UID but this doesn't matter
+		TUid owner = iRepository->Owner() ;
+		TServerResources::AddOwnerIdLookupMapping (aUid.iUid, owner.iUid) ;
+
+		CleanupStack::Pop(rep);
+		}
+	}
+
+void CServerRepository::Close(MObserver& aObserver)
+	{
+	if(iRepository)
+		{
+		// cancel to ensure any read/write locks are released and transaction settings cleaned up
+		CancelTransaction();
+		if(iRepository->RemoveObserver(aObserver)==0)
+			{
+			TInt i = FindRepository(iRepository->Uid());
+			__ASSERT_ALWAYS(i>=0, Panic(ERepositoryNotFound));
+
+			// Check cache size and carry out forced eviction if necessary			
+			// Start Eviction if the repository fits in the cache	
+			if (TServerResources::iCacheManager->Enabled()&&
+				TServerResources::iCacheManager->StartEviction(iRepository))
+				{
+				// Repository added to the idle list in eviction order
+				__CENTREP_TRACE2("CENTREP: Repository Became Idle when closing repository %x size %d", iRepository->Uid().iUid, iRepository->Size());
+				}
+			else
+				{
+				iOpenRepositories.Remove(i);
+				delete iRepository;
+				__CENTREP_TRACE1("CENTREP: Repository Delete when closing repository %x", iRepository->Uid().iUid);
+				}
+			}
+		else
+			{
+			__CENTREP_TRACE1("CENTREP: Observer Removed when closing repository %x", iRepository->Uid().iUid);
+			}
+		iRepository = 0;
+		}
+	}
+	
+/**
+The method will make an attempt to restore current repository's consistency if previous
+CommitChangesL() failed.
+@leave System-wide error codes
+*/
+void CServerRepository::RestoreConsistencyL()
+	{
+	if(iRepository)
+		{
+		iRepository->RestoreConsistencyL();
+		}
+	}
+	
+/**
+Attempt to reset a single key to it's value in the file in the given location. Routine
+attempts to find a .cre file first. If ( and only if ) a cre file doesn't exist the 
+routine attempts to find a txt file.
+Note that it would be possible to use LoadRepositoryLC here but for the txt file
+that would take longer. This is because in LoadRepositoryLC the txt file is 
+completely processed. The Reset specific txt file opening code below is quicker because 
+it is just attempting to find the reset key.
+*/	
+void CServerRepository::ResetFromIniFileL(TUint32 aId, 
+										  TCentRepLocation aLocation,
+										  TBool& aKeyFound)
+	{
+	aKeyFound=EFalse;
+
+	// Attempt to reset key to value in cre file if it exists
+	
+	// Attempt to create a temporary repository from the cre file in aLocation
+	CSharedRepository* rep = new(ELeave) CSharedRepository(iRepository->Uid());
+	CleanupStack::PushL(rep);
+	TInt err = rep->CreateRepositoryFromCreFileL(aLocation);
+
+	// Search for aId in the temporary repository
+	if (err!=KErrNotFound)
+		{		
+		// Note that for all errors except KErrNotFound code leaves and doesn't
+		// attempt to look for txt file. This is intentional. Code does not 
+		// attempt to support coexisting cre and txt files.
+		User::LeaveIfError(err);
+		
+		// Search for aId in the temporary repository
+		TServerSetting* s = rep->iSettings.Find(aId);					
+		if(s)
+			{
+			aKeyFound=ETrue;
+			// Mark the setting as default again
+			s->SetClean();
+			iRepository->ResetAndPersistL(*s);
+			s->SetAccessPolicy(GetFallbackAccessPolicy(aId));
+			}
+			
+		CleanupStack::PopAndDestroy(rep);
+		return;
+		}
+	else
+		{
+		CleanupStack::PopAndDestroy(rep);
+		}
+		
+	HBufC* fileName(NULL);	
+	TServerResources::CreateRepositoryFileNameLC(fileName,iRepository->Uid(),aLocation,EIni);
+	
+	CIniFileIn* inputFile = 0;
+	TInt r = CIniFileIn::NewLC(inputFile,fileName,aLocation);
+	if(r==KErrNone)
+		{
+		//we don't want to read this stuff again... just skip over to get to settings!
+		inputFile->SkipOwnerSectionL() ;
+		inputFile->SkipTimeStampSectionL() ;
+		inputFile->SkipDefaultMetaSectionL() ;
+		inputFile->SkipPlatSecSectionL();
+		
+		// Find start of Main section
+		inputFile->FindMainSectionL();
+	
+		TServerSetting s;
+		TBool singleMetaFound=EFalse;
+		TBool singleReadPolicyFound=EFalse;
+		TBool singleWritePolicyFound=EFalse;
+		TSecurityPolicy singleReadPolicy;
+		TSecurityPolicy singleWritePolicy;
+
+		// Note that calling CIniFile::ReadSettingL causes the single policy ( if it exists ) to be read from the
+		// file being reset to, but doesn't update the single policy array, which is not required in the reset case. 
+		while((r=inputFile->ReadSettingL(s,singleReadPolicy, singleWritePolicy, singleReadPolicyFound, singleWritePolicyFound, singleMetaFound)) == KErrNone)
+			{	
+			iRepository->SetMetaDataOnRead( s, singleMetaFound);			
+			if(s.Key()==aId)
+				{
+				// Mark the setting as default again
+				s.SetClean();
+				iRepository->ResetAndPersistL(s);
+				s.SetAccessPolicy(GetFallbackAccessPolicy(aId));
+				aKeyFound = ETrue;
+				break;
+				}
+			s.Reset();
+			}
+
+	
+		}
+	CleanupStack::PopAndDestroy(inputFile);	 // inputFile
+	CleanupStack::PopAndDestroy(fileName);	 // filename
+	}
+
+TInt CServerRepository::ResetL(TUint32 aId)
+	{
+	// not yet supported in transactions
+	ASSERT(!IsInTransaction());
+
+	// if setting has not changed, there nothing to do
+	TServerSetting *targetSetting = GetSetting(aId) ;
+
+	if (targetSetting)
+		{
+		if ((targetSetting->Meta() & KMetaDefaultValue))
+			{
+			return KErrNone;
+			}
+		}
+
+	TInt error = KErrNone;
+	TBool keyReset = EFalse;
+
+	// Check for default value in any installed file first
+	ResetFromIniFileL(aId, EInstall, keyReset);
+	if (keyReset)
+		return KErrNone;
+
+	// Either we couldn't find a matching key or
+	// there wasn't an installed file - try for a ROM
+	// file
+	ResetFromIniFileL(aId, ERom, keyReset);
+	if (keyReset)
+		return KErrNone;
+	
+	// No default value found in install or ROM file
+	// delete the key!
+	error = iRepository->DeleteAndPersist(aId);
+
+	return error ;
+	}
+	
+void CServerRepository::ResetRepositoriesL()
+	{
+	// Read contents of persist directory to get a list of repositories
+	CDir* persistDir;
+	TPtr dataDirectory = TServerResources::iDataDirectory->Des();
+	User::LeaveIfError(TServerResources::iFs.GetDir(dataDirectory,
+													KEntryAttNormal,
+													ESortNone,
+													persistDir));
+
+	CleanupStack::PushL(persistDir);
+
+	const TInt fileCount = persistDir->Count();
+
+	// Open each repositories in the persist directory
+	// and restore the settings.
+	for(TInt i = 0; i < fileCount; ++i)
+		{
+		// Attempt to extract a repository UID from directory entry
+		TUid uid;
+		if (!TServerResources::GetUid(const_cast<TEntry&>((*persistDir)[i]), uid))
+			{
+			CSessionNotifier notifier;
+
+			// Create shared repository
+			CServerRepository *repository = new(ELeave) CServerRepository;
+			CleanupStack::PushL(repository);
+
+			repository->OpenL(uid, notifier);
+		
+			// Restore settings
+			repository->ResetRepositoryL();
+
+			// delete repository.
+			repository->Close(notifier);
+			CleanupStack::PopAndDestroy(repository);
+			}
+		}
+	CleanupStack::PopAndDestroy(persistDir);
+	}
+
+TInt CServerRepository::ResetRepositoryL()
+	{
+	// for each key in combined ROM/Install restore
+	TUid uid = iRepository->Uid();
+
+	CSharedRepository* repository = 0;
+	
+	// Create a rep using the ROM file
+  	TBool romExists=TServerResources::RomFileExistsL(uid);
+	if(romExists)
+		{
+		LoadRepositoryLC(uid, ETrue, repository, CIniFileIn::ERomOnly);
+		}
+		
+	// Create install rep for merging
+	CSharedRepository *installRep = 0;
+	TBool installExists=TServerResources::InstallFileExistsL(uid);
+	if(installExists)
+		{			
+		LoadRepositoryLC(uid, ETrue, installRep, CIniFileIn::EInstallOnly);
+		}
+		
+	TInt err=KErrNone;
+	if(	romExists && installExists)
+		{
+		// If install and ROM exist create a merged rep to Reset against
+		repository->MergeL(*installRep, ESWIUpgradeMerge);
+		}
+	else if(!romExists && !installExists)
+		{
+		// Reset against empty repository
+		repository = new(ELeave) CSharedRepository(uid);
+		CleanupStack::PushL(repository);
+		}
+
+	for(TInt i = 0; i < repository->iSettings.Count(); i++)
+		{
+		TServerSetting* setting = &repository->iSettings[i];
+
+		if ((setting->Meta() & KMetaRfsValue) != KMetaRfsValue)
+			{
+			continue;
+			}
+		TUint32 key = setting->Key();
+
+		// If the clean is set on setting in the persist, nothing to do
+		TServerSetting *targetSetting = GetSetting(key);
+
+		if (targetSetting)
+			{
+			if (targetSetting->Meta() & KMetaDefaultValue)
+				{
+				continue;
+				}
+			}
+		iRepository->ResetNoPersistL(*setting);
+		}
+
+	// Persist settings
+	iRepository->CommitChangesL();
+
+	CleanupStack::PopAndDestroy(repository);
+
+	return err;
+	}
+
+
+TInt CServerRepository::ResetAllL()
+	{
+	// not yet supported in transactions
+	ASSERT(!IsInTransaction());
+	// fail all sessions' transactions first
+	iRepository->FailAllTransactions(/*aExcludeTransactor*/NULL);
+
+	TUid uid = iRepository->Uid();
+
+	// Reset
+ 	 	
+	// Create a rep using the ROM file
+	CSharedRepository* rep = 0;
+  	TBool romExists=TServerResources::RomFileExistsL(uid);
+	if(romExists)
+		{
+		LoadRepositoryLC(uid, ETrue, rep, CIniFileIn::ERomOnly);
+		}
+		
+	// Create install rep for merging
+	CSharedRepository *installRep = 0;
+	TBool installExists=TServerResources::InstallFileExistsL(uid);
+	if(installExists)
+		{			
+		LoadRepositoryLC(uid, ETrue, installRep, CIniFileIn::EInstallOnly);
+		}
+		
+	TInt err=KErrNone;
+	if(	romExists && installExists)
+		{
+		// If install and ROM exist create a merged rep to Reset against
+		rep->MergeL(*installRep, ESWIUpgradeMerge);
+		err=iRepository->ResetAllNoPersistL(*rep);
+		CleanupStack::PopAndDestroy(installRep);
+		CleanupStack::PopAndDestroy(rep);
+		}
+	else if(romExists)
+		{
+		// Reset against ROM
+		err=iRepository->ResetAllNoPersistL(*rep);
+		CleanupStack::PopAndDestroy(rep);
+		}
+	else if(installExists)
+		{
+		// Reset against install
+		err=iRepository->ResetAllNoPersistL(*installRep);
+		CleanupStack::PopAndDestroy(installRep);
+		}
+	else
+		{
+		// Reset against empty repository
+		rep = new(ELeave) CSharedRepository(uid);
+		CleanupStack::PushL(rep);
+		err=iRepository->ResetAllNoPersistL(*rep);
+		CleanupStack::PopAndDestroy(rep);
+		}
+	
+	return err;
+	}
+
+TInt CServerRepository::FindRepository(TUid aUid) const
+	{
+	TInt i;
+	for(i=iOpenRepositories.Count()-1; i>=0; i--)
+		if(iOpenRepositories[i]->Uid()==aUid)
+			break;
+	return i;
+	}
+	
+// Handle install directory file update. 
+void CServerRepository::HandleSWIUpdateL(TUid aUid, TTime aModified, CSessionNotifier &aNotifier)
+	{		
+	// A file create or update has just occurred in the SWI directory. 
+	// Need to check if this is a new install. 
+	
+	if(TServerResources::PersistsFileExistsL(aUid) ||
+	   TServerResources::RomFileExistsL(aUid))
+		{	
+		// Create a rep using the ROM or persists file
+		OpenL(aUid, aNotifier);
+		if(iRepository->IsTransactionActive())			
+			{
+			// Fail transactions on any currently open session
+			iRepository->FailAllTransactions(NULL);
+			}
+			
+		// Create install rep for merging
+ 		CSharedRepository *installRep = 0;
+ 		LoadRepositoryLC(aUid, ETrue, installRep, CIniFileIn::EInstallOnly);
+	
+		// Perform merge
+		iRepository->HandleUpdateMergeL(aModified, *installRep);
+						
+		CleanupStack::PopAndDestroy(installRep);
+		Close(aNotifier);
+		}
+	else	// No ROM or persists
+		{
+		// Create install rep for persisting
+		OpenL(aUid, aNotifier);
+	
+		iRepository->CommitChangesL();
+		Close(aNotifier);
+		}
+	}
+
+
+// Handle install directory file delete 
+void CServerRepository::HandleSWIDeleteL(TUid aUid, CSessionNotifier &aNotifier)
+	{			
+	// A file delete has just occurred in the SWI directory. If there is no ROM file
+	// this is a complete uninstall, so delete persists file.Otherwise, do downgrade
+	// merge.
+	
+	if(TServerResources::RomFileExistsL(aUid))		// ROM file, this is an upgrade uninstall
+		{
+		if(!TServerResources::PersistsFileExistsL(aUid))
+			{
+			// If we are downgrading the ROM, there should be a persists file because the
+			// original upgrade should have created one.
+			// However if there isn't a persists file, there's nothing to do, so just return
+			return;
+			}
+			
+		// Create a rep using the persists file
+		OpenL(aUid, aNotifier);
+		if(iRepository->IsTransactionActive())			
+			{
+			// Fail transactions on any currently open session
+			iRepository->FailAllTransactions(NULL);
+			}
+		
+		// Create ROM rep for merging
+	 	CSharedRepository *romRep = 0;
+		LoadRepositoryLC(aUid, ETrue, romRep, CIniFileIn::ERomOnly);
+
+		// Perform merge
+		iRepository->HandleDeleteMergeL(*romRep);
+		
+		CleanupStack::PopAndDestroy(romRep);
+		Close(aNotifier);
+		}
+	else											// No ROM file, this is a complete uninstall
+		{		
+		if(TServerResources::PersistsFileExistsL(aUid))
+			{
+		 	TServerResources::DeletePersistsFileL(aUid);
+		 	
+			// Check if the repository was open
+			TInt i = FindRepository(aUid);
+
+			// If repository is open, fail all transactions 
+			if(i>KErrNotFound)			   					  
+				{
+				OpenL(aUid, aNotifier);
+				if(iRepository->IsTransactionActive())			
+					{
+					// Fail transactions on any currently open session
+					iRepository->FailAllTransactions(NULL);
+					}
+				iRepository->ResetContent();
+				Close(aNotifier);				
+				}
+			}
+		}
+	}
+
+void CServerRepository::StoreRepositoryContentsL(CStreamStore& aStore, TStreamId & aSettingStreamId, TStreamId & aDeletedSettingsStreamId) const
+	{
+	RStoreWriteStream outStream;
+	aSettingStreamId = outStream.CreateLC(aStore); // Creates the write stream
+	iRepository->WriteBackupStream(outStream); // Only care about repository contents.
+	outStream.CommitL(); // Commits the stream
+	CleanupStack::PopAndDestroy(&outStream); // Performs cleanup on the write stream object
+
+	
+	aDeletedSettingsStreamId = outStream.CreateLC(aStore); // Creates the write for settings stream
+	iRepository->WriteDeletedSettingsStream(outStream) ;
+	outStream.CommitL(); // Commits the stream
+	CleanupStack::PopAndDestroy(&outStream); // Performs cleanup on the write stream object
+	}
+	
+void CServerRepository::RestoreRepositoryContentsL(CStreamStore& aStore, TStreamId aSettingStreamId, TStreamId aDeletedSettingsStreamId)
+	{
+	RStoreReadStream inStream;
+	inStream.OpenLC(aStore, aSettingStreamId); // Creates the write stream
+	iRepository->InternalizeL(inStream); // Only care about repository contents.
+	CleanupStack::PopAndDestroy(&inStream);    // Perform cleanup on the read stream object
+
+	// If the backup contains a list of deleted settings read them in and apply them.
+	if (aDeletedSettingsStreamId != KNullStreamId)
+		{
+		inStream.OpenLC(aStore, aDeletedSettingsStreamId); // Creates read stream for deleted settings (if available)
+
+		TCardinality numDeletedSettings ;
+		inStream >> numDeletedSettings ;
+		
+		for (TInt i = 0; i < numDeletedSettings; i++)
+			{
+			TUint32 settingToDelete ;
+			inStream >> settingToDelete ;
+			iRepository->DeleteNoPersist(settingToDelete) ; 		
+			}
+		CleanupStack::PopAndDestroy(&inStream);            // Perform cleanup on the read stream object		
+		}
+	return;
+	}
+
+static void CancelTransactionCleanupOperation(TAny* aRepository)
+	{
+	static_cast<CServerRepository*>(aRepository)->CancelTransaction();
+	}
+
+// So CancelTransaction is called in case of Leave. Must pop with CleanupStack::Pop() or similar
+void CServerRepository::CleanupCancelTransactionPushL()
+	{
+	CleanupStack::PushL(TCleanupItem(CancelTransactionCleanupOperation, this));
+	}
+
+/**
+@internalTechnology
+Check the range of security policies against RMessage
+@return
+	KErrNone if read access policies of all settings in array pass,
+	KErrPermissionDenied if any single policy fails.
+*/
+TInt CServerRepository::CheckReadPermissions(RSettingPointerArray& aSettings, const TClientRequest& aMessage, const char *aDiagnostic)
+	{
+	TInt error = KErrNone;
+	TInt numSettings = aSettings.Count();
+	for (TInt i = 0; i < numSettings; i++)
+		{
+		ASSERT(aSettings[i]);
+		const TServerSetting& setting = *aSettings[i];
+		if (!aMessage.CheckPolicy(GetReadAccessPolicy(setting),aDiagnostic))
+			{
+			error = KErrPermissionDenied;
+			break;
+			}
+		}
+	return error;
+	}
+
+/** Returns pointer array of settings whose keys match the partial key and mask. Combines
+settings from the persistent list with those in the transaction, with priority given to the
+latter, including settings flagged as deleted eliminating the corresponding entry from the 
+persistent settings (plus themselves so the final list has no settings flagged as deleted in it).
+Can also call this method when not in a transaction.
+In case of error, aMatches may contain entries and must be Reset.
+*/
+TInt CServerRepository::FindSettings(TUint32 aPartialKey, TUint32 aIdMask, RSettingPointerArray& aMatches) const
+	{
+	TInt error = FindPersistentSettings(aPartialKey, aIdMask, aMatches);
+	// try to be most efficient when no transaction changes
+	if ((iTransactionSettings.Count() > 0) && IsInActiveReadWriteTransaction() && (KErrNone == error))
+		{
+		RSettingPointerArray transactionSettings;
+		error = FindTransactionSettings(aPartialKey, aIdMask, transactionSettings);
+		if (error == KErrNone)
+			{
+			error = RSettingsArray::Merge(aMatches, transactionSettings);
+			}
+		transactionSettings.Reset();
+		}
+	return error;
+	}
+
+TInt CServerRepository::TransactionDeleteRangeL(const TClientRequest& aMessage, TUint32& aErrorKey)
+	{
+	// all write operations now done in a transaction
+	ASSERT(IsInActiveReadWriteTransaction());
+	TInt error = KErrNone;
+	aErrorKey = KUnspecifiedKey;
+		
+	TUint32 partialKey = aMessage.Int0();
+	TUint32 keyMask = aMessage.Int1();
+	
+	RSettingPointerArray settingsToDelete;
+	error = FindSettings(partialKey, keyMask, settingsToDelete);
+	CleanupClosePushL(settingsToDelete);
+	
+	TInt numSettings = settingsToDelete.Count();
+
+	if ((error == KErrNone) && (numSettings == 0))
+		{
+		error = KErrNotFound;
+		aErrorKey = partialKey;
+		}
+		
+	for (TInt i = 0; (i < numSettings) && (error == KErrNone); i++)
+		{
+		ASSERT(settingsToDelete[i]);
+		TServerSetting& settingToDelete = *(settingsToDelete[i]);
+		TUint32 key = settingToDelete.Key();
+		// must pass write access policies of key
+		if (!aMessage.CheckPolicy(GetWriteAccessPolicy(settingToDelete),
+			__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::DeleteRangeL - Attempt made to delete a setting")))
+			{
+			error = KErrPermissionDenied;
+			aErrorKey = key;
+			}
+		else
+			{
+			// delete it
+			// Ensure there is a delete placeholder at the location
+			if (GetTransactionSetting(key) == &settingToDelete)
+				{
+				// we are deleting a setting that is already in the transaction list: Flag it as deleted
+				settingToDelete.Reset();
+				settingToDelete.SetDeleted();
+				}
+			else
+				{
+				// create a new placeholder and set as deleted
+				TServerSetting newSetting(key);
+				newSetting.SetDeleted();
+				iTransactionSettings.OrderedInsertL(newSetting);
+				}
+			}
+		}
+	
+	CleanupStack::PopAndDestroy(&settingsToDelete);
+
+	if ((error != KErrNone) && (error != KErrNotFound))
+		{
+		FailTransaction(error, aErrorKey);
+		}
+	return error;
+	}
+
+TInt CServerRepository::TransactionMoveL(const TClientRequest& aMessage, TUint32& aErrorKey)
+	{
+	// all write operations now done in a transaction
+	ASSERT(IsInActiveReadWriteTransaction());
+	TInt error = KErrNone;
+	aErrorKey = KUnspecifiedKey;
+
+	TUint32 sourcePartialKey = aMessage.Int0();
+	TUint32 targetPartialKey = aMessage.Int1();	
+	TUint32 idMask = aMessage.Int2();
+	TUint32 maskedSourcePartialKey = sourcePartialKey & idMask;
+	TUint32 maskedTargetPartialKey = targetPartialKey & idMask;
+	TUint32 sourceToTarget = maskedSourcePartialKey ^ maskedTargetPartialKey;
+	if (sourceToTarget == 0)
+		{
+		// not moving anywhere: must return now as this trivial case fails with later logic
+		return KErrNone;
+		}
+
+	RSettingPointerArray sourceSettings;
+	error = FindSettings(maskedSourcePartialKey, idMask, sourceSettings);
+	CleanupClosePushL(sourceSettings);
+
+	TInt numSettings = sourceSettings.Count();
+
+	if ((error == KErrNone) && (numSettings == 0))
+		{
+		error = KErrNotFound;
+		aErrorKey = sourcePartialKey;
+		}
+
+	for (TInt i = 0; (i < numSettings) && (error == KErrNone); i++)
+		{
+		ASSERT(sourceSettings[i]);
+		TServerSetting& sourceSetting = *(sourceSettings[i]);
+		TUint32 sourceKey = sourceSetting.Key();
+		TUint32 targetKey = sourceKey ^ sourceToTarget;
+		TServerSetting* targetSetting = GetSetting(targetKey);
+		// must pass both read and write access policies of source key
+		if (!aMessage.CheckPolicy(GetReadAccessPolicy(sourceSetting),
+			__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to read a setting")))
+			{
+			error = KErrPermissionDenied;
+			aErrorKey = sourceKey;
+			}
+		else if (!aMessage.CheckPolicy(GetWriteAccessPolicy(sourceSetting),
+			__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to delete a setting")))
+			{
+			error = KErrPermissionDenied;
+			aErrorKey = sourceKey;
+			}
+		else if (targetSetting && !targetSetting->IsDeleted())
+			{
+			// set error to KErrPermissionDenied in preference to KErrAlreadyExists
+			if (!aMessage.CheckPolicy(GetWriteAccessPolicy(*targetSetting),
+				__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to create a setting")))
+				{
+				error = KErrPermissionDenied;
+				}
+			else
+				{
+				error = KErrAlreadyExists;
+				}
+			aErrorKey = targetKey;
+			}
+		else if (!aMessage.CheckPolicy(GetFallbackWriteAccessPolicy(targetKey),
+				__PLATSEC_DIAGNOSTIC_STRING("CenRep: CServerRepository::MoveL - Attempt made to create a setting")))
+			{
+			error = KErrPermissionDenied;
+			aErrorKey = targetKey;
+			}
+		else
+			{
+			// move it
+			// 1. create a copy at the new location
+			if (targetSetting)
+				{
+				// must be set as deleted and already in the transaction settings so can overwrite
+				ASSERT(targetSetting->IsDeleted());
+				error = targetSetting->Replace(sourceSetting);
+				if (error == KErrNone)
+					{
+					targetSetting->SetKey(targetKey);
+					targetSetting->SetMeta(sourceSetting.Meta() & (~KMetaDefaultValue));
+					// setting takes the access policy of the target key
+					targetSetting->SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
+					}
+				}
+			else
+				{
+				TServerSetting newSetting;
+				error = newSetting.Replace(sourceSetting);
+				if (error == KErrNone)
+					{
+					newSetting.SetKey(targetKey);
+					newSetting.SetMeta(sourceSetting.Meta() & (~KMetaDefaultValue));
+					// setting takes the access policy of the target key
+					newSetting.SetAccessPolicy(GetFallbackAccessPolicy(targetKey));
+					newSetting.PushL(); // only needed for strings
+					iTransactionSettings.OrderedInsertL(newSetting);
+					newSetting.Pop();	// only needed for strings
+					}
+				}
+			// 2. ensure there is a delete placeholder at the old location
+			if (GetTransactionSetting(sourceKey) == &sourceSetting)
+				{
+				// we are moving a setting that is already in the transaction list: Set it deleted
+				sourceSetting.Reset();
+				sourceSetting.SetDeleted();
+				}
+			else
+				{
+				// create a new placeholder and set as deleted
+				TServerSetting newSetting(sourceKey);
+				newSetting.SetDeleted();
+				iTransactionSettings.OrderedInsertL(newSetting);
+				}
+			}
+		}
+		
+	CleanupStack::PopAndDestroy(&sourceSettings);
+
+	if ((error != KErrNone) && (error != KErrNotFound))
+		{
+		FailTransaction(error, aErrorKey);
+		}
+	return error;
+	}