// 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 CSBESession class.
//
//
/**
@file
*/
#include <e32std.h>
#include <e32base.h>
#include "sbeserver.h"
#include "sbesession.h"
#include "sbeclientserver.h"
#include "sbepanic.h"
#include "sbedataownermanager.h"
#include <connect/sbtypes.h>
#include "sblog.h"
#include <apgcli.h>
namespace conn
{
/** This block size for the internal buffer
@internalTechnology
*/
const TInt KSBBufferBlockSize = 4096;
CSBESession::CSBESession() : iTransferBuf(NULL), iTransferTextBuf(NULL), iArrayCount(0)
/**
Class Constructor
*/
{
}
CSBESession::~CSBESession()
/**
Class destructor
*/
{
//
// If the client has detached properly, they should
// have done this - but just in case.
Server().DropSession();
ResetTransferBuf();
delete iExtCurEntry;
}
void CSBESession::CreateL()
/**
Creates a connection between the Secure Backup Engine server and the Secure
Backup Engine session. Increments the server's session count
*/
{
//
// Increase the servers session count.
Server().AddSession();
}
void CSBESession::ServiceL(const RMessage2& aMessage)
/**
Called by the client server framework to service a message request
from a client.
@param aMessage Reference to a RMessage2 object
*/
{
#ifdef SBE_LOGGING_ENABLED
RThread thread;
aMessage.Client(thread);
const TFullName threadName( thread.FullName() );
thread.Close();
#endif
switch(aMessage.Function())
{
//
// Connection config getting/setting.
case ESBEMsgGetGSHHandle:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetGSHHandle for thread: %S", &threadName);
aMessage.Complete(Server().GlobalSharedHeap());
break;
}
case ESBEMsgPrepDataOwnerInfo:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepDataOwnerInfo for thread: %S", &threadName);
PrepDataOwnerInfoL(aMessage);
break;
}
case ESBEMsgGetDataOwnerInfo:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetDataOwnerInfo for thread: %S", &threadName);
ReturnDataOwnerInfoL(aMessage);
break;
}
case ESBEMsgPrepPublicFiles:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepPublicFiles for thread: %S", &threadName);
PrepPublicFileListL(aMessage);
break;
}
case ESBEMsgGetPublicFiles:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetPublicFiles for thread: %S", &threadName);
ReturnPublicFileListL(aMessage);
break;
}
case ESBEMsgPrepPublicFilesRaw:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepPublicFilesRaw for thread: %S", &threadName);
PrepPublicFileListRawL(aMessage);
break;
}
case ESBEMsgGetPublicFilesRaw:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetPublicFilesRaw for thread: %S", &threadName);
ReturnPublicFileListRawL(aMessage);
break;
}
case ESBEMsgPrepPublicFilesXML:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepPublicFilesXML for thread: %S", &threadName);
PrepPublicFileListXMLL(aMessage);
break;
}
case ESBEMsgGetPublicFilesXML:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetPublicFilesXML for thread: %S", &threadName);
ReturnPublicFileListXMLL(aMessage);
break;
}
case ESBEMsgSetBURMode:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgSetBURMode for thread: %S", &threadName);
SetBURModeL(aMessage);
break;
}
case ESBEMsgSetSIDListPartial:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgSetSIDListPartial for thread: %S", &threadName);
SetSIDListForPartialBURL(aMessage);
break;
}
case ESBEMsgPrepSIDStatus:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepSIDStatus for thread: %S", &threadName);
PrepSIDStatusL(aMessage);
break;
}
case ESBEMsgGetSIDStatus:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetSIDStatus for thread: %S", &threadName);
ReturnSIDStatusL(aMessage);
break;
}
case ESBEMsgRequestDataSync:
case ESBEMsgRequestDataAsync:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgRequestDataSync / ESBEMsgRequestDataAsync for thread: %S", &threadName);
TRAPD(reqDataErr, RequestDataAsyncL(aMessage));
if (reqDataErr != KErrNone)
{
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
User::Leave(reqDataErr);
}
break;
}
case ESBEMsgSupplyDataSync:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgSupplyDataSync for thread: %S", &threadName);
TRAPD(supDataErr, SupplyDataSyncL(aMessage));
if (supDataErr != KErrNone)
{
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
User::Leave(supDataErr);
}
break;
}
case ESBEMsgAllSnapshotsSupplied:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgAllSnapshotsSupplied for thread: %S", &threadName);
AllSnapshotsSuppliedL(aMessage);
break;
}
case ESBEMsgGetExpectedDataSize:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetExpectedDataSize for thread: %S", &threadName);
GetExpectedDataSizeL(aMessage);
break;
}
case ESBEMsgAllSystemFilesRestored:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgAllSystemFilesRestored for thread: %S", &threadName);
AllSystemFilesRestoredL();
aMessage.Complete(KErrNone);
break;
}
case ESBEMsgPrepLargePublicFiles:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgPrepPublicFiles for thread: %S", &threadName);
PrepLargePublicFileListL(aMessage);
break;
}
case ESBEMsgGetLargePublicFiles:
{
__LOG1("CSBESession::ServiceL() - ESBEMsgGetPublicFiles for thread: %S", &threadName);
ReturnLargePublicFileListL(aMessage);
break;
}
default:
{
__LOG1("CSBESession::ServiceL() - UNKNOWN OP CODE for thread: %S", &threadName);
User::Leave(KErrNotSupported);
}
}
__LOG1("CSBESession::ServiceL() - Completed OK for thread: %S", &threadName);
}
inline CSBEServer& CSBESession::Server() const
/**
Returns a non-cost reference to this CServer object.
@return The non-const reference to this.
*/
{
return *static_cast<CSBEServer*>(const_cast<CServer2*>(CSession2::Server()));
}
void CSBESession::PrepDataOwnerInfoL(const RMessage2& aMessage)
/**
Prepares the
*/
{
TInt err = KErrNone;
ResetTransferBuf();
RPointerArray<CDataOwnerInfo> doiArray;
TRAP(err,
{
Server().DataOwnerManager().GetDataOwnersL(doiArray);
iTransferBuf = HBufC8::NewL(KSBBufferBlockSize);
TPtr8 transferBufPtr(iTransferBuf->Des());
iArrayCount = doiArray.Count();
HBufC8* dataOwnerBuffer = NULL;
for (TInt index = 0; index < iArrayCount; index++)
{
dataOwnerBuffer = doiArray[index]->ExternaliseLC();
if (transferBufPtr.Size() + dataOwnerBuffer->Size() > transferBufPtr.MaxSize())
{
iTransferBuf = iTransferBuf->ReAllocL(transferBufPtr.MaxSize() + KSBBufferBlockSize);
transferBufPtr.Set(iTransferBuf->Des());
}
// Append the flattened data owner to the IPC transfer buffer
transferBufPtr.Append(*dataOwnerBuffer);
CleanupStack::PopAndDestroy(dataOwnerBuffer);
}
}
); // TRAP
doiArray.ResetAndDestroy();
doiArray.Close();
User::LeaveIfError(err);
// complete the message with the total size of the buffer so that the
// client can create the appropriate sized descriptor for receiving the data
aMessage.Complete(iTransferBuf->Des().Size());
}
void CSBESession::ReturnDataOwnerInfoL(const RMessage2& aMessage)
/**
Return the previously populated buffer to the client
@param aMessage The message sent by the client to the server
*/
{
__ASSERT_DEBUG(iTransferBuf, Panic(KErrNotFound));
// return the previously allocated transfer buffer
aMessage.WriteL(0, *iTransferBuf);
aMessage.Complete(iArrayCount);
ResetTransferBuf();
}
void CSBESession::PrepPublicFileListL(const RMessage2& aMessage)
/**
Compile a list of public files owned by a particular SID to be backed up
@param aMessage The message sent by the client to the server
*/
{
RFileArray fileArray;
CleanupClosePushL(fileArray);
HBufC8* pGenericDataTypeBuffer = HBufC8::NewLC(aMessage.GetDesLengthL(1));
TPtr8 genericDataTypeBuffer(pGenericDataTypeBuffer->Des());
aMessage.ReadL(1, genericDataTypeBuffer);
TDriveNumber drive = static_cast<TDriveNumber>(aMessage.Int0());
CSBGenericDataType* pGenericDataType = CSBGenericDataType::NewL(*pGenericDataTypeBuffer);
CleanupStack::PopAndDestroy(pGenericDataTypeBuffer);
CleanupStack::PushL(pGenericDataType);
Server().DataOwnerManager().GetPublicFileListL(pGenericDataType, drive, fileArray);
CleanupStack::PopAndDestroy(pGenericDataType);
iTransferBuf = fileArray.ExternaliseL();
CleanupStack::PopAndDestroy(&fileArray);
// complete the message with the total size of the buffer so that the
// client can create the appropriate sized descriptor for receiving the data
aMessage.Complete(iTransferBuf->Des().MaxSize());
}
void CSBESession::ReturnPublicFileListL(const RMessage2& aMessage)
/** Return the previously populated buffer to the client
@param aMessage The message sent by the client to the server */
{
__ASSERT_DEBUG(iTransferBuf, Panic(KErrArgument));
// return the previously allocated transfer buffer
aMessage.WriteL(0, *iTransferBuf);
aMessage.Complete(KErrNone);
ResetTransferBuf();
}
void CSBESession::PrepPublicFileListRawL(const RMessage2& aMessage)
/**
Compile a raw list of public files owned by a particular SID to be backed up
@param aMessage The message sent by the client to the server
*/
{
RRestoreFileFilterArray fileFilterArray;
CleanupClosePushL(fileFilterArray);
TPckgBuf<TDriveNumber> driveNumPkg;
HBufC8* pGenericDataTypeBuffer = HBufC8::NewLC(aMessage.GetDesLengthL(1));
TPtr8 genericDataTypeBuffer(pGenericDataTypeBuffer->Des());
aMessage.ReadL(0, driveNumPkg);
aMessage.ReadL(1, genericDataTypeBuffer);
CSBGenericDataType* pGenericDataType = CSBGenericDataType::NewL(*pGenericDataTypeBuffer);
CleanupStack::PopAndDestroy(pGenericDataTypeBuffer);
CleanupStack::PushL(pGenericDataType);
Server().DataOwnerManager().GetRawPublicFileListL(pGenericDataType, driveNumPkg(), fileFilterArray);
CleanupStack::PopAndDestroy(pGenericDataType);
iTransferBuf = fileFilterArray.ExternaliseL();
CleanupStack::PopAndDestroy(&fileFilterArray);
// complete the message with the total size of the buffer so that the
// client can create the appropriate sized descriptor for receiving the data
aMessage.Complete(iTransferBuf->Des().MaxSize());
}
void CSBESession::ReturnPublicFileListRawL(const RMessage2& aMessage)
/** Return the previously populated buffer to the client
@param aMessage The message sent by the client to the server */
{
__ASSERT_DEBUG(iTransferBuf, Panic(KErrArgument));
// return the previously allocated transfer buffer
aMessage.WriteL(0, *iTransferBuf);
aMessage.Complete(KErrNone);
ResetTransferBuf();
}
void CSBESession::PrepPublicFileListXMLL(const RMessage2& aMessage)
/**
*/
{
TPckgBuf<TDriveNumber> driveNumPkg;
TPckgBuf<TSecureId> sidPkg;
ResetTransferBuf();
iTransferTextBuf = HBufC::NewL(0);
Server().DataOwnerManager().GetXMLPublicFileListL(sidPkg(), driveNumPkg(), iTransferTextBuf);
iTransferBuf = HBufC8::NewL(0);
aMessage.Complete(iTransferBuf->Des().MaxSize());
}
void CSBESession::ReturnPublicFileListXMLL(const RMessage2& aMessage)
/**
Return the previously populated buffer to the client
@param aMessage The message sent by the client to the server
*/
{
__ASSERT_DEBUG(iTransferBuf, Panic(KErrArgument));
// return the previously allocated transfer buffer
aMessage.WriteL(0, *iTransferTextBuf);
aMessage.Complete(KErrNone);
ResetTransferBuf();
}
void CSBESession::SetBURModeL(const RMessage2& aMessage)
/**
Set the Backup and Restore mode on/off and configure the BUR options
@param aMessage The message sent by the client to the server
*/
{
TDriveList driveList;
aMessage.ReadL(0, driveList);
TBURPartType burType = static_cast<TBURPartType>(aMessage.Int1());
TBackupIncType incType = static_cast<TBackupIncType>(aMessage.Int2());
// Unlock the global heap
Server().GSHInterface().ResetHeap(Server().GlobalSharedHeap());
Server().DataOwnerManager().SetBURModeL(driveList, burType, incType);
aMessage.Complete(KErrNone);
}
void CSBESession::SetSIDListForPartialBURL(const RMessage2& aMessage)
/**
Set a list of SID's that require base backup regardless of the device backup mode
@param aMessage The message sent by the client to the server
*/
{
HBufC8* flatArray = HBufC8::NewLC(aMessage.GetDesLengthL(0));
TPtr8 flatArrayPtr(flatArray->Des());
aMessage.ReadL(0, flatArrayPtr);
Server().DataOwnerManager().SetSIDListForPartialBURL(flatArrayPtr);
CleanupStack::PopAndDestroy(flatArray);
aMessage.Complete(KErrNone);
}
void CSBESession::PrepSIDStatusL(const RMessage2& aMessage)
/**
Extract the array of SID's of which the status is required
@param aMessage The message sent from the client to the server
*/
{
ResetTransferBuf();
iTransferBuf = HBufC8::NewL(aMessage.GetDesLengthL(0));
TPtr8 transBuf(iTransferBuf->Des());
// Copy the IPC'd buffer into our transfer buffer
aMessage.ReadL(0, transBuf);
aMessage.Complete(KErrNone);
}
void CSBESession::ReturnSIDStatusL(const RMessage2& aMessage)
/**
Populate and return the array of SID's complete with their statuses
@param aMessage The message sent from the client to the server
*/
{
RSIDStatusArray* pStatusArray = RSIDStatusArray::InternaliseL(*iTransferBuf);
CleanupStack::PushL(pStatusArray);
CleanupClosePushL(*pStatusArray);
// We're finished with the received externalised SIDStatusArray for now, delete it
ResetTransferBuf();
// Ask DOM to populate the Statuses in the status array
Server().DataOwnerManager().SIDStatusL(*pStatusArray);
iTransferBuf = pStatusArray->ExternaliseL();
CleanupStack::PopAndDestroy(2, pStatusArray);
aMessage.WriteL(0, *iTransferBuf);
aMessage.Complete(KErrNone);
ResetTransferBuf();
}
void CSBESession::RequestDataAsyncL(const RMessage2& aMessage)
/**
Handle the client's asynchronous request for data from the SBE
*/
{
iMessage = aMessage;
__LOG("CSBESession::RequestDataAsyncL() - START");
TBool finished = EFalse; // Set by DOM, initialised to eliminate warning
HBufC8* pTransferredBuf = HBufC8::NewLC(iMessage.GetDesLengthL(0));
TPtr8 transBuf(pTransferredBuf->Des());
// Copy the IPC'd buffer into our transfer buffer
iMessage.ReadL(0, transBuf);
// Extract the generic type from the client IPC request
CSBGenericTransferType* pGenericType = CSBGenericTransferType::NewL(*pTransferredBuf);
CleanupStack::PopAndDestroy(pTransferredBuf);
CleanupStack::PushL(pGenericType);
TPtr8& writeBuf = Server().GSHInterface().WriteBufferL(Server().GlobalSharedHeap());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(ETrue);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).GenericTransferTypeBuffer() = pGenericType->Externalise();
// Call the DOM to populate the GSH with the data to return
Server().DataOwnerManager().RequestDataL(pGenericType, writeBuf, finished);
CleanupStack::PopAndDestroy(pGenericType);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).iFinished = finished;
__LOG2("CSBESession::RequestDataAsyncL() - Server-side data length: %d, address: 0x%08x", writeBuf.Length(), writeBuf.Ptr());
//__LOGDATA("CSBESession::RequestDataAsyncL() - %S", writeBuf.Ptr(), writeBuf.Length());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
if (!iMessage.IsNull())
{
iMessage.Complete(KErrNone);
}
__LOG("CSBESession::RequestDataAsyncL() - END");
}
void CSBESession::RequestDataSyncL(const RMessage2& aMessage)
/**
Handle the client's synchronous request for data from the SBE
*/
{
__LOG("CSBESession::RequestDataSyncL() - START");
TBool finished = EFalse; // Set by DOM, initialised to eliminate warning
HBufC8* pTransferredBuf = HBufC8::NewLC(aMessage.GetDesLengthL(0));
TPtr8 transBuf(pTransferredBuf->Des());
// Copy the IPC'd buffer into our transfer buffer
aMessage.ReadL(0, transBuf);
// Extract the generic type from the client IPC request
CSBGenericTransferType* pGenericType = CSBGenericTransferType::NewL(*pTransferredBuf);
CleanupStack::PopAndDestroy(pTransferredBuf);
CleanupStack::PushL(pGenericType);
TPtr8& writeBuf = Server().GSHInterface().WriteBufferL(Server().GlobalSharedHeap());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(ETrue);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).GenericTransferTypeBuffer() = pGenericType->Externalise();
// Call the DOM to populate the GSH with the data to return
Server().DataOwnerManager().RequestDataL(pGenericType, writeBuf, finished);
CleanupStack::PopAndDestroy(pGenericType);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).iFinished = finished;
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
__LOG2("CSBESession::RequestDataSyncL() - Server-side data length: %d, address: 0x%08x", writeBuf.Length(), writeBuf.Ptr());
//__LOGDATA("CSBESession::RequestDataSyncL() - %S", writeBuf.Ptr(), writeBuf.Length());
aMessage.Complete(KErrNone);
__LOG("CSBESession::RequestDataSyncL() - END");
}
void CSBESession::SupplyDataSyncL(const RMessage2& aMessage)
/**
Handle the client's synchronous request to supply data to the SBE
*/
{
__LOG("CSBESession::SupplyDataSyncL() - START");
TBool finished = aMessage.Int0();
CSBGenericTransferType* pGenericType = CSBGenericTransferType::NewL(
Server().GSHInterface().Header(Server().GlobalSharedHeap())
.GenericTransferTypeBuffer());
CleanupStack::PushL(pGenericType);
TPtrC8& readBuf = Server().GSHInterface().ReadBufferL(Server().GlobalSharedHeap());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(ETrue);
__LOG2("CSBESession::SupplyDataSyncL() - Server-side data length: %d, address: 0x%08x", readBuf.Length(), readBuf.Ptr());
//__LOGDATA("CSBESession::SupplyDataSyncL() - %S", readBuf.Ptr(), readBuf.Length());
Server().DataOwnerManager().SupplyDataL(pGenericType, readBuf, finished);
CleanupStack::PopAndDestroy(pGenericType);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
aMessage.Complete(KErrNone);
__LOG("CSBESession::SupplyDataSyncL() - END");
}
void CSBESession::GetExpectedDataSizeL(const RMessage2& aMessage)
/**
Return the size of data that the DOM expects to send back to the PC
*/
{
TUint size;
TPckg<TUint> sizePkg(size);
TInt bufferLen = aMessage.GetDesLengthL(0);
HBufC8* transTypeBuf = HBufC8::NewL(bufferLen);
CleanupStack::PushL(transTypeBuf);
TPtr8 transTypeBufDes(transTypeBuf->Des());
aMessage.ReadL(0, transTypeBufDes);
CSBGenericTransferType* pGenericType = CSBGenericTransferType::NewL(transTypeBufDes);
CleanupStack::PopAndDestroy(transTypeBuf);
CleanupStack::PushL(pGenericType);
aMessage.ReadL(1, sizePkg);
Server().DataOwnerManager().GetExpectedDataSizeL(pGenericType, sizePkg());
CleanupStack::PopAndDestroy(pGenericType);
aMessage.WriteL(1, sizePkg);
aMessage.Complete(KErrNone);
}
void CSBESession::AllSnapshotsSuppliedL(const RMessage2& aMessage)
/**
*/
{
Server().DataOwnerManager().AllSnapshotsSuppliedL();
aMessage.Complete(KErrNone);
}
void CSBESession::AllSystemFilesRestoredL()
/**
Sent by the client to indicate that all registration files
@param aMessage IPC message sent from the client
*/
{
Server().DataOwnerManager().AllSystemFilesRestoredL();
}
void CSBESession::PrepLargePublicFileListL(const RMessage2& aMessage)
/**
Compile a list of public files owned by a particular SID to be backed up
@param aMessage The message sent by the client to the server
*/
{
HBufC8* pGenericDataTypeBuffer = HBufC8::NewLC(aMessage.GetDesLengthL(1));
TPtr8 genericDataTypeBuffer(pGenericDataTypeBuffer->Des());
TDriveNumber drive = static_cast<TDriveNumber>(aMessage.Int0());
aMessage.ReadL(1, genericDataTypeBuffer);
TInt cursor = aMessage.Int2();
TInt maxSize = aMessage.Int3();
CSBGenericDataType* pGenericDataType = CSBGenericDataType::NewL(*pGenericDataTypeBuffer);
CleanupStack::PopAndDestroy(pGenericDataTypeBuffer);
CleanupStack::PushL(pGenericDataType);
// Create a transfer type (ignored by the client side, just here for future reference
CSBGenericTransferType* transType = NULL;
switch (pGenericDataType->DerivedTypeL())
{
case ESIDDerivedType:
{
CSBSecureId* sid = CSBSecureId::NewL(pGenericDataType);
CleanupStack::PushL(sid);
transType = CSBSIDTransferType::NewL(sid->SecureIdL(), drive, EPublicFileListing);
CleanupStack::PopAndDestroy(sid);
break;
}
case EPackageDerivedType:
{
CSBPackageId* pkg = CSBPackageId::NewL(pGenericDataType);
CleanupStack::PushL(pkg);
transType = CSBPackageTransferType::NewL(pkg->PackageIdL(), drive, ESystemData);
CleanupStack::PopAndDestroy(pkg);
break;
}
case EJavaDerivedType:
{
CSBJavaId* java = CSBJavaId::NewL(pGenericDataType);
CleanupStack::PushL(java);
transType = CSBJavaTransferType::NewL(java->SuiteHashL(), drive, EJavaMIDletData);
CleanupStack::PopAndDestroy(java);
break;
}
default:
{
__LOG1("Unknown generic data type supplied, leaving with KErrUnknown (%d)", KErrUnknown);
User::Leave(KErrUnknown);
}
}
CleanupStack::PushL(transType);
// Get a writeable buffer from the global shared heap
TPtr8& writeBuf = Server().GSHInterface().WriteBufferL(Server().GlobalSharedHeap());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(ETrue);
Server().GSHInterface().Header(Server().GlobalSharedHeap()).GenericTransferTypeBuffer() = transType->Externalise();
// This is required to look up the MIME type of the file entry and convert it into a textual representation
RApaLsSession apaSession;
User::LeaveIfError(apaSession.Connect());
CleanupClosePushL(apaSession);
// Copy file entries from the cursor until either the end of the list is reached or the
// max response size ceiling is reached. Store the number added for the call to ReturnLargePublicFileListL
iFinished = EFalse;
TInt currentIndex = cursor;
TInt currentSize = 0;
iTotalEntries = 0;
if (currentIndex == 0)
{
// Starting from the beginning, remove previously saved entry
delete iExtCurEntry;
iExtCurEntry = 0;
}
while (currentSize < maxSize)
{
if (!iExtCurEntry)
{
TEntry entry;
Server().DataOwnerManager().GetNextPublicFileL(pGenericDataType, (currentIndex == 0), drive, entry);
if (entry.iName.Length())
{
++currentIndex;
// Pull the next entry out of the list and translate into CSBEFileEntry
CSBEFileEntry* pEntry = CSBEFileEntry::NewLC(entry, apaSession);
// Pack it into the GSH
iExtCurEntry = pEntry->ExternaliseLC();
CleanupStack::Pop(iExtCurEntry);
CleanupStack::PopAndDestroy(pEntry);
}
}
// else - use the remaining entry from the previous call
if (iExtCurEntry)
{
// If this entry isn't going to bust our max RAM parameter, then pack it in
currentSize += iExtCurEntry->Size();
if (currentSize <= maxSize)
{
writeBuf.Append(*iExtCurEntry);
delete iExtCurEntry;
iExtCurEntry = 0;
++iTotalEntries;
}
// else - leave iExtCurEntry until the next call
}
else
{
// No more entries left, must have reached the end of the list
iFinished = ETrue;
break;
}
}
CleanupStack::PopAndDestroy(&apaSession);
__LOG2("CSBESession::PrepLargePublicFileListL() - Server-side data length: %d, address: 0x%08x", writeBuf.Length(), writeBuf.Ptr());
Server().GSHInterface().Header(Server().GlobalSharedHeap()).iFinished = iFinished;
Server().GSHInterface().Header(Server().GlobalSharedHeap()).SetLockedFlag(EFalse);
CleanupStack::PopAndDestroy(transType);
CleanupStack::PopAndDestroy(pGenericDataType);
aMessage.Complete(KErrNone);
}
void CSBESession::ReturnLargePublicFileListL(const RMessage2& aMessage)
/** Return the previously populated buffer to the client
@param aMessage The message sent by the client to the server */
{
TPckg<TBool> finPkg(iFinished);
TPckg<TInt> totalPkg(iTotalEntries);
aMessage.WriteL(0, finPkg);
aMessage.WriteL(1, totalPkg);
aMessage.Complete(KErrNone);
}
void CSBESession::ResetTransferBuf()
/**
*/
{
if (iTransferBuf != NULL)
{
delete iTransferBuf;
iTransferBuf = NULL;
}
if (iTransferTextBuf != NULL)
{
delete iTransferTextBuf;
iTransferTextBuf = NULL;
}
iArrayCount = 0;
}
}