metadataengine/server/src/mdsserversession.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
--- /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;
+	}
+