diff -r 000000000000 -r d0791faffa3f backupandrestore/backupengine/src/sbedataowner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/backupandrestore/backupengine/src/sbedataowner.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,3722 @@ +// 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: +// Implementation of CDataOwner +// +// + +/** + @file +*/ +#include + +#include "sbedataowner.h" +#include "abserver.h" +#include "sbtypes.h" +#include "sblog.h" +#include "sbeparserdefs.h" +#include + +namespace conn + { + _LIT(KDrive, "?:"); + _LIT(KDriveAndSlash, "?:\\"); + _LIT(KPrivateMatch, "?:\\private\\*"); + _LIT(KPrivateSidMatch, "?:\\private\\"); + _LIT(KSys, "?:\\sys\\*"); + _LIT(KSystem, "?:\\system\\*"); + _LIT(KResource, "?:\\resource\\*"); + _LIT(KOther, "*\\..\\*"); + _LIT(KPad, "00000000"); // Used for padding if required + _LIT(KQuestionMark, "?"); + _LIT8(KVersion, "1.0"); + _LIT( KExclamationAsDrive, "!"); // Used to generic drives for public data as in .SIS file package + _LIT( KPrivateNoBackup, "?:\\private\\????????\\NoBackup\\*"); // Used to exclude the file if it is in "NoBackup" folder. + + + + void CleanupRPointerArray(TAny* aPtr) + { + RPointerArray* array = static_cast*>(aPtr); + array->ResetAndDestroy(); + delete array; + } + + // CSelection // + + /** + + Symbian 2nd phase construction creates a Selection + + @param aType - Selection Type + @param aSelection - Selection Nmae + @return CSelection a pointer to a new object + */ + CSelection* CSelection::NewLC(TSelectionType aType, const TDesC& aSelection) + { + CSelection* self = new (ELeave) CSelection(aType); + CleanupStack::PushL(self); + self->ConstructL(aSelection); + return self; + } + + /** + Standard C++ destructor + */ + CSelection::~CSelection() + { + delete iSelection; + } + + /** + Standard C++ constructor + */ + CSelection::CSelection(TSelectionType aType) : iType(aType) + { + } + + /** + Symbian 2nd phase constructor + */ + void CSelection::ConstructL(const TDesC& aSelection) + { + iSelection = aSelection.AllocL(); + } + + /** + Selection Type + + @return TSelectionType Type + */ + TSelectionType CSelection::SelectionType() const + { + return iType; + } + + /** + Selection Name + + @return const TDesC& Name + */ + const TDesC& CSelection::SelectionName() const + { + return *iSelection; + } + + // CSelection End // + + CDataOwner* CDataOwner::NewL(TSecureId aSID, CDataOwnerManager* apDataOwnerManager) + /** Symbian OS static constructor + + @param aSID secure id of data owner + @param apDataOwnerManager data owner manager to access resources + @return a CDataOwner object + */ + { + CDataOwner* self = CDataOwner::NewLC(aSID, apDataOwnerManager); + CleanupStack::Pop(self); + + return self; + } + + CDataOwner* CDataOwner::NewLC(TSecureId aSID, CDataOwnerManager* apDataOwnerManager) + /** Symbian OS static constructor + + @param aSID secure id of data owner + @param apDataOwnerManager data owner manager to access resources + @return a CDataOwner object + */ + { + CDataOwner* self = new(ELeave) CDataOwner(aSID, apDataOwnerManager); + CleanupStack::PushL(self); + + self->ConstructL(); + + return self; + } + + CDataOwner::CDataOwner(TSecureId aSID, CDataOwnerManager* apDataOwnerManager) : + iStatus(EUnset), iFilesParsed(EFalse), iPrimaryFile(EFalse), /*iBackupAsPartial(EFalse), */ + iSecureId(aSID), + iBufferFileWriter(NULL), iBufferFileReader(NULL), iBufferSnapshotWriter(NULL), + iTempSnapshotHolder(NULL), ipDataOwnerManager(apDataOwnerManager) + /** Standard C++ constructor + + @param aSID secure id of data owner + @param apDataOwnerManager data owner manager to access resources + */ + { + } + + void CDataOwner::ConstructL() + /** Symbian 2nd stage constructor */ + { + iRegistrationFiles = new (ELeave) CDesCArrayFlat(KDesCArrayGranularity); + iPrivatePath = HBufC::NewL(0); + iProxyInformationArray.Reset(); + iPublicDirStack.Reset(); + iPublicDirNameStack.Reset(); + iPublicExcludes.Reset(); + } + + CDataOwner::~CDataOwner() + /** Standard C++ destructor + */ + { + // Close the RArrays + iProxyInformationArray.Close(); + iStateByDrive.Close(); + iProxyStateByDrive.Close(); + iDBMSSelections.Close(); + + iPublicSelections.ResetAndDestroy(); + iPassiveSelections.ResetAndDestroy(); + iSnapshots.ResetAndDestroy(); + + for (TInt x = iPublicDirStack.Count(); x > 0; --x) + { + iPublicDirStack[x-1].Close(); + delete iPublicDirNameStack[x-1]; + } + iPublicDirStack.Close(); + iPublicDirNameStack.Close(); + iPublicExcludes.Close(); + + delete iPrivatePath; + delete iBufferFileWriter; + delete iBufferFileReader; + delete iBufferSnapshotWriter; + delete iBufferSnapshotReader; + delete iTempSnapshotHolder; + delete iRegistrationFiles; + } + + void CDataOwner::AddRegistrationFilesL(const TDesC& aFileName) + /** Adds a registration file + + Adds a registration file to the list of registration files for this data owner + + @param aFileName the filename of the + */ + { + iRegistrationFiles->AppendL(aFileName); + } + + void CDataOwner::StartProcessIfNecessaryL() + /** + Start the active process + */ + { + // Do we need to check that the process is started? + if (iActiveInformation.iSupported && iActiveInformation.iActiveDataOwner) + { + // Get the list of currently running processes + TBool processFound = EFalse; + TFullName processName; + TFindProcess findProcess; + while (!processFound && (findProcess.Next(processName) == KErrNone)) + { + RProcess process; + CleanupClosePushL(process); + if (process.Open(processName) == KErrNone) // Should we leave on any errors? + { + if (process.SecureId() == iSecureId) + { + // Process already exists - see if it's previuosly connected and has a current session + __LOG1("Process %S already exists - not starting", &processName); + TRAPD(err, iStatus = ipDataOwnerManager->ABServer().SessionReadyStateL(iSecureId)); + if (err == KErrNone) + { + __LOG2("Existing session for process %S has status %d", &processName, iStatus); + } // if + else + { + __LOG1("Existing process %S hasn't yet connected to a session", &processName); + iStatus = EDataOwnerNotConnected;//ReadyState only check session state when this status not equal to 'EDataOwnerReadyNoImpl' and 'EDataOwnerReady' + } // else + + processFound = ETrue; + } // if + } // if + + CleanupStack::PopAndDestroy(&process); + } // while + + // If the process is not started then we need to start it + if (!processFound) + { + // Create the process + TUidType uidType(KNullUid, KNullUid, iSecureId); + RProcess process; + CleanupClosePushL(process); + TInt createErr = process.Create(iActiveInformation.iProcessName, KNullDesC, uidType); + if (createErr != KErrNone) + { + __LOG2("Process %S failed to start(%d)", &iActiveInformation.iProcessName, createErr); + iStatus = EDataOwnerFailed; + } // if + else + { + __LOG1("Process %S started.", &iActiveInformation.iProcessName); + process.Resume(); + } // else + + CleanupStack::PopAndDestroy(&process); + } // if + } // if + } + + + void CDataOwner::ParseFilesL() + /** Parse the registration files + + @leave KErrGeneral data owner has no primary registration file + */ + { + if (!iFilesParsed) + { + TUint count = iRegistrationFiles->Count(); + TBool foundPrimaryFile = EFalse; + while(count--) + { + const TDesC& fileName = (*iRegistrationFiles)[count]; + + // Determine if this is the primary file + iPrimaryFile = (fileName.FindF(KPrimaryBackupRegistrationFile) != KErrNotFound); + if (iPrimaryFile) + { + foundPrimaryFile = ETrue; + } + + // Parse file + + __LOG2("CDataOwner::ParseFilesL() - [0x%08x] - parsing reg file: %S...", iSecureId.iId, &fileName); + TRAPD(err, ParseFileL(fileName)); + if (err == KErrNone) + { + __LOG1("CDataOwner::ParseFilesL() - [0x%08x] - ...file parsed okay", iSecureId.iId); + } + else + { + __LOG2("CDataOwner::ParseFilesL() - [0x%08x] - ...*** PARSING FAILED *** - error: %d", iSecureId.iId, err); + User::Leave(err); + } + + // Add the registration file to the exclude list + CSelection* selection = CSelection::NewLC(EExclude, fileName); + iPassiveSelections.AppendL(selection); + CleanupStack::Pop(selection); + } + + // Check that a primary file was found, as there must be one + if (!foundPrimaryFile) + { + User::Leave(KErrGeneral); + } // if + + iFilesParsed = ETrue; + } // if + + if (!iActiveInformation.iSupported && (iPassiveInformation.iSupported || iSystemInformation.iSupported)) + { + iStatus = EDataOwnerReady; + } + } + + void CDataOwner::GetExpectedDataSizeL(TTransferDataType aTransferType, + TDriveNumber aDriveNumber, TUint& aSize) + /** Gets the expected data size of the backkup. + + @param aTransferType the type of the transfer + @param aDriveNumber the drive to check for files + @param aSize on return the total size in bytes of the backup + @leave KErrNotReady the snapshot has not been set + */ + { + aSize = 0; + switch (aTransferType) + { + case EPassiveSnapshotData: + { + __LOG1("CDataOwner::GetExpectedDataSizeL() - START - EPassiveSnapshotData - aDriveNumber: %c", aDriveNumber + 'A'); + + CDesCArray* files = new(ELeave) CDesC16ArrayFlat(KDesCArrayGranularity); + CleanupStack::PushL(files); + + BuildFileListL(iPassiveSelections, aDriveNumber, aTransferType, EFalse, NULL, NULL, files); + + // DBMS file? + AddDBMSFilesL(aDriveNumber, files, NULL); + + TUint count = files->Count(); + aSize = count * sizeof(TSnapshot); + __LOG2("CDataOwner::GetExpectedDataSizeL() - passive snapshot count: %d, expected size: %d", count, aSize); + + CleanupStack::PopAndDestroy(files); + break; + } + case EPassiveBaseData: + case EPassiveIncrementalData: + { + __LOG1("CDataOwner::GetExpectedDataSizeL() - START - EPassiveBaseData/EPassiveIncrementalData - aDriveNumber: %c", aDriveNumber + 'A'); + + RFileArray files; + CleanupClosePushL(files); + + // Find all the files + if (aTransferType == EPassiveBaseData) + { + __LOG("CDataOwner::GetExpectedDataSizeL() - EPassiveBaseData"); + BuildFileListL(iPassiveSelections, aDriveNumber, aTransferType, EFalse, NULL, &files, NULL); + + // Do we need to add the DBMS file? + AddDBMSFilesL(aDriveNumber, NULL, &files); + } // if + else + { + __LOG("CDataOwner::GetExpectedDataSizeL() - EPassiveIncrementalData"); + + // Do we have a snapshot? + const TUint count = iSnapshots.Count(); + RSnapshots* pSnapshot = NULL; + for (TInt x = 0; !pSnapshot && (x < count); x++) + { + if (iSnapshots[x]->iDriveNumber == aDriveNumber) + { + pSnapshot = &(iSnapshots[x]->iSnapshots); + } // if + } // for x + + BuildFileListL(iPassiveSelections, aDriveNumber, aTransferType, EFalse, pSnapshot, &files, NULL); + + // Do we need to add the DBMS file? + AddDBMSFilesL(aDriveNumber, NULL, &files); + } // else + + // Calculate the expected data size + const TUint count = files.Count(); + __LOG1("CDataOwner::GetExpectedDataSizeL() - passive file count: %d", count); + aSize = (count * sizeof(TFileFixedHeader)); + for (TInt x = 0; x < count; x++) + { + const TEntry& fileEntry = files[x]; + const TInt fileSize = fileEntry.iSize; + __LOG2("CDataOwner::GetExpectedDataSizeL() - passive file: %S, size: %d", &fileEntry.iName, fileSize); + + aSize += fileEntry.iName.Length(); + aSize += fileSize; + } + CleanupStack::PopAndDestroy(&files); + break; + } + case EActiveBaseData: + case EActiveIncrementalData: + { + __LOG1("CDataOwner::GetExpectedDataSizeL() - START - EActiveBaseData/EActiveIncrementalData - aDriveNumber: %c", aDriveNumber + 'A'); + // Only request expected data size if it's for this data owner, not the proxies + if (iActiveInformation.iSupported && iActiveInformation.iActiveDataOwner && (iActiveInformation.iActiveType != EProxyImpOnly)) + { + ipDataOwnerManager->ABServer().GetExpectedDataSizeL(iSecureId, aDriveNumber, aSize); + } + else + { + aSize = 0; + __LOG1("CDataOwner::GetExpectedDataSizeL() - ACTIVE BASE - DO 0x%08x is PROXY, so setting size to 0!", iSecureId.iId); + } + + } break; + case EActiveSnapshotData: + { + __LOG1("CDataOwner::GetExpectedDataSizeL() - START - EActiveSnapshotData - aDriveNumber: %c", aDriveNumber + 'A'); + aSize = 0; // ABClient M class doesn't provide retrieval of snapshot data size + } break; + default: + __LOG1("CDataOwner::GetExpectedDataSizeL() - START - ERROR - UNSUPPORTED TYPE! => KErrNotSupported - aDriveNumber: %c", aDriveNumber + 'A'); + User::Leave(KErrNotSupported); + } // switch + + __LOG2("CDataOwner::GetExpectedDataSizeL() - END - size is: %d, data owner 0x%08x", aSize, iSecureId.iId); + } + + + void CDataOwner::GetPublicFileListL(TDriveNumber aDriveNumber, RFileArray& aFiles) + /** Gets the public file list + + Gets the public file list for the given drive + @param aDriveNumber the drive to retrieve the public files for + @param aFiles on return a list of public files + */ + { + BuildFileListL(iPublicSelections, aDriveNumber, EPassiveBaseData, ETrue, NULL, &aFiles, NULL); + } + + + void CDataOwner::GetRawPublicFileListL(TDriveNumber aDriveNumber, + RRestoreFileFilterArray& aRestoreFileFilter) + /** Gets the raw public file list + + @param aDriveNumber the drive to return the list for + @param aRestoreFileFilter on return the file filter + */ + { + // Convert drive number to letter + TChar drive; + User::LeaveIfError(ipDataOwnerManager->GetRFs().DriveToChar(aDriveNumber, drive)); + + const TUint count = iPublicSelections.Count(); + for (TInt x = 0; x < count; x++) + { + TBool include = (iPublicSelections[x]->SelectionType() == EInclude); + TFileName filename; + + const TDesC& selectionName = iPublicSelections[x]->SelectionName(); + // Name + TBool add = false; + if ((selectionName.Length() > 1) && (selectionName[1] == KColon()[0])) + { + // It has a drive specified + TInt drive; + ipDataOwnerManager->GetRFs().CharToDrive(selectionName[0], drive); + if (static_cast(drive) == aDriveNumber) + { + add = true; + filename.Append(selectionName); + } // if + } // if + else if (selectionName[0] == KBackSlash()[0]) + { + add = true; + filename.Append(drive); + filename.Append(KColon); + filename.Append(selectionName); + } // if + else + { + filename.Append(drive); + filename.Append(KColon); + filename.Append(KBackSlash); + filename.Append(selectionName); + } // else + + if (add) + { + aRestoreFileFilter.AppendL(TRestoreFileFilter(include, filename)); + } // if + } // for x + } + + void CDataOwner::ProcessSupplyDataL(TDriveNumber aDriveNumber, TTransferDataType aTransferType, + TDesC8& aBuffer, TBool aLastSection) + /** Supply data to the data owner + + @param aDriveNumber the drive requesting data for + @param aTransferType the type of transfer + @param aBuffer the buffer containing the data + @param aLastSection have we received all our information + @leave KErrNotReady In the process of another call + @leave KErrNotSupported Unsupported transfer type + @leave KErrCorrupt If commands have been issued that violate the allowed sequence + */ + { + TBURPartType burType = ipDataOwnerManager->BURType(); + __LOG2("CDataOwner::ProcessSupplyDataL() - START - drive: %c, aTransferType: %d", aDriveNumber + 'A', aTransferType); + + + switch (aTransferType) + { + case EPassiveSnapshotData: + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying passive snapshot data to data owner with SID 0x%08x", iSecureId.iId); + // Check that no passive data has been received for a data owner that doesn't support it + if (!iPassiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Passive restore has been requested but isn't supported"); + User::Leave(KErrCorrupt); + } + + // Check that no snapshot is supplied after backup data has been requested during a backup + if (((burType == EBURBackupFull) || (burType == EBURBackupPartial)) && + (StateByDriveL(aDriveNumber).iPassiveBaseDataRequested || + StateByDriveL(aDriveNumber).iPassiveIncDataRequested)) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Snapshot has been supplied after data has been requested"); + User::Leave(KErrCorrupt); + } + + // Check that no snapshot is supplied for a data owner expecting base backup + if (iPassiveInformation.iBaseBackupOnly) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Snapshot data has been supplied for a base data owner"); + User::Leave(KErrCorrupt); + } + + // Check that no snapshot data is provided after backup data has been supplied during a restore + if (((burType == EBURRestorePartial) || (burType == EBURRestoreFull)) + && (StateByDriveL(aDriveNumber).iPassiveBaseDataReceived || + StateByDriveL(aDriveNumber).iPassiveIncDataReceived)) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Snapshot has been supplied after restore data has been supplied"); + User::Leave(KErrCorrupt); + } + + SupplyPassiveSnapshotDataL(aDriveNumber, aBuffer, aLastSection); + + if (aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveSnapshotReceived = ETrue; + } + break; + } + case EPassiveBaseData: + case EPassiveIncrementalData: + { + if (aTransferType == EPassiveBaseData) + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying passive base data to data owner with SID 0x%08x", iSecureId.iId); + } + else if (aTransferType == EPassiveIncrementalData) + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying passive inc data to data owner with SID 0x%08x", iSecureId.iId); + } + + // Check that no passive data has been received for a data owner that doesn't support it + if (!iPassiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Passive restore data has been supplied but isn't supported"); + User::Leave(KErrCorrupt); + } + + // Check that no incremental data has been received for a SID that doesn't support it + if (iPassiveInformation.iBaseBackupOnly && (aTransferType == EPassiveIncrementalData)) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Incremental restore data has been received for a base only data owner"); + User::Leave(KErrCorrupt); + } + + // Passive Base data should only have been provided once for a SID + if ((aTransferType == EPassiveBaseData) && StateByDriveL(aDriveNumber).iPassiveBaseDataReceived) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Data is being restored more than once to a DO"); + User::Leave(KErrCorrupt); + } + + // A snapshot should already have been supplied if we're incremental + if (!StateByDriveL(aDriveNumber).iPassiveSnapshotReceived && (aTransferType == EPassiveIncrementalData)) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Snapshot has not yet been supplied and should have whether we're base or inc"); + User::Leave(KErrCorrupt); + } + + // If incremental data is being supplied, then base data must already have been supplied + if ((aTransferType == EPassiveIncrementalData) && !StateByDriveL(aDriveNumber).iPassiveBaseDataReceived) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Incremental data supplied before base data"); + User::Leave(KErrCorrupt); + } + + SupplyPassiveBaseDataL(aDriveNumber, aBuffer, aLastSection); + + if ((aTransferType == EPassiveBaseData) && aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveBaseDataReceived = ETrue; + } + + if ((aTransferType == EPassiveIncrementalData) && aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveIncDataReceived = ETrue; + } + break; + } + case EActiveSnapshotData: + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying active snapshot data to data owner with SID 0x%08x", iSecureId.iId); + + // Check that no active data has been received for a data owner that doesn't support it + if (!iActiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active snapshot data has been supplied for a DO that doesn't support it"); + User::Leave(KErrCorrupt); + } + + // Check that no active data has been received for a data owner that doesn't support it + if (!iActiveInformation.iSupportsIncremental) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active snapshot data has been supplied for a base only Data Owner"); + User::Leave(KErrCorrupt); + } + + // Check that no snapshot is supplied after backup data has been requested during a backup + if (((burType == EBURBackupFull) || (burType == EBURBackupPartial)) && StateByDriveL(aDriveNumber).iActiveBaseDataRequested) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active snapshot has been supplied after backup data has been requested"); + User::Leave(KErrCorrupt); + } + + // Check that no snapshot data is provided after backup data has been supplied during a restore + if (((burType == EBURRestorePartial) || (burType == EBURRestoreFull)) && StateByDriveL(aDriveNumber).iActiveBaseDataReceived) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active snapshot data has been supplied after restore data"); + User::Leave(KErrCorrupt); + } + + ipDataOwnerManager->ABServer().SupplyDataL(iSecureId, aDriveNumber, aTransferType, + aBuffer, aLastSection); + + if (aLastSection) + { + StateByDriveL(aDriveNumber).iActiveSnapshotReceived = ETrue; + } + } break; + case EActiveBaseData: + case EActiveIncrementalData: + { + if (aTransferType == EActiveBaseData) + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying active base data to data owner with SID 0x%08x", iSecureId.iId); + } + else if (aTransferType == EActiveIncrementalData) + { + __LOG1("CDataOwner::ProcessSupplyDataL() - Supplying active incremental data to data owner with SID 0x%08x", iSecureId.iId); + } + + const TUint supportedProxyCount = iProxyInformationArray.Count(); + TInt offset = 0; + + // Only unpack from the first supply message + if (StateByDriveL(aDriveNumber).iFirstActiveTransaction) + { + iCurrentProxy = 0; + TInt proxyCountCheck = 0; + UnpackTypeAdvance(proxyCountCheck, aBuffer, offset); + StateByDriveL(aDriveNumber).iFirstActiveTransaction = EFalse; + __LOG1("CDataOwner::ProcessSupplyDataL() - Proxy Info : Unpacked TotalProxyCount = %d", proxyCountCheck); + + // If the backup stream specifies a different number of proxy's to the registration file, + // then we're looking at different reg file versions. This isn't supported as far as proxy's + // are concerned + if (supportedProxyCount != proxyCountCheck) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Number of proxies supported (reg file) differs from backed up data"); + User::Leave(KErrCorrupt); + } + + // Check that no active data has been requested for a data owner that doesn't support it + if ((!iActiveInformation.iSupported) && (supportedProxyCount == 0)) + { + // No proxies or active data + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active data has been received but this DO doesn't support Active/Proxies"); + User::Leave(KErrCorrupt); + } + + // Reset proxy state information for this drive + for (TInt numProxy=0; numProxy < supportedProxyCount; numProxy++) + { + ProxyStateByDriveL(aDriveNumber,numProxy) = TProxyStateByDrive(aDriveNumber,numProxy); + } + + for (TInt numProxies=0;numProxies= aBuffer.Length()-offset ) + { + + // more data was expected but both server and data mgr have finished, then leave + if (proxyFinished && dataLengthRemaining > aBuffer.Length()-offset) + { + User::Leave(KErrCorrupt); + } + + // use the buffer upto the end + currentBufferLen = aBuffer.Length() - offset; + currentBufferConsumed = ETrue; + } + else + { + // use the buffer upto the remaining length of this proxy + currentBufferLen = dataLengthRemaining; + } + + // Create a pointer to the data of this proxy + TPtrC8 buffer(aBuffer.Mid(offset, currentBufferLen)); + iProxyInformationArray[iCurrentProxy].iDataSupplied += currentBufferLen; + __LOG1("CDataOwner::ProcessSupplyDataL() - iProxyConsumedLength = %D",iProxyInformationArray[iCurrentProxy].iDataSupplied); + + offset += currentBufferLen; + + TBool proxyLastSection = EFalse; + + // If the data to send is the last section, set proxyLastSection with true. + if ((iProxyInformationArray[iCurrentProxy].iOpInProgress == (TInt)ETrue) && (iProxyInformationArray[iCurrentProxy].iDataSupplied == iProxyInformationArray[iCurrentProxy].iDataRequested)) + { + __LOG("CDataOwner::ProcessSupplyDataL() - Last Section to Proxy"); + proxyLastSection = ETrue; + } + else + { + proxyLastSection = proxyFinished; + } + + + // Call the proxy and give it the restore data. + ipDataOwnerManager->ABServer().SupplyDataL( + iProxyInformationArray[iCurrentProxy].iSecureId, + aDriveNumber, + aTransferType, + buffer, + proxyLastSection, + ProxyStateByDriveL(aDriveNumber,iCurrentProxy).iOpInProgress, + iSecureId); + + + // If the proxy still has data to send, record the fact to that the + // data server or datamanager can supply again. + if (!proxyFinished) + { + __LOG("CDataOwner::ProcessSupplyDataL() - Proxy Info : Multipart send not complete, expecting more proxy data"); + ProxyStateByDriveL(aDriveNumber,iCurrentProxy).iOpInProgress = ETrue; + } + else + { + __LOG("CDataOwner::ProcessSupplyDataL() - Proxy Info : Send complete"); + ProxyStateByDriveL(aDriveNumber,iCurrentProxy).iOpInProgress = EFalse; + ProxyStateByDriveL(aDriveNumber,iCurrentProxy).iDataSupplied = ETrue; + + } + + __LOG2("CDataOwner::ProcessSupplyDataL() - Check proxyConsumedLength = %D & proxyTotalDataLength = %D",iProxyInformationArray[iCurrentProxy].iDataSupplied,iProxyInformationArray[iCurrentProxy].iDataRequested); + if (iProxyInformationArray[iCurrentProxy].iDataSupplied == iProxyInformationArray[iCurrentProxy].iDataRequested) + { + __LOG("CDataOwner::ProcessSupplyDataL() - Resetting internal variables"); + // when whole packet from server is read. + iProxyInformationArray[iCurrentProxy].iDataSupplied = 0; + iProxyInformationArray[iCurrentProxy].iDataRequested = 0; + } + + // Check + if ( (iProxyInformationArray[iCurrentProxy].iOpInProgress == (TInt)ETrue) && (iProxyInformationArray[iCurrentProxy].iDataSupplied == iProxyInformationArray[iCurrentProxy].iDataRequested) ) + { + __LOG("CDataOwner::ProcessSupplyDataL() - Proxy Finished"); + iCurrentProxy++; + } + + } // while more proxies. + + // Active data can be sent under 2 circumstances, data for a proxy and data for an actual active client + if (iActiveInformation.iSupported && iActiveInformation.iActiveDataOwner && (offset < aBuffer.Size())) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State iActiveInformation.iSupported"); + // Active Base data should only have been provided once for a SID + if ((aTransferType == EActiveBaseData) && StateByDriveL(aDriveNumber).iActiveBaseDataReceived) + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - Active restore data has been provided more than once for this DO"); + User::Leave(KErrCorrupt); + } + + TPtrC8 buffer(aBuffer.Mid(offset)); + + ipDataOwnerManager->ABServer().SupplyDataL( + iSecureId, + aDriveNumber, + aTransferType, + buffer, + aLastSection, + StateByDriveL(aDriveNumber).iOpInProgress); + + if (!aLastSection) + { + StateByDriveL(aDriveNumber).iOpInProgress = ETrue; + } + else + { + StateByDriveL(aDriveNumber).iOpInProgress = EFalse; + StateByDriveL(aDriveNumber).iFirstActiveTransaction = ETrue; + if (aTransferType == EActiveBaseData) + { + StateByDriveL(aDriveNumber).iActiveBaseDataReceived = ETrue; + } + + if (aTransferType == EActiveIncrementalData) + { + StateByDriveL(aDriveNumber).iActiveIncDataReceived = ETrue; + } + } + } + } break; + default: + { + __LOG("CDataOwner::ProcessSupplyDataL() - State Error - An unsupported transfer type has been supplied"); + User::Leave(KErrNotSupported); + } + } // switch + } + + void CDataOwner::SupplyDataL(TDriveNumber aDriveNumber, TTransferDataType aTransferType, + TDesC8& aBuffer, TBool aLastSection) + /** Supply data to the data owner + + @param aDriveNumber the drive requesting data for + @param aTransferType the type of transfer + @param aBuffer the buffer containing the data + @param aLastSection have we received all our information + @leave KErrNotReady In the process of another call + @leave KErrNotSupported Unsupported transfer type + @leave KErrCorrupt If commands have been issued that violate the allowed sequence + */ + { + __LOG5("CDataOwner::SupplyDataL() - START - SID: 0x%08x, aDrive: %c, aTransferType: %d, aLastSection: %d, iState: %d", iSecureId.iId, aDriveNumber + 'A', aTransferType, aLastSection, iState.iState); + // Check our state + if (!((iState.iState == ENone) || + ((iState.iState == ESupply) && (iState.iDriveNumber == aDriveNumber) && + (iState.iTransferType == aTransferType)))) + { + User::Leave(KErrNotReady); + } + + // Set the state? + if (iState.iState == ENone) + { + iState.iState = ESupply; + iState.iDriveNumber = aDriveNumber; + iState.iTransferType = aTransferType; + } // if + + // What are we doing then? + // We must trap any errors and rethrow them so we can reset our state + TInt err = KErrNone; + + // Do we need to perform a cleanup before restore? + if ((aTransferType == EPassiveBaseData) || + (aTransferType == EPassiveIncrementalData) || + (aTransferType == EActiveBaseData) || + (aTransferType == EActiveIncrementalData)) + { + TRAP(err, CleanupBeforeRestoreL(aDriveNumber)); + } + if (err != KErrNone) + { + __LOG2("CDataOwner::SupplyDataL() - Data owner 0x%08x, drive %d could not cleanup before restore", iSecureId.iId, aDriveNumber); + } + + TRAP(err, ProcessSupplyDataL(aDriveNumber, aTransferType, aBuffer, aLastSection)); + + + // Was there an error? + if (err != KErrNone) + { + iState.iState = ENone; + delete iBufferFileReader; + iBufferFileReader = NULL; + delete iBufferSnapshotReader; + iBufferSnapshotReader = NULL; + User::Leave(err); + } // if + + if (aLastSection) // If last section reset state + { + iState.iState = ENone; + } // if + __LOG("CDataOwner::SupplyDataL() - END"); + } // SupplyDataL + + + void CDataOwner::ProcessRequestDataL(TDriveNumber aDriveNumber, TTransferDataType aTransferType, + TPtr8& aBuffer, TBool& aLastSection) + /** + So that the TRAPD isn't massive, this switch statement has been moved to this function + */ + { + __LOG4("CDataOwner::ProcessRequestDataL() - START - aDrive: %c, aTransferType: %d, aBuffer.Ptr(): 0x%08x, aBuffer.Length(): %d", aDriveNumber + 'A', aTransferType, aBuffer.Ptr(), aBuffer.Length()); + //__LOGDATA("CDataOwner::ProcessRequestDataL() - %S", aBuffer.Ptr(), aBuffer.Length() ); + + // + switch (aTransferType) + { + case EPassiveSnapshotData: + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting passive snapshot data from data owner with SID 0x%08x", iSecureId.iId); + + // Check that no passive data has been requested for a data owner that doesn't support it + if (!iPassiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Passive snapshot data has been requested for a non-passive data owner"); + User::Leave(KErrCorrupt); + } + + // Check that snapshot data is only requested once + if (StateByDriveL(aDriveNumber).iPassiveSnapshotRequested) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Passive snapshot data has been requested more than once"); + User::Leave(KErrCorrupt); + } + + RequestPassiveSnapshotDataL(aDriveNumber, aBuffer, aLastSection); + + if (aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveSnapshotRequested = ETrue; + } + break; + } + case EPassiveBaseData: + case EPassiveIncrementalData: + { + if (aTransferType == EPassiveBaseData) + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting passive base data from data owner with SID 0x%08x", iSecureId.iId); + } + else if (aTransferType == EPassiveIncrementalData) + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting passive inc data from data owner with SID 0x%08x", iSecureId.iId); + } + + // Check that no passive data has been requested for a data owner that doesn't support it + if (!iPassiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Passive backup data has been requested for a non-passive data owner"); + User::Leave(KErrCorrupt); + } + + // Check that if this is an incremental backup, complete snapshot data has been received + if ((aTransferType == EPassiveIncrementalData) && !StateByDriveL(aDriveNumber).iPassiveSnapshotReceived) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Incremental data has been requested without a snapshot being supplied"); + User::Leave(KErrCorrupt); + } + + // Check that Passive data has only been requested once for a Data Owner + if (((aTransferType == EPassiveBaseData) && StateByDriveL(aDriveNumber).iPassiveBaseDataRequested) || + ((aTransferType == EPassiveIncrementalData) && StateByDriveL(aDriveNumber).iPassiveIncDataRequested)) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Passive data has been requested more than once for this data owner"); + User::Leave(KErrCorrupt); + } + + // Check that for base backup, no snapshot data has been supplied + if ((aTransferType == EPassiveBaseData) && StateByDriveL(aDriveNumber).iPassiveSnapshotReceived) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Snapshot data has been received for a base only data owner"); + User::Leave(KErrCorrupt); + } + + // Check that only Base OR Incremental data is requested - not both + if (((aTransferType == EPassiveBaseData) && StateByDriveL(aDriveNumber).iPassiveIncDataRequested) || + ((aTransferType == EPassiveIncrementalData) && StateByDriveL(aDriveNumber).iPassiveBaseDataRequested)) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Base and Incremental data have been requested in the same session"); + User::Leave(KErrCorrupt); + } + + RequestPassiveDataL(aTransferType, aDriveNumber, aBuffer, aLastSection); + + if ((aTransferType == EPassiveBaseData) && aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveBaseDataRequested = ETrue; + } + + if ((aTransferType == EPassiveIncrementalData) && aLastSection) + { + StateByDriveL(aDriveNumber).iPassiveIncDataRequested = ETrue; + } + break; + } + case EActiveSnapshotData: + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting active snapshot data from data owner with SID 0x%08x", iSecureId.iId); + + // Check that active data hasn't been requested for a data owner that doesn't support it + if (!iActiveInformation.iSupported) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active snapshot data has been requested from a non-active data owner"); + User::Leave(KErrCorrupt); + } + + // Check that no active snapshot data has been requested for a base only active data owner + if (!iActiveInformation.iSupportsIncremental) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active snapshot data has been requested from a base only data owner"); + User::Leave(KErrCorrupt); + } + + // Check that the Active client has prepared it's data and is ready + if (iStatus != EDataOwnerReady) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active Snapshot data has been requested from a data owner that isn't ready"); + User::Leave(KErrNotReady); + } + + // Check that snapshot data is only requested once + if (StateByDriveL(aDriveNumber).iActiveSnapshotRequested) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active Snapshot data has been requested more than once"); + User::Leave(KErrCorrupt); + } + + // Request the snapshot data from the abclient + ipDataOwnerManager->ABServer().RequestDataL(iSecureId, aDriveNumber, aTransferType, + aBuffer, aLastSection); + + if (aLastSection) + { + StateByDriveL(aDriveNumber).iActiveSnapshotRequested = ETrue; + } + } break; + case EActiveBaseData: + case EActiveIncrementalData: + { + if (aTransferType == EActiveBaseData) + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting active base data from data owner with SID 0x%08x", iSecureId.iId); + } + else if (aTransferType == EActiveIncrementalData) + { + __LOG1("CDataOwner::ProcessRequestDataL() - Requesting active inc data from data owner with SID 0x%08x", iSecureId.iId); + } + + TInt supportedProxyCount = iProxyInformationArray.Count(); + TInt offset = 0; + + // Prepend the number of proxies into the data stream + if (StateByDriveL(aDriveNumber).iFirstActiveTransaction) + { + // Check that no active data has been requested for a data owner that doesn't support it + if ((!iActiveInformation.iSupported) && (supportedProxyCount == 0)) + { + // No proxies or active data + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active data has been requested from a non-active/no proxy data owner"); + User::Leave(KErrCorrupt); + } + + StateByDriveL(aDriveNumber).iFirstActiveTransaction = EFalse; + + PackTypeAdvance(supportedProxyCount, aBuffer, offset); + __LOG1("CDataOwner::ProcessRequestDataL() - Proxy Info : Packing TotalProxyCount = %d", supportedProxyCount); + + aBuffer.SetLength(offset); + //__LOGDATA( "CDataOwner::ProcessRequestDataL() - after adding proxy info - %S", aBuffer.Ptr(), aBuffer.Length() ); + + // Reset proxy state information for this drive + for (TInt numProxy=0; numProxy < supportedProxyCount; numProxy++) + { + ProxyStateByDriveL(aDriveNumber,numProxy) = TProxyStateByDrive(aDriveNumber,numProxy); + } + } + + // Proxy data is always at the beginning of the data block + for (TInt index = 0; index < supportedProxyCount; index++) + { + __LOG2("CDataOwner::ProcessRequestDataL() - Proxy Info : Packing proxy info %d of %d", index + 1, supportedProxyCount); + + // Request data from each of the data owners that haven't yet been added + // If the buffer's overflowed, then let the PC request again + if (!ProxyStateByDriveL(aDriveNumber,index).iDataRequested && aLastSection) + { + if (static_cast(aBuffer.MaxSize() - aBuffer.Size()) > (sizeof(TBool) + sizeof(TInt32) + sizeof(TSecureId))) + { + // Pack protocol into active stream [Proxy data length][Proxy SID][Proxy Data] + // Set the descriptor to be maximum length and use the offset to determine where we're up to + aBuffer.SetMax(); + + // buffer for proxy data finished flag + TPtr8 finishedBuf(aBuffer.MidTPtr(offset, sizeof(TBool))); + offset += sizeof(TBool); + + // buffer for length + TPtr8 lengthBuf(aBuffer.MidTPtr(offset, sizeof(TInt32))); + offset += sizeof(TInt32); + + // buffer for the sid + TPtr8 sidBuf(aBuffer.MidTPtr(offset, sizeof(TSecureId))); + offset += sizeof(TSecureId); + + // Create a buffer for the data + TPtr8 buffer(aBuffer.MidTPtr(offset)); + + // Call the proxy + ipDataOwnerManager->ABServer().RequestDataL( + iProxyInformationArray[index].iSecureId, + aDriveNumber, + aTransferType, + buffer, + aLastSection, + ProxyStateByDriveL(aDriveNumber,index).iOpInProgress, + iSecureId); + + TInt size = buffer.Size(); + + // Write the proxy protocol block to the active backup data stream + PackType(aLastSection, finishedBuf, 0); + __LOG1("CDataOwner::ProcessRequestDataL() - Proxy Info : FinishedFlag = %d", aLastSection); + + PackType(size, lengthBuf, 0); + __LOG1("CDataOwner::ProcessRequestDataL() - Proxy Info : ProxyStreamSize= %d", size); + + PackType(iProxyInformationArray[index].iSecureId, sidBuf, 0); + __LOG1("CDataOwner::ProcessRequestDataL() - Proxy Info : ProxySID = 0x%08x", iProxyInformationArray[index].iSecureId.iId); + + // Update the offset and main buffer size + offset += size; + aBuffer.SetLength(offset); + + // If the proxy still has data to send, record the fact to that the PC can request again + if (!aLastSection) + { + ProxyStateByDriveL(aDriveNumber,index).iOpInProgress = ETrue; + } + else + { + ProxyStateByDriveL(aDriveNumber,index).iOpInProgress = EFalse; + ProxyStateByDriveL(aDriveNumber,index).iDataRequested = ETrue; + } + } + else + { + // If there's not enough room for the protocol info, then set the last section flag + aLastSection = EFalse; + } + } + } + + if (iActiveInformation.iSupported && iActiveInformation.iActiveDataOwner && (aBuffer.Size() < aBuffer.MaxLength())) + { + // Check that if this is a base backup, no snapshot has been provided + if ((aTransferType == EActiveBaseData) && StateByDriveL(aDriveNumber).iActiveSnapshotReceived) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - A snapshot has been provided before a request for base data"); + User::Leave(KErrCorrupt); + } + + // Check that if this is an incremental backup that at least one complete snapshot has been sent + if ((aTransferType == EActiveIncrementalData) && !StateByDriveL(aDriveNumber).iActiveSnapshotReceived) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - No snapshot has been supplied, yet incremental data has been requested"); + User::Leave(KErrCorrupt); + } + + // Check that only one (possibly multi-part) request of actual data is made to an active backup client + if (((aTransferType == EActiveBaseData) && StateByDriveL(aDriveNumber).iActiveBaseDataRequested) || + ((aTransferType == EActiveIncrementalData) && StateByDriveL(aDriveNumber).iActiveIncDataRequested)) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Active data has been requested more than once (not counting multi-part)"); + User::Leave(KErrCorrupt); + } + + // Check that only Base OR Incremental data is requested - not both + if (((aTransferType == EActiveBaseData) && StateByDriveL(aDriveNumber).iActiveIncDataRequested) || + ((aTransferType == EActiveIncrementalData) && StateByDriveL(aDriveNumber).iActiveBaseDataRequested)) + { + __LOG("CDataOwner::ProcessRequestDataL() - State Error - Only active base or incremental data can be requested in the same session"); + User::Leave(KErrCorrupt); + } + + // Create a buffer pointer allowing the client to fill the remainder of the buffer + TInt currentBufferLength = aBuffer.Size(); + aBuffer.SetMax(); + + TPtr8 buffer(aBuffer.MidTPtr(currentBufferLength)); + + // Request data from the abclient + ipDataOwnerManager->ABServer().RequestDataL( + iSecureId, + aDriveNumber, + aTransferType, + buffer, + aLastSection, + StateByDriveL(aDriveNumber).iOpInProgress); + + aBuffer.SetLength(currentBufferLength + buffer.Size()); + + // If the active data owner still has data to send, record the fact to that the PC can request again + if (!aLastSection) + { + StateByDriveL(aDriveNumber).iOpInProgress = ETrue; + } + else + { + StateByDriveL(aDriveNumber).iOpInProgress = EFalse; + StateByDriveL(aDriveNumber).iFirstActiveTransaction = ETrue; + if (aTransferType == EActiveBaseData) + { + StateByDriveL(aDriveNumber).iActiveBaseDataRequested = ETrue; + } + + if (aTransferType == EActiveIncrementalData) + { + StateByDriveL(aDriveNumber).iActiveIncDataRequested = ETrue; + } + } + } // Active data owner + } break; + default: + { + User::Leave(KErrNotSupported); + } + } // switch + + __LOG2("CDataOwner::ProcessRequestDataL() - NEAR END - aBuffer.Ptr(): 0x%08x, aBuffer.Length(): %d", aBuffer.Ptr(), aBuffer.Length()); + //__LOGDATA( "CDataOwner::ProcessRequestDataL() - %S", aBuffer.Ptr(), aBuffer.Length() ); + __LOG("CDataOwner::ProcessRequestDataL() - END"); + } + + void CDataOwner::RequestDataL(TDriveNumber aDriveNumber, TTransferDataType aTransferType, + TPtr8& aBuffer, TBool& aLastSection) + { + aLastSection = ETrue; // Set the last section to be true by default + + // Check our state + if (!((iState.iState == ENone) || + ((iState.iState == ERequest) && (iState.iDriveNumber == aDriveNumber) && + (iState.iTransferType == aTransferType)))) + { + User::Leave(KErrNotReady); + } + + // Set the state? + if (iState.iState == ENone) + { + iState.iState = ERequest; + iState.iDriveNumber = aDriveNumber; + iState.iTransferType = aTransferType; + } + + // What are we doing then? + // We must trap any errors and rethrow them so we can reset our state + TRAPD(err, ProcessRequestDataL(aDriveNumber, aTransferType, aBuffer, aLastSection)); + + if (err != KErrNone) + { + __LOG4("CDataOwner::RequestDataL() - drive: %c:, aTransferType: %d, secureId: 0x%08x - ERROR: %d", 'a' + aDriveNumber, aTransferType, iSecureId.iId, err); + iState.iState = ENone; + delete iBufferFileWriter; + iBufferFileWriter = NULL; + delete iBufferSnapshotWriter; + iBufferSnapshotWriter = NULL; + User::Leave(err); + } // if + + if (aLastSection) // If last section reset state + { + iState.iState = ENone; + } // if + } // RequestDataL + + void CDataOwner::RestoreCompleteL() + /** Indicate to the active client that the restore operation has been completed + */ + { + // Find all of the drives that this data owner could have stored data on + TDriveList driveList; + GetDriveListL(driveList); + + for (TInt driveCountIndex = 0; driveCountIndex < KMaxDrives; driveCountIndex++) + { + if (driveList[driveCountIndex]) + { + // If the particular drive is supported, then indicate that the restore is complete + ipDataOwnerManager->ABServer().RestoreCompleteL(iSecureId, static_cast(driveCountIndex)); + } + } + } + + + TSecureId CDataOwner::SecureId() const + /** Get the secure id of the data owner + + @return the secure id of the data owner + */ + { + return iSecureId; + } + + TDataOwnerStatus CDataOwner::ReadyState() + /** Gets the ready state of the data owner + + @return The ready state + */ + { + TDataOwnerStatus status = EDataOwnerReady; + TInt proxyIndex = 0; + const TUint proxyCount = iProxyInformationArray.Count(); + CDataOwner* pProxyDataOwner = NULL; // TRAPD forces us to use a pointer instead of ref + + while ((proxyIndex < proxyCount) && (status == EDataOwnerReady || status == EDataOwnerReadyNoImpl)) + { + // For each proxy required, query for ready state + TRAPD(err, pProxyDataOwner = &(ipDataOwnerManager->DataOwnerL( + iProxyInformationArray[proxyIndex].iSecureId))); + + // If the proxy data owner doesn't exist - then error + if (err == KErrNotFound) + { + status = EDataOwnerNotFound; + } + else + { + if (pProxyDataOwner->ActiveInformation().iActiveType != EActiveOnly) + { + // Get the status from each of the supported proxies + status = pProxyDataOwner->ReadyState(); + proxyIndex++; + } + else + { + status = EDataOwnerFailed; + break; + } + + } + } + + + // If this data owner has only proxy data to backup, then echo the state of the proxies + if ((proxyCount > 0) && !iActiveInformation.iActiveDataOwner) // is passive + { + if (status == EDataOwnerReadyNoImpl) // proxy (eg.cent rep) is ready + { + iStatus = EDataOwnerReady; + } + else + { + iStatus = status; + } + } + + if ((iActiveInformation.iActiveDataOwner) && (iStatus != EDataOwnerReady) && (iStatus != EDataOwnerReadyNoImpl)) + { + TRAPD(err, iStatus = ipDataOwnerManager->ABServer().SessionReadyStateL(iSecureId)); + if (err != KErrNone) + { + iStatus = EDataOwnerNotConnected; + } + } + + // If all of the proxies are ok, then set the status to be that of this data owner + if (status == EDataOwnerReady || status == EDataOwnerReadyNoImpl) + { + status = iStatus; + } + + + __LOG2("CDataOwner::ReadyState() - Ready status for data owner 0x%08x is %d", iSecureId.iId, static_cast(status)); + + return status; + } + + void CDataOwner::SetReadyState(TDataOwnerStatus aDataOwnerStatus) + /** + Set upon a ConfirmReadyForBUR IPC call from an active backup client + */ + { + __LOG2("CDataOwner::SetReadyState() - Setting ready state of data owner 0x%08x to %d", iSecureId.iId, static_cast(aDataOwnerStatus)); + iStatus = aDataOwnerStatus; + if (aDataOwnerStatus == EDataOwnerReady && iActiveInformation.iActiveType == EProxyImpOnly) + { + iStatus = EDataOwnerReadyNoImpl; + } + } + + TCommonBURSettings CDataOwner::CommonSettingsL() + /** Get the common settings of the data owner + + @pre CDataOwner::ParseFilesL() must have been called + @return the common settings of the data owner + @leave KErrNotReady if CDataOwner::ParseFilesL() not called + */ + { + __LOG2("CDataOwner::CommonSettingsL() - START - sid: 0x%08x, iFilesParsed: %d", iSecureId.iId, iFilesParsed); + if (!iFilesParsed) + { + User::Leave(KErrNotReady); + } + + __LOG2("CDataOwner::CommonSettingsL() - Active Supported: %d, proxyCount: %d", iActiveInformation.iSupported, iProxyInformationArray.Count()); + TCommonBURSettings settings = ENoOptions; + if (iActiveInformation.iSupported || iProxyInformationArray.Count()) + { + settings |= EActiveBUR; + } // if + + __LOG1("CDataOwner::CommonSettingsL() - Passive Supported: %d", iPassiveInformation.iSupported); + if (iPassiveInformation.iSupported) + { + settings |= EPassiveBUR; + } + + __LOG1("CDataOwner::CommonSettingsL() - System Supported: %d", iSystemInformation.iSupported); + if (iSystemInformation.iSupported) + { + settings |= EHasSystemFiles; + } + + __LOG2("CDataOwner::CommonSettingsL() - SelActive: %d, SelPassive: %d", iActiveInformation.iSupportsSelective, iPassiveInformation.iSupportsSelective); + if (iActiveInformation.iSupportsSelective && iPassiveInformation.iSupportsSelective) + { + settings |= ESupportsSelective; + } + + __LOG1("CDataOwner::CommonSettingsL() - Reboot required: %d", iRestoreInformation.iRequiresReboot); + if (iRestoreInformation.iRequiresReboot) + { + settings |= ERequiresReboot; + } + + __LOG("CDataOwner::CommonSettingsL() - END"); + return settings; + } + + TPassiveBURSettings CDataOwner::PassiveSettingsL() + /** Get the passive settings of the data owner + + @pre CDataOwner::ParseFilesL() must have been called + @return the passive settings of the data owner + @leave KErrNotReady if CDataOwner::ParseFilesL() not called + */ + { + if (!iFilesParsed) + { + User::Leave(KErrNotReady); + } + + TPassiveBURSettings settings = ENoPassiveOptions; + if (iPassiveInformation.iSupported) + { + if (iPassiveInformation.iDeleteBeforeRestore) + { + settings |= EDeleteBeforeRestore; + } // if + if (!iPassiveInformation.iBaseBackupOnly) + { + settings |= EPassiveSupportsInc; + } // if + } // if + if (iPublicInformation.iSupported) + { + settings |= EHasPublicFiles; + } // if + + + return settings; + } + + TActiveBURSettings CDataOwner::ActiveSettingsL() + /** Get the active settings of the data owner + + @pre CDataOwner::ParseFilesL() must have been called + @return the active settings of the data owner + @leave KErrNotReady if CDataOwner::ParseFilesL() not called + */ + { + if (!iFilesParsed) + { + User::Leave(KErrNotReady); + } + + TActiveBURSettings settings = ENoActiveOptions; + if (iActiveInformation.iSupported) + { + if (iActiveInformation.iRequiresDelayToPrepareData) + { + settings |= EDelayToPrepareData; + } // if + if (iActiveInformation.iSupportsIncremental) + { + settings |= EActiveSupportsInc; + } // if + } // if + + return settings; + } + + /** + Get ActiveInformation of the data owner + + @return TActiveInformation active information + */ + TActiveInformation CDataOwner::ActiveInformation() + { + return iActiveInformation; + } + + void CDataOwner::GetDriveListL(TDriveList& aDriveList) + /** Get the drive list for the data owner + + @pre CDataOwner::ParseFilesL() must have been called + @return the active settings of the data owner + @leave KErrNotReady if CDataOwner::ParseFilesL() not called + */ + { + __LOG2("CDataOwner::GetDriveListL() - SID: 0x%08x, iFilesParsed: %d", iSecureId.iId, iFilesParsed); + if (!iFilesParsed) + { + User::Leave(KErrNotReady); + } + + // Get the list of available drives, dont return drives that dont exist. + TDriveList existingDrives; + const TInt error = ipDataOwnerManager->GetRFs().DriveList(existingDrives); + if ( error != KErrNone ) + { + __LOG1("CDataOwner::GetDriveListL() - couldnt get drive list: %d", error); + } + User::LeaveIfError(error); + + // We now no longer return the Z drive, it has been decided that the Z drive will always be the + // ROM. Backing up and restoring the ROM drive should not be possible, as what is the point + + TDriveList notToBackup = ipDataOwnerManager->Config().ExcludeDriveList(); + + for (TInt i = 0; i < KMaxDrives; i++) + { + if (notToBackup[i]) // if this drive is set + { + // don't include this drive + existingDrives[i] = EFalse; + } + } + + // If we do active backup or dbms backup then we + // have to say all drives + if ((iActiveInformation.iSupported) || (iDBMSSelections.Count())) + { + __LOG("CDataOwner::GetDriveListL() - active DO, so using all existing drives"); + aDriveList = existingDrives; + } // if + else + { + // See where we have files? + TBool allDrives = EFalse; + + // Reset drives passed in + aDriveList.SetLength(KMaxDrives); + aDriveList.FillZ(); + + // Loop through passive files + TInt count = iPassiveSelections.Count(); + __LOG1("CDataOwner::GetDriveListL() - checking %d passive file entries...", count); + for (TInt x = 0; !allDrives && x < count; x++) + { + const TDesC& selection = iPassiveSelections[x]->SelectionName(); + if (iPassiveSelections[x]->SelectionType() != EExclude) + { + TInt drive = GetDrive(selection); + + if (drive == -1) + { + __LOG3("CDataOwner::GetDriveListL() - passive[%2d/%2d] => all drives (no specific drive letter) - fullName: %S", x+1, count, &selection); + allDrives = ETrue; + } + else if (existingDrives[drive] != 0) + { + __LOG4("CDataOwner::GetDriveListL() - passive[%2d/%2d] => drive: %c, fullName: %S", x+1, count, drive + 'A', &selection); + aDriveList[drive] = ETrue; + } + } + + } // for + + __LOG(" "); + + // Loop through public files + count = iPublicSelections.Count(); + __LOG1("CDataOwner::GetDriveListL() - checking %d public file entries...", count); + + for (TInt x = 0; !allDrives && (x < count); x++) + { + const TDesC& selection = iPublicSelections[x]->SelectionName(); + if (iPublicSelections[x]->SelectionType() != EExclude) + { + TInt drive = GetDrive(selection); + + if (drive == -1) + { + __LOG3("CDataOwner::GetDriveListL() - public[%2d/%2d] => all drives (no specific drive letter) - fullName: %S", x+1, count, &selection); + allDrives = ETrue; + } + else if (existingDrives[drive] != 0) + { + __LOG4("CDataOwner::GetDriveListL() - public[%2d/%2d] => drive: %c, fullName: %S", x+1, count, drive + 'A', &selection); + aDriveList[drive] = ETrue; + } + } + } // for + + if (allDrives) + { + __LOG("CDataOwner::GetDriveListL() - using all drives!"); + aDriveList = existingDrives; + } // if + } // else + + #ifdef SBE_LOGGING_ENABLED + TBuf<256> drivePrint; + // + for(TInt i=0; iParserProxy().ParseL(aFileName, *this); + } + + void CDataOwner::PrivatePathL(const TDesC& aFileName) + /** Get the private path + @param aPath The path to extract the drive from + */ + { + delete iPrivatePath; + TParsePtrC parse(aFileName); + iPrivatePath = parse.Path().AllocL(); + } + + TInt CDataOwner::GetDrive(const TDesC& aPath) const + /** Gets the drive relating to a path. + + @param aPath The path to extract the drive from + @return A TDriveNumber or -1 if a drive is not specified + */ + { + TInt ret = KErrNotFound; + + if (aPath.Length() > 0) + { + if (ipDataOwnerManager->GetRFs().CharToDrive(static_cast(aPath[0]).GetLowerCase(), ret) != KErrNone) + { + ret = KErrNotFound; + } // if + } + + return ret; + } + + void CDataOwner::BuildFileListL(const RSelections& aFileSelection, + const TDriveNumber aDriveNumber, + const TTransferDataType aTransferType, + const TBool aIsPublic, + RSnapshots* apSnapshots, + RFileArray* apFileEntries, + CDesCArray* apFileNames) + /** Builds a file list. + + Builds a file list for a given selection. + + @param aFileSelection the selection + @param aDriveNumber The drive that the file resides on + @param aTransferType The type of the transfer + @param aIsPublic Are we building a public file list + @param apSnapshots A snapshot to compare files against + @param apFileEntries Array of file info's to populate + @param apFileNames Array of file names to populate + */ + { + TInt count = aFileSelection.Count(); + __LOG4("CDataOwner::BuildFileListL() - START - aDriveNumber: %c, count: %d, aIsPublic: %d, aTransferType: %d", aDriveNumber + 'A', count, aIsPublic, aTransferType); + // Split selections into include and exclude + RArray include; + CleanupClosePushL(include); + RArray exclude; + CleanupClosePushL(exclude); + // sort the snapshost to speed up IsNewerL() + if (apSnapshots) + { + apSnapshots->Sort(CSnapshot::Compare); + } + + __LOG("CDataOwner::BuildFileListL() - file selection listing...:"); + for (TInt x = 0; x < count; x++) + { + const TDesC& selectionName = aFileSelection[x]->SelectionName(); + __LOG3("CDataOwner::BuildFileListL() - selection[%03d]: %S, type: %d", x, &selectionName, aFileSelection[x]->SelectionType()); + if (aFileSelection[x]->SelectionType() == EInclude) + { + include.AppendL(selectionName); + } // if + else + { + exclude.AppendL(selectionName); + } // else + } // for x + + // Loop through all includes + count = include.Count(); + __LOG("CDataOwner::BuildFileListL() - include listing...:"); + TFileName* fileName = new(ELeave) TFileName(); + CleanupStack::PushL(fileName); + for (TInt x = 0; x < count; x++) + { + fileName->Zero(); + TChar drive; + User::LeaveIfError(ipDataOwnerManager->GetRFs().DriveToChar(aDriveNumber, drive)); + + const TDesC& includeEntry( include[x] ); + __LOG2("CDataOwner::BuildFileListL() - entry[%03d] is: %S", x, &includeEntry); + + // See if the drive is specified + if (includeEntry[0] == KBackSlash()[0]) + { + // Add the drive + fileName->Append(drive); + fileName->Append(KColon); + fileName->Append(includeEntry); + } + else if (static_cast(includeEntry[0]).GetLowerCase() == drive.GetLowerCase()) + { + fileName->Copy(includeEntry); + } // else + + + __LOG2("CDataOwner::BuildFileListL() - entry[%03d] filename is therefore: %S", x, fileName); + if (fileName->Length() > 0) + { + + // Check to see if fileName is just a drive(we cant get an entry) + TBool isDrive = EFalse; + if ((fileName->MatchF(KDrive) != KErrNotFound) || + (fileName->MatchF(KDriveAndSlash) != KErrNotFound)) + { + isDrive = ETrue; + __LOG("CDataOwner::BuildFileListL() - filename is a drive"); + } // if + + TEntry entry; + TBool isEntry = EFalse; + if (!isDrive) + { + TInt err = ipDataOwnerManager->GetRFs().Entry(*fileName, entry); + __LOG1("CDataOwner::BuildFileListL() - get entry error: %d", err); + entry.iName = *fileName; + switch (err) + { + case KErrNone: + isEntry = ETrue; + break; + case KErrNotFound: + case KErrPathNotFound: + case KErrBadName: + break; + default: + User::Leave(err); + } // switch + } // if + + if (isDrive || (isEntry && entry.IsDir())) + { + __LOG("CDataOwner::BuildFileListL() - parsing directory..."); + ParseDirL(*fileName, exclude, aTransferType, aIsPublic, apSnapshots, apFileEntries, apFileNames); + + #ifdef SBE_LOGGING_ENABLED + if (apFileNames) + { + const TInt fNameCount = apFileNames->Count(); + for(TInt k=0; kAppendL(entry); + } // if + + if (apFileNames) + { + apFileNames->AppendL(*fileName); + } // else + } // if + } // if + else + { + __LOG("CDataOwner::BuildFileListL() - file is excluded!"); + } + } // if + } // else + } // if + } // for x + CleanupStack::PopAndDestroy(fileName); + CleanupStack::PopAndDestroy(&exclude); + CleanupStack::PopAndDestroy(&include); + __LOG("CDataOwner::BuildFileListL() - END"); + } + + void CDataOwner::ParseDirL(const TDesC& aDirName, + const RArray& aExclude, + const TTransferDataType aTransferType, + const TBool aIsPublic, + RSnapshots* apSnapshots, + RFileArray* apFileEntries, + CDesCArray* apFileNames) + /** Parses a directory for files. + + Parses the given directory for files. The function is called recursivily if a directory is found. + + @param aDirName the directory to search + @param aExclude a list of directories or files to exclude + @param apFileEntries Array of file entries to populate + @param apFileNames Array of filenames to populate + */ + { + CDir* pFiles = NULL; + + // This function requires a / on the end otherwise it does not work! + TFileName* path = new(ELeave) TFileName(aDirName); + CleanupStack::PushL(path); + + if ((*path)[path->Length() - 1] != KBackSlash()[0]) + { + path->Append(KBackSlash); + } + + TInt err = ipDataOwnerManager->GetRFs().GetDir(*path, KEntryAttMatchMask, ESortNone, pFiles); + if ((err != KErrNone) && (err != KErrNotFound)) // Do we need to leave? + { + User::Leave(err); + } // if + + CleanupStack::PushL(pFiles); + + // sort the snapshost to speed up IsNewerL() + if (apSnapshots) + { + apSnapshots->Sort(CSnapshot::Compare); + } + + TUint count = pFiles->Count(); + + if (count==0) + { + // empty directory + TEntry entry; + TInt err = ipDataOwnerManager->GetRFs().Entry(*path, entry); + entry.iName = *path; + if (entry.IsDir() && (!IsExcluded(aIsPublic, entry.iName, aExclude))) + { + // append empty directory entry to the list + entry.iSize = 0; + if (apFileEntries) + { + apFileEntries->AppendL(entry); + } + if (apFileNames) + { + apFileNames->AppendL(entry.iName); + } + } + } + + TFileName* fileName = new(ELeave) TFileName(); + CleanupStack::PushL(fileName); + + while(count--) + { + TEntry entry((*pFiles)[count]); + + fileName->Zero(); + // Build full path + fileName->Append(*path); + fileName->Append(entry.iName); + entry.iName = *fileName; + + if (!IsExcluded(aIsPublic, entry.iName, aExclude)) + { + if (entry.IsDir()) + { + ParseDirL(entry.iName, aExclude, aTransferType, aIsPublic, apSnapshots, apFileEntries, apFileNames); + } // if + else + { + TInt err = KErrNone; + TBool newer = EFalse; + if (apSnapshots && (aTransferType == EPassiveIncrementalData)) + { + TRAP(err, IsNewerL(entry.iName, entry, apSnapshots, newer)); + } // if + if (!apSnapshots || + (aTransferType == EPassiveBaseData) || + newer || + (err != KErrNone)) + { + if (apFileEntries) + { + // Add to list of files + apFileEntries->AppendL(entry); + } // if + + if (apFileNames) + { + apFileNames->AppendL(entry.iName); + } // else + } // if + } // else + } // if + } // while + + // Cleanup + CleanupStack::PopAndDestroy(fileName); + CleanupStack::PopAndDestroy(pFiles); + CleanupStack::PopAndDestroy(path); + } + + + void CDataOwner::GetNextPublicFileL(TBool aReset, TDriveNumber aDriveNumber, TEntry& aEntry) + /** Gets the next public file associated with the data owner + + @param aReset set true to start reading from the beginning of the list + @param aDriveNumber the drive to retrieve the public files for + @param aEntry on return the next entry in the list, an empty entry indicates the end of the list has been reached + */ + { + TInt stackCount; + TFileName fileName; + TBool endOfList = EFalse; + TBool gotEntry = EFalse; + TChar drive; + User::LeaveIfError(ipDataOwnerManager->GetRFs().DriveToChar(aDriveNumber, drive)); + + if (aReset) + { + // Reset and start at the beginning + iPublicFileIndex = -1; + + // Go through and close all RDirs, then reset the array. + for (stackCount = iPublicDirStack.Count(); stackCount > 0; --stackCount) + { + iPublicDirStack[stackCount-1].Close(); + delete iPublicDirNameStack[stackCount-1]; + } + iPublicDirStack.Reset(); + iPublicDirNameStack.Reset(); + + // Build the list of excludes + iPublicExcludes.Reset(); + TInt selectionCount = iPublicSelections.Count(); + for (TInt x = 0; x < selectionCount; ++x) + { + const TDesC& selectionName = iPublicSelections[x]->SelectionName(); + __LOG3("CDataOwner::GetNextPublicFileL() - selection[%03d]: %S, type: %d", x, &selectionName, iPublicSelections[x]->SelectionType()); + if (iPublicSelections[x]->SelectionType() == EExclude) + { + iPublicExcludes.AppendL(selectionName); + } // else + } // for x + } // if (aReset) + + while (!endOfList && !gotEntry) + { + stackCount = iPublicDirStack.Count(); + if (stackCount == 0) + { + // Directory stack is empty, proceed to the next included file entry + do { ++iPublicFileIndex; } + while (iPublicFileIndex < iPublicSelections.Count() && + iPublicSelections[iPublicFileIndex]->SelectionType() != EInclude); + + if (iPublicFileIndex < iPublicSelections.Count()) + { + const TDesC& selectionName = iPublicSelections[iPublicFileIndex]->SelectionName(); + + if (selectionName[0] == KBackSlash()[0]) + { + // Add the drive + fileName.Zero(); + fileName.Append(drive); + fileName.Append(KColon); + fileName.Append(selectionName); + } + else + { + // Handle the Exclamation (!) in Public data paths, if any. + // Exclamation mark in place of drive letter means that the path is to be checked in all available drives. + // And any dataowner can keep their public files in any drive and it can be mentioned in backup_registration file as below. + // + // + // + + if ( selectionName[0] == KExclamationAsDrive()[0]) + { + // Map public data path using current drive being backed up. + fileName.Zero(); + fileName.Append(drive); + fileName.Append( selectionName.Mid(1) ); + } + else + if (static_cast(selectionName[0]).GetUpperCase() == drive.GetUpperCase()) + { + fileName.Copy(selectionName); + } // else + + } // else + + __LOG1("CDataOwner::GetNextPublicFileL() - next include entry filename is therefore: %S", &fileName); + if (fileName.Length() > 0) + { + + // Check to see if fileName is just a drive(we cant get an entry) + TBool isDrive = EFalse; + if ((fileName.MatchF(KDrive) != KErrNotFound) || + (fileName.MatchF(KDriveAndSlash) != KErrNotFound)) + { + isDrive = ETrue; + __LOG("CDataOwner::GetNextPublicFileL() - filename is a drive"); + } // if + + TBool isEntry = EFalse; + if (!isDrive) + { + TInt err = ipDataOwnerManager->GetRFs().Entry(fileName, aEntry); + __LOG1("CDataOwner::GetNextPublicFileL() - get entry error: %d", err); + aEntry.iName = fileName; + switch (err) + { + case KErrNone: + isEntry = ETrue; + break; + case KErrNotFound: + case KErrPathNotFound: + case KErrBadName: + break; + default: + User::Leave(err); + } // switch + + // Must have a trailing backslash on a directory + if (aEntry.IsDir() && (fileName[fileName.Length() - 1] != '\\')) + { + fileName.Append(KBackSlash); + } + } // if + + if (isDrive || (isEntry && aEntry.IsDir())) + { + __LOG("CDataOwner::GetNextPublicFileL() - parsing directory..."); + RDir dir; + dir.Open(ipDataOwnerManager->GetRFs(), fileName, KEntryAttMaskSupported); + iPublicDirStack.AppendL(dir); + iPublicDirNameStack.AppendL(fileName.AllocL()); + ++stackCount; + } // if + else if (isEntry) + { + if (!IsExcluded(ETrue, fileName, iPublicExcludes)) + { + gotEntry = ETrue; + } + else + { + __LOG("CDataOwner::BuildFileListL() - file is excluded!"); + } + } // if + } // else if + } + else + { + endOfList = ETrue; + } + } // if (stackCount == 0) + + if (stackCount > 0) + { + // There is a directory on the stack, so iterate through it + RDir& dir = iPublicDirStack[stackCount-1]; + TInt err = dir.Read(aEntry); + + if (err == KErrNone) + { + // Succesfully read the next directory entry + + // Build full file path + fileName.Zero(); + + // loop through dir stack adding entries seperated by '\'. + for (TInt x = 0; x < iPublicDirStack.Count(); ++x) + { + fileName.Append(*iPublicDirNameStack[x]); + // Add a backslash if there's not already one + if (fileName[fileName.Length()-1] != KBackSlash()[0]) + { + fileName.Append(KBackSlash); + } + } + + // Append the currently entry name to complete the path + fileName.Append(aEntry.iName); + + if (aEntry.IsDir()) + { + // Must have a trailing backslash on directory paths + fileName.Append(KBackSlash); + + // Open the directory and push it onto the dir stack + RDir dir; + User::LeaveIfError(dir.Open(ipDataOwnerManager->GetRFs(), fileName, KEntryAttMaskSupported)); + iPublicDirStack.AppendL(dir); + iPublicDirNameStack.AppendL(aEntry.iName.AllocL()); + ++stackCount; + } + else + { + // Update entry with full path ready to return + aEntry.iName = fileName; + gotEntry = ETrue; + } + // if (entry.IsDir()) + + } + else if (err == KErrEof) + { + // Finished reading this directory, close it and pop it from the directory stack + stackCount--; + + iPublicDirStack[stackCount].Close(); + iPublicDirStack.Remove(stackCount); + + delete iPublicDirNameStack[stackCount]; + iPublicDirNameStack.Remove(stackCount); + } + else + { + User::Leave(err); + } + } // if (stackCount > 0) + } + + if (endOfList) + { + // If the end of the list has been reached, make sure that an empty TEntry is returned + aEntry = TEntry(); + } + } + + + TBool CDataOwner::IsExcluded(const TBool aIsPublic, const TDesC& aFileName, const RArray& aExclude) + /** Checks to see if a given file is excluded + + Checks to see if the given file is not in a private directory or in the exclude list. + + @param aFileName file to check + @param aExclude list of excluded files + @return ETrue if excluded otherwise EFalse + */ + { + TBool ret = EFalse; + + // Check it is not in sys, resource, system or backwards path + ret = (!((aFileName.MatchF(KSystem) == KErrNotFound) && + (aFileName.MatchF(KResource) == KErrNotFound) && + (aFileName.MatchF(KSys) == KErrNotFound) && + (aFileName.MatchF(KOther) == KErrNotFound) + ) + ); + + // If this is public backup remove the private directory + if (!ret && aIsPublic) + { + ret = (!(aFileName.MatchF(KPrivateMatch) == KErrNotFound)); + } + + /** + * Check whether file is in the "NoBackup" folder or not, if yes exclude it from the backup + * @note: All files which are kept in "NoBackup" folder under the private directory will be + * excluded from the backup by default. + */ + if (!ret) + { + ret = (!(aFileName.MatchF(KPrivateNoBackup) == KErrNotFound)); + } + + // See if the file is in a private directory the data owner can access + if (!ret && (aFileName.MatchF(KPrivateMatch) != KErrNotFound)) + { + // The path includes a private directory, make sure it is the data owners + // private directory. + const TInt KSecureIdLength(8); // This is currently the length of a secure id + TBuf sid; + sid.Num(iSecureId, EHex); + TFileName match(KPrivateSidMatch()); + match.Append(KPad().Ptr(), KPad().Length() - sid.Length()); + match.Append(sid); + match.Append(KStar); + ret = (aFileName.MatchF(match) == KErrNotFound); + } // if + + if (!ret) + { + // Is the file in the exclude list? + const TInt count = aExclude.Count(); + for (TInt x = 0; !ret && x < count; x++) + { + __LOG1("file name: %S",&aFileName); + if (aExclude[x][0] == KBackSlash()[0]) + { + // Compare with out drive + TFileName compare = KQuestionMark(); + compare.Append(KColon); + compare.Append(aExclude[x]); + ret = (!(aFileName.MatchF(compare) == KErrNotFound)); + } // if + else + { + // Normal compare + ret = (aFileName.CompareF(aExclude[x]) == 0); + } // else + } // for x + } // if + + __LOG2("CDataOwner::IsExcluded() - END - returns excluded: %d for file: %S", ret, &aFileName); + return ret; + } + + void CDataOwner::SupplyPassiveSnapshotDataL(TDriveNumber aDriveNumber, TDesC8& aBuffer, TBool aLastSection) + /** Handles the supply of passive snapshot data + + @param aBuffer The buffer containing the snapshot data. + @param aLastSection Is this the last section? + */ + { + __LOG2("CDataOwner::SupplyPassiveSnapshotDataL() - START - aDriveNumber: %c, aLastSection: %d", aDriveNumber + 'A', aLastSection); + + TInt err = KErrNone; + if (iBufferSnapshotReader == NULL) + { + __LOG("CDataOwner::SupplyPassiveSnapshotDataL() - making temporary snapshot holder.."); + iTempSnapshotHolder = CSnapshotHolder::NewL(); + iTempSnapshotHolder->iDriveNumber = aDriveNumber; + iBufferSnapshotReader = CBufferSnapshotReader::NewL(iTempSnapshotHolder->iSnapshots); + + __LOG("CDataOwner::SupplyPassiveSnapshotDataL() - trying to unpack snapshots from buffer..."); + TRAP(err, iBufferSnapshotReader->StartL(aBuffer, aLastSection)); + __LOG1("CDataOwner::SupplyPassiveSnapshotDataL() - unpack result was: %d", err); + } // if + else + { + __LOG("CDataOwner::SupplyPassiveSnapshotDataL() - continuing unpack operation..."); + TRAP(err, iBufferSnapshotReader->ContinueL(aBuffer, aLastSection)); + __LOG1("CDataOwner::SupplyPassiveSnapshotDataL() - continued unpack operation result was: %d", err); + } + + if ((err != KErrNone) || aLastSection) + { + delete iBufferSnapshotReader; + iBufferSnapshotReader = NULL; + + if (err == KErrNone) + { + __LOG("CDataOwner::SupplyPassiveSnapshotDataL() - Snapshots identified ok!"); + + iSnapshots.AppendL(iTempSnapshotHolder); + iTempSnapshotHolder = NULL; + } // if + else + { + __LOG1("CDataOwner::SupplyPassiveSnapshotDataL() - END - leaving with error: %d", err); + User::Leave(err); + } // else + } // if + + __LOG("CDataOwner::SupplyPassiveSnapshotDataL() - END"); + } + + void CDataOwner::SupplyPassiveBaseDataL(const TDriveNumber aDriveNumber, TDesC8& aBuffer, TBool aLastSection) + /** Handles the supply of passive base data + */ + { + __LOG3("CDataOwner::SupplyPassiveBaseDataL() - START - drive: %c, aLastSection: %d, iBufferFileReader: 0x%08x", aDriveNumber + 'A', aLastSection, iBufferFileReader); + + TInt err = KErrNone; + if (iBufferFileReader == NULL) + { + iBufferFileReader = CBufferFileReader::NewL(ipDataOwnerManager->GetRFs(), FindSnapshot(aDriveNumber), this); + + TRAP(err, iBufferFileReader->StartL(aBuffer, aLastSection)); + } // if + else + { + TRAP(err, iBufferFileReader->ContinueL(aBuffer, aLastSection)); + } // else + + if ((err != KErrNone) || aLastSection) + { + if ( err != KErrNone ) + { + __LOG1("CDataOwner::SupplyPassiveBaseDataL() - ERROR - error: %d", err); + } + + delete iBufferFileReader; + iBufferFileReader = NULL; + + User::LeaveIfError(err); + } // if + + __LOG("CDataOwner::SupplyPassiveBaseDataL() - END"); + } + + void CDataOwner::RequestPassiveSnapshotDataL(TDriveNumber aDriveNumber, TPtr8& aBuffer, + TBool& aLastSection) + /** Handles the request for passive snapshot data + + @param aDriveNumber The drive snapshot data is required. + @param aBuffer The buffer to write the data too. + @param aLastSection On return set to true if finished. + */ + { + __LOG3("CDataOwner::RequestPassiveSnapshotDataL() - START - aDriveNumber: %c, owner: 0x%08x, bufferLen: %d", aDriveNumber + 'A', iSecureId.iId, aBuffer.Length() ); + + if (iBufferSnapshotWriter == NULL) + { + RFileArray fileinfos; + CleanupClosePushL(fileinfos); + + CDesCArray* filenames = new(ELeave) CDesCArrayFlat(KDesCArrayGranularity); + CleanupStack::PushL(filenames); + + BuildFileListL(iPassiveSelections, aDriveNumber, EPassiveBaseData, EFalse, NULL, &fileinfos, filenames); + + // Add the DBMS file + AddDBMSFilesL(aDriveNumber, filenames, &fileinfos); + + const TInt count = fileinfos.Count(); + if (count > 0) + { + __LOG1("CDataOwner::SupplyPassiveBaseDataL() - got %d entries...", count); + + // Create a tempory snapshot holder + RSnapshots* tempSnapshots = new(ELeave) RSnapshots(); + TCleanupItem cleanup(CleanupRPointerArray, tempSnapshots); + CleanupStack::PushL(cleanup); + + for (TInt x = 0; x < count; x++) + { + const TDesC& fileName = (*filenames)[x]; + CSnapshot* snapshot = CSnapshot::NewLC(fileinfos[x].iModified.Int64(), fileName); + __LOG3("CDataOwner::RequestPassiveSnapshotDataL() - snapshot[%2d/%2d] = %S", x+1, count, &fileName); + tempSnapshots->AppendL(snapshot); + CleanupStack::Pop(snapshot); + } // for x + + // Create a buffer writer + iBufferSnapshotWriter = CBufferSnapshotWriter::NewL(tempSnapshots); + CleanupStack::Pop(tempSnapshots); + + __LOG("CDataOwner::RequestPassiveSnapshotDataL() - writing snapshots to buffer..."); + iBufferSnapshotWriter->StartL(aBuffer, aLastSection); + if (aLastSection) + { + delete iBufferSnapshotWriter; + iBufferSnapshotWriter = NULL; + } // if + + + } // if + else + { + aLastSection = ETrue; + } // else + + CleanupStack::PopAndDestroy(filenames); + CleanupStack::PopAndDestroy(&fileinfos); + } // if + else + { + iBufferSnapshotWriter->ContinueL(aBuffer, aLastSection); + if (aLastSection) + { + delete iBufferSnapshotWriter; + iBufferSnapshotWriter = NULL; + } // if + } // else + + __LOG2("CDataOwner::RequestPassiveSnapshotDataL() - END - aLastSection: %d, bufferLen: %d", aLastSection, aBuffer.Length()); + } // RequestPassiveSnapShotDataL + + void CDataOwner::RequestPassiveDataL(TTransferDataType aTransferType, + TDriveNumber aDriveNumber, TPtr8& aBuffer, + TBool& aLastSection) + /** Handles the request for passive base data + + @param aDriveNumber The drive that files must be on. + @param aBuffer The buffer to write the data to. + @param aLastSection On return set to true if finished. + */ + { + __LOG4("CDataOwner::RequestPassiveDataL() - START - aDrive: %c, aTransferType: %d, iSecureId: 0x%08x, iBufferFileWriter: 0x%08x", aDriveNumber + 'A', aTransferType, iSecureId.iId, iBufferFileWriter); + + // Build the list of files + if (iBufferFileWriter == NULL) + { + CDesCArray* filenames = new(ELeave) CDesCArrayFlat(KDesCArrayGranularity); + CleanupStack::PushL(filenames); + + if (aTransferType == EPassiveBaseData) + { + __LOG("CDataOwner::RequestPassiveDataL() - EPassiveBaseData..."); + BuildFileListL(iPassiveSelections, aDriveNumber, aTransferType, EFalse, NULL, NULL, filenames); + + // Add the DBMS file + AddDBMSFilesL(aDriveNumber, filenames, NULL); + } // if + else + { + // Do we have a snapshot? + const TInt count = iSnapshots.Count(); + RSnapshots* pSnapshot = NULL; + for (TInt x = 0; !pSnapshot && (x < count); x++) + { + if (iSnapshots[x]->iDriveNumber == aDriveNumber) + { + pSnapshot = &(iSnapshots[x]->iSnapshots); + } // if + } // for x + + BuildFileListL(iPassiveSelections, aDriveNumber, aTransferType, EFalse, pSnapshot, NULL, filenames); + + // Do we need to add the DBMS file? + AddDBMSFilesL(aDriveNumber, filenames, NULL); + } // else + + + __LOG1("CDataOwner::RequestPassiveDataL() - Got %d files...", filenames->Count()); + if (filenames->Count() > 0) + { + // Create a file writer + iBufferFileWriter = CBufferFileWriter::NewL(ipDataOwnerManager->GetRFs(), filenames); + CleanupStack::Pop(filenames); + + iBufferFileWriter->StartL(aBuffer, aLastSection); + if (aLastSection) + { + delete iBufferFileWriter; + iBufferFileWriter = NULL; + } + } // if + else + { + CleanupStack::PopAndDestroy(filenames); + aLastSection = ETrue; + } // else + + } // if + else + { + iBufferFileWriter->ContinueL(aBuffer, aLastSection); + if (aLastSection) + { + delete iBufferFileWriter; + iBufferFileWriter = NULL; + } // if + } // else + + __LOG("CDataOwner::RequestPassiveDataL() - END"); + } + + void CDataOwner::IsNewerL(const TDesC& aFileName, const TEntry& aFile, const RSnapshots* aSnapshots, TBool& aNewer) + /** Check to see if a file is newer. + + Checks to see if aFile is newer than the one contained in aFiles. + + @param aFile the file to check. + @param aFiles the array of files to check agaisnt + @param aNewer on return ETrue if aFile is newer, EFalse otherwise. + @leave KErrNotFound if aFile does not exist in aFiles. + */ + { + CSnapshot* snapshot = CSnapshot::NewLC(TTime().Int64(), aFileName); + TInt res = aSnapshots->Find(snapshot, CSnapshot::Match); + CleanupStack::PopAndDestroy(snapshot); + User::LeaveIfError(res); + if (aFile.iModified.Int64() > (*aSnapshots)[res]->Modified()) + { + aNewer = ETrue; + } + else + { + aNewer = EFalse; + } + } + + RSnapshots* CDataOwner::FindSnapshot(TDriveNumber aDriveNumber) + /** Searches the snapshots find a snapshot + + @param aDriveNumber find snapshot for drive aDriveNumber + @return The snapshot or NULL + */ + { + const TInt count = iSnapshots.Count(); + __LOG3("CDataOwner::FindSnapshot() - START - aDriveNumber: %c, count: %d, iSecureId: 0x%08x", aDriveNumber + 'A', count, iSecureId.iId); + + RSnapshots* pRet = NULL; + + for (TInt x = 0; !pRet && (x < count); x++) + { + CSnapshotHolder* snapshotHolder = iSnapshots[x]; + + #ifdef SBE_LOGGING_ENABLED + const TInt entryCount = snapshotHolder->iSnapshots.Count(); + __LOG4("CDataOwner::FindSnapshot() - snapshot[%02d] - drive: %c, entry Count: %d, addr: 0x%08x", x, snapshotHolder->iDriveNumber + 'A', entryCount, &snapshotHolder->iSnapshots); + + for(TInt i=0; iiSnapshots[i]->FileName(); + __LOG2("CDataOwner::FindSnapshot() - file[%04d]: %S", i+1, &snapshot); + } + #endif + + if (snapshotHolder->iDriveNumber == aDriveNumber) + { + pRet = &(snapshotHolder->iSnapshots); + } // if + } // for x + + __LOG1("CDataOwner::FindSnapshot() - END - ret: 0x%08x", pRet); + return pRet; + } + + /** + Returns a reference to a state by drive object. Object is located using aDrive as a key + @param aDrive Index identifying the TDataOwnerStateByDrive + */ + TDataOwnerStateByDrive& CDataOwner::StateByDriveL(TDriveNumber& aDrive) + { + TBool found = EFalse; + const TInt count = iStateByDrive.Count(); + TInt index = 0; + + // Loop around until we find + while ((index < count) && !found) + { + if (iStateByDrive[index].iDrive == aDrive) + { + found = ETrue; + } + else + { + ++index; + } + } + + // We must have found, otherwise error + if (!found) + { + User::Leave(KErrNotFound); + } + + return iStateByDrive[index]; + } + + /** + Returns a reference to a proxy state by drive object. Object is located using aDrive and aProxy as keys + @param aDrive Index identifying the TProxyStateByDrive + @param aProxy Index identifying the proxy + */ + TProxyStateByDrive& CDataOwner::ProxyStateByDriveL(TDriveNumber& aDrive, TInt aProxy) + { + TBool found = EFalse; + const TInt count = iProxyStateByDrive.Count(); + TInt index = 0; + + // Loop around until we find + while ((index < count) && !found) + { + if (iProxyStateByDrive[index].iDrive == aDrive && + iProxyStateByDrive[index].iProxy == aProxy) + { + found = ETrue; + } + else + { + ++index; + } + } + + // Add a new entry if not found + if (!found) + { + iProxyStateByDrive.Append(TProxyStateByDrive(aDrive,aProxy)); + index = count; + } + + return iProxyStateByDrive[index]; + } + + + + /** + Called to re-create the state-by-drive array + */ + void CDataOwner::BuildDriveStateArrayL() + { + TDriveList driveList; + driveList.SetMax(); + + TRAPD(err, GetDriveListL(driveList)); + __LOG2("CDataOwner::BuildDriveStateArrayL() - START - SID: 0x%08x, error: %d", iSecureId.iId, err); + + if (err == KErrNone) + { + for (TInt index = 0; index < KMaxDrives; index++) + { + if (driveList[index]) + { + // Add a new state object to the array of states + iStateByDrive.AppendL(TDataOwnerStateByDrive(static_cast(index))); + } + } + } + else + { + __LOG1("CDataOwner::BuildDriveStateArrayL() - Warning! error ocurred whilst getting the drivelist from data owner %08x", iSecureId.iId); + } + } + + + /** + Adds the list of DBMS files to a filename list + */ + void CDataOwner::AddDBMSFilesL(TDriveNumber aDriveNumber, CDesCArray* apFileNames, RFileArray* apEntries) + { + const TInt count = iDBMSSelections.Count(); + __LOG3("CDataOwner::AddDBMSFilesL() - START - aDriveNumber: %c, owner: 0x%08x, count: %d", aDriveNumber + 'A', iSecureId.iId, count); + + if (count > 0) + { + // Get DB connection + RDbs dbs; + User::LeaveIfError(dbs.Connect()); + CleanupClosePushL(dbs); + + for (TInt x = 0; x < count; x++) + { + // Get list of filenames + TInt err = KErrNone; + CDbStrings* pFilenames = NULL; + TRAP(err, pFilenames = dbs.BackupPathsL(iSecureId, iDBMSSelections[x])); + + if (err == KErrNone) + { + CleanupStack::PushL(pFilenames); + + __LOG1("CDataOwner::AddDBMSFilesL() - getting backup paths for owner returned error: %d", err); + + const TInt count = pFilenames->Count(); + for (TInt x = 0; x < count; x++) + { + const TDesC& pFileName = (*pFilenames)[x]; + __LOG3("CDataOwner::AddDBMSFilesL() - file[%3d/%3d] = %S", x + 1, count, &pFileName); + + TInt drive = -1; + TInt driveerr = RFs::CharToDrive( pFileName[0], drive); + if ((driveerr == KErrNone) && (drive == aDriveNumber)) + { + if (apFileNames) + { + __LOG1("CDataOwner::AddDBMSFilesL() - adding validated filename: %S", &pFileName); + apFileNames->AppendL( pFileName ); + } + if (apEntries) + { + TEntry entry; + TInt entryError = ipDataOwnerManager->GetRFs().Entry( pFileName, entry); + __LOG2("CDataOwner::AddDBMSFilesL() - drive entry result for file \'%S\' is: %d", &pFileName, entryError); + if (entryError == KErrNone) + { + __LOG1("CDataOwner::AddDBMSFilesL() - adding validated entry: %S", &pFileName); + apEntries->AppendL(entry); + } // if + else if (entryError != KErrNotFound) + { + __LOG2("CDataOwner::AddDBMSFilesL() - Could not get entry for 0x%08x, error: %d", iSecureId.iId, entryError); + } // else if + } // if + } // if + else + { + __LOG("CDataOwner::AddDBMSFilesL() - File is not applicable for this drive => file ignored"); + } + } // for x + + // Cleanup + CleanupStack::PopAndDestroy(pFilenames); + } + else + { + __LOG2("CDataOwner::AddDBMSFilesL() - RDbs error %d SID: 0x%08x", err, iSecureId.iId); + } // else + } // for x + + // Cleanup + CleanupStack::PopAndDestroy(&dbs); + } // if + + __LOG2("CDataOwner::AddDBMSFilesL() - END - aDriveNumber: %c, owner: 0x%08x", aDriveNumber + 'A', iSecureId.iId); + } // AddDBMSFiles + + /** Disables system data + */ + void CDataOwner::DisableSystemData() + { + iSystemInformation.iSupported = EFalse; + } // Disable system data + + TInt CDataOwner::AddProxyToList(TProxyInformation aProxy) + /** Adds proxy to list making sure there are no duplicates + @param TProxyInformation Proxy to add + @return error if Append failes + */ + { + TInt count = iProxyInformationArray.Count(); + TBool found = EFalse; + + while (count && !found) + { + --count; + if (iProxyInformationArray[count].iSecureId == aProxy.iSecureId) + { + found = ETrue; + } + } + + TInt err = KErrNone; + if (!found) + { + err = iProxyInformationArray.Append(aProxy); + __LOG2("Data owner(0x%08x): Adding Proxy(0x%08x) to the list", iSecureId.iId,aProxy.iSecureId.iId); + } + return err; + } + + void CDataOwner::CleanupBeforeRestoreL(TDriveNumber& aDriveNumber) + /** Performs a cleanup before restore if required + @param aDriveNumber drive to clear + */ + { + const TBool passiveDeleteBeforeRestore = iPassiveInformation.iDeleteBeforeRestore; + const TBool driveAlreadyCleaned = StateByDriveL(aDriveNumber).iDeleteBeforeRestorePerformed; + + __LOG4("CDataOwner::CleanupBeforeRestoreL() - START - aDriveNumber: %c, owner: 0x%08x, passiveDeleteBeforeRestore: %d, driveAlreadyCleaned: %d", aDriveNumber + 'A', iSecureId.iId, passiveDeleteBeforeRestore, driveAlreadyCleaned); + + if ( passiveDeleteBeforeRestore && !driveAlreadyCleaned ) + { + RSelections* selections = new(ELeave) RSelections(); + TCleanupItem cleanup(CleanupRPointerArray, selections); + CleanupStack::PushL(cleanup); + // The path to search for files to delete + + CSelection* selection = NULL; + const TDesC& privatePath = *iPrivatePath; + if (privatePath[0] == KBackSlash()[0]) + { + selection = CSelection::NewLC(EInclude, privatePath); + } // if + else + { + selection = CSelection::NewLC(EInclude, privatePath.Right(privatePath.Length() - 2)); + } // else + selections->AppendL(selection); + CleanupStack::Pop(selection); + + // Find the files to delete + CDesCArray* toDelete = new(ELeave) CDesCArrayFlat(KDesCArrayGranularity); + CleanupStack::PushL(toDelete); + + BuildFileListL(*selections, aDriveNumber, EPassiveBaseData, EFalse, NULL, NULL, toDelete); + + // Loop through the files to delete, deleting them + const TInt count = toDelete->Count(); + for (TInt x = 0; x < count; x++) + { + const TDesC& fileName = (*toDelete)[x]; + + __LOG3("CDataOwner::CleanupBeforeRestoreL() - checking file[%2d/%2d] for match = %S", x + 1, count, &fileName); + + // Check it is not a backup registration file + if ( fileName.MatchF(KBackupRegistrationFile) == KErrNotFound ) + { + TInt deleteError=0; + if((fileName[(fileName.Length())-1])== KBackSlash()[0]) + { + deleteError = ipDataOwnerManager->GetRFs().RmDir( fileName ); + } + else + { + deleteError = ipDataOwnerManager->GetRFs().Delete( fileName ); + } + __LOG2("CDataOwner::CleanupBeforeRestoreL() - trying to deleting file %S (error was: %d)", &fileName, deleteError); + User::LeaveIfError(deleteError); + } // if + } // for + + // Mark as done + StateByDriveL(aDriveNumber).iDeleteBeforeRestorePerformed = ETrue; + + // Cleanup + CleanupStack::PopAndDestroy(toDelete); + CleanupStack::PopAndDestroy(selections); + } // if + + __LOG2("CDataOwner::CleanupBeforeRestoreL() - END - aDriveNumber: %c, owner: 0x%08x", aDriveNumber + 'A', iSecureId.iId); + } + /** + Check if the file is in the include list + + @param TDesC& aFileName file name to check + @return TBool ETrue if file is in the include list + */ + TBool CDataOwner::ValidFileL(const TDesC& aFileName) + { + __LOG2("CDataOwner::ValidFileL() - START - owner: 0x%08x, aFileName: %S", iSecureId.iId, &aFileName); + + TInt include = EFalse; + + const TInt count = iPassiveSelections.Count(); + for (TInt i =0; i < count; i++) + { + const TDesC& selectionName = iPassiveSelections[i]->SelectionName(); + TInt match = aFileName.FindF(selectionName); + __LOG5("CDataOwner::ValidFileL() - match result against file[%3d/%3d], selectionType: %d, matchResult: %d, name: %S", i+1, count, iPassiveSelections[i]->SelectionType(), match, &selectionName); + + if (match >= 0) + { + if (iPassiveSelections[i]->SelectionType() == EInclude) + { + __LOG("CDataOwner::ValidFileL() - file included"); + include = ETrue; + } + else + { + __LOG("CDataOwner::ValidFileL() - file excluded"); + include = EFalse; + break; + } // else if + } //if + + } // for + + + const TInt dbmsSelectionCount = iDBMSSelections.Count(); + if (dbmsSelectionCount && !include) + { + __LOG1("CDataOwner::ValidFileL() - checking against %d DBMS files...", dbmsSelectionCount); + + for (TInt j = 0; j < dbmsSelectionCount; j++) + { + const TDesC& pDbmsFileName = iDBMSSelections[j].Name(); + const TInt matchResult = aFileName.FindF( pDbmsFileName ); + + __LOG4("CDataOwner::ValidFileL() - checking against DBMS file[%2d/%2d] with result: %d (%S)...", j+1, dbmsSelectionCount, matchResult, &pDbmsFileName); + + if ( matchResult ) + { + __LOG("CDataOwner::ValidFileL() - DBMS file included"); + include = ETrue; + break; + } // if + }//for + } // if + + __LOG1("CDataOwner::ValidFileL() - END - valid file result is: %d", include); + return include; + } + + // + // MContentHandler Implementaion // + // + + + + void CDataOwner::OnStartDocumentL(const RDocumentParameters& /*aDocParam*/, TInt aErrorCode) + /** MContentHandler::OnStartDocumentL() + */ + { + if (aErrorCode != KErrNone) + { + __LOG1("CDataOwner::OnStartDocumentL() - error = %d", aErrorCode); + User::Leave(aErrorCode); + } + } + + void CDataOwner::OnEndDocumentL(TInt aErrorCode) + /** MContentHandler::OnEndDocumentL() + */ + { + if (aErrorCode != KErrNone) + { + // just to satifsy UREL compiler + (void) aErrorCode; + __LOG1("CDataOwner::OnEndDocumentL() - error = %d", aErrorCode); + } + } + + void CDataOwner::OnStartElementL(const RTagInfo& aElement, + const RAttributeArray& aAttributes, + TInt aErrorCode) + /** MContentHandler::OnStartElementL() + + @leave KErrUnknown an unknown element + */ + { + if (aErrorCode != KErrNone) + { + __LOG1("CDataOwner::OnStartElementL() - error = %d", aErrorCode); + User::LeaveIfError(aErrorCode); + } + + TBool unknownElement = EFalse; + const TDesC8& localName = aElement.LocalName().DesC(); + if (localName == KIncludeFile) + { + HandlePathL(EInclude, aAttributes, EFalse); + } + else if (!localName.CompareF(KIncludeDirectory)) + { + HandlePathL(EInclude, aAttributes, ETrue); + } + else if (!localName.CompareF(KExclude)) + { + HandlePathL(EExclude, aAttributes, EFalse); + } + else if (!localName.CompareF(KBackupRegistration)) + { + HandleBackupRegistrationL(aAttributes); + } + else if (!localName.CompareF(KDBMSBackup)) + { + User::LeaveIfError(HandleDBMSBackupL(aAttributes)); + } + else if (!localName.CompareF(KSystemBackup)) + { + User::LeaveIfError(HandleSystemBackup(aAttributes)); + } + else if (!localName.CompareF(KProxyDataManager)) + { + User::LeaveIfError(HandleProxyDataManager(aAttributes)); + } + else if (!localName.CompareF(KCenrepBackup)) + { + User::LeaveIfError(HandleCenrepBackup(aAttributes)); + } + else if (!localName.CompareF(KPublicBackup)) + { + iCurrentElement = EPublic; + User::LeaveIfError(HandlePublicBackup(aAttributes)); + } + else if (!localName.CompareF(KPassiveBackup)) + { + iCurrentElement = EPassive; + // Only allow passive to be switched on in primary files + if (iPrimaryFile) + { + User::LeaveIfError(HandlePassiveBackup(aAttributes)); + } + } + else if (iPrimaryFile) + { + // These remaining elements are only allowed in primary files + if (!localName.CompareF(KActiveBackup)) + { + User::LeaveIfError(HandleActiveBackupL(aAttributes)); + } + else if (!localName.CompareF(KRestore)) + { + User::LeaveIfError(HandleRestore(aAttributes)); + } + else + { + unknownElement = ETrue; + } + } // if primary file true + else + { + unknownElement = ETrue; + } + + if (unknownElement) + { + __LOG1("CDataOwner::OnStartElementL() - Unknown element while parsing 0x%08x", iSecureId.iId); + } + } + + + void CDataOwner::OnEndElementL(const RTagInfo& aElement, TInt aErrorCode) + /** MContentHandler::OnEndElementL() + */ + { + if (aErrorCode != KErrNone) + { + __LOG1("CDataOwner::OnEndElementL() - error = %d", aErrorCode); + User::Leave(aErrorCode); + } + + const TDesC8& localName = aElement.LocalName().DesC(); + if (!localName.CompareF(KPassiveBackup)) + { + iCurrentElement = ENoElement; + } // if + else if (localName == KPublicBackup) + { + iCurrentElement = ENoElement; + } // else if + } + + void CDataOwner::OnContentL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/) + /** MContentHandler::OnContentL() + */ + { + // Not handled + } + + void CDataOwner::OnStartPrefixMappingL(const RString& /*aPrefix*/, + const RString& /*aUri*/, TInt /*aErrorCode*/) + /** MContentHandler::OnStartPrefixMappingL() + */ + { + // Not handled + } + + void CDataOwner::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/) + /** MContentHandler::OnEndPrefixMappingL() + */ + { + // Not handled + } + + void CDataOwner::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/) + /** MContentHandler::OnIgnorableWhiteSpaceL() + */ + { + // Not handled + } + + void CDataOwner::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/) + /** MContentHandler::OnSkippedEntityL() + */ + { + // Not handled + } + + void CDataOwner::OnProcessingInstructionL(const TDesC8& /*aTarget*/, + const TDesC8& /*aData*/, + TInt /*aErrorCode*/) + /** MContentHandler::OnProcessingInstructionL() + */ + { + // Not handled + } + + void CDataOwner::OnError(TInt aErrorCode) + /** MContentHandler::OnError() + + @leave aErrorCode + */ + { + (void)aErrorCode; + __LOG1("CDataOwner::OnError() - error = %d", aErrorCode); + } + + TAny* CDataOwner::GetExtendedInterface(const TInt32 /*aUid*/) + /** MContentHandler::OnEndPrefixMappingL() + */ + { + return NULL; + } + + void CDataOwner::HandleBackupRegistrationL(const RAttributeArray& aAttributes) + /** Handles the "backup_registration" element + + @param aAttributes the attributes for the element + @return KErrNone no errors + @return KErrUnknown unknown version + */ + { + if (aAttributes.Count() == 1) + { + // Check the version is correct. + if (aAttributes[0].Value().DesC() != KVersion()) // Only version we know about + { + __LOG1("CDataOwner::HandleBackupRegistrationL() - Unknown version at SID(0x%08x)", iSecureId.iId); + User::Leave(KErrNotSupported); + } // else + } // if + } + + + TInt CDataOwner::HandlePassiveBackup(const RAttributeArray& aAttributes) + /** Handles the "passive_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iPassiveInformation.iSupported = ETrue; + + // Loop through reading out attribute values + const TInt count = aAttributes.Count(); + for (TInt x = 0; x < count; x++) + { + const TDesC8& localName = aAttributes[x].Attribute().LocalName().DesC(); + + if ( localName.CompareF(KSupportsSelective) == 0 ) + { + const TBool supportsSelective = ( aAttributes[x].Value().DesC().CompareF(KYes) == 0 ); + iPassiveInformation.iSupportsSelective = supportsSelective; + __LOG2("CDataOwner::HandlePassiveBackup(0x%08x) - iPassiveInformation.iSupportsSelective: %d", iSecureId.iId, supportsSelective); + } // if + else if ( localName.CompareF(KDeleteBeforeRestore) == 0 ) + { + // AW This logic looks somewhat strange. + if (!aAttributes[x].Value().DesC().CompareF(KYes)) + { + __LOG1("CDataOwner::HandlePassiveBackup(0x%08x) - iPassiveInformation.iDeleteBeforeRestore: ETrue", iSecureId.iId); + iPassiveInformation.iDeleteBeforeRestore |= ETrue; + } // if + else + { + __LOG1("CDataOwner::HandlePassiveBackup(0x%08x) - iPassiveInformation.iDeleteBeforeRestore: EFalse", iSecureId.iId); + iPassiveInformation.iDeleteBeforeRestore |= EFalse; + } // else + } // else if + else if ( localName.CompareF(KBaseBackupOnly) == 0 ) + { + const TBool baseBackupOnly = ( aAttributes[x].Value().DesC().CompareF(KYes) == 0 ); + iPassiveInformation.iBaseBackupOnly = baseBackupOnly; + __LOG2("CDataOwner::HandlePassiveBackup(0x%08x) - iPassiveInformation.iBaseBackupOnly: %d", iSecureId.iId, baseBackupOnly); + } // else if + else + { + __LOG1("CDataOwner::HandlePassiveBackup() - Unknown element while parsing 0x%08x", iSecureId.iId); + } // else + } // for x + + return KErrNone; + } + + + TInt CDataOwner::HandlePublicBackup(const RAttributeArray& aAttributes) + /** Handles the "public_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iPublicInformation.iSupported = ETrue; + + if (aAttributes.Count() > 0) + { + const TBool deleteBeforeRestore = ( aAttributes[0].Value().DesC().CompareF(KYes) == 0 ); + iPublicInformation.iDeleteBeforeRestore = deleteBeforeRestore; + __LOG2("CDataOwner::HandlePublicBackup(0x%08x) - iPublicInformation.iDeleteBeforeRestore: %d", iSecureId.iId, deleteBeforeRestore); + } // if + + return KErrNone; + } + + TInt CDataOwner::HandleSystemBackup(const RAttributeArray& /*aAttributes*/) + /** Handles the "system_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iSystemInformation.iSupported = ETrue; + __LOG2("CDataOwner::HandleSystemBackup(0x%08x) - iSystemInformation.iSupported: %d", iSecureId.iId, iSystemInformation.iSupported); + + return KErrNone; + } + + + TInt CDataOwner::HandleCenrepBackup(const RAttributeArray& /*aAttributes*/) + /** Handles the "cenrep_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + TInt err = KErrNone; + TProxyInformation proxyInformation; + + proxyInformation.iSecureId = ipDataOwnerManager->Config().CentRepId(); + + err = AddProxyToList(proxyInformation); + + if (err == KErrNone) + { + + if (iActiveInformation.iSupported == EFalse) + { + iActiveInformation.iSupported = ETrue; + iActiveInformation.iSupportsIncremental = EFalse; + iStatus = EDataOwnerNotConnected; + } + + } + + __LOG2("CDataOwner::HandleCenrepBackup(0x%08x) - proxy creation error: %d", iSecureId.iId, err); + return err; + } + + TInt CDataOwner::HandleProxyDataManager(const RAttributeArray& aAttributes) + /** Handles the "proxy_data_manager" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + TInt err = KErrNone; + + TProxyInformation proxyInformation; + + const TDesC8& localName = aAttributes[0].Attribute().LocalName().DesC(); + if (!localName.CompareF(KProxySID)) + { + // The value returned from the XML element attribute parse + const TDesC8& hexString = aAttributes[0].Value().DesC(); + TPtrC8 strippedSID; + + // Test for lower case hex leader chars + TInt result = hexString.FindF(KHexLeader); + + if (result != KErrNotFound) + { + if (hexString.Length() < (result + KHexLeader().Size())) + { + __LOG1("CDataOwner::HandleProxyDataManager() - The Hex number has incorrect number of digits", iSecureId.iId); + } + // Strip off the preceeding upper case hex leader characters + strippedSID.Set(hexString.Mid(result + KHexLeader().Size())); + } + else + { + // There were no leading characters in the data + strippedSID.Set(hexString); + } + + TLex8 sIdLex(strippedSID); + err = sIdLex.Val(proxyInformation.iSecureId.iId, EHex); + + if (err == KErrNone && proxyInformation.iSecureId.iId != iSecureId.iId) + { + err = AddProxyToList(proxyInformation); + + if (err == KErrNone) + { + if (iActiveInformation.iSupported == EFalse) + { + iActiveInformation.iSupported = ETrue; + iActiveInformation.iSupportsIncremental = EFalse; + iStatus = EDataOwnerNotConnected; + } + } + + __LOG3("CDataOwner::HandleProxyDataManager(0x%08x) - proxy creation error: %d for proxySid: 0x%08x", iSecureId.iId, err, proxyInformation.iSecureId.iId); + } + else + { + __LOG1("CDataOwner::HandleProxyDataManager() - Not a Hex Number specified in reg_file of 0x%08x)", iSecureId.iId); + err = KErrNone; // We shouldn't return an error unless Append has errored (OOM etc.) + } + } // else it's corrupt - don't error, just ignore this attribute + + return err; + } + + TInt CDataOwner::HandleDBMSBackupL(const RAttributeArray& aAttributes) + /** Handles the "dbms_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iPassiveInformation.iSupported = ETrue; + + const TInt count = aAttributes.Count(); + for (TInt x = 0; x < count; x++) + { + const TDesC8& localName = aAttributes[x].Attribute().LocalName().DesC(); + if (localName.Length() > 0) + { + if (!localName.CompareF(KDatabase)) + { + __LOG1("CDataOwner::HandleDBMSBackup(0x%08x) - Still using deprecated 'database' attribute", iSecureId.iId); + } + else if (!localName.CompareF(KPolicy)) + { + TName policy; + if (KErrNone == ipDataOwnerManager->ParserProxy().ConvertToUnicodeL(policy, aAttributes[x].Value().DesC())) + { + TLex lex(policy); + TUint32 temp; + lex.Val(temp, EHex); + + // Check we have not seen this Uid before + const TInt count = iDBMSSelections.Count(); + TBool toAdd = ETrue; + for (TInt x = 0; toAdd && (x < count); x++) + { + if (iDBMSSelections[x].iUid == temp) + { + toAdd = EFalse; + } // if + } // for + + // Add to list of Uid's + if (toAdd) + { + __LOG2("CDataOwner::HandleDBMSBackup(0x%08x) - adding database with policy uid: 0x%08x", iSecureId.iId, temp); + TUid tempUID; + tempUID.iUid = temp; + TRAP_IGNORE(iDBMSSelections.AppendL(tempUID)); + } // if + } // if + else + { + __LOG1("CDataOwner::HandleDBMSBackup(0x%08x) - Error converting policy number", iSecureId.iId); + } // else + } // else if + } // if + else + { + __LOG1("CDataOwner::HandleDBMSBackup(0x%08x) - Incorrect use of attributes", iSecureId.iId); + } + } // for x + + return KErrNone; + } + + TInt CDataOwner::HandleActiveBackupL(const RAttributeArray& aAttributes) + /** Handles the "active_backup" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iActiveInformation.iSupported = ETrue; + iActiveInformation.iActiveDataOwner = ETrue; + iStatus = EDataOwnerNotConnected; + + const TInt count = aAttributes.Count(); + for (TInt x = 0; (iActiveInformation.iSupported && (x < count)); x++) + { + const TDesC8& localName = aAttributes[x].Attribute().LocalName().DesC(); + if (!localName.CompareF(KProcessName)) + { + if (KErrNone != ipDataOwnerManager->ParserProxy().ConvertToUnicodeL(iActiveInformation.iProcessName, aAttributes[x].Value().DesC())) + { + iActiveInformation.iSupported = EFalse; + __LOG1("CDataOwner::HandleActiveBackup(0x%08x) - Error converting process name", iSecureId.iId); + } + } + else if (!localName.CompareF(KRequiresDelay)) + { + const TBool required = ( aAttributes[x].Value().DesC().CompareF(KYes) == 0 ); + iActiveInformation.iRequiresDelayToPrepareData = required; + __LOG2("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iRequiresDelayToPrepareData: %d", iSecureId.iId, required); + } // else if + else if (!localName.CompareF(KSupportsSelective)) + { + const TBool required = ( aAttributes[x].Value().DesC().CompareF(KYes) == 0 ); + iActiveInformation.iSupportsSelective = required; + __LOG2("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iSupportsSelective: %d", iSecureId.iId, required); + } // else if + else if (!localName.CompareF(KSupportsInc)) + { + const TBool required = ( aAttributes[x].Value().DesC().CompareF(KYes) == 0 ); + iActiveInformation.iSupportsIncremental = required; + __LOG2("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iSupportsIncremental: %d", iSecureId.iId, required); + } // else if + else if (!localName.CompareF(KActiveType)) + { + const TDesC8& value = aAttributes[x].Value().DesC(); + if (!value.CompareF(KActiveOnly)) + { + __LOG1("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iActiveType: EActiveOnly", iSecureId.iId); + iActiveInformation.iActiveType = EActiveOnly; + } + else if (!value.CompareF(KActiveAndProxy)) + { + __LOG1("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iActiveType: EActiveAndProxyImpl", iSecureId.iId); + iActiveInformation.iActiveType = EActiveAndProxyImpl; + } + else if (!value.CompareF(KProxyOnly)) + { + __LOG1("CDataOwner::HandleActiveBackup(0x%08x) - iActiveInformation.iActiveType: EProxyImpOnly", iSecureId.iId); + iActiveInformation.iActiveType = EProxyImpOnly; + } + } + } // for x + + return KErrNone; + } + + + TInt CDataOwner::HandleRestore(const RAttributeArray& aAttributes) + /** Handles the "restore" element + + @param aAttributes the attributes for the element + @return KErrNone + */ + { + iRestoreInformation.iSupported = ETrue; + + if (aAttributes.Count() == 1) + { + if (!aAttributes[0].Attribute().LocalName().DesC().CompareF(KRequiresReboot)) + { + const TBool required = ( aAttributes[0].Value().DesC().CompareF(KYes) == 0 ); + iRestoreInformation.iRequiresReboot = required; + __LOG2("CDataOwner::HandleRestore(0x%08x) - iRestoreInformation.iRequiresReboot: %d", iSecureId.iId, required); + } // if + } // if + + return KErrNone; + } + + + void CDataOwner::HandlePathL(const TSelectionType aType, + const RAttributeArray& aAttributes, + const TBool aDir) + /** Handles the "include_file", "include_directory" and "exclude" elements + + @param aType The selection type + @param aAttributes The attributes for the element + @param aDir The element was found in an element? + */ + { + // Check we dont have a NULL string + if (aAttributes[0].Value().DesC().Length() > 0) + { + TFileName filename; + if (KErrNone != ipDataOwnerManager->ParserProxy().ConvertToUnicodeL(filename, aAttributes[0].Value().DesC())) + { + __LOG1("CDataOwner::HandlePathL(0x%08x) - EPassive - Could not convert filename", iSecureId.iId); + return; + } + else + { + __LOG3("CDataOwner::HandlePathL(0x%08x) - path in the registration file is: %S [type: %d]", iSecureId.iId, &filename, aType); + } + + // If it is a directory is do we add a trailing backslash, + if (aDir && (filename[filename.Length() - 1] != '\\')) + { + filename.Append(KBackSlash); + } // if + + + switch (iCurrentElement) + { + case EPassive: + { + TFileName selectionName; + // first check for absolute path + TInt offset = filename.FindC(*iPrivatePath); + if (offset == KErrNotFound) + { + //check for collon path + offset = filename.FindC(KColon); + if (offset != KErrNotFound) + { + // someone other absoulute path + __LOG2("CDataOwner::HandlePathL(0x%08x) - Path is not recognised by the data owner : %S", iSecureId.iId, &filename); + return; + } + else + { + selectionName = *iPrivatePath; + if (filename[0] == '\\') + { + // the filename begins with \, thefore we need to chop it off + selectionName.SetLength(selectionName.Length() - 1); + } + selectionName.Append(filename); + } + } + else + { + // get the path but not the drive (e.g c:) + selectionName.Copy(filename.Right(filename.Length() - offset) ); + } + + CSelection* selection = CSelection::NewLC(aType, selectionName); + iPassiveSelections.AppendL(selection); + CleanupStack::Pop(selection); + __LOG3("CDataOwner::HandlePathL(0x%08x) - Added selection: %S [type: %d]", iSecureId.iId, &selectionName, aType); + break; + } + case EPublic: + { + // check if path relative or absolute + if (filename.FindC(KColon) != KErrNotFound) + { + CSelection* selection = CSelection::NewLC(aType, filename); + iPublicSelections.AppendL(selection); + CleanupStack::Pop(selection); + __LOG3("CDataOwner::HandlePathL(0x%08x) - Added selection: %S [type: %d]", iSecureId.iId, &filename, aType); + } + else + { + __LOG3("CDataOwner::HandlePathL(0x%08x) - Not an Absolute Path: %S [type: %d]", iSecureId.iId, &filename, aType); + return; + } + break; + } + } // switch + } // if + else + { + __LOG1("CDataOwner::HandlePathL(0x%08x) - Path attribute error", iSecureId.iId); + } // else + } + + + CSnapshotHolder* CSnapshotHolder::NewL() + /** Symbain OS constructor + + @return a CSnapshotHolder object + */ + { + CSnapshotHolder* self = NewLC(); + CleanupStack::Pop(self); + + return self; + } + + CSnapshotHolder* CSnapshotHolder::NewLC() + /** Symbain OS constructor + + @return a CSnapshotHolder object + */ + { + CSnapshotHolder* self = new(ELeave) CSnapshotHolder(); + CleanupStack::PushL(self); + + return self; + } + + CSnapshotHolder::CSnapshotHolder() + /** Default C++ Constructor + */ + { + } + + CSnapshotHolder::~CSnapshotHolder() + /** Default C++ Constructor + */ + { + iSnapshots.ResetAndDestroy(); + } + + + } // namespace conn + +