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