backupandrestore/backupengine/src/sbeclientsession.cpp
changeset 0 d0791faffa3f
child 15 f85613f12947
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/backupandrestore/backupengine/src/sbeclientsession.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,879 @@
+// 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 RSBEClientSession class.
+// 
+//
+
+/**
+ @file
+*/
+
+#include "sbeclientsession.h"
+#include "sbeclientserver.h"
+#include <connect/sbtypes.h>
+#include <connect/panic.h>
+
+namespace conn
+	{
+
+	RSBEClientSession* RSBEClientSession::NewL()
+	/** Symbian OS constructor 
+	@return pointer to an instantiated RSBEClientSession object */
+		{
+		RSBEClientSession* self = new (ELeave) RSBEClientSession();
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		CleanupStack::Pop(self);
+		return self;
+		}
+
+	void RSBEClientSession::ConstructL()
+	/** Symbian second phase constructor */
+		{
+        iGSHInterface = CHeapWrapper::NewL();
+		}
+		
+	RSBEClientSession::RSBEClientSession() : iCallbackHandler(NULL)
+	/** Class constructor. */
+		{
+		}
+
+	RSBEClientSession::~RSBEClientSession()
+	/** Class destructor. */
+		{
+		delete iGSHInterface;
+		delete iCallbackHandler;
+		}
+
+	void RSBEClientSession::Close()
+	/** Closes the Secure Backup Engine handle. */
+		{
+		iGlobalSharedHeap.Close();
+		RSessionBase::Close();
+		}
+
+	TInt RSBEClientSession::Connect()
+	/** Connects the handle to the Secure Backup Engine.
+
+	@return KErrNone if successful, KErrCouldNotConnect otherwise
+	*/
+		{
+        TInt nRetry = KSBERetryCount;
+		TInt nRet = KErrNotFound;
+
+		while(nRetry > 0 && nRet != KErrNone)
+			{
+		    const TSecurityPolicy policy(static_cast<TSecureId>(KSBServerUID3));
+			nRet = CreateSession(KSBEServerName, Version(), KSBEASyncMessageSlots, EIpcSession_Unsharable,&policy);
+			if(nRet == KErrNotFound || nRet == KErrServerTerminated)
+				{
+				StartServer();
+				}
+			nRetry--;
+			}
+			
+		// If we were succesful, then get a handle to the server created and owned GSH
+		if (nRet == KErrNone)
+			{
+			nRet = GetGlobalSharedHeapHandle();
+			}
+
+		return nRet;
+		}
+
+	TVersion RSBEClientSession::Version() const
+	/** Returns the version of this API
+
+	@return The version of this API
+	*/
+		{
+	    return TVersion (KSBEMajorVersionNumber,
+							KSBEMinorVersionNumber,
+							KSBEBuildVersionNumber);
+	  	}
+
+	//
+	// Server startup code
+	TInt RSBEClientSession::StartServer()
+	/** Start the server as a thread on WINS or a process on ARM.
+	
+	Called by Connect when the kernel is unable to create a session
+	with the SBE server (as its not running).
+
+	@return Standard Symbian OS code from RProcess/RThread create.
+	*/
+		{
+        //
+		// Servers UID
+		const TUidType serverUid(KNullUid, KNullUid, KSBServerUID3);
+		
+	
+		RProcess server;
+    	TInt nRet=server.Create(KSBImageName,KNullDesC,serverUid);
+    	if (nRet != KErrNone)
+    	    {
+    		return nRet;
+    		}
+    		
+    	TRequestStatus stat;
+    	server.Rendezvous(stat);
+    	if (stat != KRequestPending)
+    		{
+    		server.Kill(0);
+    		}
+    	else
+    		{
+    		server.Resume();
+    		}
+    	User::WaitForRequest(stat);
+    	return (server.ExitType() == EExitPanic) ? KErrGeneral : stat.Int();
+		
+		}
+
+
+	void RSBEClientSession::ListOfDataOwnersL(RPointerArray<CDataOwnerInfo>& aDataOwners)
+	/**
+	Return the list of private data owners on the device that have backup registration files.
+	If a leave does occur, then aDataOwners
+	
+	@param aDataOwners Pointer array holding the list of Data owners requiring backup functionality.
+			Any items present in this array will be lost
+	*/
+		{
+		// Get the server to construct the flattened array and return the size of it		
+		TInt result = SendReceive(ESBEMsgPrepDataOwnerInfo);
+		
+		User::LeaveIfError(result);
+		
+		iDataOwnersArray = &aDataOwners;
+		
+		PopulateListOfDataOwnersL(result);
+		}
+		
+	void RSBEClientSession::PublicFileListL(TDriveNumber aDrive, CSBGenericDataType& aGenericDataType, 
+												RFileArray& aFiles)
+	/**
+	Get the list of public files to backup for a particular Data Owner on a particular drive
+	
+	@param aDrive The drive that the public files exist on
+	@param aGenericDataType Reference to the generic data type that is being passed to the SBEngine.
+	@param aFiles An empty array of file information that will be filled with details of the public files
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+		// request the public file list
+		TInt result = SendReceive(ESBEMsgPrepPublicFiles, TIpcArgs(aDrive, 
+						&(aGenericDataType.Externalise())));
+		
+		User::LeaveIfError(result);
+
+		iFileArray = &aFiles;
+		
+		PopulatePublicFileListL(result);
+		}
+		
+	void RSBEClientSession::RawPublicFileListL(	TDriveNumber aDrive, 
+												CSBGenericDataType& aGenericDataType, 
+												RRestoreFileFilterArray& aFileFilter)
+	/**
+	Get the list of public files to backup for a particular Data Owner on a particular drive for 
+	a partial restore
+	
+	@param aDrive The drive that the public files exist on
+	@param aGenericDataType Reference to the generic data type that is passed to the SBEngine.
+	@param aFileFilter Empty array that will be filled with the files/directories to be backed up 
+	on return
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        // ensure that the array is cleared out before populating with externalised data
+		aFileFilter.Reset();
+		
+		TPckgC<TDriveNumber> drive(aDrive);
+
+		// request the public file list
+		TInt result = SendReceive(ESBEMsgPrepPublicFilesRaw, TIpcArgs(&drive, 
+				&(aGenericDataType.Externalise())));
+		
+		User::LeaveIfError(result);
+
+		// Create a descriptor big enough for the array to be externalised into
+		HBufC8* pFileArray = HBufC8::NewL(result);
+		CleanupStack::PushL(pFileArray);
+		
+		TPtr8 fileArray(pFileArray->Des());
+		User::LeaveIfError(SendReceive(ESBEMsgGetPublicFilesRaw, TIpcArgs(&fileArray)));
+		
+		RRestoreFileFilterArray* pFileFilter = RRestoreFileFilterArray::InternaliseL(fileArray);
+		CleanupStack::PushL(pFileFilter);
+		CleanupClosePushL(*pFileFilter);
+		
+		TInt count = pFileFilter->Count();
+		for (TInt x = 0; x < count; x++)
+			{
+				aFileFilter.AppendL((*pFileFilter)[x]);
+			} // for x
+
+		CleanupStack::PopAndDestroy(pFileFilter); // CleanupClosePushL(*pFileFilter)
+		CleanupStack::PopAndDestroy(pFileFilter); // CleanupStack::PushL(pFileFilter)
+		CleanupStack::PopAndDestroy(pFileArray);
+		}
+	
+	void RSBEClientSession::PublicFileListXMLL(TDriveNumber aDrive, TSecureId aSID, HBufC*& aFileList)
+	/**
+	Get the list of public files in XML format
+
+	@param aDrive The drive to get the list for
+	@param aSID The SID of the data owner to get the public files for
+	@param aFileList The descriptor to populate on return should be NULL
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        TPckgC<TDriveNumber> drive(aDrive);
+		TPckgC<TSecureId> sid(aSID);
+
+		// request the public file list
+		TInt result = SendReceive(ESBEMsgPrepPublicFilesXML, TIpcArgs(&drive, &sid));
+		
+		User::LeaveIfError(result);
+
+		// Create a descriptor big enough for the array to be externalised into
+		aFileList = HBufC::NewL(result);
+	
+		TPtr fileList(aFileList->Des());
+		User::LeaveIfError(SendReceive(ESBEMsgPrepPublicFilesXML, TIpcArgs(&fileList)));
+		}
+	
+	void RSBEClientSession::SetBURModeL(const TDriveList& aDriveList, TBURPartType aBURType, 
+						  TBackupIncType aBackupIncType)
+	/**
+	Set the Backup and Restore mode on/off and configure the BUR options
+	
+	@param aDriveList Array of drives that are to be backed up during the operations
+	@param aBURType Set the device into Full/Partial BUR or normal operation
+	@param aBackupIncType Base/Incremental backup
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+		User::LeaveIfError(SendReceive(ESBEMsgSetBURMode, TIpcArgs(&aDriveList, aBURType, aBackupIncType)));
+		}
+		
+	void RSBEClientSession::SetSIDListForPartialBURL(RSIDArray& aSIDs)
+	/**
+	If a partial backup is required then this sets the list of data owners.
+	This method must only be called when the device has just been put into backup or restore mode.
+	It must only be called once for a backup or restore operation.
+
+	@param aSIDs array of affected data owners.
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        HBufC8* pFlattenedArray = aSIDs.ExternaliseL();
+		CleanupStack::PushL(pFlattenedArray);
+		
+		TPtrC8 flatArray(pFlattenedArray->Des());
+		
+		User::LeaveIfError(SendReceive(ESBEMsgSetSIDListPartial, TIpcArgs(&flatArray)));
+
+		CleanupStack::PopAndDestroy(pFlattenedArray);
+		}
+		
+	void RSBEClientSession::SIDStatusL(RSIDStatusArray& aSIDStatus)
+	/**
+	Gets the status of a set of data owners.
+	This method must only be called in backup or restore mode.
+
+	@param aSIDStatus an array of structures for information about data owners. On return
+	the status information is filled in.
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        HBufC8* pExternalisedArray = aSIDStatus.ExternaliseL();
+		CleanupStack::PushL(pExternalisedArray);
+		
+		TPtr8 externArray(pExternalisedArray->Des());
+		User::LeaveIfError(SendReceive(ESBEMsgPrepSIDStatus, TIpcArgs(&externArray)));
+		
+		// Reset the descriptor, ready for getting the returned externalised array
+		externArray.Zero();
+		
+		User::LeaveIfError(SendReceive(ESBEMsgGetSIDStatus, TIpcArgs(&externArray)));
+		RSIDStatusArray* pInternalisedArray = RSIDStatusArray::InternaliseL(externArray);
+
+		CleanupStack::PopAndDestroy(pExternalisedArray); // pExternalisedArray
+		
+		CleanupStack::PushL(pInternalisedArray);
+		CleanupClosePushL(*pInternalisedArray);
+		
+		aSIDStatus.Reset();
+
+		// Copy the returned array into the passed array
+		TInt count = pInternalisedArray->Count();
+		for (TInt index = 0; index < count; index++)
+			{
+			aSIDStatus.AppendL((*pInternalisedArray)[index]);
+			}
+		CleanupStack::PopAndDestroy(pInternalisedArray);	// pInternalisedArray->Close()
+		CleanupStack::PopAndDestroy(pInternalisedArray); // pInternalisedArray
+		}
+	
+	TPtr8& RSBEClientSession::TransferDataAddressL()
+	/**
+	Provides access to the base of the global chunk used to transfer data between
+	the Secure Backup Engine and a Secure Backup Server.  This method should be used
+	when the Secure Backup Server is providing data to the Secure Backup Engine (either as part 
+	of a restore operation or when supplying snapshots during a backup operation.
+
+	The Secure Backup Engine only uses one global chunk at a time. It is not permissible to
+	try to carry out multiple backup or restore operations in parallel.  Normally a chunk
+	of global heap would be protected by a mutex.  In this case, all the methods of the 
+	CSecureBackupEngine must be regarded as synchronous and mutually exclusive - it is not
+	permissible to make parallel calls.
+
+	The global chunk used during a backup or restore operation may change and so the address must
+	be requested whenever required rather than being cached.
+
+	@return Pointer to the start of the buffer for writing
+	*/
+		{
+        return iGSHInterface->WriteBufferL(iGlobalSharedHeap);
+		}
+
+	TPtrC8& RSBEClientSession::TransferDataInfoL(CSBGenericTransferType*& aGenericTransferType,
+												 TBool& aFinished)
+	/**
+	Provides access to the data received from the Secure Backup Engine during a backup operation.
+
+	This method should be called after a synchronous or asynchronous request for data has
+	completed.
+
+	@param aGenericTransferType Pointer reference that a Generic Transfer Type is allocated to
+	@param aFinished Flag that will be set to ETrue if the data on the GSH is the last in the series
+	@return Pointer to the start of the buffer for reading
+	*/
+		{
+        TPtrC8& returnedBuf = iGSHInterface->ReadBufferL(iGlobalSharedHeap);
+		
+		TDesC8& genTypeBuffer = iGSHInterface->Header(iGlobalSharedHeap).GenericTransferTypeBuffer();
+		if (genTypeBuffer.Size() == 0)
+			{
+			User::Leave(KErrNotReady);
+			}
+		
+		// Create a new client-side transfer type and pass ownership
+		aGenericTransferType = CSBGenericTransferType::NewL(genTypeBuffer);
+		CleanupStack::PushL(aGenericTransferType);
+		
+		aFinished = iGSHInterface->Header(iGlobalSharedHeap).iFinished;
+
+		CleanupStack::Pop(aGenericTransferType);
+		
+		return returnedBuf;
+		}
+
+	TInt RSBEClientSession::GetGlobalSharedHeapHandle()
+	/**
+	Requests the handle for the Global Anonymous Shared Heap from the server that owns it and
+	sets the member RChunk with it.
+	
+	@return An error code resulting from the server request for the handle, KErrNone if ok
+	*/
+		{
+        TInt ret = SendReceive(ESBEMsgGetGSHHandle);
+		
+		// ret is negative if an error has ocurred
+		if (ret > KErrNone)
+			{
+			ret = iGlobalSharedHeap.SetReturnedHandle(ret);
+			
+			// Since a handle was returned, there were no errors
+			ret = KErrNone;
+			}
+		
+		return ret;
+		}
+		
+	void RSBEClientSession::RequestDataL(CSBGenericTransferType& aGenericTransferType, 
+		TRequestStatus& aStatus)
+	/**
+	Asynchronous request of the Secure Backup Engine to supply data for a particular data owner.
+	When the supplied TRequestStatus has been completed by the server, TransferDataInfoL should
+	be called to retrieve the requested data.
+	
+	@param aGenericTransferType Reference to the identifier of the data requested
+	@param aStatus TRequestStatus object used by the server to signal the client that a response 
+	is ready
+	*/
+		{
+        const TDesC8& transBuf = aGenericTransferType.Externalise();
+		SendReceive(ESBEMsgRequestDataAsync, TIpcArgs(&transBuf), aStatus);
+		}
+
+	void RSBEClientSession::RequestDataL(CSBGenericTransferType& aGenericTransferType)
+	/**
+	Synchronous request of the Secure Backup Engine to supply data for a particular data owner.
+	When the supplied TRequestStatus has been completed by the server, TransferDataInfoL should
+	be called to retrieve the requested data.
+	
+	@param aGenericTransferType Reference to the identifier of the data requested
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        User::LeaveIfError(SendReceive(ESBEMsgRequestDataSync, 
+			TIpcArgs(&(aGenericTransferType.Externalise()))));
+		}
+		
+	void RSBEClientSession::SupplyDataL(CSBGenericTransferType& aGenericTransferType, 
+		TBool aFinished, TRequestStatus& aStatus)
+	/**
+	Synchronous method for signalling to the server that the client has placed an amount 
+	of data in the Global Shared Heap and
+	
+	@param aGenericTransferType Information about the data that has been transferred
+	@param aFinished ETrue indicates that additional SupplyDataL calls will be made as 
+	part of this transfer operation
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        iGSHInterface->Header(iGlobalSharedHeap).GenericTransferTypeBuffer() 
+			= aGenericTransferType.Externalise();
+
+		SendReceive(ESBEMsgSupplyDataSync, TIpcArgs(aFinished), aStatus);
+		}
+
+	void RSBEClientSession::SupplyDataL(CSBGenericTransferType& aGenericTransferType, 
+		TBool aFinished)
+	/**
+	Synchronous method for signalling to the server that the client has placed an amount 
+	of data in the Global Shared Heap and
+	
+	@param aGenericTransferType Information about the data that has been transferred
+	@param aFinished ETrue indicates that additional SupplyDataL calls will be made as 
+	part of this transfer operation
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        iGSHInterface->Header(iGlobalSharedHeap).GenericTransferTypeBuffer() 
+			= aGenericTransferType.Externalise();
+			
+		User::LeaveIfError(SendReceive(ESBEMsgSupplyDataSync, TIpcArgs(aFinished)));
+		}
+		
+	void RSBEClientSession::AllSnapshotsSuppliedL()
+	/**
+	This methods informs the data owner that all snapshots have been supplied.
+
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        User::LeaveIfError(SendReceive(ESBEMsgAllSnapshotsSupplied));
+	
+		}
+		
+	TUint RSBEClientSession::ExpectedDataSizeL(CSBGenericTransferType& aGenericTransferType)
+	/**
+	Get the expected total size of the data to be returned by the SBE for the purposes 
+	of calculating progress information
+	
+	@param aGenericTransferType Reference to the identifier of the data to be retrieved
+	@leave If a synchronous IPC call to the SBEngine returns an error code (i.e. if SBEngine leaves)
+	*/
+		{
+        TPckgBuf<TUint> sizePkg;
+
+		TPtrC8 genType(aGenericTransferType.Externalise());
+		
+		User::LeaveIfError(SendReceive(ESBEMsgGetExpectedDataSize, TIpcArgs(&genType, &sizePkg)));
+			
+		return sizePkg();
+		}
+		
+	void RSBEClientSession::AllSystemFilesRestored()
+	/**
+	Signal the Secure Backup Engine that registration files are to be parsed and Active data owners 
+	are to be started
+	*/
+		{
+        SendReceive(ESBEMsgAllSystemFilesRestored);
+		}
+	
+	/**
+	Return the list of private data owners on the device that have backup registration files.
+	If a leave does occur, then aDataOwners
+	
+	@param aDataOwners Pointer array holding the list of Data owners requiring backup functionality.
+			Any items present in this array will be lost
+	@param aStatus is TRequestStatus&
+	*/
+	void RSBEClientSession::ListOfDataOwnersL(RPointerArray<CDataOwnerInfo>& aDataOwners, TRequestStatus& aStatus)
+		{
+		if (iCallbackHandler == NULL)
+			{
+			iCallbackHandler = CSBECallbackHandler::NewL(*this);				
+			}
+
+		if (iCallbackHandler->IsActive())
+			{
+			User::Leave(KErrInUse);
+			}
+		else
+			{
+			iDataOwnersArray = &aDataOwners;
+			SendReceive(ESBEMsgPrepDataOwnerInfo, iCallbackHandler->iStatus);
+			iCallbackHandler->StartL(aStatus, EListOfDataOwners);
+			}
+		}
+	
+	/**
+	Get the list of public files to backup for a particular Data Owner on a particular drive
+	
+	@param aDrive The drive that the public files exist on
+	@param aGenericDataType Reference to the generic data type that is being passed to the SBEngine.
+	@param aFiles An empty array of file information that will be filled with details of the public files
+	@param aStatus A reference to TRequestStatus
+	
+	*/	
+	void RSBEClientSession::PublicFileListL(TDriveNumber aDrive, CSBGenericDataType& aGenericDataType, RFileArray& aFiles, TRequestStatus& aStatus)
+		{
+		if (iCallbackHandler == NULL)
+			{
+			iCallbackHandler = CSBECallbackHandler::NewL(*this);				
+			}
+	
+		if (iCallbackHandler->IsActive())
+			{
+			User::Leave(KErrInUse);
+			}
+		else
+			{
+			iFileArray = &aFiles;
+			// request the public file list
+			SendReceive(ESBEMsgPrepPublicFiles, TIpcArgs(aDrive, &(aGenericDataType.Externalise())), iCallbackHandler->iStatus);
+			iCallbackHandler->StartL(aStatus,EPublicFileList);
+			}
+		}
+		
+	void RSBEClientSession::SetBURModeL(const TDriveList& aDriveList, TBURPartType aBURType, 
+								  TBackupIncType aBackupIncType, TRequestStatus& aStatus)
+	/**
+	Set the Backup and Restore mode on/off and configure the BUR options asynchronously.
+	
+	@param aDriveList Array of drives that are to be backed up during the operations
+	@param aBURType Set the device into Full/Partial BUR or normal operation
+	@param aBackupIncType Base/Incremental backup
+	@param aStatus A reference to TRequestStatus
+	*/
+
+		{
+		SendReceive(ESBEMsgSetBURMode, TIpcArgs(&aDriveList, aBURType, aBackupIncType), aStatus);
+		}
+	
+	/**
+	This methods informs the data owner that all snapshots have been supplied.
+
+	@param aStatus A reference to TRequestStatus
+	*/	
+	void RSBEClientSession::AllSnapshotsSuppliedL(TRequestStatus& aStatus)
+		{
+		SendReceive(ESBEMsgAllSnapshotsSupplied, aStatus);
+		}
+	
+	/**
+	Signal the Secure Backup Engine that registration files are to be parsed and Active data owners 
+	are to be started
+	
+	@param aStatus A reference to TRequestStatus
+	*/	
+	void RSBEClientSession::AllSystemFilesRestoredL(TRequestStatus& aStatus)
+		{
+		SendReceive(ESBEMsgAllSystemFilesRestored, aStatus);
+		}
+				
+	
+	/**
+	Method to perform and IPC call to populate list of data owners.
+	@param aBufferSize Size of the buffer needed to be allocated for the IPC call
+	
+	@InternalTechnology
+	*/
+	void RSBEClientSession::PopulateListOfDataOwnersL(TUint aBufferSize)
+		{
+		__ASSERT_DEBUG(iDataOwnersArray, Panic(KErrBadHandle));
+		iDataOwnersArray->ResetAndDestroy();
+					
+		// Create a descriptor that's appropriate to hold the buffer to be returned		
+		HBufC8* pReturnedBuf = HBufC8::NewL(aBufferSize);
+		
+		CleanupStack::PushL(pReturnedBuf);
+
+		TPtr8 returnedBuf(pReturnedBuf->Des());
+		// Request that the server returns the previously packed array
+		TInt result = SendReceive(ESBEMsgGetDataOwnerInfo, TIpcArgs(&returnedBuf));
+		User::LeaveIfError(result);
+		
+		TInt offset = 0;
+		
+		for (TInt index = 0; index < result; index++)
+			{
+			CDataOwnerInfo* pDOI = CDataOwnerInfo::NewL(returnedBuf.Mid(offset));
+			CleanupStack::PushL(pDOI);
+
+			iDataOwnersArray->AppendL(pDOI);
+
+			CleanupStack::Pop(pDOI);
+			
+			offset += (*iDataOwnersArray)[index]->Size();
+			}
+			
+		CleanupStack::PopAndDestroy(pReturnedBuf);
+		}
+	
+	/**
+	Method to perform and IPC call to populate list of public files.
+	@param aBufferSize Size of the buffer needed to be allocated for the IPC call
+	
+	@InternalTechnology
+	*/	
+	void RSBEClientSession::PopulatePublicFileListL(TUint aBufferSize)
+		{
+		__ASSERT_DEBUG(iFileArray, Panic(KErrBadHandle));
+		iFileArray->Reset();
+		
+		// Create a descriptor big enough for the array to be externalised into
+		HBufC8* pFileArray = HBufC8::NewL(aBufferSize);
+		CleanupStack::PushL(pFileArray);
+		
+		TPtr8 fileArray(pFileArray->Des());
+		User::LeaveIfError(SendReceive(ESBEMsgGetPublicFiles, TIpcArgs(&fileArray)));
+		
+		RFileArray* pFiles = RFileArray::InternaliseL(fileArray);
+		CleanupStack::PopAndDestroy(pFileArray);
+		CleanupStack::PushL(pFiles);
+		CleanupClosePushL(*pFiles);
+		
+		TInt count = pFiles->Count();
+		for (TInt x = 0; x < count; x++)
+			{
+			iFileArray->AppendL((*pFiles)[0]);
+			pFiles->Remove(0);					// We're running out of memory, hence be frugal
+			} // for x
+		
+		CleanupStack::PopAndDestroy(pFiles); // CleanupClosePushL(*pFiles)
+		CleanupStack::PopAndDestroy(pFiles); // CleanupStack::PushL(pFiles)
+		}
+
+	void RSBEClientSession::PublicFileListL(TDriveNumber aDrive, CSBGenericDataType& aGenericDataType, 
+								RPointerArray<CSBEFileEntry>& aFileList, TBool& aFinished,
+								TInt aTotalListCursor, TInt aMaxResponseSize, TRequestStatus& aStatus)
+	/** 
+	This asynchronous method is used to retrieve the list of public files for the specified data owner
+	on the specified drive. Upon completion of aStatus, the caller should check aFileList 
+	@param aDrive The drive that contains the public files being retrieved
+	@param aGenericDataType The identifier for the data owner that owns the public files
+	@param aFileList Upon completion of aStatus, this array will contain the list of public files returned
+	@param aFinished Upon completion of aStatus, this flag will be set to indicate that there are more 
+						file entries available for this data owner and another call to this method should be made
+	@param aTotalListCursor Specifies the index into the complete list of public files for this data owner to start 
+						the next chunk of file entries from. The number of entries returned by a call to this
+						method can be determined by querying the count of aFileList
+	@param aMaxResponseSize The maximum total size in bytes of externalised CSBEFileEntry objects that will be returned
+	@param aStatus The TRequestStatus that will be completed once the engine has fully processed this request
+	*/
+		{
+		if (iCallbackHandler == NULL)
+			{
+			iCallbackHandler = CSBECallbackHandler::NewL(*this);				
+			}
+	
+		if (iCallbackHandler->IsActive())
+			{
+			User::Leave(KErrInUse);
+			}
+		else
+			{
+			iFileList = &aFileList;
+			iFinished = &aFinished;
+			iTotalListCursor = &aTotalListCursor;
+/*			TPckgC<TDriveNumber> drivePkg(aDrive);
+			TPckgC<TInt> cursorPkg(aTotalListCursor);
+			TPckgC<TInt> maxResp(aMaxResponseSize);*/
+			SendReceive(ESBEMsgPrepLargePublicFiles, TIpcArgs(static_cast<TInt>(aDrive), 
+				&(aGenericDataType.Externalise()), aTotalListCursor, aMaxResponseSize), 
+				iCallbackHandler->iStatus);
+			iCallbackHandler->StartL(aStatus,ELargePublicFileList);
+			}
+		}
+	
+	void RSBEClientSession::PopulateLargePublicFileListL(TInt aResult)
+	/** 
+	Callback following the asynchronous completion of the request for the public file list
+	@param aResult The error code returned by the engine as a result of the initial request
+	*/
+		{
+		// Retrieve the return parameters (finished flag and entry count) from SBE
+		if (KErrNone == aResult)
+			{
+			TBool finishedFlag;
+			TInt numEntries;
+			TPckg<TBool> finishPkg(finishedFlag);
+			TPckg<TInt> numEntriesPkg(numEntries);
+			User::LeaveIfError(SendReceive(ESBEMsgGetLargePublicFiles, TIpcArgs(&finishPkg, &numEntriesPkg)));
+			
+			*iFinished = finishPkg();
+			TInt numberOfReturnedEntries = numEntriesPkg();
+			
+			iFileList->ResetAndDestroy();
+			TInt cursor = 0;
+			TPtrC8 returnedBuf(iGSHInterface->ReadBufferL(iGlobalSharedHeap));
+			
+			// Retrieve the file list from GSH
+			// Pack into the previously supplied array
+			for (TInt entryIndex = 0; entryIndex < numberOfReturnedEntries; ++entryIndex)
+				{
+				TInt bytesRead = 0;
+				CSBEFileEntry* nextEntry = CSBEFileEntry::NewLC(returnedBuf.Mid(cursor), bytesRead);
+				cursor += bytesRead;
+				iFileList->AppendL(nextEntry);
+				CleanupStack::Pop(nextEntry);
+				}
+			}
+		else
+			{
+			*iFinished = EFalse;
+			}
+		}
+
+
+	//
+	// CSBECallbackHandler //
+	//	
+	
+	/** Symbian OS constructor 
+	@param aClientSession reference to a ClientSession to call callbacks on
+	@return pointer to an instantiated RSBEClientSession object 
+	*/
+	CSBECallbackHandler* CSBECallbackHandler::NewL(RSBEClientSession& aClientSession)
+		{
+		CSBECallbackHandler* self = new (ELeave) CSBECallbackHandler(aClientSession);
+		CleanupStack::PushL(self);
+		self->ConstructL();
+		CleanupStack::Pop(self);
+		return self;
+		}
+		
+	/** Symbian second phase constructor */
+	void CSBECallbackHandler::ConstructL()
+		{
+		}
+		
+	/** Class constructor. */
+	CSBECallbackHandler::CSBECallbackHandler(RSBEClientSession& aClientSession)
+		: CActive(EPriorityNormal), iClientSession(aClientSession)
+		{
+		CActiveScheduler::Add(this);
+		}
+	/** Class destructor. */
+	CSBECallbackHandler::~CSBECallbackHandler()
+		{
+		Cancel();
+		}
+	
+	/** Starts Callback Handler
+	
+	@param aStatus Reference to the Client's request Status
+	@param aState State in order to make a relevant callback
+	
+	*/	
+	void CSBECallbackHandler::StartL(TRequestStatus& aStatus, TState aState)
+		{	
+		aStatus = KRequestPending;
+		iObserver = &aStatus;
+		iState = aState;
+		SetActive();
+		}
+		
+	/**
+	Cancels outsanding request
+	*/
+  	void CSBECallbackHandler::CancelRequest()
+  		{
+  		Cancel();
+  		}
+	/**
+	CActive::RunL() implementation
+	*/	
+	void CSBECallbackHandler::RunL()
+		{
+		TInt result = iStatus.Int();
+		if (result >= KErrNone)
+			{			
+			switch (iState)
+				{
+			case EListOfDataOwners:
+				iClientSession.PopulateListOfDataOwnersL(result);
+				break;
+			case EPublicFileList:
+				iClientSession.PopulatePublicFileListL(result);
+				break;
+			case ELargePublicFileList:
+				iClientSession.PopulateLargePublicFileListL(result);
+				break;
+			default:
+				result = KErrNotSupported;
+				break;
+				} //switch
+			} // if
+			
+		User::LeaveIfError(result);
+		
+		CompleteObserver(KErrNone);
+		}
+	
+	/**
+	CActive::DoCancel() implmenation
+	Completes observer's status with KErrCancel and sets the state to None
+	*/	
+	void CSBECallbackHandler::DoCancel()
+		{
+		iState = ENone;
+		// just to avoid repeating the code
+		CompleteObserver(KErrCancel);
+		}
+	
+	/**
+	Method for completing Client's request status
+	@param aError Completion Error
+	*/
+	void CSBECallbackHandler::CompleteObserver(TInt aError)
+		{
+		if(iObserver)
+			{
+			User::RequestComplete(iObserver, aError);
+			iObserver = NULL;
+			}
+		}
+		
+	/**
+	If RunL() leaves a CompleteObserver() method called
+	
+	@aError Error code
+	*/
+	TInt CSBECallbackHandler::RunError(TInt aError)
+		{
+		CompleteObserver(aError);
+		return KErrNone;
+		}
+		
+
+	} // conn namespace