diff -r 000000000000 -r 08ec8eefde2f persistentstorage/centralrepository/cenrepsrv/backup.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/centralrepository/cenrepsrv/backup.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,891 @@ +// 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 +#include +#include +#include +#include "srvres.h" +#include "cachemgr.h" +#include "srvparams.h" +#include "shrepos.h" +#include "sessnotf.h" +#include "backup.h" + +#define UNUSED_VAR(a) a = a + +_LIT (KBackupFileName, "BACKUP") ; +_LIT (KRestoreFileName, "RESTORE") ; +_LIT(KBackupFileExt, ".bak"); +_LIT(KRestoreFileExt, ".rst"); + + +TRepositoryBackupState CRepositoryBackupClient::iBackupStatus ; + + +// +// Backup stream index class - Used to hold association between a UID (in +// our case the UID of a repository) and a stream ID - Can't use CStreamDictionary +// because that only lets you retrieve stream IDs by a (previously known) UID rather +// than iterate through its contentsretrieving UID/StreamID pairs... +// + + +// +// CRepositoryBackupStreamIndex::AddL +// +// Add a new repository UID and stream ID pair to the index +void CRepositoryBackupStreamIndex::AddL(TUid aUid, TStreamId aSettingStreamId, TStreamId aDeletedSettingsStreamId, TStreamId aInstalledSettingsStreamId) + { + TRepositoryBackupStreamIndexElement newIndexElement; + newIndexElement.Set(aUid,aSettingStreamId, aDeletedSettingsStreamId, aInstalledSettingsStreamId) ; + iStreamIndex.AppendL(newIndexElement); + } + + +// +// CRepositoryBackupStreamIndex::GetNext +// +// Iterate through the index retrieving the next Reposirory UID and Stream ID +// pair. +// +TInt CRepositoryBackupStreamIndex::GetNext(TUid& aUid, TStreamId& aSettingsStreamId, TStreamId& aDeletedSettingsStreamId, TStreamId& aInstalledSettingsStreamId) + { + TInt error = KErrNone ; + if (iIndex < iStreamIndex.Count()) + { + iStreamIndex[iIndex++].Get(aUid, aSettingsStreamId, aDeletedSettingsStreamId, aInstalledSettingsStreamId) ; + } + else + { + error = KErrNotFound ; + } + return error ; + } + + +// +// Backup client class. +// +// Has Active object functionality to monitor the state of the publish and subscribe +// flags associated with backup and restore and also implements MActiveBackupDataClient +// to perform active backup according to the "proxy data holder" model. +// + + + +// +// Usual 2 phase construction factory NewL NewLC classes +// +CRepositoryBackupClient* CRepositoryBackupClient::NewLC(RFs& aFs) + { + CRepositoryBackupClient* me = new(ELeave)CRepositoryBackupClient(aFs); + CleanupStack::PushL(me) ; + me->ConstructL() ; + return me ; + } + + +CRepositoryBackupClient* CRepositoryBackupClient::NewL(RFs& aFs) + { + CRepositoryBackupClient* me = CRepositoryBackupClient::NewLC(aFs) ; + CleanupStack::Pop(me) ; + return me ; + } + + + +// +// Constructor - doesn't really do anything! +// +CRepositoryBackupClient::CRepositoryBackupClient(RFs& aFs) : CActive(EPriorityStandard), iFs(aFs), iRomScanDone(EFalse) + { + } + + +// +// Phase 2 constructor +// +void CRepositoryBackupClient::ConstructL() + { + // Create repository object + iRepository = new(ELeave) CServerRepository; + + // Notifier needed to open repositories. + iNotifier = new(ELeave)CSessionNotifier ; + + // Attach to Backup/Restore Pub/Sub property. + User::LeaveIfError(iBackupRestoreProperty.Attach(KUidSystemCategory, KUidBackupRestoreKey)) ; + + // Add ourself to the active scheduler + CActiveScheduler::Add(this) ; + + // Initialise backup/restore status + iBackupStatus = ENoBackupActivty ; + + // Set active and request notification of changes to backup/restore + // Pub/Sub property. + StartL() ; + } + + + +// +// Destructor +// +CRepositoryBackupClient::~CRepositoryBackupClient() + { + Cancel(); + + iBackupRestoreProperty.Close() ; + + if (iRepository) + { + iRepository->Close(); + delete(iRepository); + } + + if (iNotifier) + delete(iNotifier) ; + + if (iActiveBackupClient) + delete(iActiveBackupClient) ; + + iRestoredRepositoriesArray.ResetAndDestroy(); + iRestoredRepositoriesArray.Close(); + + iFile.Close(); + } + + + + +// +// DoCancel - mandatory for active objects. +// +void CRepositoryBackupClient::DoCancel() + { + iBackupRestoreProperty.Cancel() ; + } + + + +// +// RunError +// +TInt CRepositoryBackupClient::RunError(TInt aError) + { + iRestoredRepositoriesArray.ResetAndDestroy(); + UNUSED_VAR(aError); + return KErrNone; + } + + + + +// +// Test BUR Pub/Sub property set status, and notify BUR that we're +// ready to go as appropriate. +// +void CRepositoryBackupClient::TestBURstatusL(void) + { + TInt BURstatus ; + TRepositoryBackupState lastBackupStatus = ENoBackupActivty; + if (iBackupRestoreProperty.Get(BURstatus) != KErrNotFound) + { + BURstatus &= KBURPartTypeMask ; + switch (BURstatus) + { + case EBURUnset: // State not yet set. Treat as no backup/restore in progress. + case EBURNormal: + // No backup or restore in progress. Probably + // means we've just completed an operation? + + lastBackupStatus = iBackupStatus; + iBackupStatus = ENoBackupActivty ; + + // Back to normal, so enable cache + TServerResources::iCacheManager->EnableCache(); + // delete the CActiveBackupClient + if (iActiveBackupClient) + { + delete iActiveBackupClient ; + iActiveBackupClient = NULL ; + } + + // Notify the changed keys if a restoration was just completed + if((lastBackupStatus == ERestoreInProgress)) + { + for(TInt i = 0; i < iRestoredRepositoriesArray.Count(); i++) + { + iRepository->OpenL(iRestoredRepositoriesArray[i]->Uid(), *iNotifier, EFalse); + iRepository->RestoreNotify(*iRestoredRepositoriesArray[i]); + iRepository->Close(); + } + iRestoredRepositoriesArray.ResetAndDestroy(); + } + + break ; + + case EBURBackupFull : + case EBURBackupPartial : + // We don't distinguish between full and partial backups + // as the Backup engine will give us UIDs for all the + // repository data owners that want their stuff backed up + // anyway. + + // We don't want cache activity during backup + TServerResources::iCacheManager->DisableCache(); + + // Any (and all!) repositories which have been opened in the + // course of system boot and normal operation will have been + // added to TServerResources::iOwnerIdLookUpTable as they were + // opened but there may well be repositories which need backing + // up and haven't yet been opened so we need to make sure that + // the lookup table is complete. + CompleteOwnerIdLookupTableL(); + + // Register with BUR engine + if (!iActiveBackupClient) + { + iActiveBackupClient = CActiveBackupClient::NewL(this) ; + } + iActiveBackupClient->ConfirmReadyForBURL(KErrNone); + iBackupStatus = EBackupInProgress ; + break ; + + case EBURRestoreFull : + case EBURRestorePartial : + // We don't distinguish between full and partial restore + // either! + + // We don't want cache activity during restore either! + TServerResources::iCacheManager->DisableCache(); + + // Register with BUR engine + if (!iActiveBackupClient) + { + iActiveBackupClient = CActiveBackupClient::NewL(this) ; + } + iActiveBackupClient->ConfirmReadyForBURL(KErrNone); + iBackupStatus = ERestoreInProgress ; + break ; + + } + } + } + + +// +// Request notification of changes in BUR Pub/Sub status +// +void CRepositoryBackupClient::StartL() + { + if (!IsActive()) + { + TestBURstatusL(); + NotifyChange(); + } + } + + +// +// Request notification of changes in BUR Pub/Sub status +// +void CRepositoryBackupClient::NotifyChange() + { + // Watch for changes in the property state. + iBackupRestoreProperty.Subscribe(iStatus) ; + SetActive(); + } + + +// +// Handle changes of backup state through publish/subscribe +// +void CRepositoryBackupClient::RunL() + { + NotifyChange() ; + TestBURstatusL(); + } + + +// +// We can't estimate data size without A) having the SID of the data owner who's data +// is to be backed up and B) going through the whole process of preparing the backup. +// +// The only sensible thing we can do is return an arbitrary value! +// +TUint CRepositoryBackupClient::GetExpectedDataSize(TDriveNumber /* aDrive */) + { + return KArbitraryNumber ; + } + + + + +// +// Called by BUR engine to request a chunk of backup data. +// +void CRepositoryBackupClient::GetBackupDataSectionL(TPtr8& aBuffer, TBool& aFinished) + { + const TInt chunkSize = aBuffer.MaxSize() ; + + aFinished = EFalse ; + + // Pass a chunk of our prepared backup data in aBuffer + User::LeaveIfError(iFile.Read(aBuffer, chunkSize)) ; + TInt bytesRead = aBuffer.Length() ; + + // Check to see if this was the last chunk of data. + if (bytesRead < chunkSize) + { + // Set "finished" flag so that BUR knows we're through... + aFinished = ETrue ; + + // ...and then tidy up by closing and deleting the backup file. + iFile.Close() ; + TParse backupFilePath ; + User::LeaveIfError(backupFilePath.Set(KBackupFileName, TServerResources::iBURDirectory, &KBackupFileExt)); + TInt fileDeleteErr=iFs.Delete(backupFilePath.FullName()) ; + #ifdef _DEBUG + if (fileDeleteErr != KErrNone) + { + RDebug::Print(_L("CRepositoryBackupClient::GetBackupDataSectionL - Failed to delete file. Error = %d"), fileDeleteErr); + } + #else + UNUSED_VAR(fileDeleteErr); + #endif + + } + } + +// +// CRepositoryBackupClient::RestoreComplete +// +// Called when a Complete set of backup data has been received and written +// to a file. We now need to open the file as a stream store, get the +// index (list of repository UID and corresponding stream ID pairs, and then +// reconstruct and save each repository in turn. +// +void CRepositoryBackupClient::RestoreComplete(TDriveNumber /* aDrive */) + { + } + + + +// +// CRepositoryBackupClient::RestoreCompleteL +// +// Does the actual work of reconstructing repositories from backup data +// +// +void CRepositoryBackupClient::RestoreCompleteL() + { + // All restore data recived so we can now recreate the repositories from the + // backup store + // Attempt to open the restore file as a CDirectFileStore + TParse restoreFilePath ; + User::LeaveIfError(restoreFilePath.Set(KRestoreFileName, TServerResources::iBURDirectory, &KRestoreFileExt)); + CDirectFileStore* store = CDirectFileStore::OpenLC (iFs,restoreFilePath.FullName(), EFileRead|EFileShareReadersOnly); + if (store->Type()[0] != KDirectFileStoreLayoutUid) + { + // store wasn't quite what we were expecting - can't return an error, can't leave + // so all we can do is close the file, tidy up as best we can, and bail out!!!! + CleanupStack::PopAndDestroy(store); + // If a debug build - record error + TInt fileDeleteErr=iFs.Delete(restoreFilePath.FullName()) ; + #ifdef _DEBUG + if (fileDeleteErr != KErrNone) + { + RDebug::Print(_L("CRepositoryBackupClient::RestoreCompleteL - Failed to delete file. Error = %d"), fileDeleteErr); + } + #else + UNUSED_VAR(fileDeleteErr); + #endif + + User::Leave(KErrCorrupt); + } + + + + // Get the root stream and attempt to read a backup file header from it + TStreamId rootStreamId = store->Root() ; + RStoreReadStream rootStream ; + RStoreReadStream indexStream ; + rootStream.OpenLC(*store, rootStreamId); + TRepositoryBackupStreamHeader header ; + TRAPD(err, header.InternalizeL(rootStream)) ; + + // Check for a valid header by checking that the UID matches the UID + // of Central Repository and that the version number is sane. + if (err == KErrNotSupported) + { + // Not a valid header - assume it's an old style backup stream, + // set extensions supported to none, set index stream to be + // root stream and reset read pointer to beginning. + iBackupExtensionsSupported = ENoBackupExtensions ; + + CleanupStack::PopAndDestroy(&rootStream) ; + CleanupStack::PopAndDestroy(store) ; + + // Try re-opening as old-style backup stream with index + // as root stream. + CDirectFileStore* store = CDirectFileStore::OpenLC (iFs,restoreFilePath.FullName(), EFileRead|EFileShareReadersOnly); + indexStream.OpenLC(*store, rootStreamId) ; + } + else + { + // Got a valid header. Check for extensions supported by this + // stream and get stream to read index from + CleanupStack::PopAndDestroy(&rootStream) ; + iBackupExtensionsSupported = header.getBackupExtensionsSupported(); + TStreamId indexStreamId = header.getIndexStreamId() ; + indexStream.OpenLC (*store, indexStreamId) ; + } + + CRepositoryBackupStreamIndex *restoreStreamIndex = CRepositoryBackupStreamIndex::NewLC(); + restoreStreamIndex->InternalizeL(indexStream, iBackupExtensionsSupported); + + + // Iterate through index and attempt restore of each repository stream + // we find in it. + restoreStreamIndex->Reset() ; + TUid repositoryUid ; + TStreamId settingsStreamId(KNullStreamIdValue); + TStreamId deletedSettingsStreamId(KNullStreamIdValue); + TStreamId installedSettingsStreamId(KNullStreamIdValue); + + while (restoreStreamIndex->GetNext(repositoryUid, settingsStreamId, deletedSettingsStreamId, installedSettingsStreamId) == KErrNone) + { + iRepository->OpenL(repositoryUid, *iNotifier, EFalse); + iRepository->FailAllTransactions(); + // Add the restored repository to the restored repositories list. + // Pass its changed-keys list to further restoring functions to add entries for post-restoration notification. + TInt repIndex = AddRestoredRepositoryL(repositoryUid); + iRepository->RestoreRepositoryContentsL(*store, settingsStreamId, deletedSettingsStreamId, *iRestoredRepositoriesArray[repIndex]); + iRepository->CommitChangesL(); + iRepository->Close(); + // If the backup contains an installed repository containing default values for the settings, read them in + if (installedSettingsStreamId != KNullStreamId) + { + // create an empty repository in install directory, and restore the data from backup file + iRepository->RestoreInstallRepositoryL(repositoryUid, *store, installedSettingsStreamId, *iRestoredRepositoriesArray[repIndex]); + // remove the .ini install file (if exists) because it will clash with the restored file + TServerResources::DeleteCentrepFileL(repositoryUid, EInstall, EIni); + } + } + + CleanupStack::PopAndDestroy(restoreStreamIndex) ; + CleanupStack::PopAndDestroy(&indexStream); + CleanupStack::PopAndDestroy(store); + // If a debug build - record error + TInt fileDeleteErr=iFs.Delete(restoreFilePath.FullName()); + #ifdef _DEBUG + if (fileDeleteErr != KErrNone) + { + RDebug::Print(_L("CRepositoryBackupClient::RestoreCompleteL (2nd) - Failed to delete file. Error = %d"), fileDeleteErr); + } + #else + UNUSED_VAR(fileDeleteErr); + #endif + + } + +// +// CRepositoryBackupClient::CompleteOwnerIdLookupTableL +// +// Open each repository in TServerResources::iDataDirectory. +// Save the Rep UID and Owner Id of the rep to be used by +// InitialiseGetProxyBackupDataL. +void CRepositoryBackupClient::CompleteOwnerIdLookupTableL() + { + + // Read contents of persist, install, and ROM directories and + // use them to build a list of repository candidates. + RArray repositoryList ; + CleanupClosePushL(repositoryList) ; + + for (TBackupDirectoryScan scanDir = EScanRom; scanDir <= EScanPersist; scanDir = (TBackupDirectoryScan)(scanDir+1)) + { + TPtrC directoryName ; + switch (scanDir) + { + case EScanRom : + if (TServerResources::iRomDirectory) + { + directoryName.Set(TServerResources::iRomDirectory->Des()) ; + } + else + { + // if ROM directory doesn't exist or there are no files, skip scanning + continue; + } + break ; + + case EScanInstall : + directoryName.Set(TServerResources::iInstallDirectory->Des()) ; + break ; + + case EScanPersist : + directoryName.Set(TServerResources::iDataDirectory->Des()) ; + break ; + } + + RDir dir; + CleanupClosePushL(dir); + User::LeaveIfError(dir.Open(iFs, directoryName, KEntryAttNormal)); + + TEntryArray dirEntries; + TInt readError = KErrNone; + + while (readError != KErrEof) + { + readError = dir.Read(dirEntries); + + if(readError != KErrNone && readError != KErrEof) + { + User::Leave(readError); + } + else + { + const TInt dirCount = dirEntries.Count(); + for (TInt i=0; i(dirEntries[i]), uid)) + { + insertionError=repositoryList.InsertInUnsignedKeyOrder(uid.iUid) ; + // Should leave in all cases other than KErrNone or KErrAlreadyExists + if((insertionError != KErrNone) && (insertionError != KErrAlreadyExists )) + { + User::Leave(insertionError); + } + } + } + } + } + + CleanupStack::PopAndDestroy(&dir); + } + + // Open all repositories in turn. Save repository UID and owner ID + // in lookup table. + for(TInt i = 0; iOpenL(TUid::Uid(repositoryList[i]), *iNotifier)); + if (err == KErrNoMemory) + { + User::Leave(err) ; + } + + else if (err == KErrNone) + { + // The act of opening a repository will cause it to add itself to the + // Repository/Owner UID mapping table so we don't need to do anything + // and can close it immediately! + iRepository->Close(); + } + } + } + + CleanupStack::PopAndDestroy() ; // repositoryList + } + +// CRepositoryBackupClient::InitialiseGetProxyBackupDataL +// +// Prepare data to be backed up. We get the Sid/Uid of the entity whos data +// is to be backed up. What we do is to open each repository in turn (identified +// by directory listing), check its owner, and if it matches the Sid/Uid we've +// been given by secure backup externalise it to a stream within a file store. +// +void CRepositoryBackupClient::InitialiseGetProxyBackupDataL(TSecureId aSID, TDriveNumber /* aDrive */) + { + // Prepare data for backup. + + // Create file store + TParse backupFilePath ; + User::LeaveIfError(backupFilePath.Set(KBackupFileName, TServerResources::iBURDirectory, &KBackupFileExt)); + CDirectFileStore* store = CDirectFileStore::ReplaceLC(iFs, backupFilePath.FullName(), + (EFileWrite | EFileShareExclusive)); + const TUid uid2 = KNullUid ; + store->SetTypeL(TUidType(KDirectFileStoreLayoutUid, uid2, KServerUid3)) ; + + // Create a Backup Stream index + CRepositoryBackupStreamIndex* backupStreamIndex = CRepositoryBackupStreamIndex::NewLC(); + + // Find the reps owned by aSID + for(TInt i = 0; i < TServerResources::iOwnerIdLookUpTable.Count(); ++i) + { + const TOwnerIdMapping& lookupTableEntry = TServerResources::iOwnerIdLookUpTable[i]; + + if ( lookupTableEntry.iOwner == aSID ) + { + TStreamId settingStreamId(KNullStreamIdValue); + TStreamId deletedSettingsStreamId(KNullStreamIdValue); + TStreamId installedSettingStreamId(KNullStreamIdValue); + // Found one match, open the repository and externalise content. + TUid uid = TUid::Uid(lookupTableEntry.iRepUid); + TRAPD(err,iRepository->OpenL(uid, *iNotifier)); + if (err == KErrNoMemory) + { + User::Leave(err) ; + } + else if (err == KErrNone) + { + iRepository->FailAllTransactions(); + // externalise repository contents + iRepository->StoreRepositoryContentsL(*store, settingStreamId, deletedSettingsStreamId); + // Close repository. + iRepository->Close(); + } + + TBool installExists=TServerResources::InstallFileExistsL(uid); + if(installExists) + { + // load existing repository from install directory (default values installed post-build by SWI) + // and externalise installed repository contents + TRAPD(err, iRepository->BackupInstallRepositoryL(uid, *store, installedSettingStreamId)); + // We trap and discard most errors to be able to continue backing up other repositories in the list + if (err == KErrNoMemory) + { + User::Leave(err) ; + } + else if (err != KErrNone) + { + // If for any reason we haven't been able to back up the install repository, + // we create an empty stream to preserve the format + installedSettingStreamId = KNullStreamIdValue; + } + } + // Add all to store index + backupStreamIndex->AddL(uid, settingStreamId, deletedSettingsStreamId, installedSettingStreamId) ; + + } + } + // Write the stream index/dictionary as root stream within the store + // so we can access it when we do a restore later on + RStoreWriteStream indexStream ; + TStreamId indexStreamId = indexStream.CreateLC(*store) ; + backupStreamIndex->ExternalizeL(indexStream) ; + indexStream.CommitL() ; + CleanupStack::PopAndDestroy(&indexStream) ; + CleanupStack::PopAndDestroy (backupStreamIndex) ; + + // Create the Header and write it as the root stream within the store + // so we can access it when we do a restore later on + TRepositoryBackupStreamHeader header (indexStreamId) ; + RStoreWriteStream rootStream ; + TStreamId rootStreamId = rootStream.CreateLC(*store) ; + header.ExternalizeL(rootStream) ; + rootStream.CommitL() ; + + CleanupStack::PopAndDestroy(&rootStream) ; + store->SetRootL(rootStreamId); + store->CommitL(); + CleanupStack::PopAndDestroy(store) ; + + // Attempt to open file containing store ready to read back and send to + // BUR engine as a stream of bytes. + User::LeaveIfError(iFile.Open(iFs, backupFilePath.FullName(), (EFileRead | EFileShareExclusive))) ; + } + + + + +// +// CRepositoryBackupClient::InitialiseRestoreProxyBaseDataL +// +// Called when secure backup is about to start sending restore data. +// +void CRepositoryBackupClient::InitialiseRestoreProxyBaseDataL(TSecureId aSID, TDriveNumber /* aDrive*/) + { + // prepare for restore - Don't think we need to do anything here except prepare + // data structures to receive incoming data + + // Save SID so we can check that it corresponds with the owner information + // in the restored data. + iSid = aSID ; + + // Open file to receive restored data + TParse restoreFilePath ; + User::LeaveIfError(restoreFilePath.Set(KRestoreFileName, TServerResources::iBURDirectory, &KRestoreFileExt)); + User::LeaveIfError(iFile.Replace (iFs, restoreFilePath.FullName(), (EFileWrite | EFileShareExclusive))); + } + + + + +// +// CRepositoryBackupClient::RestoreBaseDataSectionL +// +// Called when secure backup has a chunk of restore data for us. Last data +// segment identified by aFinished. +// +void CRepositoryBackupClient::RestoreBaseDataSectionL(TDesC8& aBuffer, TBool aFinished) + { + // Receive a chunk of restore data in aBuffer + User::LeaveIfError(iFile.Write (aBuffer)) ; + if (aFinished) + { + iFile.Close() ; + + // All restore data recived so we can now recreate the repositories from the + // backup store + RestoreCompleteL(); + } + } + +void CRepositoryBackupClient::TerminateMultiStageOperation() + { + // Backup/Restore operation aborted! + // Tidy up all temporary data. + HBufC* burFileName = HBufC::New(KMaxFileName); + if(burFileName==NULL) + { + return; + } + TPtr burFileNamePtr(burFileName->Des()); + iFile.FullName(burFileNamePtr); //get the full name of the temporary file + iFile.Close(); // close the file + // If a debug build - record error + TInt fileDeleteErr=iFs.Delete(burFileNamePtr); + #ifdef _DEBUG + if (fileDeleteErr != KErrNone) + { + RDebug::Print(_L("CRepositoryBackupClient::TerminateMultiStageOperation - Failed to delete file. Error = %d"), fileDeleteErr); + } + #else + UNUSED_VAR(fileDeleteErr); + #endif + + delete burFileName; + } + + +// +// CRepositoryBackupClient::GetDataChecksum +// +// Not required and we don't implement it. +// +TUint CRepositoryBackupClient::GetDataChecksum(TDriveNumber /* aDrive */) + { + return KArbitraryNumber; + } + +// +// CRepositoryBackupClient::GetSnapshotDataL +// +// Only required for incremental backup (which we don't support +// +void CRepositoryBackupClient::GetSnapshotDataL(TDriveNumber /* aDrive */, TPtr8& /* aBuffer */, TBool& /* aFinished */) + { + User::Leave(KErrNotSupported) ; + } + +// +// CRepositoryBackupClient::InitialiseGetBackupDataL +// +// Used by "normal" active backup to prepare data - we use +// InitialiseRestoreProxyBaseDataL so this shouldn't be called! +// +void CRepositoryBackupClient::InitialiseGetBackupDataL(TDriveNumber /* aDrive */) + { + User::Leave(KErrNotSupported) ; + } + + + +void CRepositoryBackupClient::InitialiseRestoreBaseDataL(TDriveNumber /* aDrive */) + { + // Check this! I Don't think this method should get called as we're a proxy + // and so implement InitialiseGetProxyBackupDataL!! + User::Leave(KErrNotSupported) ; + } + + + + +void CRepositoryBackupClient::InitialiseRestoreIncrementDataL(TDriveNumber /* aDrive */) + { + // Check this! I Don't think this method should get called as we're a proxy + // so don't do incremental backup!! + User::Leave(KErrNotSupported) ; + } + + + +void CRepositoryBackupClient::RestoreIncrementDataSectionL(TDesC8& /* aBuffer */, TBool /* aFinished */) + { + // Check this! I Don't think this method should get called as we're a proxy + // so don't do incremental backup!! + User::Leave(KErrNotSupported) ; + } + + +// +// Incremental backup isn't supported for the proxy data holder model so this +// method should never be called. +// +// Not acceptable to leave even though it's an ...L function which we don't implement +void CRepositoryBackupClient::AllSnapshotsSuppliedL() + { + ; + } + + + +// +// Incremental backup not supported +// +void CRepositoryBackupClient::ReceiveSnapshotDataL(TDriveNumber /* aDrive */, TDesC8& /* aBuffer */, TBool /* aLastSection */) + { + User::Leave(KErrNotSupported) ; + } + +/** +Adds a new entry to the restored repository list with the specified repository uid. + +Creates an object of the CRestoredRepository and inserts it to the list. +If a repository of the specified uid is already on the list, the created object will +be deleted and no repeated entry will be inserted to the list. + +@param aUid The uid of the repository to be added to this array. +@return The index of the new or existing entry within the list. +*/ +TInt CRepositoryBackupClient::AddRestoredRepositoryL(TUid aUid) + { + CRestoredRepository* rstRepos = new(ELeave) CRestoredRepository(aUid); + CleanupStack::PushL(rstRepos); + TInt err = iRestoredRepositoriesArray.InsertInOrder(rstRepos, TLinearOrder(CRestoredRepository::CompareUids)); + if(err != KErrNone && err != KErrAlreadyExists) + User::Leave(err); + TInt index = iRestoredRepositoriesArray.FindInOrderL(rstRepos, TLinearOrder(CRestoredRepository::CompareUids)); + CleanupStack::Pop(); + + if(err == KErrAlreadyExists) + { + delete rstRepos; + } + return index; + }