--- 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();
+ }