backupandrestore/backupengine/src/sbpackagedatatransfer.cpp
changeset 0 d0791faffa3f
child 6 ef55b168cedb
--- /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 <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;
+                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<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)
+			{
+			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<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