--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/metadataengine/server/src/mdsserversession.cpp Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,1627 @@
+/*
+* Copyright (c) 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: This is Metadata engine server session file
+*
+*/
+
+
+// INCLUDE FILES
+#include "mdsserversession.h"
+
+#include "mdcresult.h"
+#include "mdslogger.h"
+#include "mdcserializationbuffer.h"
+#include "mdsserver.h"
+#include "mdsmanipulationengine.h"
+#include "mdsmaintenanceengine.h"
+#include "mdsfindengine.h"
+#include "mdsobjectlocklist.h"
+#include "mdsnotifier.h"
+#include "mdsschema.h"
+#include "mdcresult.h"
+#include "mdcitem.h"
+
+#include "mdsutils.h"
+
+__USES_LOGGER
+
+
+// ========================= MEMBER FUNCTIONS ==================================
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+//
+CMdSServerSession* CMdSServerSession::NewL( CMdSServer& aServer )
+ {
+ CMdSServerSession* self = CMdSServerSession::NewLC( aServer );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// NewLC
+// ---------------------------------------------------------------------------
+//
+CMdSServerSession* CMdSServerSession::NewLC( CMdSServer& aServer )
+ {
+ CMdSServerSession* self = new ( ELeave ) CMdSServerSession( aServer );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ConstructL()
+ {
+ iServer.IncrementSessions();
+ }
+
+// ---------------------------------------------------------------------------
+// Default constructor
+// ---------------------------------------------------------------------------
+//
+CMdSServerSession::CMdSServerSession( CMdSServer& aServer )
+ : iServer( aServer )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CMdSServerSession::~CMdSServerSession()
+ {
+ iFindEngines.ResetAndDestroy();
+ iFindEngines.Close();
+
+ iServer.LockList().UnlockBySession( *this );
+ iServer.Notifier().RemoveEntriesBySession( *this );
+ iServer.DecrementSessions();
+
+ // purge any pending notifications
+ iNotificationCache.ResetAndDestroy();
+ iNotificationCache.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Service the server message
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ServiceL( const RMessage2& aMessage )
+ {
+ __LOG2( ELogServer, "ServiceL message: %d uid: %.8x",
+ aMessage.Function(),
+ aMessage.Identity());
+
+ if( iServer.BackupOrRestoreRunning() )
+ {
+ aMessage.Complete( KErrServerBusy );
+ return;
+ }
+
+ TRAPD( err, ServiceFunctionL( aMessage ) );
+ if( err != KErrNone )
+ {
+ aMessage.Complete( err );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// ServiceFunctionL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ServiceFunctionL( const RMessage2& aMessage )
+ {
+ TInt complete(KErrNone);
+
+ switch ( aMessage.Function() )
+ {
+ // Add items
+ case EAdd:
+ {
+ AddL( aMessage );
+ break;
+ }
+
+ // Add relation def
+ case EAddRelationDef:
+ {
+ AddRelationDefL(aMessage);
+ iServer.Notifier().NotifySchemaAddedL();
+ break;
+ }
+
+ // Add event def
+ case EAddEventDef:
+ {
+ AddEventDefL(aMessage);
+ iServer.Notifier().NotifySchemaAddedL();
+ break;
+ }
+
+ // Remove items
+ case ERemove:
+ {
+ RemoveL( aMessage );
+ break;
+ }
+
+ // Find items
+ case EFind:
+ {
+ TRAPD( err, FindL( aMessage ) );
+ if ( err != KErrNone )
+ {
+ if ( err != KErrNotReady )
+ {
+ FindCancel( aMessage, err );
+ return;
+ }
+ complete = err;
+ }
+ break;
+ }
+
+ case EAsyncFind:
+ {
+ TRAPD( err, FindAsyncL( aMessage ) );
+ if ( err != KErrNone)
+ {
+ if(err != KErrNotReady)
+ {
+ FindCancel( aMessage, err );
+ return;
+ }
+ complete = err;
+ }
+ else
+ {
+ // if no error don't complete message
+ return;
+ }
+ break;
+ }
+
+ case EContinueAsyncFind:
+ {
+ TRAPD( err, FindContinueAsyncL( aMessage ) );
+ if ( err != KErrNone )
+ {
+ FindCancel( aMessage, err );
+ }
+
+ // if no error don't complete message
+ return;
+ }
+
+ case ECancelFind:
+ {
+ FindCancel( aMessage, KErrNone );
+ return;
+ }
+
+ case ECheckObject:
+ {
+ CheckObjectL( aMessage );
+ break;
+ }
+
+ case EGetData:
+ {
+ GetDataL( aMessage );
+ break;
+ }
+
+ case ECancelObject:
+ {
+ CancelObjectL( aMessage );
+ break;
+ }
+
+ case EUpdate:
+ {
+ UpdateL( aMessage );
+ break;
+ }
+
+ case ERegister:
+ {
+ RegisterL( aMessage );
+ break;
+ }
+
+ case EListen:
+ {
+ ListenL( aMessage );
+
+ // if no error don't complete message
+ return;
+ }
+
+ case EUnregister:
+ {
+ UnregisterL( aMessage );
+ break;
+ }
+
+ case EShutdown:
+ {
+ ShutdownL( aMessage );
+ break;
+ }
+
+ case EImportMetadata:
+ case EAsyncImportMetadata:
+ {
+ ImportMetadataL( aMessage );
+ break;
+ }
+
+ case EExportMetadata:
+ case EAsyncExportMetadata:
+ {
+ ExportMetadataL( aMessage );
+ break;
+ }
+
+ case EImportSchema:
+ {
+ TRAPD( err, ImportSchemaL( aMessage ) );
+ if(err != KErrNone && err != KErrAccessDenied)
+ {
+ // Map all other errors to KErrCorrupt
+ err = KErrCorrupt;
+ }
+
+ if(!err)
+ {
+ iServer.Notifier().NotifySchemaAddedL();
+ }
+
+ complete = err;
+ break;
+ }
+
+ case EAddMemoryCard:
+ {
+ AddMemoryCardL( aMessage );
+ break;
+ }
+
+ case EGetMemoryCard:
+ {
+ GetMemoryCardL( aMessage );
+ break;
+ }
+
+ case ECheckMemoryCard:
+ {
+ CheckMemoryCardL( aMessage );
+ break;
+ }
+
+ case ESetMedia:
+ {
+ SetMediaL( aMessage );
+ break;
+ }
+
+ case EGetMedia:
+ {
+ GetMediaL( aMessage );
+ break;
+ }
+
+ case EGetPresentMedias:
+ {
+ GetPresentMediasL( aMessage );
+ break;
+ }
+
+ case ESetFileToPresent:
+ {
+ complete = KErrNotSupported;
+ break;
+ }
+
+ case ESetFilesToPresent:
+ {
+ SetFilesToPresentL(aMessage);
+ break;
+ }
+
+ case ESetFilesToNotPresent:
+ {
+ SetFilesToNotPresentL(aMessage);
+ break;
+ }
+
+ case ERemoveFilesNotPresent:
+ {
+ RemoveFilesNotPresentL(aMessage);
+ break;
+ }
+
+ case EGetSchemaVersion:
+ {
+ GetSchemaVersionL(aMessage);
+ break;
+ }
+
+ case ESetObjectToPresentByGuid:
+ {
+ SetObjectToPresentByGuidL(aMessage);
+ break;
+ }
+
+ case EResetDB:
+ {
+ #ifdef _DEBUG
+ iServer.ResetDBL();
+ #else
+ User::Leave( KErrNotSupported );
+ #endif
+ break;
+ }
+
+ case ESetHarvestingPrioritizationChunk:
+ {
+ iServer.SetHarvestingPrioritizationChunkL( aMessage, 0 );
+ break;
+ }
+
+ case EAddHarvestingPrioritizationObserver:
+ {
+ User::LeaveIfError( iServer.AddHarvestingPrioritizationObserver( aMessage ) );
+ // if no error don't complete message
+ return;
+ }
+
+ case ECancelHarvestingPrioritizationObserver:
+ {
+ User::LeaveIfError( iServer.CancelHarvestingPrioritizationObserver() );
+ break;
+ }
+
+ case EChangePath:
+ {
+ ChangePathL( aMessage );
+ break;
+ }
+
+ case EChangeMediaId:
+ {
+ ChangeMediaIdL( aMessage );
+ break;
+ }
+
+ case ESetPending:
+ {
+ SetPendingL( aMessage );
+ }
+ break;
+
+ case EResetPending:
+ {
+ ResetPendingL( aMessage );
+ }
+ break;
+
+ case EGetPendingCount:
+ {
+ complete = GetPendingCountL( aMessage );
+ }
+ break;
+
+ case EGetPending:
+ {
+ complete = GetPendingL( aMessage );
+ }
+ break;
+
+ default:
+ iServer.PanicClient( aMessage, EBadRequest );
+ }
+
+ aMessage.Complete(complete);
+ }
+
+// ---------------------------------------------------------------------------
+// QueriesCompleteL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::QueriesCompleteL()
+ {
+ // check if all queries are complete
+ for( TInt i = iFindEngines.Count() - 1; i >= 0; i--)
+ {
+ CMdSFindEngine* fe = iFindEngines[i];
+
+ if( !fe->IsComplete() )
+ {
+ User::Leave( KErrNotReady );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// AddL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::AddL( const RMessage2& aMsg )
+ {
+ if ( iServer.DiskFull() )
+ {
+ User::Leave( KErrDiskFull );
+ }
+
+ TInt resultLength = aMsg.GetDesLengthL( 1 );
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aMsg, 0 );
+ CMdCSerializationBuffer* resultBuf = CMdCSerializationBuffer::NewLC( resultLength );
+
+ iServer.Manipulate().AddL( *buffer, *resultBuf, this );
+
+ aMsg.WriteL(1, resultBuf->Buffer() );
+ CleanupStack::PopAndDestroy( resultBuf );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+// ---------------------------------------------------------------------------
+// AddRelationDefL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::AddRelationDefL(const RMessage2 &aMsg)
+ {
+ TDefId namespaceId = aMsg.Int0();
+
+ TInt nameLength = aMsg.GetDesLength( EAddDefArgDefName );
+ if ( nameLength < 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+ HBufC* namebuf = HBufC::NewLC( nameLength );
+ TPtr bufdes = namebuf->Des();
+ aMsg.ReadL( EAddDefArgDefName, bufdes );
+
+ iServer.Manipulate().AddRelationDefL( namespaceId, *namebuf );
+
+ iServer.Schema().SerializeToSharedMemoryL();
+
+ CleanupStack::PopAndDestroy( namebuf );
+ }
+
+void CMdSServerSession::AddEventDefL(const RMessage2 &aMsg)
+ {
+ TDefId namespaceId = aMsg.Int0();
+
+ TInt nameLength = aMsg.GetDesLength( EAddDefArgDefName );
+ if ( nameLength < 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+ HBufC* namebuf = HBufC::NewLC( nameLength );
+ TPtr bufdes = namebuf->Des();
+ aMsg.ReadL( EAddDefArgDefName, bufdes );
+
+ iServer.Manipulate().AddEventDefL( namespaceId, *namebuf );
+
+ iServer.Schema().SerializeToSharedMemoryL();
+
+ CleanupStack::PopAndDestroy( namebuf );
+ }
+
+// RemoveL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::RemoveL( const RMessage2& aMsg )
+ {
+ TInt successfulLength = aMsg.GetDesLengthL( 1 );
+
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aMsg, 0 );
+ CMdCSerializationBuffer* successfullBuffer = CMdCSerializationBuffer::NewLC( successfulLength );
+
+ iServer.Manipulate().RemoveL( *buffer, *successfullBuffer );
+ aMsg.WriteL( 1, successfullBuffer->Buffer() );
+ CleanupStack::PopAndDestroy( 2, buffer ); // successfullBuffer, buffer
+ }
+
+// ---------------------------------------------------------------------------
+// FindL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::FindL( const RMessage2& aMsg )
+ {
+ __LOGLB( ELogServer, "-> Find Sync" );
+
+ // check that all queries are complete
+ QueriesCompleteL();
+
+ TInt serializedCriteriaLength = aMsg.GetDesLength( EFindArgConditions );
+ CMdCSerializationBuffer* serializedCriteriaBuffer = CMdCSerializationBuffer::NewLC( serializedCriteriaLength );
+ TPtr8 serializedCriteriaBufferPtr(serializedCriteriaBuffer->Buffer());
+ aMsg.ReadL( EFindArgConditions, serializedCriteriaBufferPtr );
+
+ const TUint32 queryId = (TUint32)aMsg.Int0();
+
+ CMdSFindEngine* find = CMdSFindEngine::NewLC( queryId, *this,
+ iServer.LockList(), iServer.Schema() );
+ find->SetFindCriteria( serializedCriteriaBuffer );
+ find->CreateResultSet( aMsg );
+ find->SetFindParams( (TUint32)aMsg.Int3() );
+
+ CleanupStack::Pop( find );
+ CleanupStack::Pop( serializedCriteriaBuffer );
+ CleanupStack::PushL( find );
+
+ // check clients user level (whether access to confidential data or not)
+ TUserLevel userLevel = EUserLevelNone;
+ userLevel = ( aMsg.HasCapability( ECapabilityReadDeviceData ) ?
+ EUserLevelDeviceAccess : EUserLevelNormal );
+
+ find->FindL( userLevel );
+
+ CleanupStack::Pop( find );
+
+ iFindEngines.Append( find );
+ }
+
+// ---------------------------------------------------------------------------
+// FindAsyncL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::FindAsyncL( const RMessage2& aMsg )
+ {
+ __LOGLB( ELogServer, "-> Find Async" );
+
+ // check that all queries are complete
+ QueriesCompleteL();
+
+ TInt serializedCriteriaLength = aMsg.GetDesLength( EFindArgConditions );
+ CMdCSerializationBuffer* serializedCriteriaBuffer = CMdCSerializationBuffer::NewLC( serializedCriteriaLength );
+ TPtr8 serializedCriteriaBufferPtr(serializedCriteriaBuffer->Buffer());
+ aMsg.ReadL( EFindArgConditions, serializedCriteriaBufferPtr );
+
+ const TUint32 queryId = (TUint32)aMsg.Int0();
+
+ CMdSFindEngine* find = CMdSFindEngine::NewLC( queryId, *this,
+ iServer.LockList(), iServer.Schema() );
+ find->SetFindCriteria( serializedCriteriaBuffer );
+ find->CreateResultSet( aMsg );
+ find->SetFindParams( (TUint32)aMsg.Int3() );
+
+ CleanupStack::Pop( find );
+ CleanupStack::Pop( serializedCriteriaBuffer );
+ CleanupStack::PushL( find );
+
+ // check clients user level (whether access to confidential data or not)
+ TUserLevel userLevel = EUserLevelNone;
+ userLevel = ( aMsg.HasCapability( ECapabilityReadDeviceData ) ?
+ EUserLevelDeviceAccess : EUserLevelNormal );
+
+ find->FindAsyncL( userLevel );
+
+ CleanupStack::Pop( find );
+
+ iFindEngines.Append( find );
+ }
+
+// ---------------------------------------------------------------------------
+// FindContinueAsyncL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::FindContinueAsyncL( const RMessage2& aMsg )
+ {
+ __LOGLB( ELogServer, "-> Find Continue" );
+
+ CMdSFindEngine* findEngine = NULL;
+
+ const TUint32 queryId = (TUint32)aMsg.Int0();
+
+ const TInt count = iFindEngines.Count();
+
+ TInt feIndex = 0;
+
+ for( TInt i = 0; i < count; i++ )
+ {
+ if( queryId == iFindEngines[i]->QueryId() )
+ {
+ findEngine = iFindEngines[i];
+
+ feIndex = i;
+ break;
+ }
+ }
+
+ // no correct find engine found
+ if( !findEngine )
+ {
+ User::Leave( KErrNotFound );
+ }
+ // find engine is already complete
+ else if( findEngine->IsComplete() )
+ {
+ delete findEngine;
+
+ iFindEngines.Remove( feIndex );
+
+ User::Leave( KErrCompletion );
+ }
+
+ findEngine->CreateResultSet( aMsg );
+
+ findEngine->ContinueAsync();
+ }
+
+// ---------------------------------------------------------------------------
+// FindCancel
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::FindCancel( const RMessage2& aMsg, TInt aError )
+ {
+ __LOGLB( ELogServer, "-> Find Cancel" );
+
+ const TUint32 queryId = (TUint32)aMsg.Int0();
+
+ const TInt count = iFindEngines.Count();
+
+ for( TInt i = 0; i < count; i++ )
+ {
+ CMdSFindEngine* findEngine = iFindEngines[i];
+
+ if( queryId == findEngine->QueryId() )
+ {
+ findEngine->Cancel( aError );
+
+ delete findEngine;
+
+ iFindEngines.Remove( i );
+
+ aMsg.Complete( aError );
+ return;
+ }
+ }
+
+ // complete message even if correct find engine wasn't found
+ aMsg.Complete( KErrNotFound );
+ }
+
+// ---------------------------------------------------------------------------
+// CheckObjectL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::CheckObjectL( const RMessage2& aMsg )
+ {
+ TPckgBuf<TDefId> namespaceDefIdPckg;
+ TInt nsDefIdLength = aMsg.GetDesLengthL( ECheckObjectArgNamespaceDefId );
+ if( nsDefIdLength != sizeof( TDefId ) )
+ {
+ User::Leave( KErrArgument );
+ }
+ aMsg.Read( ECheckObjectArgNamespaceDefId, namespaceDefIdPckg );
+ const TDefId namespaceDefId = namespaceDefIdPckg();
+
+ const TInt resultBufferLength = aMsg.GetDesLengthL( ECheckObjectArgObject );
+ if( resultBufferLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ CMdCSerializationBuffer* buffer = NULL;
+
+ const TInt type = aMsg.Int0();
+ switch( type )
+ {
+ case ECheckObjectByUri:
+ {
+ TInt uriLength = aMsg.GetDesLengthL( ECheckObjectArgTypeValue );
+ if( uriLength <= 0 )
+ {
+ User::Leave( KErrArgument );
+ }
+ RBuf uri;
+ uri.Create( uriLength );
+ CleanupClosePushL( uri );
+ aMsg.ReadL( ECheckObjectArgTypeValue, uri );
+ buffer = iServer.Manipulate().CheckObjectL( resultBufferLength, uri, namespaceDefId );
+ CleanupStack::PopAndDestroy( &uri );
+ CleanupStack::PushL( buffer );
+ }
+ break;
+
+ case ECheckObjectById:
+ {
+ TPckgBuf<TItemId> idPckg;
+ TInt idLength = aMsg.GetDesLengthL( ECheckObjectArgTypeValue );
+ if( idLength != sizeof( TItemId ) )
+ {
+ User::Leave( KErrArgument );
+ }
+ aMsg.Read( ECheckObjectArgTypeValue, idPckg );
+ const TItemId id = idPckg();
+ buffer = iServer.Manipulate().CheckObjectL( resultBufferLength, id, namespaceDefId );
+ CleanupStack::PushL( buffer );
+ }
+ break;
+
+ case ECheckObjectByIds:
+ {
+ TInt idLength = aMsg.GetDesLengthL( ECheckObjectArgTypeValue );
+ if( idLength < CMdCSerializationBuffer::KRequiredSizeForTUint32 )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ CMdCSerializationBuffer* ids = CMdCSerializationBuffer::NewLC( idLength );
+ TPtr8 idsPtr( ids->Buffer() );
+ aMsg.ReadL( ECheckObjectArgTypeValue, idsPtr );
+
+ buffer = iServer.Manipulate().CheckObjectL( resultBufferLength, *ids, namespaceDefId );
+
+ CleanupStack::PopAndDestroy( ids );
+
+ CleanupStack::PushL( buffer );
+ }
+ break;
+
+ default:
+ {
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+ aMsg.WriteL( ECheckObjectArgObject, buffer->Buffer() );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+
+// ---------------------------------------------------------------------------
+// GetDataL writes to the client the data from the required operation
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::GetDataL( const RMessage2& aMsg )
+ {
+ TMdEServRqst serverRequest = (TMdEServRqst)aMsg.Int2();
+
+ switch( serverRequest )
+ {
+ case ELoadSchema:
+ {
+ __LOGLB( ELogServer, "-> Get data (Schema)" );
+ TPckgBuf<TInt> handleBuf( iServer.Schema().SharedMemoryHandleL() );
+ aMsg.WriteL( 1, handleBuf );
+ }
+ break;
+ case EFind:
+ case EAsyncFindSetReady:
+ case EAsyncFindComplete:
+ {
+ __LOGLB( ELogServer, "-> Get data (Find)" );
+
+ const TUint32 queryId = (TUint32)aMsg.Int0();
+
+ CMdSFindEngine* findEngine = NULL;
+
+ const TInt count = iFindEngines.Count();
+
+ TInt findEngineIndex;
+ for( findEngineIndex = 0; findEngineIndex < count; findEngineIndex++ )
+ {
+ if( queryId == iFindEngines[findEngineIndex]->QueryId() )
+ {
+ findEngine = iFindEngines[findEngineIndex];
+ break;
+ }
+ }
+
+ if( !findEngine )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ TMdCQueryLockType extraData = (TMdCQueryLockType)aMsg.Int3();
+ if (extraData == ELock && aMsg.HasCapability( ECapabilityWriteDeviceData ) )
+ {
+ findEngine->LockFindResultObjectsL( iServer.LockList() );
+ }
+
+ // write result to client's result buffer
+ aMsg.WriteL( 1, findEngine->ResultsL().Buffer() );
+
+ if ( serverRequest != EAsyncFindSetReady )
+ {
+ delete findEngine;
+
+ iFindEngines.Remove( findEngineIndex );
+ }
+ }
+ break;
+ case EListen:
+ {
+ __LOGLB( ELogServer, "-> Get data (Listen)" );
+ CMdSNotifier::TEntry& entry = iServer.Notifier().FindEntryL( aMsg.Int3() );
+ CMdCSerializationBuffer* buffer = entry.GetDataBuffer();
+ CleanupStack::PushL( buffer );
+ aMsg.WriteL( 1, buffer->Buffer() );
+ CleanupStack::PopAndDestroy( buffer );
+ }
+ break;
+ default:
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CancelObjectL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::CancelObjectL( const RMessage2& aMsg )
+ {
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aMsg, 0 );
+
+ const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( *buffer );
+ if ( itemIds.iObjectIds.iPtr.iCount != 1 )
+ {
+ User::Leave( KErrArgument );
+ }
+ TItemId idValue;
+ buffer->PositionL( itemIds.iObjectIds.iPtr.iOffset );
+ buffer->ReceiveL( idValue );
+
+ CMdsSchema& schema = iServer.Schema();
+ const CMdsNamespaceDef* namespaceDef = schema.GetNamespaceByIdL( itemIds.iNamespaceDefId );
+
+ if (iServer.LockList().IsLocked( *namespaceDef, idValue ) )
+ {
+ iServer.LockList().UnlockById( *namespaceDef, idValue );
+ }
+ else
+ {
+ idValue = KNoId;
+ }
+
+ buffer->PositionL( itemIds.iObjectIds.iPtr.iOffset );
+ buffer->InsertL( idValue );
+
+ aMsg.WriteL( 0, buffer->Buffer() );
+ CleanupStack::PopAndDestroy( buffer ); // buffer
+ }
+
+// ---------------------------------------------------------------------------
+// UpdateL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::UpdateL( const RMessage2& aMsg )
+ {
+ TInt successfulLength = aMsg.GetDesLengthL( 1 );
+
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( aMsg, 0 );
+ CMdCSerializationBuffer* successfullBuffer = CMdCSerializationBuffer::NewLC( successfulLength );
+
+ iServer.Manipulate().UpdateL( *buffer, *successfullBuffer );
+ aMsg.WriteL( 1, successfullBuffer->Buffer() );
+ CleanupStack::PopAndDestroy( 2, buffer ); // successfullBuffer, buffer
+ }
+
+// ---------------------------------------------------------------------------
+// RegisterL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::RegisterL( const RMessage2& aMsg )
+ {
+ __LOG3( ELogServer, "-> Register %u for NS: %u Type: %d",
+ (TUint32)aMsg.Int0(), (TDefId)aMsg.Int3(), aMsg.Int1() );
+
+ TInt length = aMsg.GetDesLength( 2 );
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC( length );
+ TPtr8 bufferPtr( buffer->Buffer() );
+ aMsg.ReadL( 2, bufferPtr );
+
+ iServer.Notifier().CreateEntryL( aMsg.Int0(),
+ (TConditionType)aMsg.Int1(), buffer, (TDefId)aMsg.Int3(), *this,
+ aMsg.HasCapability(ECapabilityReadDeviceData) );
+
+ CleanupStack::Pop( buffer );
+ }
+
+// ---------------------------------------------------------------------------
+// ListenL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ListenL( const RMessage2& aMsg )
+ {
+ const TInt notifierId = aMsg.Int0();
+ __LOG1( ELogServer, "-> Listen %d", notifierId );
+
+ CMdSNotifier::TEntry& entry = iServer.Notifier().FindEntryL( notifierId );
+ entry.SetupForCallback( aMsg, 1 );
+
+ const TInt count = iNotificationCache.Count();
+ for( TInt i = 0; i < count; ++i )
+ {
+ const TInt notificationCacheId = iNotificationCache[i]->iId;
+ const TInt entryId = entry.Id();
+
+ if( notificationCacheId == entryId )
+ {
+ // The cache holds a new notification for this notifier, trigger it
+ CNotificationCacheItem* item = iNotificationCache[i];
+ iNotificationCache.Remove(i);
+
+ CleanupStack::PushL( item );
+
+ entry.TriggerCachedL( item->iCode, item->iData );
+
+ // take ownership of iData from item and delete it
+ item->iData = NULL;
+ CleanupStack::PopAndDestroy( item );
+
+ return;
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// UnregisterL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::UnregisterL( const RMessage2& aMsg )
+ {
+ __LOG1( ELogServer, "-> Unregister %d", aMsg.Int0() );
+ TInt id = aMsg.Int0();
+ iServer.Notifier().RemoveEntryL(id);
+ TInt count = iNotificationCache.Count();
+ for(TInt i(count - 1); i >= 0; --i)
+ {
+ if(iNotificationCache[i]->iId == id)
+ {
+ delete iNotificationCache[i]->iData;
+ iNotificationCache[i]->iData = NULL;
+ iNotificationCache.Remove(i);
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CacheNotificationL caches a notifier event
+// ---------------------------------------------------------------------------
+//
+
+CMdCSerializationBuffer* CMdSServerSession::CombineBuffersL(CMdCSerializationBuffer& aLeftBuffer,
+ CMdCSerializationBuffer& aRightBuffer )
+ {
+ // IDs are always stored in object IDs,
+ // even if those are actually relation or event IDs
+
+ aLeftBuffer.PositionL( KNoOffset );
+ aRightBuffer.PositionL( KNoOffset );
+
+ const TMdCItemIds& leftItemIds = TMdCItemIds::GetFromBufferL( aLeftBuffer );
+ const TMdCItemIds& rightItemIds = TMdCItemIds::GetFromBufferL( aRightBuffer );
+
+ // check that namespaces match
+ if ( leftItemIds.iNamespaceDefId != rightItemIds.iNamespaceDefId )
+ {
+ return NULL;
+ }
+
+ // create new buffer, which will contain combined results
+ const TInt leftBufferSize = aLeftBuffer.Size();
+ const TInt rightBufferSize = aRightBuffer.Size();
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC(
+ leftBufferSize + rightBufferSize );
+
+ TMdCItemIds combinedItemIds;
+
+ // use left buffer's data as base line
+ Mem::Copy( &combinedItemIds, &leftItemIds, sizeof( TMdCItemIds ) );
+
+ // and add right buffer's relation count
+ combinedItemIds.iObjectIds.iPtr.iCount += rightItemIds.iObjectIds.iPtr.iCount;
+
+ combinedItemIds.SerializeL( *buffer );
+
+ // move left and right buffer to begin of relations
+ aLeftBuffer.PositionL( leftItemIds.iObjectIds.iPtr.iOffset );
+ aRightBuffer.PositionL( rightItemIds.iObjectIds.iPtr.iOffset );
+
+ // copy IDs from left and right buffers to combined buffer
+ for (TInt i = 0; i < leftItemIds.iObjectIds.iPtr.iCount; ++i)
+ {
+ TItemId id;
+ aLeftBuffer.ReceiveL( id );
+ buffer->InsertL( id );
+ }
+
+ for (TInt i = 0; i < rightItemIds.iObjectIds.iPtr.iCount; ++i)
+ {
+ TItemId id;
+ aRightBuffer.ReceiveL( id );
+ buffer->InsertL( id );
+ }
+
+ CleanupStack::Pop( buffer );
+ return buffer;
+ }
+
+CMdCSerializationBuffer* CMdSServerSession::CombineItemBuffersL( CMdCSerializationBuffer& aLeftBuffer,
+ CMdCSerializationBuffer& aRightBuffer )
+ {
+ // Current implementation supports only combining relations
+ // (used in remove relation item observer case)
+
+ aLeftBuffer.PositionL( KNoOffset );
+ aRightBuffer.PositionL( KNoOffset );
+
+ const TMdCItems& leftItems = TMdCItems::GetFromBufferL( aLeftBuffer );
+ const TMdCItems& rightItems = TMdCItems::GetFromBufferL( aRightBuffer );
+
+ // check that namespaces match
+ if ( leftItems.iNamespaceDefId != rightItems.iNamespaceDefId )
+ {
+ return NULL;
+ }
+
+ // create new buffer, which will contain combined results
+ const TInt leftBufferSize = aLeftBuffer.Size();
+ const TInt rightBufferSize = aRightBuffer.Size();
+ CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC(
+ leftBufferSize + rightBufferSize );
+
+ TMdCItems combinedItems;
+
+ // use left buffer's data as base line
+ Mem::Copy( &combinedItems, &leftItems, sizeof( TMdCItems ) );
+
+ // and add right buffer's relation count
+ combinedItems.iRelations.iPtr.iCount += rightItems.iRelations.iPtr.iCount;
+
+ combinedItems.SerializeL( *buffer );
+
+ // move left and right buffer to begin of relations
+ aLeftBuffer.PositionL( leftItems.iRelations.iPtr.iOffset );
+ aRightBuffer.PositionL( rightItems.iRelations.iPtr.iOffset );
+
+ // copy relations from left and right buffers to combined buffer
+ for ( TUint32 i = 0; i < leftItems.iRelations.iPtr.iCount; ++i )
+ {
+ TMdCRelation& leftRelation = CONST_CAST( TMdCRelation&,
+ TMdCRelation::GetFromBufferL( aLeftBuffer ) );
+
+ leftRelation.SerializeL( *buffer );
+ }
+
+ for ( TUint32 i = 0; i < rightItems.iRelations.iPtr.iCount; ++i )
+ {
+ TMdCRelation& rightRelation = CONST_CAST( TMdCRelation&,
+ TMdCRelation::GetFromBufferL( aRightBuffer ) );
+
+ rightRelation.SerializeL( *buffer );
+ }
+
+ CleanupStack::Pop( buffer );
+ return buffer;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CacheNotificationL caches a notifier event
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::CacheNotificationL(TInt aId, TUint32 aCompleteCode, CMdCSerializationBuffer* aData)
+ {
+ CleanupStack::PushL( aData );
+
+ const TInt notificationCount = iNotificationCache.Count();
+
+ const TInt KMaxCachedItems = 256;
+
+ if(notificationCount > KMaxCachedItems)
+ {
+ User::Leave( KErrOverflow );
+ }
+
+ if( aData )
+ {
+ // search for matching notification and combine new results to it
+ for (TInt i = 0; i < notificationCount; ++i)
+ {
+ CNotificationCacheItem& notificationItem = *iNotificationCache[i];
+ if ( notificationItem.iId == aId && notificationItem.iCode == aCompleteCode )
+ {
+ CMdCSerializationBuffer* data = NULL;
+ // combine buffers
+ if ( notificationItem.iCode != ERelationItemNotifyRemove )
+ {
+ data = CombineBuffersL( *notificationItem.iData, *aData );
+ }
+ else
+ {
+ data = CombineItemBuffersL( *notificationItem.iData, *aData );
+ }
+ // delete unecessary ones and change iData to new data
+ if (data)
+ {
+ CleanupStack::PopAndDestroy( aData );
+
+ delete notificationItem.iData;
+ notificationItem.iData = data;
+ return;
+ }
+ }
+ }
+ }
+
+ // change ownership of aData to item
+ CNotificationCacheItem* item =
+ new (ELeave) CNotificationCacheItem( aId, aCompleteCode, aData );
+ CleanupStack::Pop( aData );
+ CleanupStack::PushL( item );
+
+ iNotificationCache.AppendL( item );
+
+ CleanupStack::Pop( item );
+ }
+
+CMdSServer& CMdSServerSession::GetServer() const
+ {
+ return iServer;
+ }
+
+// ---------------------------------------------------------------------------
+// ShutdownL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ShutdownL( const RMessage2& /*aMsg*/ )
+ {
+ __LOGLB( ELogServer, "-> Shutdown session" );
+
+ const TInt count = iFindEngines.Count();
+
+ for( TInt i = 0; i < count; i++ )
+ {
+ CMdSFindEngine* fe = iFindEngines[i];
+
+ fe->Cancel( KErrNone );
+ }
+ iFindEngines.ResetAndDestroy();
+ iFindEngines.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// SizeToRemoteL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::SizeToRemoteL( const RMessage2& aMsg,
+ TInt aMessageSlot, TInt aSize)
+ {
+ __LOGLB( ELogServer, "-> Size to remote" );
+ TPckgBuf<TInt> sizeBuf( aSize );
+ aMsg.WriteL( aMessageSlot, sizeBuf );
+ }
+
+// ---------------------------------------------------------------------------
+// ImportSchemaL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ImportSchemaL( const RMessage2& aMsg )
+ {
+ __LOGLB( ELogServer, "-> Import schema" );
+
+ const TInt fileNameLength = aMsg.GetDesLength( 0 );
+ if ( fileNameLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ RBuf fileName;
+ fileName.Create( fileNameLength );
+ CleanupClosePushL( fileName );
+ aMsg.ReadL( 0, fileName );
+
+ TVendorId id = aMsg.VendorId();
+ iServer.Maintenance().ImportSchemaL( iServer.Schema(), fileName, id.iId );
+ CleanupStack::PopAndDestroy( &fileName );
+ }
+
+// ---------------------------------------------------------------------------
+// ImportMetadataL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ImportMetadataL( const RMessage2& aMsg )
+ {
+ __LOGLB( ELogServer, "-> Import (async?) metadata" );
+
+ const TInt fileNameLength = aMsg.GetDesLength( 0 );
+ if ( fileNameLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ RBuf fileName;
+ fileName.Create( fileNameLength );
+ CleanupClosePushL( fileName );
+ aMsg.ReadL( 0, fileName );
+
+ // if result is negative then result is error code
+ // else result is item import fail count
+ TInt result = iServer.Maintenance().ImportMetadataL(
+ iServer.Manipulate(), iServer.Schema(), fileName );
+
+ CleanupStack::PopAndDestroy( &fileName );
+
+ TPckgBuf<TInt> failBuf( result );
+ aMsg.WriteL( 1, failBuf );
+ }
+
+// ---------------------------------------------------------------------------
+// ExportMetadataL
+// ---------------------------------------------------------------------------
+//
+void CMdSServerSession::ExportMetadataL( const RMessage2& aMsg )
+ {
+ const TInt fileNameLength = aMsg.GetDesLength( 0 );
+ if ( fileNameLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ RBuf fileName;
+ fileName.Create( fileNameLength );
+ CleanupClosePushL( fileName );
+ aMsg.ReadL( 0, fileName );
+
+ CMdCSerializationBuffer* items = CMdCSerializationBuffer::NewLC( aMsg, 1 );
+
+ iServer.Maintenance().ExportMetadataL( iServer.Schema(), fileName, *items );
+
+ CleanupStack::PopAndDestroy( 2, &fileName ); // items, fileName
+ }
+
+void CMdSServerSession::AddMemoryCardL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.ReadL( 0, mediaIdPckg );
+
+ iServer.Manipulate().AddMemoryCardL( mediaId );
+ }
+
+void CMdSServerSession::GetMemoryCardL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+
+ iServer.Manipulate().GetMemoryCardL( mediaId );
+
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.WriteL( 0, mediaIdPckg );
+ }
+
+void CMdSServerSession::CheckMemoryCardL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.ReadL( 0, mediaIdPckg );
+
+ TBool result = iServer.Manipulate().CheckMemoryCardL( mediaId );
+
+ TPckg<TBool> resultPckg( result );
+ aMessage.WriteL( 1, resultPckg );
+ }
+
+void CMdSServerSession::SetMediaL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.ReadL( 0, mediaIdPckg );
+ TChar drive;
+ TPckg<TChar> drivePckg( drive );
+ aMessage.ReadL( 1, drivePckg );
+ TBool presentState;
+ TPckg<TBool> presentStatePckg( presentState );
+ aMessage.ReadL( 2, presentStatePckg );
+
+ iServer.Manipulate().SetMediaL( mediaId, drive, presentState );
+ }
+
+void CMdSServerSession::GetMediaL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.ReadL( 0, mediaIdPckg );
+
+ TChar drive;
+ TBool presentState;
+
+ const TBool exists = iServer.Manipulate().GetMediaL( mediaId, drive,
+ presentState );
+
+ if( exists )
+ {
+ TPckg<TChar> drivePckg( drive );
+ aMessage.WriteL( 1, drivePckg );
+ TPckg<TBool> presentStatePckg( presentState );
+ aMessage.WriteL( 2, presentStatePckg );
+ }
+
+ TPckg<TBool> existsPckg( exists );
+ aMessage.WriteL( 3, existsPckg );
+ }
+
+void CMdSServerSession::GetPresentMediasL(const RMessage2& aMessage)
+ {
+ // buffer size for media info for every possible drive
+ const TInt32 KMediaInfoSize = sizeof( TMdEMediaInfo ) * KMaxDrives;
+
+ RBuf8 mediaInfoBuffer;
+ mediaInfoBuffer.Create( KMediaInfoSize );
+ CleanupClosePushL( mediaInfoBuffer );
+
+ const TInt32 mediaCount = iServer.Manipulate().GetPresentMediasL(
+ mediaInfoBuffer );
+
+ TPckgC<TInt32> mediaCountPckg( mediaCount );
+ aMessage.WriteL( 0, mediaCountPckg );
+
+ if( mediaCount > 0)
+ {
+ const TInt32 mediaInfosLength = aMessage.GetDesMaxLength( 1 );
+ if ( mediaInfosLength < KMediaInfoSize )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ aMessage.WriteL( 1, mediaInfoBuffer );
+ }
+
+ CleanupStack::PopAndDestroy(); //mediaInfoBuffer
+ }
+
+void CMdSServerSession::SetFilesToPresentL(const RMessage2& aMessage)
+ {
+ TMdSMediaIdAndCount mediaIdAndCount;
+ TPckg<TMdSMediaIdAndCount> mediaIdAndCountPckg( mediaIdAndCount );
+ aMessage.Read( 0, mediaIdAndCountPckg );
+
+ CMdCSerializationBuffer* uris = CMdCSerializationBuffer::NewLC( aMessage, 1 );
+ CMdCSerializationBuffer* fileInfos = CMdCSerializationBuffer::NewLC( aMessage, 2 );
+
+ TInt resultsSize = aMessage.GetDesMaxLengthL( 3 );
+ if( resultsSize < ( mediaIdAndCount.iCount * CMdCSerializationBuffer::KRequiredSizeForTUint8 ) )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+ CMdCSerializationBuffer* results = CMdCSerializationBuffer::NewLC( resultsSize );
+
+ iServer.Manipulate().SetFilesToPresentL(
+ mediaIdAndCount.iMediaId, mediaIdAndCount.iCount, *uris, *fileInfos,
+ *results );
+
+ aMessage.WriteL( 3, results->Buffer() );
+
+ CleanupStack::PopAndDestroy( results );
+ CleanupStack::PopAndDestroy( fileInfos );
+ CleanupStack::PopAndDestroy( uris );
+ }
+
+
+void CMdSServerSession::SetFilesToNotPresentL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.Read( 0, mediaIdPckg );
+
+ TBool startUp;
+ TPckg<TBool> startUpPckg( startUp );
+ aMessage.Read( 1, startUpPckg );
+
+ // only accept correct media IDs, other are silently ignored
+ if( mediaId != 0 )
+ {
+ iServer.Manipulate().SetFilesToNotPresentL( mediaId, startUp );
+ }
+ }
+
+void CMdSServerSession::RemoveFilesNotPresentL(const RMessage2& aMessage)
+ {
+ TUint32 mediaId;
+ TPckg<TUint32> mediaIdPckg( mediaId );
+ aMessage.Read( 0, mediaIdPckg );
+
+ TBool startUp;
+ TPckg<TBool> startUpPckg( startUp );
+ aMessage.Read( 1, startUpPckg );
+
+ iServer.Manipulate().RemoveFilesNotPresentL( mediaId, startUp );
+ }
+
+void CMdSServerSession::GetSchemaVersionL(const RMessage2& aMessage)
+ {
+ TInt majorVersion, minorVersion;
+
+ iServer.Manipulate().GetSchemaVersionL( majorVersion, minorVersion );
+
+ TPckg<TInt> pckgMajorVersion( majorVersion );
+ TPckg<TInt> pckgMinorVersion( minorVersion );
+ aMessage.WriteL( 0, pckgMajorVersion );
+ aMessage.WriteL( 1, pckgMinorVersion );
+ }
+
+void CMdSServerSession::SetObjectToPresentByGuidL(const RMessage2& aMessage)
+ {
+ TInt64 guidHigh;
+ TPckg<TInt64> guidHighPckg( guidHigh );
+ aMessage.ReadL( ESetObjectToPresentByGuidArgGuidHigh, guidHighPckg );
+
+ TInt64 guidLow;
+ TPckg<TInt64> guidLowPckg( guidLow );
+ aMessage.ReadL( ESetObjectToPresentByGuidArgGuidLow, guidLowPckg );
+
+ iServer.Manipulate().SetObjectToPresentByGuidL( guidHigh, guidLow );
+ }
+
+void CMdSServerSession::ChangePathL(const RMessage2& aMessage)
+ {
+ const TInt oldPathLength = aMessage.GetDesLength( 0 );
+ if ( oldPathLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ const TInt newPathLength = aMessage.GetDesLength( 1 );
+ if ( newPathLength <= 0 )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ RBuf oldPath;
+ oldPath.Create( oldPathLength );
+ CleanupClosePushL( oldPath );
+ aMessage.ReadL( 0, oldPath );
+
+ RBuf newPath;
+ newPath.Create( newPathLength );
+ CleanupClosePushL( newPath );
+ aMessage.ReadL( 1, newPath );
+
+ iServer.Manipulate().ChangePathL( oldPath, newPath );
+
+ CleanupStack::PopAndDestroy(&newPath);
+ CleanupStack::PopAndDestroy(&oldPath);
+ }
+
+void CMdSServerSession::ChangeMediaIdL( const RMessage2& /*aMessage*/ )
+ {
+ iServer.Manipulate().ChangeMediaIdL();
+ }
+
+void CMdSServerSession::SetPendingL(const RMessage2& aMessage)
+ {
+ const TInt serializedObjectIdsLength = aMessage.GetDesLength( 0 );
+
+ if ( serializedObjectIdsLength < 0 || serializedObjectIdsLength % sizeof( TItemId ) )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ if( serializedObjectIdsLength > 0 )
+ {
+ RArray<TItemId> objectIds;
+ CleanupClosePushL( objectIds );
+
+ HBufC8* serializedObjectIds = HBufC8::NewLC( serializedObjectIdsLength );
+
+ TPtr8 ptr = serializedObjectIds->Des();
+ aMessage.ReadL( 0, ptr );
+
+ DeserializeArrayL( *serializedObjectIds, objectIds );
+
+ iServer.Manipulate().SetPendingL( objectIds );
+
+ CleanupStack::PopAndDestroy( serializedObjectIds );
+
+ CleanupStack::PopAndDestroy( &objectIds );
+ }
+ }
+
+void CMdSServerSession::ResetPendingL(const RMessage2& aMessage)
+ {
+ const TInt serializedObjectIdsLength = aMessage.GetDesLength( 0 );
+
+ if ( serializedObjectIdsLength < 0 || serializedObjectIdsLength % sizeof( TItemId ) )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ if( serializedObjectIdsLength > 0 )
+ {
+ RArray<TItemId> objectIds;
+ CleanupClosePushL( objectIds );
+
+ HBufC8* serializedObjectIds = HBufC8::NewLC( serializedObjectIdsLength );
+
+ TPtr8 ptr = serializedObjectIds->Des();
+ aMessage.ReadL( 0, ptr );
+
+ DeserializeArrayL( *serializedObjectIds, objectIds );
+
+ iServer.Manipulate().ResetPendingL( objectIds );
+
+ CleanupStack::PopAndDestroy( serializedObjectIds );
+
+ CleanupStack::PopAndDestroy( &objectIds );
+ }
+ }
+
+TInt CMdSServerSession::GetPendingCountL(const RMessage2& aMessage)
+ {
+ TDefId objectDefId;
+ TPckg<TDefId> objectDefIdPckg( objectDefId );
+ aMessage.ReadL( 0, objectDefIdPckg );
+
+ TInt result = iServer.Manipulate().GetPendingCountL( objectDefId );
+
+ TPckg<TInt> objectIdCountPckg( result );
+ aMessage.WriteL( 1, objectIdCountPckg );
+
+ return KErrNone;
+ }
+
+TInt CMdSServerSession::GetPendingL(const RMessage2& aMessage)
+ {
+ TDefId objectDefId;
+ TPckg<TDefId> objectDefIdPckg( objectDefId );
+ aMessage.ReadL( 0, objectDefIdPckg );
+
+ const TInt serializedObjectIdsLength = aMessage.GetDesLength( 2 );
+
+ if ( serializedObjectIdsLength < sizeof(TItemId) ||
+ serializedObjectIdsLength % sizeof(TItemId) )
+ {
+ User::Leave( KErrBadDescriptor );
+ }
+
+ RArray<TItemId> objectIds;
+ CleanupClosePushL( objectIds );
+
+ TInt bufferSize = serializedObjectIdsLength / sizeof(TItemId);
+
+ TInt result = iServer.Manipulate().GetPendingL( objectDefId, bufferSize, objectIds );
+
+ const TInt objectIdCount = objectIds.Count();
+
+ TPckg<TInt> resultPckg( result );
+ aMessage.WriteL( 3, resultPckg );
+
+ TPckg<TInt> objectIdCountPckg( objectIdCount );
+ aMessage.WriteL( 1, objectIdCountPckg );
+
+ if( objectIdCount > 0 )
+ {
+ HBufC8* serializedObjectIds = SerializeArrayL( objectIds );
+ CleanupStack::PushL( serializedObjectIds );
+
+ aMessage.WriteL( 2, serializedObjectIds->Des() );
+
+ CleanupStack::PopAndDestroy( serializedObjectIds );
+ }
+
+ CleanupStack::PopAndDestroy( &objectIds );
+
+ return KErrNone;
+ }
+