diff -r 000000000000 -r d0791faffa3f backupandrestore/backupengine/src/sbpackagedatatransfer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/backupandrestore/backupengine/src/sbpackagedatatransfer.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,1808 @@ + +// 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 +#include +#include +#include + +#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(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; kSize(); + 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; + Cleanup(); + return; + } + else if(KErrNone != err) + { + iState.iState = ENone; + 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(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(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(const_cast(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(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 include; + CleanupClosePushL(include); + RArray 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. + // + // + // + + 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(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& 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) + { + iMetaData = iSWIBackup.GetMetaDataL(iPackageID, iFiles); + 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& 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 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