// 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 <d32dbms.h>
#include "sbedataowner.h"
#include "abserver.h"
#include "sbtypes.h"
#include "sblog.h"
#include "sbeparserdefs.h"
#include "sbepanic.h"
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<CBase>* array = static_cast<RPointerArray<CBase>*>(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<TDriveNumber>(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<iProxyInformationArray.Count();numProxies++)
{
iProxyInformationArray[numProxies].iDataRequested = 0;
iProxyInformationArray[numProxies].iDataSupplied = 0;
iProxyInformationArray[numProxies].iOpInProgress = ETrue;
}
}
__LOG1("CDataOwner::ProcessSupplyDataL() - Supplying active base data of size = %D", aBuffer.Length());
// Restore the proxy data first
TBool currentBufferConsumed = EFalse;
while ( (iCurrentProxy < supportedProxyCount) && (!currentBufferConsumed))
{
__LOG2("CDataOwner::ProcessSupplyDataL() - Proxy Info : Unpacking proxy info %d of %d", iCurrentProxy + 1, supportedProxyCount);
// Unpack the proxy's finished flag, len and sid if we are handling the proxy for the first time
if ( iProxyInformationArray[iCurrentProxy].iDataSupplied == 0)
{
UnpackTypeAdvance(iProxyInformationArray[iCurrentProxy].iOpInProgress, aBuffer, offset);
__LOG1("CDataOwner::ProcessSupplyDataL() - Proxy Info : FinishedFlag = %d", iProxyInformationArray[iCurrentProxy].iOpInProgress);
UnpackTypeAdvance(iProxyInformationArray[iCurrentProxy].iDataRequested, aBuffer, offset);
__LOG1("CDataOwner::ProcessSupplyDataL() - Proxy Info : ProxyDataStreamLength = %d", iProxyInformationArray[iCurrentProxy].iDataRequested);
TSecureId proxySecureId;
UnpackTypeAdvance(proxySecureId, aBuffer, offset);
if ( iProxyInformationArray[iCurrentProxy].iSecureId.iId != proxySecureId.iId )
{
User::Leave(KErrCorrupt);
}
__LOG1("CDataOwner::ProcessSupplyDataL() - Proxy Info : ProxySID = 0x%08x", proxySecureId.iId);
}
// Is no more data coming , either from the buffer manager or from the server
TBool proxyFinished = iProxyInformationArray[iCurrentProxy].iOpInProgress && aLastSection;
TInt dataLengthRemaining = iProxyInformationArray[iCurrentProxy].iDataRequested - iProxyInformationArray[iCurrentProxy].iDataSupplied;
TInt currentBufferLen = 0;
// The data remaining for this proxy is more than data in this buffer
if (dataLengthRemaining >= 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<TUint>(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<TDriveNumber>(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<TInt>(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<TInt>(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; i<KMaxDrives; i++)
{
if (aDriveList[i] != 0)
{
const TDriveUnit driveUnit(i);
const TDriveName name(driveUnit.Name());
drivePrint.Append(name);
if (i < KMaxDrives - 1)
{
drivePrint.Append(_L(", "));
}
}
}
__LOG2("CDataOwner::GetDriveListL() - END - SID: 0x%08x, supports drives: %S", iSecureId.iId, &drivePrint);
#endif
}
void CDataOwner::SetBackedUpAsPartial(TBool aPartial)
/**
Inform's the data owner that upon a partial backup, this DO is to be backed up
*/
{
iBackupAsPartial = aPartial;
}
TBool CDataOwner::PartialAffectsMe() const
/**
Accessor to discover whether or not the sbe client has specified this Data Owner to be backed
up as part of a partial backup
@return ETrue if this data owner has been requested to backup as partial
*/
{
return iBackupAsPartial;
}
void CDataOwner::ParseFileL(const TDesC& aFileName)
/** Parse a given registration file
@param aFileName the registration file to parse
*/
{
__LOG2("CDataOwner::ParseFileL() - START - aFileName: %S, iPrimaryFile: %d", &aFileName, iPrimaryFile);
PrivatePathL(aFileName);
// Parse the file
ipDataOwnerManager->ParserProxy().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<TChar>(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<TPtrC> include;
CleanupClosePushL(include);
RArray<TPtrC> 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<TChar>(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; k<fNameCount; k++)
{
const TDesC& fileName = (*apFileNames)[k];
__LOG2("CDataOwner::BuildFileListL() - directory entry[%03d] %S", k, &fileName);
}
}
__LOG("CDataOwner::BuildFileListL() - end of parsing directory");
#endif
} // if
else
{
if (isEntry)
{
const TBool isExcluded = IsExcluded(aIsPublic, *fileName, exclude);
if (!isExcluded)
{
TInt err = KErrNone;
TBool newer = EFalse;
if (apSnapshots && (aTransferType == EPassiveIncrementalData))
{
TRAP(err, IsNewerL(*fileName, entry, apSnapshots, newer));
} // if
if (!apSnapshots ||
(aTransferType == EPassiveBaseData) ||
newer ||
(err != KErrNone))
{
__LOG1("CDataOwner::BuildFileListL() - adding fully verified file: %S", fileName);
if (apFileEntries)
{
// Add to list of files
apFileEntries->AppendL(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<TPtrC>& 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.
// <public_backup>
// <include_directory name="!:\mydatabases\" />
// </public_backup>
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<TChar>(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<TPtrC>& 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<KSecureIdLength> 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; i<entryCount; i++)
{
const TDesC& snapshot = snapshotHolder->iSnapshots[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<TDriveNumber>(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;
}
}
else if(!localName.CompareF(KCallbackDelayTime))
{
const TDesC8& value = aAttributes[x].Value().DesC();
TInt timeValue = 0;
TLex8 lex(value);
TInt err = lex.Val(timeValue);
if( err == KErrNone && timeValue > 0)
iActiveInformation.iCallbackDelayTime = TTimeIntervalMicroSeconds32(timeValue);
else
iActiveInformation.iCallbackDelayTime = KABCallbackDefaultTimeout;
}
} // 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 <include_dir/> 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