cryptoservices/filebasedcertificateandkeystores/source/certapps/server/CFSCertAppsServer.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
child 30 cf642210ecb7
--- a/cryptoservices/filebasedcertificateandkeystores/source/certapps/server/CFSCertAppsServer.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/filebasedcertificateandkeystores/source/certapps/server/CFSCertAppsServer.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,469 +1,470 @@
-/*
-* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "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 "CFSCertAppsServer.h"
-#include "CCertAppsSession.h"
-#include "CCertAppsConduit.h"
-#include "fstokencliserv.h"
-#include "fstokenutil.h"
-#include "certstorepatchdata.h"
-#include <certificateapps.h>
-#include <u32hal.h> 
-
-// Filename where all data is stored
-_LIT(KCertAppsFilename,"certclients.dat");
-_LIT(KCertAppsFile,"certclients*.dat");
-
-CFSCertAppsServer* CFSCertAppsServer::NewL()
-	{
-	CFSCertAppsServer* self = new (ELeave) CFSCertAppsServer();
-	CleanupStack::PushL(self);
-	self->ConstructL();
-	CleanupStack::Pop(self);
-	return self;
-	}
-
-CFSCertAppsServer::CFSCertAppsServer()
-	{
-	}
-
-void CFSCertAppsServer::ConstructL()
-	{
-	iConduit = CCertAppsConduit::NewL(*this);
-	
-	// Connect to the filesystem
-	User::LeaveIfError(iFs.Connect());
-
-	iPatchableConst = KAggregateCertStore;
-	
-	#ifdef __WINS__
-		// For the emulator allow the constant to be patched via epoc.ini
-		UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
-		(TAny*)"KAggregateCertStore", &iPatchableConst); // read emulator property (if present)
-	#endif		
-	
-	// Retrieves the store
-	OpenStoreL();
-	}
-
-CFSCertAppsServer::~CFSCertAppsServer()
-	{
-	delete iStore;
- 	iFs.Close();
-	iClients.Close();
-	delete iConduit;
-	}
-
-CCertAppsSession* CFSCertAppsServer::CreateSessionL()
-	{
-	return CCertAppsSession::NewL(*iConduit); 
-	}
-
-void CFSCertAppsServer::AddL(const TCertificateAppInfo& aClient)
-	{
-	// see if application already exists. If so, then leave
-	
-	if (FindApplication(aClient.Id()))
-		{
-		User::Leave(KErrAlreadyExists);
-		}
-	User::LeaveIfError(iClients.Append(aClient));
-	TRAPD(err, ReplaceAndCommitL(-1));
-	if (err != KErrNone)
-		{
-		// We must remove the client from iClients if we didn't manage 
-		// to add it to the store
-		iClients.Remove(iClients.Count() - 1);
-		User::Leave(err);
-		}
-	}
-
-void CFSCertAppsServer::RemoveL(const TUid& aUid)
-	{
-	// Make sure the application for that uid exists
-	TInt i;
-	if (!FindApplication(aUid, &i))
-		{
-		User::Leave(KErrNotFound);
-		}
-
-	ReplaceAndCommitL(i);
-	
-	// We managed to remove it from the store, so we remove it from the
-	// iClients array
-	iClients.Remove(i);
-	}
-
-TInt CFSCertAppsServer::ApplicationCountL() const
-	{
-	return iClients.Count();
-	}
-
-void CFSCertAppsServer::ApplicationsL(RArray<TCertificateAppInfo>& aAppArray) const
-	{
-	// Make a copy of the array
-	TInt count = iClients.Count();
-
-	for (TInt i = 0; i < count; ++i)
-		{
-		aAppArray.Append(iClients[i]);
-		}
-	}
-
-void CFSCertAppsServer::ApplicationL(const TUid& aUid, TCertificateAppInfo& aInfo) const
-	{
-	const TCertificateAppInfo* app = FindApplication(aUid);
-
-	// leave if not found
-	if (!app)
-		{
-		User::Leave(KErrNotFound);
-		}
-
-	// make a copy and return to client
-	aInfo = *app;
-	}
-
-const TCertificateAppInfo* CFSCertAppsServer::FindApplication(const TUid& aUid, TInt* aIndex) const
-	{
-	// This helper function tries to find an application with the given
-	// Uid. It returns NULL if not found. aIndex returns the index into
-	// the array successful
-	const TCertificateAppInfo* retVal = NULL;
-	TInt end = iClients.Count();
-	for (TInt i = 0; i < end; ++i)
-		{
-		if (iClients[i].Id() == aUid)
-			{
-			// check if an index is required to be returned
-			if (aIndex)
-				{
-				*aIndex = i;
-				}
-			retVal = &iClients[i];
-			break;
-			}
-		}
-
-	return retVal;
-	}
-
-void CFSCertAppsServer::AggregateStoreFileL(const TDesC& aFile)
-	{
-	ASSERT(iPatchableConst);
-
-	// if patchable constant is enabled
-	// 1. open read-only permanent file store on each file.
-	// 2. open certificate client entry list of each store.
-	// 3. aggregate the entries.
-	RFile file;
-	User::LeaveIfError(file.Open(iFs, aFile, EFileRead));
-	CleanupClosePushL(file);
-	CPermanentFileStore* store = CPermanentFileStore::FromL(file);
-	// now owned by store
-	CleanupStack::Pop(&file); 
-	CleanupStack::PushL(store);
-
-	// Read id of cert list stream
-	TStreamId streamId;
-	RStoreReadStream stream;
-	stream.OpenLC(*store, store->Root());
-	stream >> streamId;
-	CleanupStack::PopAndDestroy(&stream);
-	
-	// Read the certificate's clients entry list
-	stream.OpenLC(*store, streamId);
-	TInt count = stream.ReadInt32L();
-	RArray<TCertificateAppInfo> entryList;
-	for (TInt i = 0 ; i < count ; i++)
-		{
-		TCertificateAppInfo clientInfo;
-		stream >> clientInfo;
-		entryList.AppendL(clientInfo);
-		}
-	CleanupStack::PopAndDestroy(&stream);
-	CleanupClosePushL(entryList);
-
-	MergeCertificateEntryListL(entryList);
-	// cleanup entryList and store instances.
-	CleanupStack::PopAndDestroy(2,store);		
-	}
-
-TBool CFSCertAppsServer::FindUid(const TUid& aUid)
-	{
-	TInt end = iClients.Count();
-	for (TInt i = 0; i < end; ++i)
-		{
-		if (iClients[i].Id() == aUid)
-			{
-			return ETrue;
-			}
-		}
-	return EFalse;
-	}
-
-void CFSCertAppsServer::MergeCertificateEntryListL(const RArray<TCertificateAppInfo>& aSourceList)
-	{
-	ASSERT(iPatchableConst);
-
-	// if patchable constant is enabled
-	TInt sourceCount = aSourceList.Count();
-	for(TInt i = 0; i < sourceCount; i++)
-		{
-		// compare if the uid pre-exists in the composite list.
-		if (!FindUid(aSourceList[i].Id()))
-			{
-			// Aggregation: append this entry to the composite list.
-			iClients.AppendL(aSourceList[i]);
-			}
-		// Eclipsing: Higher order store cert client entries with same UIDs take precedence over lower order  
-		// store cert client entries therefore the later are not included in the composite cert client entry list.
-		// Higher order store client entries are ones which are aggregated prior to other client entries. 
-		}
-	}
-
-void CFSCertAppsServer::OpenCompositeStoreL(const TDesC& aFilename)
-	{
-	ASSERT(iPatchableConst);
-
-	// 1. create a new empty certstore file under system drive with the name 'certclients.dat'. 
-	// 2. this will be the composite store and the instances 'iEntryList' and 'iStore' will be initialized with this.
-	// 3. make private rom drive path where certstore files are located.
-	// 4. collect the certstore file names in a list.
-	// 5. make private rom drive path on each file.
-	// 6. populate the composite store with certificate client entries present in rom drive certstores.
-	
-	// create a new empty certstore file 'certclients.dat' under system drive.
-	CreateStoreL(aFilename);	
-	// restore permanent store on it 
-	// this will be the composite store after complete aggregation. 
-	ReadStoreContentsL(aFilename);
-		
-	RBuf romFilename;
-	romFilename.CreateL(KMaxFilenameLength);
-	CleanupClosePushL(romFilename);
-	FileUtils::MakePrivateROMFilenameL(iFs, KCertAppsFile, romFilename);
-	CDir* filenameList = NULL;
-	User::LeaveIfError(iFs.GetDir(romFilename, KEntryAttNormal, ESortByName|EDescending, filenameList));
-	CleanupStack::PopAndDestroy(&romFilename);
-	CleanupStack::PushL(filenameList);
-	TInt count = filenameList->Count();
-	
-	// aggregate ROM stores iteratively 
-	for(TInt index = 0; index < count; index++)		
-		{
-		RBuf fileName;
-		fileName.CreateL(KMaxFileName);
-		CleanupClosePushL(fileName);	
-		FileUtils::MakePrivateROMFilenameL(iFs, ((*filenameList)[index]).iName, fileName);
-		// if there is any corrupt certstore present then we will simply ignore its
-		// aggregation and proceed with aggregating remaining stores.
-		TRAP_IGNORE(AggregateStoreFileL(fileName));
-		CleanupStack::PopAndDestroy(&fileName);	
-		}
-	// write the 'iClients' to the composite store.	
-	ReplaceAndCommitL(-1);	
-	CleanupStack::PopAndDestroy(filenameList);
-	}
-
-// this logic should be handled by a superclass or mixin
-void CFSCertAppsServer::OpenStoreL()
-	{
-	RBuf filename;
-	filename.CreateL(KMaxFilenameLength);
-	CleanupClosePushL(filename);		
-	FileUtils::MakePrivateFilenameL(iFs, KCertAppsFilename, filename);
-
-	// Attempt to open the store
-	// need to test opening corrupt store
-	TRAPD(err, ReadStoreContentsL(filename));
-
-	if (err == KErrNoMemory || err == KErrInUse)
-		{
-		User::Leave(err);
-		}
-	
-	if (err != KErrNone)
-		{
-		// Couldn't open RAM based store, copy from ROM	
-		FileUtils::EnsurePathL(iFs, filename);		
-	
-		if(iPatchableConst)
-			{
-			OpenCompositeStoreL(filename);
-			}
-		else
-			{
-			RBuf romFilename;
-			romFilename.CreateL(KMaxFilenameLength);
-			CleanupClosePushL(romFilename);			
-			FileUtils::MakePrivateROMFilenameL(iFs, KCertAppsFilename, romFilename);
-			
-			if (FileUtils::ExistsL(iFs, romFilename))
-				{
-				FileUtils::CopyL(iFs, romFilename, filename);
-				}
-			else
-				{
-				CreateStoreL(filename);
-				}
-			CleanupStack::PopAndDestroy(&romFilename);
-			//Retry open, and leave on failure
-			ReadStoreContentsL(filename);			
-			}
-		}
-	CleanupStack::PopAndDestroy(&filename);
-	ASSERT(iStore);
-	}
-
-void CFSCertAppsServer::ReadStoreContentsL(const TDesC& aFilename)
-	{
-	// Make sure the store is not read-only
-	User::LeaveIfError(iFs.SetAtt(aFilename, KEntryAttNormal, KEntryAttReadOnly));
-
-	RFile file;
-	User::LeaveIfError(file.Open(iFs, aFilename, EFileRead | EFileWrite));
-	CleanupClosePushL(file);
-	CPermanentFileStore* store = CPermanentFileStore::FromL(file);
-	CleanupStack::Pop(&file);
-	CleanupStack::PushL(store);
-
-	// now read the root stream to get the id of our main stream
-	RStoreReadStream readStream;
-	readStream.OpenLC(*store, store->Root());
-	readStream >> iId;	// This can leave
-	CleanupStack::PopAndDestroy(&readStream);
-
-	// finally, restore the stream which contains the client arrays.
-	// First long is the number of entries, then each entry 
-	readStream.OpenLC(*store, iId);
-	TInt count = readStream.ReadInt32L();
-	for (TInt i = 0; i < count; ++i)
-		{
-		TCertificateAppInfo clientInfo;
-		readStream >> clientInfo;
-		User::LeaveIfError(iClients.Append(clientInfo));
-		}
-	CleanupStack::PopAndDestroy(&readStream);
-
-	ASSERT(!iStore);
-	iStore = store;
-	CleanupStack::Pop(store);
-	}
-
-void CFSCertAppsServer::CreateStoreL(const TDesC& aFilename)
-	{
-	// If for some reason we can't complete the creation of the store, we want
-	// to be sure that we don't leave a half-constructed store on the device
-	// as we will then be in trouble when we try to open the store
-	TCleanupItem deleteStoreFile(DeleteStoreFile, this);
-	CleanupStack::PushL(deleteStoreFile);
-
-	iFs.Delete(aFilename); // ignore errors
-
-	RFile file;
-	User::LeaveIfError(file.Create(iFs, aFilename, EFileWrite));
-	CleanupClosePushL(file);
-	
-	CPermanentFileStore* store = CPermanentFileStore::NewL(file);
-	CleanupStack::Pop(&file); // now owned by store
-	CleanupStack::PushL(store);
-	store->SetTypeL(KPermanentFileStoreLayoutUid);
-
-	RStoreWriteStream clientsStream;
-	TStreamId id = clientsStream.CreateLC(*store);
-	WriteClientArrayL(clientsStream);
-	CleanupStack::PopAndDestroy(&clientsStream);
-
-	RStoreWriteStream rootStream;
-	TStreamId rootId = rootStream.CreateLC(*store);
-	rootStream << id;
-	rootStream.CommitL();
-	CleanupStack::PopAndDestroy(&rootStream);
-
-	store->SetRootL(rootId);
-	store->CommitL();
-
-	CleanupStack::PopAndDestroy(store);
-	CleanupStack::Pop(); // deleteStoreFile
-	}
-
-void CFSCertAppsServer::RevertStore(TAny* aStore)
-	{
-	// this is a CleanupItem
-	__ASSERT_DEBUG(aStore, PanicServer(EPanicNotInitialised));
-
-	CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore *>(aStore);
-	store->Revert();
-	}
-
-void CFSCertAppsServer::DeleteStoreFile(TAny *aThis)
-	{
-	__ASSERT_DEBUG(aThis, PanicServer(EPanicNotInitialised));
-
-	// should call non-static member
-	
-	CFSCertAppsServer* self = reinterpret_cast<CFSCertAppsServer*>(aThis);
-
-	// Something strange has occurred if we can't get the ramStorePath.
-	// Since we can't leave we have to ignore the error
-	TFileName ramStorePath;
-	TRAPD(err, FileUtils::MakePrivateFilenameL(self->iFs, KCertAppsFilename, ramStorePath));
-	if (!err)
-		{
-		self->iFs.Delete(ramStorePath);
-		}
-	}
-
-void CFSCertAppsServer::ReplaceAndCommitL(TInt aExcludedIndex)
-	{
-	TCleanupItem cleanupStore(RevertStore, iStore);
-	CleanupStack::PushL(cleanupStore);
-
-	// compact the store 
-	iStore->ReclaimL(); // do we need to reclaim
-	iStore->CompactL();
-
-	RStoreWriteStream outputStream;
-	outputStream.ReplaceLC(*iStore, iId);
-
-	WriteClientArrayL(outputStream, aExcludedIndex);
-
-	CleanupStack::PopAndDestroy(&outputStream);
-	iStore->CommitL();
-	CleanupStack::Pop(); // cleanupStore
-	}
-
-void CFSCertAppsServer::WriteClientArrayL(RWriteStream& stream, TInt aExcludedIndex) const
-	{
-	// the count of elements to be written is the arraycount - 1 if we exclude 
-	// something, otherwise the arraycount
-	TInt arrayEnd = iClients.Count();
-	TInt count = (aExcludedIndex < 0) ? (arrayEnd) : (arrayEnd - 1);
-
-	stream.WriteInt32L(count);
-
-	for (TInt i = 0; i < arrayEnd; ++i)
-		{
-		if (i != aExcludedIndex)
-			{
-			stream << iClients[i];	// This can leave
-			}
-		}
-	stream.CommitL();
-	}
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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 "CFSCertAppsServer.h"
+#include "CCertAppsSession.h"
+#include "CCertAppsConduit.h"
+#include "fstokencliserv.h"
+#include "fstokenutil.h"
+
+#include <certstorepatchdata.h>
+#include <certificateapps.h>
+#include <u32hal.h> 
+
+// Filename where all data is stored
+_LIT(KCertAppsFilename,"certclients.dat");
+_LIT(KCertAppsFile,"certclients*.dat");
+
+CFSCertAppsServer* CFSCertAppsServer::NewL()
+	{
+	CFSCertAppsServer* self = new (ELeave) CFSCertAppsServer();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+CFSCertAppsServer::CFSCertAppsServer()
+	{
+	}
+
+void CFSCertAppsServer::ConstructL()
+	{
+	iConduit = CCertAppsConduit::NewL(*this);
+	
+	// Connect to the filesystem
+	User::LeaveIfError(iFs.Connect());
+
+	iPatchableConst = KAggregateCertStore;
+	
+	#ifdef __WINS__
+		// For the emulator allow the constant to be patched via epoc.ini
+		UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalIntProperty,
+		(TAny*)"KAggregateCertStore", &iPatchableConst); // read emulator property (if present)
+	#endif		
+	
+	// Retrieves the store
+	OpenStoreL();
+	}
+
+CFSCertAppsServer::~CFSCertAppsServer()
+	{
+	delete iStore;
+ 	iFs.Close();
+	iClients.Close();
+	delete iConduit;
+	}
+
+CCertAppsSession* CFSCertAppsServer::CreateSessionL()
+	{
+	return CCertAppsSession::NewL(*iConduit); 
+	}
+
+void CFSCertAppsServer::AddL(const TCertificateAppInfo& aClient)
+	{
+	// see if application already exists. If so, then leave
+	
+	if (FindApplication(aClient.Id()))
+		{
+		User::Leave(KErrAlreadyExists);
+		}
+	User::LeaveIfError(iClients.Append(aClient));
+	TRAPD(err, ReplaceAndCommitL(-1));
+	if (err != KErrNone)
+		{
+		// We must remove the client from iClients if we didn't manage 
+		// to add it to the store
+		iClients.Remove(iClients.Count() - 1);
+		User::Leave(err);
+		}
+	}
+
+void CFSCertAppsServer::RemoveL(const TUid& aUid)
+	{
+	// Make sure the application for that uid exists
+	TInt i;
+	if (!FindApplication(aUid, &i))
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	ReplaceAndCommitL(i);
+	
+	// We managed to remove it from the store, so we remove it from the
+	// iClients array
+	iClients.Remove(i);
+	}
+
+TInt CFSCertAppsServer::ApplicationCountL() const
+	{
+	return iClients.Count();
+	}
+
+void CFSCertAppsServer::ApplicationsL(RArray<TCertificateAppInfo>& aAppArray) const
+	{
+	// Make a copy of the array
+	TInt count = iClients.Count();
+
+	for (TInt i = 0; i < count; ++i)
+		{
+		aAppArray.Append(iClients[i]);
+		}
+	}
+
+void CFSCertAppsServer::ApplicationL(const TUid& aUid, TCertificateAppInfo& aInfo) const
+	{
+	const TCertificateAppInfo* app = FindApplication(aUid);
+
+	// leave if not found
+	if (!app)
+		{
+		User::Leave(KErrNotFound);
+		}
+
+	// make a copy and return to client
+	aInfo = *app;
+	}
+
+const TCertificateAppInfo* CFSCertAppsServer::FindApplication(const TUid& aUid, TInt* aIndex) const
+	{
+	// This helper function tries to find an application with the given
+	// Uid. It returns NULL if not found. aIndex returns the index into
+	// the array successful
+	const TCertificateAppInfo* retVal = NULL;
+	TInt end = iClients.Count();
+	for (TInt i = 0; i < end; ++i)
+		{
+		if (iClients[i].Id() == aUid)
+			{
+			// check if an index is required to be returned
+			if (aIndex)
+				{
+				*aIndex = i;
+				}
+			retVal = &iClients[i];
+			break;
+			}
+		}
+
+	return retVal;
+	}
+
+void CFSCertAppsServer::AggregateStoreFileL(const TDesC& aFile)
+	{
+	ASSERT(iPatchableConst);
+
+	// if patchable constant is enabled
+	// 1. open read-only permanent file store on each file.
+	// 2. open certificate client entry list of each store.
+	// 3. aggregate the entries.
+	RFile file;
+	User::LeaveIfError(file.Open(iFs, aFile, EFileRead));
+	CleanupClosePushL(file);
+	CPermanentFileStore* store = CPermanentFileStore::FromL(file);
+	// now owned by store
+	CleanupStack::Pop(&file); 
+	CleanupStack::PushL(store);
+
+	// Read id of cert list stream
+	TStreamId streamId;
+	RStoreReadStream stream;
+	stream.OpenLC(*store, store->Root());
+	stream >> streamId;
+	CleanupStack::PopAndDestroy(&stream);
+	
+	// Read the certificate's clients entry list
+	stream.OpenLC(*store, streamId);
+	TInt count = stream.ReadInt32L();
+	RArray<TCertificateAppInfo> entryList;
+	for (TInt i = 0 ; i < count ; i++)
+		{
+		TCertificateAppInfo clientInfo;
+		stream >> clientInfo;
+		entryList.AppendL(clientInfo);
+		}
+	CleanupStack::PopAndDestroy(&stream);
+	CleanupClosePushL(entryList);
+
+	MergeCertificateEntryListL(entryList);
+	// cleanup entryList and store instances.
+	CleanupStack::PopAndDestroy(2,store);		
+	}
+
+TBool CFSCertAppsServer::FindUid(const TUid& aUid)
+	{
+	TInt end = iClients.Count();
+	for (TInt i = 0; i < end; ++i)
+		{
+		if (iClients[i].Id() == aUid)
+			{
+			return ETrue;
+			}
+		}
+	return EFalse;
+	}
+
+void CFSCertAppsServer::MergeCertificateEntryListL(const RArray<TCertificateAppInfo>& aSourceList)
+	{
+	ASSERT(iPatchableConst);
+
+	// if patchable constant is enabled
+	TInt sourceCount = aSourceList.Count();
+	for(TInt i = 0; i < sourceCount; i++)
+		{
+		// compare if the uid pre-exists in the composite list.
+		if (!FindUid(aSourceList[i].Id()))
+			{
+			// Aggregation: append this entry to the composite list.
+			iClients.AppendL(aSourceList[i]);
+			}
+		// Eclipsing: Higher order store cert client entries with same UIDs take precedence over lower order  
+		// store cert client entries therefore the later are not included in the composite cert client entry list.
+		// Higher order store client entries are ones which are aggregated prior to other client entries. 
+		}
+	}
+
+void CFSCertAppsServer::OpenCompositeStoreL(const TDesC& aFilename)
+	{
+	ASSERT(iPatchableConst);
+
+	// 1. create a new empty certstore file under system drive with the name 'certclients.dat'. 
+	// 2. this will be the composite store and the instances 'iEntryList' and 'iStore' will be initialized with this.
+	// 3. make private rom drive path where certstore files are located.
+	// 4. collect the certstore file names in a list.
+	// 5. make private rom drive path on each file.
+	// 6. populate the composite store with certificate client entries present in rom drive certstores.
+	
+	// create a new empty certstore file 'certclients.dat' under system drive.
+	CreateStoreL(aFilename);	
+	// restore permanent store on it 
+	// this will be the composite store after complete aggregation. 
+	ReadStoreContentsL(aFilename);
+		
+	RBuf romFilename;
+	romFilename.CreateL(KMaxFilenameLength);
+	CleanupClosePushL(romFilename);
+	FileUtils::MakePrivateROMFilenameL(iFs, KCertAppsFile, romFilename);
+	CDir* filenameList = NULL;
+	User::LeaveIfError(iFs.GetDir(romFilename, KEntryAttNormal, ESortByName|EDescending, filenameList));
+	CleanupStack::PopAndDestroy(&romFilename);
+	CleanupStack::PushL(filenameList);
+	TInt count = filenameList->Count();
+	
+	// aggregate ROM stores iteratively 
+	for(TInt index = 0; index < count; index++)		
+		{
+		RBuf fileName;
+		fileName.CreateL(KMaxFileName);
+		CleanupClosePushL(fileName);	
+		FileUtils::MakePrivateROMFilenameL(iFs, ((*filenameList)[index]).iName, fileName);
+		// if there is any corrupt certstore present then we will simply ignore its
+		// aggregation and proceed with aggregating remaining stores.
+		TRAP_IGNORE(AggregateStoreFileL(fileName));
+		CleanupStack::PopAndDestroy(&fileName);	
+		}
+	// write the 'iClients' to the composite store.	
+	ReplaceAndCommitL(-1);	
+	CleanupStack::PopAndDestroy(filenameList);
+	}
+
+// this logic should be handled by a superclass or mixin
+void CFSCertAppsServer::OpenStoreL()
+	{
+	RBuf filename;
+	filename.CreateL(KMaxFilenameLength);
+	CleanupClosePushL(filename);		
+	FileUtils::MakePrivateFilenameL(iFs, KCertAppsFilename, filename);
+
+	// Attempt to open the store
+	// need to test opening corrupt store
+	TRAPD(err, ReadStoreContentsL(filename));
+
+	if (err == KErrNoMemory || err == KErrInUse)
+		{
+		User::Leave(err);
+		}
+	
+	if (err != KErrNone)
+		{
+		// Couldn't open RAM based store, copy from ROM	
+		FileUtils::EnsurePathL(iFs, filename);		
+	
+		if(iPatchableConst)
+			{
+			OpenCompositeStoreL(filename);
+			}
+		else
+			{
+			RBuf romFilename;
+			romFilename.CreateL(KMaxFilenameLength);
+			CleanupClosePushL(romFilename);			
+			FileUtils::MakePrivateROMFilenameL(iFs, KCertAppsFilename, romFilename);
+			
+			if (FileUtils::ExistsL(iFs, romFilename))
+				{
+				FileUtils::CopyL(iFs, romFilename, filename);
+				}
+			else
+				{
+				CreateStoreL(filename);
+				}
+			CleanupStack::PopAndDestroy(&romFilename);
+			//Retry open, and leave on failure
+			ReadStoreContentsL(filename);			
+			}
+		}
+	CleanupStack::PopAndDestroy(&filename);
+	ASSERT(iStore);
+	}
+
+void CFSCertAppsServer::ReadStoreContentsL(const TDesC& aFilename)
+	{
+	// Make sure the store is not read-only
+	User::LeaveIfError(iFs.SetAtt(aFilename, KEntryAttNormal, KEntryAttReadOnly));
+
+	RFile file;
+	User::LeaveIfError(file.Open(iFs, aFilename, EFileRead | EFileWrite));
+	CleanupClosePushL(file);
+	CPermanentFileStore* store = CPermanentFileStore::FromL(file);
+	CleanupStack::Pop(&file);
+	CleanupStack::PushL(store);
+
+	// now read the root stream to get the id of our main stream
+	RStoreReadStream readStream;
+	readStream.OpenLC(*store, store->Root());
+	readStream >> iId;	// This can leave
+	CleanupStack::PopAndDestroy(&readStream);
+
+	// finally, restore the stream which contains the client arrays.
+	// First long is the number of entries, then each entry 
+	readStream.OpenLC(*store, iId);
+	TInt count = readStream.ReadInt32L();
+	for (TInt i = 0; i < count; ++i)
+		{
+		TCertificateAppInfo clientInfo;
+		readStream >> clientInfo;
+		User::LeaveIfError(iClients.Append(clientInfo));
+		}
+	CleanupStack::PopAndDestroy(&readStream);
+
+	ASSERT(!iStore);
+	iStore = store;
+	CleanupStack::Pop(store);
+	}
+
+void CFSCertAppsServer::CreateStoreL(const TDesC& aFilename)
+	{
+	// If for some reason we can't complete the creation of the store, we want
+	// to be sure that we don't leave a half-constructed store on the device
+	// as we will then be in trouble when we try to open the store
+	TCleanupItem deleteStoreFile(DeleteStoreFile, this);
+	CleanupStack::PushL(deleteStoreFile);
+
+	iFs.Delete(aFilename); // ignore errors
+
+	RFile file;
+	User::LeaveIfError(file.Create(iFs, aFilename, EFileWrite));
+	CleanupClosePushL(file);
+	
+	CPermanentFileStore* store = CPermanentFileStore::NewL(file);
+	CleanupStack::Pop(&file); // now owned by store
+	CleanupStack::PushL(store);
+	store->SetTypeL(KPermanentFileStoreLayoutUid);
+
+	RStoreWriteStream clientsStream;
+	TStreamId id = clientsStream.CreateLC(*store);
+	WriteClientArrayL(clientsStream);
+	CleanupStack::PopAndDestroy(&clientsStream);
+
+	RStoreWriteStream rootStream;
+	TStreamId rootId = rootStream.CreateLC(*store);
+	rootStream << id;
+	rootStream.CommitL();
+	CleanupStack::PopAndDestroy(&rootStream);
+
+	store->SetRootL(rootId);
+	store->CommitL();
+
+	CleanupStack::PopAndDestroy(store);
+	CleanupStack::Pop(); // deleteStoreFile
+	}
+
+void CFSCertAppsServer::RevertStore(TAny* aStore)
+	{
+	// this is a CleanupItem
+	__ASSERT_DEBUG(aStore, PanicServer(EPanicNotInitialised));
+
+	CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore *>(aStore);
+	store->Revert();
+	}
+
+void CFSCertAppsServer::DeleteStoreFile(TAny *aThis)
+	{
+	__ASSERT_DEBUG(aThis, PanicServer(EPanicNotInitialised));
+
+	// should call non-static member
+	
+	CFSCertAppsServer* self = reinterpret_cast<CFSCertAppsServer*>(aThis);
+
+	// Something strange has occurred if we can't get the ramStorePath.
+	// Since we can't leave we have to ignore the error
+	TFileName ramStorePath;
+	TRAPD(err, FileUtils::MakePrivateFilenameL(self->iFs, KCertAppsFilename, ramStorePath));
+	if (!err)
+		{
+		self->iFs.Delete(ramStorePath);
+		}
+	}
+
+void CFSCertAppsServer::ReplaceAndCommitL(TInt aExcludedIndex)
+	{
+	TCleanupItem cleanupStore(RevertStore, iStore);
+	CleanupStack::PushL(cleanupStore);
+
+	// compact the store 
+	iStore->ReclaimL(); // do we need to reclaim
+	iStore->CompactL();
+
+	RStoreWriteStream outputStream;
+	outputStream.ReplaceLC(*iStore, iId);
+
+	WriteClientArrayL(outputStream, aExcludedIndex);
+
+	CleanupStack::PopAndDestroy(&outputStream);
+	iStore->CommitL();
+	CleanupStack::Pop(); // cleanupStore
+	}
+
+void CFSCertAppsServer::WriteClientArrayL(RWriteStream& stream, TInt aExcludedIndex) const
+	{
+	// the count of elements to be written is the arraycount - 1 if we exclude 
+	// something, otherwise the arraycount
+	TInt arrayEnd = iClients.Count();
+	TInt count = (aExcludedIndex < 0) ? (arrayEnd) : (arrayEnd - 1);
+
+	stream.WriteInt32L(count);
+
+	for (TInt i = 0; i < arrayEnd; ++i)
+		{
+		if (i != aExcludedIndex)
+			{
+			stream << iClients[i];	// This can leave
+			}
+		}
+	stream.CommitL();
+	}