diff -r 000000000000 -r d0791faffa3f backupandrestore/backupengine/src/sbeclientsession.cpp --- /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 +#include + +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(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& 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 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 drive(aDrive); + TPckgC 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 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& 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& 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 drivePkg(aDrive); + TPckgC cursorPkg(aTotalListCursor); + TPckgC maxResp(aMaxResponseSize);*/ + SendReceive(ESBEMsgPrepLargePublicFiles, TIpcArgs(static_cast(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 finishPkg(finishedFlag); + TPckg 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