// 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 CPackageDataTransfer
//
//
/**
@file
*/
#include "sbedataowner.h"
#include "sbebufferhandler.h"
#include "sbpackagedatatransfer.h"
#include "sblog.h"
#include <babackup.h>
#include <swi/backuprestore.h>
#include <swi/sisregistryentry.h>
#include <swi/sisregistrypackage.h>
#include "sbeparserdefs.h"
namespace conn
{
_LIT(KSys, "?:\\sys\\*");
_LIT(KResource, "?:\\resource\\*");
_LIT(KPrivateMatch, "?:\\private\\*");
_LIT(KImport, "*\\import\\*");
_LIT(KTempPath, ":\\system\\temp\\");
CPackageDataTransfer* CPackageDataTransfer::NewL(TUid aPid, CDataOwnerManager* aDOM)
/** Standard Symbian Constructor
@param aPid Package Id
@return a CPackageDataTransfer object
*/
{
CPackageDataTransfer* self = CPackageDataTransfer::NewLC(aPid, aDOM);
CleanupStack::Pop(self);
return self;
}
CPackageDataTransfer* CPackageDataTransfer::NewLC(TUid aPid, CDataOwnerManager* aDOM)
/** Standard Symbian Constructor
@param aPid Package Id
@return a CPackageDataTransfer object
*/
{
CPackageDataTransfer *self = new(ELeave) CPackageDataTransfer(aPid, aDOM);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CPackageDataTransfer::CPackageDataTransfer(TUid aPid, CDataOwnerManager* aDOM) :
/** Standard C++ Constructor
@param aPid Package Id
*/
iBufferSnapshotReader(NULL),
iBufferFileWriter(NULL), iBufferSnapshotWriter(NULL),
iPackageID(aPid), iSnapshot(NULL), iMetaData(NULL), ipDataOwnerManager(aDOM), iRestored(EFalse)
{
// needed for intiliazion
iDriveList.SetLength(KMaxDrives);
iDriveList.FillZ();
// needed for hashes in registry on drive C (i.e. MMC card app's hash)
iDriveList[EDriveC] = ETrue;
}
void CPackageDataTransfer::ConstructL()
/** Standard Symbian second phase constructor
*/
{
User::LeaveIfError(iSWIRestore.Connect());
User::LeaveIfError(iSWIBackup.Connect());
User::LeaveIfError(iFs.Connect());
User::LeaveIfError(iFs.ShareProtected());
iRegistrationFile = HBufC::NewL(0);
iFileName = HBufC::NewL(KMaxFileName);
iTempFileName = HBufC::NewL(KMaxFileName);
}
CPackageDataTransfer::~CPackageDataTransfer()
/** Standard C++ Destructor
*/
{
iSWIRestore.Close();
iSWIBackup.Close();
iFileHandle.Close();
iFiles.ResetAndDestroy();
iPublicSelections.ResetAndDestroy();
delete iRegistrationFile;
delete iBufferFileWriter;
delete iBufferSnapshotReader;
delete iBufferSnapshotWriter;
delete iSnapshot;
delete iMetaData;
delete iFileName;
delete iTempFileName;
iFs.Close();
}
void CPackageDataTransfer::WriteData(TAny* aItem, TPtr8& aBuffer,
TInt aSize)
/** Used to write data to a buffer
@param aItem Item to write
@param aBuffer Buffer to write aItem to
@param aSize Size of the aItem
*/
{
TUint8 *pos = reinterpret_cast<TUint8*>(aItem);
for (TInt i = 0; i < aSize; ++i)
{
aBuffer.Append(pos[i]);
}
}
TUid CPackageDataTransfer::PackageId() const
/** Returns the package Id
@return the package Id
*/
{
return iPackageID;
}
void CPackageDataTransfer::BuildPackageFileList()
/** Builds the file list of all files in the package on the given drive
@param aDriveNumber drive the files must be on to be included in the list
@param apSnapshot (OPTIONAL)A file will only be included if the file is not
in the snapshot is newer than the file in the snapshot
@param aFileNames on return the list of files
*/
{
__LOG("CPackageDataTransfer::BuildPackageFileListL() - START");
// Establish a connection to the registry and read the list of
// filenames into array.
//
iDriveList.SetLength(KMaxDrives);
iDriveList.FillZ();
// also set EDriveC to True for hashesh of the registry
iDriveList[EDriveC] = ETrue;
TUint count = iFiles.Count();
__LOG1("CPackageDataTransfer::BuildPackageFileListL() - No of files: %d", count);
while (count > 0)
{
count--;
TBool remove = EFalse;
TFileName fileName (*iFiles[count]);
if ((fileName.FindC(KPrimaryBackupRegistrationFile) < 0) &&
(fileName.MatchC(KSys) < 0) &&
(fileName.MatchC(KResource) < 0) &&
(fileName.MatchC(KImport) < 0 ))
{
remove = ETrue;
}
// check read only media
if (!remove && (NULL != iFs.IsFileInRom(fileName)))
{
remove = ETrue;
}
// check if real entry
if (!remove)
{
TEntry entry;
TInt err = iFs.Entry(fileName, entry);
if (err != KErrNone)
{
remove = ETrue;
}
}
// remove?
if (remove)
{
delete iFiles[count];
iFiles[count] = NULL;
iFiles.Remove(count);
}
else
{
// append to drive list
TInt num;
TChar ch = fileName[0];
TInt err = iFs.CharToDrive(ch, num);
if (err == KErrNone)
{
iDriveList[num] = ETrue;
}
}
} // for
#ifdef SBE_LOGGING_ENABLED
const TUint fNameCount = iFiles.Count();
if (fNameCount)
{
for(TUint k=0; k<fNameCount; k++)
{
const TDesC& file = *iFiles[k];
__LOG2("CPackageDataTransfer::BuildPackageFileListL() - Files Added - file entry[%03d] %S", k, &file);
}
}
#endif
__LOG("CPackageDataTransfer::BuildPackageFileListL() - END");
}
void CPackageDataTransfer::GetExpectedDataSizeL(TPackageDataType aTransferType, TDriveNumber aDriveNumber, TUint& aSize)
/** Get the expected data size of a request for data
@param aTransferType the type of data to check the size of
@param aDriveNumber the drive to check
@param aSize on return the size of the data
*/
{
__LOG("CPackageDataTransfer::GetExpectedDataSizeL - Begin getmetadata");
if (iMetaData == NULL)
{
TRAPD(err, iMetaData = iSWIBackup.GetMetaDataL(iPackageID, iFiles));
if(KErrNotSupported == err)
{//Non-Removable package, nothing to backup
aSize = 0;
__LOG("CPackageDataTransfer::GetExpectedDataSizeL - GetMetaDataL - KErrNotSupported");
return;
}
else if(KErrNone != err)
{
__LOG1("CPackageDataTransfer::GetExpectedDataSizeL - GetMetaDataL leave with %d", err);
User::Leave(err);
}
iMetaDataSize = iMetaData->Size();
BuildPackageFileList();
}
__LOG("CPackageDataTransfer::GetExpectedDataSizeL - End getmetadata");
if (!IsDataOnDrive(aDriveNumber))
{
// no data on drive
aSize = 0;
return;
}
aSize = iMetaData->Size();
TUint count = iFiles.Count();
switch (aTransferType)
{
case ESystemSnapshotData:
{
__LOG1("CPackageDataTransfer::GetExpectedDataSizeL() - START - ESystemSnapshotData - aDriveNumber: %c", aDriveNumber + 'A');
// Find all files
aSize = (count * sizeof(TSnapshot));
__LOG1("CPackageDataTransfer::GetExpectedDataSizeL() - passive snapshot count: %d", count);
for (TUint x = 0; x < count; x++)
{
const TDesC& fileName = *iFiles[x];
const TInt fileSize = fileName.Length();;
__LOG2("CPackageDataTransfer::GetExpectedDataSizeL() - passive snapshot file: %S, size: %d", &fileName, fileSize);
aSize += fileSize;
} // for x
break;
}
case ESystemData:
{
__LOG1("CPackageDataTransfer::GetExpectedDataSizeL() - START - ESystemData - aDriveNumber: %c", aDriveNumber + 'A');
aSize += sizeof(TInt);
TEntry entry;
__LOG1("CPackageDataTransfer::GetExpectedDataSizeL() - passive file count: %d", count);
for (TUint x = 0; x < count; x++)
{
const TDesC& fileName = *iFiles[x];
TInt err = iFs.Entry(fileName, entry);
TUint fileSize = entry.iSize;
__LOG2("CPackageDataTransfer::GetExpectedDataSizeL() - passive file: %S, size: %d", &fileName, fileSize);
switch(err)
{
case KErrNone:
aSize += fileSize;
break;
case KErrNotFound:
case KErrPathNotFound:
case KErrBadName:
__LOG2("CPackageDataTransfer::GetExpectedDataSizeL() - error getting passive file: %S, error: %d", &fileName, err);
break;
default:
User::Leave(err);
}
}
break;
}
default:
{
__LOG2("CPackageDataTransfer::GetExpectedDataSizeL() - No case for TransferType: %d, data owner 0x%08x", aTransferType, iPackageID.iUid);
User::Leave(KErrNotSupported);
}
} // switch
__LOG2("CPackageDataTransfer::GetExpectedDataSizeL() - END - size is: %d, data owner 0x%08x", aSize, iPackageID.iUid);
}
void CPackageDataTransfer::RequestDataL(TDriveNumber aDriveNumber,
TPackageDataType aTransferType,
TPtr8& aBuffer,
TBool& aLastSection)
/** Request data
@param aDriveNumber the drive you want data from
@param aTransferType the type of data you require
@param aBuffer the buffer to write the data
@param aLastSection has all the data been supplied. If all data is not
supplied a further calls to the function will return the extra
data.
*/
{
__LOG6("CPackageDataTransfer::RequestDataL() - START - aDrive: %c, aTransferType: %d, iSecureId: 0x%08x, iState.iState: %d, iState.iTransferType: %d, aBuffer.Length(): %d", aDriveNumber + 'A', aTransferType, iPackageID.iUid, iState.iState, iState.iTransferType, aBuffer.Length());
//__LOGDATA("CPackageDataTransfer::RequestDataL() - %S", aBuffer.Ptr(), aBuffer.Length() );
TInt err = KErrNone;
if (iMetaData == NULL)
{
TRAPD(err, iMetaData = iSWIBackup.GetMetaDataL(iPackageID, iFiles));
if(KErrNotSupported == err)
{//Non-Removable package, nothing to backup
iState.iState = ENone;
aLastSection = ETrue;
Cleanup();
return;
}
else if(KErrNone != err)
{
iState.iState = ENone;
aLastSection = ETrue;
Cleanup();
User::Leave(err);
}
iMetaDataSize = iMetaData->Size();
BuildPackageFileList();
}
// Check our state
if (!((iState.iState == ENone) || (iState.iState == EBuffer) ||
((iState.iState == ERequest) && (iState.iDriveNumber == aDriveNumber) &&
(iState.iTransferType == aTransferType))))
{
__LOG("CPackageDataTransfer::RequestDataL() - bad state => ERROR => KErrNotReady");
User::Leave(KErrNotReady);
}
// Set the state?
if (iState.iState == ENone)
{
iState.iDriveNumber = aDriveNumber;
iState.iTransferType = aTransferType;
}
switch (aTransferType)
{
case ESystemSnapshotData:
{
TRAP(err, RequestSnapshotL(aDriveNumber, aBuffer, aLastSection));
break;
}
case ESystemData:
{
TRAP(err, DoRequestDataL(aDriveNumber, aBuffer, aLastSection));
break;
}
default:
{
err = KErrNotSupported;
}
} // switch
if (err != KErrNone)
{
iState.iState = ENone;
Cleanup();
__LOG1("CPackageDataTransfer::RequestDataL() - Left with error: %d", err);
User::Leave(err);
} // if
__LOG("CPackageDataTransfer::RequestDataL() - END");
}
void CPackageDataTransfer::ReadData(TAny* aDestinationAddress, const TDesC8& aBuffer, TInt aSize)
/** Read data from the given buffer
@param aItem the item to fill
@param aBuffer the buffer to read the data from
@param aSize the size of the item to fill
*/
{
TUint8* pos = reinterpret_cast<TUint8*>(aDestinationAddress);
for (TInt i = 0; i < aSize; ++i)
{
pos[i] = aBuffer[i];
}
}
void CPackageDataTransfer::SupplyFileDataL( const TDesC8& aBuffer, TBool aLastSection)
/** Restores files from the buffer to the package.
@param aBuffer the buffer to read data from
@param aLastSection has all data been supplied
*/
{
__LOG1("CPackageDataTransfer::SupplyFileDataL() - START - aLastSection: %d", aLastSection);
TUint8* current = const_cast<TUint8*>(aBuffer.Ptr());
const TUint8* end = current + aBuffer.Size();
while (current < end)
{
if (!iFixedHeaderRead)
{
if (ReadFromBufferF(iFixedHeader, current, end) == EFalse)
{
__LOG("CPackageDataTransfer::SupplyFileDataL() - ReadFromBufferF() returned False so breaking!");
break;
} // if
__LOG1("CPackageDataTransfer::SupplyFileDataL() - fixed header - iFileNameLength: %d", iFixedHeader.iFileNameLength);
__LOG1("CPackageDataTransfer::SupplyFileDataL() - fixed header - iFileSize: %d", iFixedHeader.iFileSize);
__LOG1("CPackageDataTransfer::SupplyFileDataL() - fixed header - iAttributes: %d", iFixedHeader.iAttributes);
if ((iFixedHeader.iFileNameLength > KMaxFileName) || (!iFixedHeader.iFileNameLength))
{
__LOG1("CBufferFileReader::SupplyFileDataL() - Leaving - iFileNameLength: %d more then MaxLength", iFixedHeader.iFileNameLength);
User::Leave(KErrOverflow);
}
iFixedHeaderRead = ETrue;
} //if
if (!iFileNameRead)
{
TPtr8 ptr(reinterpret_cast<TUint8*>(const_cast<TUint16*>(iFileName->Des().Ptr())), iBytesRead,iFixedHeader.iFileNameLength * KCharWidthInBytes);
if (ReadFromBufferV(ptr, iFixedHeader.iFileNameLength * KCharWidthInBytes, current, end) == EFalse)
{
iBytesRead = ptr.Size();
__LOG1("CPackageDataTransfer::SupplyFileDataL() - ReadFromBufferV() returned False - Filename bytes read: %d", iBytesRead);
break;
} // if
if (iFixedHeader.iFileNameLength > KMaxFileName)
{
__LOG("CBufferFileReader::SupplyFileDataL() - Leave with KErrOverflow");
User::Leave(KErrOverflow);
}
iFileName->Des().SetLength(iFixedHeader.iFileNameLength);
iFileNameRead = ETrue;
__LOG1("CPackageDataTransfer::SupplyFileDataL() - FileName: %S", iFileName);
}
if (!iFileOpen)
{
TFileName tempPath;
// 0 is first character which will reperesent a drive
tempPath.Append((*iFileName)[0]);
tempPath.Append(KTempPath);
// Create file on the drive
TInt tempErr = iFs.MkDirAll(tempPath);
if (tempErr == KErrNone || tempErr == KErrAlreadyExists)
{
TFileName tempFile;
tempErr = iFileHandle.Temp(iFs, tempPath, tempFile, EFileWrite);
if (iTempFileName)
{
delete iTempFileName;
}
iTempFileName = tempFile.AllocL();
}
if (tempErr != KErrNone)
{
__LOG2("CPackageDataTransfer::SupplyFileDataL() - Left creating temp file in: %S , with %d", &tempPath, tempErr);
User::Leave(tempErr);
}
iFileOpen = ETrue;
}
// Write to the file
TInt filesize;
iFileHandle.Size(filesize);
if ((end - current) >= (iFixedHeader.iFileSize - filesize))
{
TPtr8 ptr(current, iFixedHeader.iFileSize - filesize, iFixedHeader.iFileSize - filesize);
User::LeaveIfError(iFileHandle.Write(ptr));
// Write the attributes & modified time
User::LeaveIfError(iFileHandle.Set(iFixedHeader.iModified, iFixedHeader.iAttributes, KEntryAttNormal));
TInt err = KErrNone;
if (((*iFileName).FindC(KPrimaryBackupRegistrationFile) >= 0) ||
((*iFileName).MatchC(KSys) >= 0) ||
((*iFileName).MatchC(KResource) >= 0) ||
((*iFileName).MatchC(KImport) >= 0) )
{
__LOG("CPackageDataTransfer::SupplyFileDataL() - about to call RestoreFileL()");
TRAP(err, iSWIRestore.RestoreFileL(iFileHandle, *iFileName));
__LOG1("CPackageDataTransfer::SupplyFileDataL() - RestoreFileL() - err :%d", err);
}
else if ((*iFileName).MatchC(KPrivateMatch) >= 0)
{
User::LeaveIfError(iFs.MkDirAll((*iFileName)));
User::LeaveIfError(iFileHandle.Rename((*iFileName)));
}
// Finished reset state
iFileHandle.Close();
// Delete temp file
if (iTempFileName)
{
// don't care if there is error
iFs.Delete(*iTempFileName);
delete iTempFileName;
iTempFileName = NULL;
}
iFileOpen = EFalse;
iFileNameRead = EFalse;
iFileName->Des().SetLength(0);
iFixedHeaderRead = EFalse;
iBytesRead = 0;
// Move current along
current += iFixedHeader.iFileSize - filesize;
}
else
{
TInt fsize = end - current;
TPtr8 ptr(current, fsize, fsize);
User::LeaveIfError(iFileHandle.Write(ptr));
break;
}
} // while
if (aLastSection && iFileOpen)
{
User::Leave(KErrUnderflow);
} // if
__LOG("CPackageDataTransfer::SupplyFileDataL() - END");
} // SupplyFileDataL
void CPackageDataTransfer::SupplyDataL(TDriveNumber aDriveNumber,
TPackageDataType aTransferType,
TDesC8& aBuffer,
TBool aLastSection)
/** Request data
@param aDriveNumber the drive you want data from
@param aTransferType the type of data you require
@param aBuffer the buffer to write the data
@param aLastSection is this the last section
*/
{
__LOG5("CPackageDataTransfer::SupplyDataL() - START - aDrive: %c, aTransferType: %d, iSecureId: 0x%08x, iState.iState: %d, iState.iTransferType: %d", aDriveNumber + 'A', aTransferType, iPackageID.iUid, iState.iState, iState.iTransferType);
if (!iRestored)
{
TInt err = KErrNone;
if (!((iState.iState == ENone) ||
((iState.iState == ESupply || iState.iState == EBuffer) && (iState.iDriveNumber == aDriveNumber) &&
(iState.iTransferType == aTransferType))))
{
__LOG("CPackageDataTransfer::SupplyDataL() - bad state => ERROR => KErrNotReady");
User::Leave(KErrNotReady);
}
// Set the state?
if (iState.iState == ENone)
{
iState.iDriveNumber = aDriveNumber;
iState.iTransferType = aTransferType;
} // if
switch (aTransferType)
{
case ESystemSnapshotData:
{
TRAP(err, SupplySnapshotL(aDriveNumber, aBuffer, aLastSection));
break;
}
case ESystemData:
{
TRAP(err, DoSupplyDataL(aDriveNumber, aBuffer, aLastSection));
break;
}
default:
{
err = KErrNotSupported;
}
} // switch
if (err != KErrNone) // Must reset state on error
{
iState.iState = ENone;
if (err != KErrAlreadyExists)
{
Cleanup();
iSWIRestore.Close();
User::LeaveIfError(iSWIRestore.Connect());
}
__LOG1("CPackageDataTransfer::SupplyDataL() - Left with error: %d", err);
User::Leave(err);
} //else
}
__LOG("CPackageDataTransfer::SupplyDataL() - END");
}
void CPackageDataTransfer::DoSupplyDataL(TDriveNumber /*aDriveNumber*/, const TDesC8& aBuffer, TBool aLastSection)
/** Handles the actual supply of package data
@param aDriveNumber not used.
@param aBuffer the data that was supplied
@param aLastSection was this the last section of data
*/
{
__LOG3("CPackageDataTransfer::DoSupplyDataL() - START - aBuffer length: %d, aLastSection: %d, iState: %d", aBuffer.Length(), aLastSection, iState.iState);
//__LOGDATA("CPackageDataTransfer::DoSupplyDataL() - %S", aBuffer.Ptr(), Min( aBuffer.Length(), 1024 ));
TInt currentPos = 0;
const TInt sourceBufferLength = aBuffer.Length();
if ( iState.iState != ESupply )
{
if (iState.iState == ENone )
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - iState == ENone - set up for initial meta data read...");
// Retrieve metadata and file list from the buffer
ReadData(&iMetaDataSize, aBuffer, sizeof(TInt));
__LOG1("CPackageDataTransfer::DoSupplyDataL() - meta data size: %d", iMetaDataSize);
currentPos += sizeof(TInt);
if (iMetaDataSize >= (KMaxTInt/2) || iMetaDataSize < 0)
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - size read is too big");
User::Leave(KErrCorrupt);
}
__LOG1("CPackageDataTransfer::DoSupplyDataL() - creating meta data buffer of length: %d bytes", iMetaDataSize);
HBufC8* metaDataBuffer = HBufC8::NewL(iMetaDataSize);
delete iMetaData;
iMetaData = metaDataBuffer;
TPtr8 data(iMetaData->Des());
if (iMetaDataSize > sourceBufferLength )
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - not enough source data to obtain entire meta data in one pass...");
if (aLastSection)
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - Underflow1");
User::Leave(KErrUnderflow);
}
else
{
data.Append(aBuffer.Mid(currentPos));
iState.iState = EBuffer;
__LOG2("CPackageDataTransfer::DoSupplyDataL() - got %d bytes of meta data (%d bytes remaining) => changing state to EBuffer", data.Length(), iMetaDataSize - data.Length() );
}
}
else
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - able to read entire meta data buffer in a single pass... ");
data.Append(aBuffer.Mid(currentPos, iMetaDataSize));
currentPos += iMetaDataSize;
}
}
else if (iState.iState == EBuffer)
{
__LOG1("CPackageDataTransfer::DoSupplyDataL() - iState == EBuffer, iMetaData length: %d", iMetaData->Length());
TPtr8 ptr( iMetaData->Des() );
const TInt leftToRead = iMetaDataSize - ptr.Length();
__LOG1("CPackageDataTransfer::DoSupplyDataL() - meta data buffer left to read: %d", leftToRead);
if (sourceBufferLength < leftToRead)
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - not enough source data to obtain remaining required meta data in this pass...");
if (aLastSection)
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - Underflow2");
User::Leave(KErrUnderflow);
}
ptr.Append(aBuffer);
__LOG1("CPackageDataTransfer::DoSupplyDataL() - meta data buffered again: %d", ptr.Length());
iState.iState = EBuffer;
return;
}
else
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - able to complete meta data read in this pass...");
ptr.Append( aBuffer.Left(leftToRead) );
__LOG1("CPackageDataTransfer::DoSupplyDataL() - meta data finished buffering, meta data size is now: %d", ptr.Length());
currentPos += leftToRead;
}
}
const TBool metaDataComplete = ( iMetaData->Length() == iMetaDataSize );
__LOG4("CPackageDataTransfer::DoSupplyDataL() - meta data complete?: %d ( %d bytes remaining out of total: %d with current length of: %d)", metaDataComplete, iMetaDataSize - iMetaData->Length(), iMetaDataSize, iMetaData->Length() );
if ( metaDataComplete )
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - Asking SWI to start a package...");
iState.iState = ESupply;
iSWIRestore.StartPackageL(iPackageID, *iMetaData);
__LOG("CPackageDataTransfer::DoSupplyDataL() - SWI StartPackageL() completed OK");
}
}
if ( iState.iState == ESupply )
{
__LOG1("CPackageDataTransfer::DoSupplyDataL() - iState == ESupply, currentPos: %d", currentPos);
// Now restore each file and commit the changes
const TPtrC8 ptr( aBuffer.Mid( currentPos ) );
//__LOGDATA("CPackageDataTransfer::DoSupplyDataL() - for supplyFileData %S", ptr.Ptr(), Min( ptr.Length(), 1024 ));
SupplyFileDataL(ptr, aLastSection);
__LOG("CPackageDataTransfer::DoSupplyDataL() - SupplyFileDataL() completed OK");
if (aLastSection)
{
__LOG("CPackageDataTransfer::DoSupplyDataL() - aLastSection - asking SWI to commit package...");
// now we can finalise the restore
iSWIRestore.CommitPackageL();
__LOG("CPackageDataTransfer::DoSupplyDataL() - Package commited OK");
iRestored = ETrue;
iState.iState = ENone;
Cleanup();
iSWIRestore.Close();
User::LeaveIfError(iSWIRestore.Connect());
}
}
__LOG("CPackageDataTransfer::DoSupplyDataL() - END");
} // SupplyDataL
void CPackageDataTransfer::SupplySnapshotL(TDriveNumber aDriveNumber, const TDesC8& aBuffer, TBool aLastSection)
/** Handles the actual supply of snapshot data
@param aDriveNumber the drive the snapshot is for
@param aBuffer the data that was supplied
@param aLastSection was this the last section of data
*/
{
__LOG("CPackageDataTransfer::SupplySnapshotL() - START");
TInt err = KErrNone;
if (iBufferSnapshotReader == NULL)
{
CSnapshotHolder* snapshot = CSnapshotHolder::NewL();
delete iSnapshot;
iSnapshot = snapshot;
iSnapshot->iDriveNumber = aDriveNumber;
iBufferSnapshotReader = CBufferSnapshotReader::NewL(iSnapshot->iSnapshots);
TRAP(err, iBufferSnapshotReader->StartL(aBuffer, aLastSection));
} // if
else
{
TRAP(err, iBufferSnapshotReader->ContinueL(aBuffer, aLastSection));
}
if ((err != KErrNone) || aLastSection)
{
delete iBufferSnapshotReader;
iBufferSnapshotReader = NULL;
User::LeaveIfError(err);
} // if
__LOG("CPackageDataTransfer::SupplySnapshotL() - END");
}
void CPackageDataTransfer::DoRequestDataL(TDriveNumber aDriveNumber, TPtr8& aBuffer, TBool& aLastSection)
/** Handles the actual request for package data
@param aDriveNumber the drive the data is from
@param aBuffer the buffer to put the supplied data
@param aLastSection has all the data been supplied. If all data is not
supplied a further calls to the function will return the extra
data.
*/
{
__LOG3("CPackageDataTransfer::DoRequestDataL() - START - iState: %d, iMetaData length: %d, iMetaDataSize: %d", iState.iState, iMetaData->Length(), iMetaDataSize);
if (iState.iState == ENone || iState.iState == EBuffer)
{
if (!IsDataOnDrive(aDriveNumber))
{
aLastSection = ETrue;
__LOG("CPackageDataTransfer::DoRequestDataL() - END - no data on drive");
//__LOGDATA("CPackageDataTransfer::DoRequestDataL() - %S", aBuffer.Ptr(), aBuffer.Length());
return;
}
// Now write the meta data to the buffer.
const TInt KSizeOfTInt = sizeof(TInt);
const TInt availableBuffer = aBuffer.MaxSize() - aBuffer.Size();
__LOG1("CPackageDataTransfer::DoRequestDataL() - available Buffer %d", availableBuffer);
if (iState.iState == ENone)
{
if ((availableBuffer - KSizeOfTInt) >= iMetaDataSize)
{
__LOG("CPackageDataTransfer::DoRequestDataL() - iState = ENone - can write entire meta data in single pass...");
WriteData(&iMetaDataSize, aBuffer, KSizeOfTInt);
aBuffer.Append(*iMetaData);
__LOG1("CPackageDataTransfer::DoRequestDataL() - iState = ENone - Written Meta Data, size %d", iMetaDataSize);
}
else if (availableBuffer - KSizeOfTInt > 0)
{
// can we write metasize and something else?
__LOG("CPackageDataTransfer::DoRequestDataL() - iState = ENone - have room for some meta data (not all)...");
WriteData(&iMetaDataSize, aBuffer, KSizeOfTInt);
// Write as much meta data as we can (allowing for buffer size) in this pass.
const TInt amountOfMetaDataToWrite = availableBuffer - KSizeOfTInt;
aBuffer.Append(iMetaData->Left(amountOfMetaDataToWrite));
// need to get rid of KSizeOfTInt
iMetaDataLeft = iMetaDataSize - amountOfMetaDataToWrite;
aLastSection = EFalse;
iState.iState = EBuffer;
__LOG2("CPackageDataTransfer::DoRequestDataL() - END - iState = ENone - Written MetaData %d, left %d", amountOfMetaDataToWrite, iMetaDataLeft);
return;
}
else
{
__LOG("CPackageDataTransfer::DoRequestDataL() - END - iState = ENone - not enough space to write MetaData, Return for more");
return;
}
}// if
else if (iState.iState == EBuffer)
{
if (availableBuffer - iMetaDataLeft >= 0)
{
const TInt readPosition = iMetaDataSize - iMetaDataLeft;
__LOG2("CPackageDataTransfer::DoRequestDataL() - iState = EBuffer - enough space for remaining meta data in this pass, size %d, readPos: %d", iMetaDataLeft, readPosition);
aBuffer.Append(iMetaData->Mid(readPosition));
}
else
{
// continute buffer
const TInt readPosition = iMetaDataSize - iMetaDataLeft;
__LOG2("CPackageDataTransfer::DoRequestDataL() - iState = EBuffer - Still buffering Meta Data, Left to write %d, readPos: %d", iMetaDataLeft, readPosition);
aBuffer.Append(iMetaData->Mid(readPosition, availableBuffer));
iMetaDataLeft -= availableBuffer;
aLastSection = EFalse;
__LOG1("CPackageDataTransfer::DoRequestDataL() - iState = EBuffer - END - Still buffering Meta Data, Left to write %d", iMetaDataLeft);
return;
}
}
TUint count = iFiles.Count();
__LOG1("CPackageDataTransfer::DoRequestDataL() - No of fileNames: %d", count);
if (count == 0)
{
aLastSection = ETrue;
__LOG("CPackageDataTransfer::DoRequestDataL() - END - no files");
return;
}
CDesCArray* files = new (ELeave) CDesCArrayFlat(KDesCArrayGranularity);
CleanupStack::PushL(files);
for (TUint i = 0; i < count; i++)
{
files->AppendL(*iFiles[i]);
}
__LOG("CPackageDataTransfer::DoRequestDataL() - starting buffer file writer...");
CBufferFileWriter* bufferFileWriter = CBufferFileWriter::NewL(iFs, files);
delete iBufferFileWriter;
iBufferFileWriter = bufferFileWriter;
iBufferFileWriter->StartL(aBuffer, aLastSection);
iState.iState = ERequest;
__LOG("CPackageDataTransfer::DoRequestDataL() - iState is now ERequest");
if (aLastSection)
{
delete iBufferFileWriter;
iBufferFileWriter = NULL;
iState.iState = ENone;
} // if
CleanupStack::Pop(files);
}
else if (iBufferFileWriter != NULL)
{
__LOG("CPackageDataTransfer::DoRequestDataL() - continuing buffer file writer from last time...");
iBufferFileWriter->ContinueL(aBuffer, aLastSection);
if (aLastSection)
{
delete iBufferFileWriter;
iBufferFileWriter = NULL;
iState.iState = ENone;
}
}
//__LOGDATA("CPackageDataTransfer::DoRequestDataL() - %S", aBuffer.Ptr(), aBuffer.Length());
__LOG("CPackageDataTransfer::DoRequestDataL() - END");
} // RequestDataL
void CPackageDataTransfer::RequestSnapshotL(TDriveNumber aDriveNumber, TPtr8& aBuffer, TBool& aLastSection)
/** Handles the request for snapshot data
@param aDriveNumber the drive the data is from
@param aBuffer the buffer to put the supplied data
@param aLastSection has all the data been supplied. If all data is not
supplied a further calls to the function will return the extra
data.
*/
{
__LOG("CPackageDataTransfer::RequestSnapshotL() - START");
if (iBufferSnapshotWriter == NULL)
{
if (!IsDataOnDrive(aDriveNumber))
{
aLastSection = ETrue;
return;
}
TUint count = iFiles.Count();
__LOG1("CPackageDataTransfer::RequestSnapshotL() - No of fileNames: %d", count);
if (count > 0)
{
RSnapshots* snapshots = new(ELeave) RSnapshots();
TCleanupItem cleanup(CleanupRPointerArray, snapshots);
CleanupStack::PushL(cleanup);
while (count--)
{
TEntry entry;
const TDesC& fileName = *(iFiles[count]);
TInt err = iFs.Entry(fileName, entry);
if (err != KErrNone)
{
continue;
}
CSnapshot* snapshot = CSnapshot::NewLC(entry.iModified.Int64(), fileName);
snapshots->AppendL(snapshot);
CleanupStack::Pop(snapshot);
}
// Create a buffer writer
// Convert entries into RSnapshots
// ownership transfer
CBufferSnapshotWriter* bufferSnapshotWriter = CBufferSnapshotWriter::NewL(snapshots);
CleanupStack::Pop(snapshots);
delete iBufferSnapshotWriter;
iBufferSnapshotWriter = bufferSnapshotWriter;
iBufferSnapshotWriter->StartL(aBuffer, aLastSection);
} // if
else
{
aLastSection = ETrue;
} // else
} // if
else
{
iBufferSnapshotWriter->ContinueL(aBuffer, aLastSection);
} // else
if (aLastSection)
{
delete iBufferSnapshotWriter;
iBufferSnapshotWriter = NULL;
}
__LOG("CPackageDataTransfer::RequestSnapshotL() - END");
}
/** Cleanup of the internal data
*/
void CPackageDataTransfer::Cleanup()
{
delete iBufferFileWriter;
iBufferFileWriter = NULL;
delete iBufferSnapshotReader;
iBufferSnapshotReader = NULL;
delete iBufferSnapshotWriter;
iBufferSnapshotWriter = NULL;
delete iSnapshot;
iSnapshot = NULL;
delete iMetaData;
iMetaData = NULL;
}
/**
Checks if there is any data on the specified drive
@param aDrive the drive to check on
@return ETrue if there is any data
*/
TBool CPackageDataTransfer::IsDataOnDrive(TDriveNumber aDrive)
{
if (!iDriveList[aDrive])
{
return EFalse;
}
else
{
return ETrue;
}
}
TCommonBURSettings CPackageDataTransfer::CommonSettingsL()
/** Get the common settings of the data owner
@pre CPackageDataTransfer::ParseFilesL() must have been called
@return the common settings of the data owner
@leave KErrNotReady if CPackageDataTransfer::ParseFilesL() not called
*/
{
TCommonBURSettings settings = ENoOptions;
__LOG1("CPackageDataTransfer::CommonSettingsL() - System Supported: %d", iSystemInformation.iSupported);
if (iSystemInformation.iSupported)
{
settings |= EHasSystemFiles;
}
return settings;
}
TPassiveBURSettings CPackageDataTransfer::PassiveSettingsL()
/** Get the passive settings of the data owner
@pre CPackageDataTransfer::ParseFilesL() must have been called
@return the passive settings of the data owner
@leave KErrNotReady if CPackageDataTransfer::ParseFilesL() not called
*/
{
__LOG1("CPackageDataTransfer::CommonSettingsL() - Public Supported: %d", iPublicInformation.iSupported);
TPassiveBURSettings settings = ENoPassiveOptions;
if (iPublicInformation.iSupported)
{
settings |= EHasPublicFiles;
} // if
return settings;
}
TActiveBURSettings CPackageDataTransfer::ActiveSettingsL()
/** Get the active settings of the data owner
@pre CPackageDataTransfer::ParseFilesL() must have been called
@return the active settings of the data owner
@leave KErrNotReady if CPackageDataTransfer::ParseFilesL() not called
*/
{
TActiveBURSettings settings = ENoActiveOptions;
return settings;
}
/** Set the registration file for the package
@param aFileName path including filename of the registration file
*/
void CPackageDataTransfer::SetRegistrationFileL(const TDesC& aFileName)
{
delete iRegistrationFile;
iRegistrationFile = aFileName.AllocL();
}
/** Parses the package registration file
@pre CPackageDataTransfer::SetRegistrationFile() must have been called
*/
void CPackageDataTransfer::ParseL()
{
if ((*iRegistrationFile).FindF(KPrimaryBackupRegistrationFile) == KErrNotFound)
{
User::Leave(KErrNotReady);
}
ipDataOwnerManager->ParserProxy().ParseL(*iRegistrationFile, *this);
}
void CPackageDataTransfer::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(iFs.DriveToChar(aDriveNumber, drive));
const TInt count = iPublicSelections.Count();
for (TInt x = 0; x < count; x++)
{
CSelection* selection = iPublicSelections[x];
TBool include = (selection->SelectionType() == EInclude);
TFileName filename;
const TDesC& selectionName = selection->SelectionName();
// Name
TBool add = false;
if ((selectionName.Length() > 1) && (selectionName[1] == KColon()[0]))
{
// It has a drive specified
TInt drive;
iFs.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 CPackageDataTransfer::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
*/
{
_LIT(KDrive, "?:");
_LIT(KDriveAndSlash, "?:\\");
_LIT( KExclamationAsDrive, "!"); // Used to generic drives for public data as in .SIS file package
// Split selections into include and exclude
RArray<TPtrC> include;
CleanupClosePushL(include);
RArray<TPtrC> exclude;
CleanupClosePushL(exclude);
TInt count = iPublicSelections.Count();
__LOG("CPackageDataTransfer::GetPublicFileListL() - file selection listing...:");
for (TInt x = 0; x < count; x++)
{
const TDesC& selectionName = iPublicSelections[x]->SelectionName();
__LOG3("CPackageDataTransfer::GetPublicFileListL() - selection[%03d]: %S, type: %d", x, &selectionName, iPublicSelections[x]->SelectionType());
if (iPublicSelections[x]->SelectionType() == EInclude)
{
include.AppendL(selectionName);
} // if
else
{
exclude.AppendL(selectionName);
} // else
} // for x
// Loop through all includes
count = include.Count();
__LOG("CPackageDataTransfer::GetPublicFileListL() - include listing...:");
for (TInt x = 0; x < count; x++)
{
TFileName fileName;
TChar drive;
User::LeaveIfError(iFs.DriveToChar(aDriveNumber, drive));
const TPtrC includeEntry( include[x] );
__LOG2("CPackageDataTransfer::GetPublicFileListL() - entry[%03d] is: %S", x, &includeEntry);
// See if the drive is specified
if (include[x][0] == KBackSlash()[0])
{
// Add the drive
fileName.Append(drive);
fileName.Append(KColon);
fileName.Append(include[x]);
}
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 ( includeEntry[0] == KExclamationAsDrive()[0])
{
// Map public data path using current drive being backed up.
fileName.Zero();
fileName.Append(drive);
fileName.Append( includeEntry.Mid(1) );
}
else
if (static_cast<TChar>(includeEntry[0]).GetUpperCase() == drive.GetUpperCase())
{
fileName.Copy(includeEntry);
} // else
} // else
__LOG2("CPackageDataTransfer::GetPublicFileListL() - 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("CPackageDataTransfer::GetPublicFileListL() - filename is a drive");
} // if
TEntry entry;
TBool isEntry = EFalse;
if (!isDrive)
{
TInt err = iFs.Entry(fileName, entry);
__LOG1("CPackageDataTransfer::GetPublicFileListL() - 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("CPackageDataTransfer::GetPublicFileListL() - parsing directory...");
ParseDirL(fileName, exclude, aFiles);
#ifdef SBE_LOGGING_ENABLED
const TInt fNameCount = aFiles.Count();
if (fNameCount)
{
for(TInt k=0; k<fNameCount; k++)
{
const TDesC& fileName = aFiles[k].iName;
__LOG2("CPackageDataTransfer::GetPublicFileListL() - directory entry[%03d] %S", k, &fileName);
}
}
__LOG("CPackageDataTransfer::GetPublicFileListL() - end of parsing directory");
#endif
} // if
else
{
if (isEntry)
{
const TBool isExcluded = IsExcluded(ETrue, fileName, exclude);
if (!isExcluded)
{
__LOG1("CPackageDataTransfer::GetPublicFileListL() - adding fully verified file: %S", &fileName);
// Add to list of files
aFiles.AppendL(entry);
} // if
else
{
__LOG("CPackageDataTransfer::GetPublicFileListL() - file is excluded!");
}
} // if
} // else
} // if
} // for x
CleanupStack::PopAndDestroy(&exclude);
CleanupStack::PopAndDestroy(&include);
__LOG("CPackageDataTransfer::GetPublicFileListL() - END");
}
void CPackageDataTransfer::ParseDirL(const TDesC& aDirName, const RArray<TPtrC>& aExclude, RFileArray& apFileEntries)
/** 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
*/
{
CDir* pFiles = NULL;
// This function requires a / on the end otherwise it does not work!
TFileName path = aDirName;
if (path[path.Length() - 1] != KBackSlash()[0])
path.Append(KBackSlash);
TInt err = iFs.GetDir(path, KEntryAttMatchMask, ESortNone, pFiles);
CleanupStack::PushL(pFiles); // Add to cleanup stack
if ((err != KErrNone) && (err != KErrNotFound)) // Do we need to leave?
{
User::Leave(err);
} // if
TUint count = pFiles->Count();
while(count--)
{
TEntry entry = (*pFiles)[count];
// Build full path
TFileName filename = path;
filename.Append(entry.iName);
entry.iName = filename;
if (!IsExcluded(ETrue, filename, aExclude))
{
if (entry.IsDir())
{
ParseDirL(filename, aExclude, apFileEntries);
} // if
else
{
// Add to list of files
apFileEntries.AppendL(entry);
} // else
} // if
} // for x
// Cleanup
CleanupStack::PopAndDestroy(pFiles);
}
void CPackageDataTransfer::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
*/
{
__LOG1("CPackageDataTransfer::GetDriveListL() - Begin - SID: 0x%08x", iPackageID.iUid);
// 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
// build package files
if (iMetaData == NULL)
{
TRAPD( err, iMetaData = iSWIBackup.GetMetaDataL(iPackageID, iFiles) );
if( err )
{
iMetaData = NULL;
iMetaDataSize = 0;
User::Leave( err );
}
else
{
iMetaDataSize = iMetaData->Size();
BuildPackageFileList();
}
}
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
iDriveList[i] = EFalse;
}
}
aDriveList = iDriveList;
__LOG1("CPackageDataTransfer::GetDriveListL() - end - SID: 0x%08x", iPackageID.iUid);
}
TBool CPackageDataTransfer::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
*/
{
_LIT(KPrivateMatch, "?:\\private\\*");
_LIT(KSystem, "?:\\system\\*");
_LIT(KResource, "?:\\resource\\*");
_LIT(KOther, "*\\..\\*");
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));
}
if (!ret)
{
// Is the file in the exclude list?
const TInt count = aExclude.Count();
for (TInt x = 0; !ret && x < count; x++)
{
if (aExclude[x][0] == KBackSlash()[0])
{
// Compare with out drive
_LIT(KQuestionMark, "?");
TFileName compare = KQuestionMark();
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;
}
/**
Method will be used for Sort on RPointerArray
@param aFirst CPackageDataTransfer& package id to compare
@param aSecond CPackageDataTransfer& package id to compare
@see RArray::Sort()
*/
TInt CPackageDataTransfer::Compare(const CPackageDataTransfer& aFirst, const CPackageDataTransfer& aSecond)
{
if (aFirst.PackageId().iUid < aSecond.PackageId().iUid)
{
return -1;
}
else if (aFirst.PackageId().iUid > aSecond.PackageId().iUid)
{
return 1;
}
else
{
return 0;
}
}
/**
Method will be used for Find on RPointerArray
@param aFirst CPackageDataTransfer& package id to match
@param aSecond CPackageDataTransfer& package id to match
@see RArray::Find()
*/
TBool CPackageDataTransfer::Match(const CPackageDataTransfer& aFirst, const CPackageDataTransfer& aSecond)
{
return (aFirst.PackageId().iUid == aSecond.PackageId().iUid);
}
//
// MContentHandler Implementaion //
//
void CPackageDataTransfer::OnStartDocumentL(const RDocumentParameters& /*aDocParam*/, TInt aErrorCode)
/** MContentHandler::OnStartDocumentL()
*/
{
if (aErrorCode != KErrNone)
{
__LOG1("CPackageDataTransfer::OnStartDocumentL() - error = %d", aErrorCode);
User::Leave(aErrorCode);
}
}
void CPackageDataTransfer::OnEndDocumentL(TInt aErrorCode)
/** MContentHandler::OnEndDocumentL()
*/
{
// just to satisfy UREL compiler
(void) aErrorCode;
__LOG1("CPackageDataTransfer::OnEndDocumentL() - error = %d", aErrorCode);
}
void CPackageDataTransfer::OnStartElementL(const RTagInfo& aElement,
const RAttributeArray& aAttributes,
TInt aErrorCode)
/** MContentHandler::OnStartElementL()
@leave KErrUnknown an unknown element
*/
{
if (aErrorCode != KErrNone)
{
__LOG1("CPackageDataTransfer::OnStartElementL() - error = %d", aErrorCode);
User::Leave(aErrorCode);
}
TPtrC8 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(KPublicBackup))
{
User::LeaveIfError(HandlePublicBackup(aAttributes));
}
else if (!localName.CompareF(KSystemBackup))
{
User::LeaveIfError(HandleSystemBackup(aAttributes));
}
else
{
__LOG1("CPackageDataTransfer::OnStartElementL() - Unknown element while parsing 0x%08x", iPackageID.iUid);
}
}
void CPackageDataTransfer::OnEndElementL(const RTagInfo& aElement, TInt aErrorCode)
/** MContentHandler::OnEndElementL()
*/
{
if (aErrorCode != KErrNone)
{
__LOG1("CPackageDataTransfer::OnEndElementL() - error = %d", aErrorCode);
User::Leave(aErrorCode);
}
TPtrC8 localName = aElement.LocalName().DesC();
if (!localName.CompareF(KPublicBackup))
{
iCurrentElement = ENoElement;
} // if
}
void CPackageDataTransfer::OnContentL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
/** MContentHandler::OnContentL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnStartPrefixMappingL(const RString& /*aPrefix*/,
const RString& /*aUri*/, TInt /*aErrorCode*/)
/** MContentHandler::OnStartPrefixMappingL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/)
/** MContentHandler::OnEndPrefixMappingL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
/** MContentHandler::OnIgnorableWhiteSpaceL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/)
/** MContentHandler::OnSkippedEntityL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnProcessingInstructionL(const TDesC8& /*aTarget*/,
const TDesC8& /*aData*/,
TInt /*aErrorCode*/)
/** MContentHandler::OnProcessingInstructionL()
*/
{
// Not handled
}
void CPackageDataTransfer::OnError(TInt aErrorCode)
/** MContentHandler::OnError()
@leave aErrorCode
*/
{
(void)aErrorCode;
__LOG1("CPackageDataTransfer::OnError() - error = %d", aErrorCode);
}
TAny* CPackageDataTransfer::GetExtendedInterface(const TInt32 /*aUid*/)
/** MContentHandler::OnEndPrefixMappingL()
*/
{
return NULL;
}
void CPackageDataTransfer::HandleBackupRegistrationL(const RAttributeArray& aAttributes)
/** Handles the "backup_registration" element
@param aAttributes the attributes for the element
@return KErrNone no errors
@return KErrUnknown unknown version
*/
{
_LIT8(KVersion, "1.0");
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)", iPackageID.iUid);
User::Leave(KErrNotSupported);
} // else
} // if
}
TInt CPackageDataTransfer::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("CPackageDataTransfer::HandlePublicBackup(0x%08x) - iPublicInformation.iDeleteBeforeRestore: %d", iPackageID.iUid, deleteBeforeRestore);
} // if
iCurrentElement = EPublic;
return KErrNone;
}
TInt CPackageDataTransfer::HandleSystemBackup(const RAttributeArray& /*aAttributes*/)
/** Handles the "system_backup" element
@param aAttributes the attributes for the element
@return KErrNone
*/
{
iSystemInformation.iSupported = ETrue;
__LOG2("CPackageDataTransfer::HandlePublicBackup(0x%08x) - iSystemInformation.iSupported: %d", iPackageID.iUid, iSystemInformation.iSupported);
return KErrNone;
}
void CPackageDataTransfer::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)
{
switch (iCurrentElement)
{
case EPublic:
{
TFileName selectionName;
if (KErrNone == ipDataOwnerManager->ParserProxy().ConvertToUnicodeL(selectionName, aAttributes[0].Value().DesC()))
{
// 2 because we expect drive leter and semicollon
if (selectionName.Length() > 2)
{
// Should we add a backslash
if (aDir &&
(selectionName[selectionName.Length() - 1] != '\\'))
{
selectionName.Append(KBackSlash);
} // if
if (selectionName[1] == ':')
{
CSelection* selection = CSelection::NewLC(aType, selectionName);
iPublicSelections.AppendL(selection);
CleanupStack::Pop(selection);
__LOG3("CPackageDataTransfer::HandlePathL(0x%08x) - Added selection: %S [type: %d]", iPackageID.iUid, &selectionName, aType);
} //if
}// if
else
{
__LOG3("CPackageDataTransfer::HandlePathL(0x%08x) - Wrong format: %S [type: %d]", iPackageID.iUid, &selectionName, aType);
}
} // if
else
{
__LOG1("CPackageDataTransfer::HandlePathL(0x%08x) - EPublic - Could not convert filename", iPackageID.iUid);
} // else
break;
};
default:
{
__LOG1("CPackageDataTransfer::HandlePathL(0x%08x) - Private data is Not Supported", iPackageID.iUid);
}
break;
} // switch
} // if
else
{
__LOG1("CPackageDataTransfer::HandlePathL(0x%08x) - Path attribute error", iPackageID.iUid);
} // else
}
// //
// MContentHandler //
//
} // namespace