messagingfw/msgsrvnstore/server/src/MSVSESS.CPP
changeset 62 db3f5fa34ec7
equal deleted inserted replaced
60:9f5ae1728557 62:db3f5fa34ec7
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #ifdef _DEBUG
       
    17 #undef _NO_SERVER_LOGGING_
       
    18 #endif
       
    19 
       
    20 
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <s32mem.h>
       
    24 #include <tmsvsystemprogress.h>
       
    25 
       
    26 #include "MSVSTD.H"
       
    27 #include "MSVIPC.H"
       
    28 #include "MSVREG.H"
       
    29 #include "MSVREGIP.H"
       
    30 #include "MSVIDS.H"
       
    31 #include "MSVUIDS.H"
       
    32 #include "MSVENTRY.H"
       
    33 #include "MSERVER.H"
       
    34 #include "MSVSERV.H"
       
    35 #include "MSVLOPS.H"
       
    36 #include "MSVROPS.H"
       
    37 #include "MSVUTILS.H"
       
    38 #include "MTSR.H"
       
    39 #include "MSVPANIC.H"
       
    40 #include "CMsvChangeBuffer.h"
       
    41 #include "MsvSecurityCapabilitySet.h"
       
    42 #include "cmsvcopystoreoperation.h"
       
    43 #include "cmsvdeletestoreoperation.h"
       
    44 #include "MSVAPI.H"
       
    45 #include "msvindexadapter.h"
       
    46 #include "msvcacheentry.h"
       
    47 #include "msvsearchsortcacheentry.h"
       
    48 #include "msvsearchsortcachemanager.h"
       
    49 #include "msvsearchsortdeltacache.h"
       
    50 #include <msvsearchsortquery.h>
       
    51 #include <msvsearchsortoperation.h>
       
    52 
       
    53 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
    54 #include <u32std.h>
       
    55 #include "cmsvconverterwaiter.h"
       
    56 #endif
       
    57 
       
    58 const TInt KMsvOperationIndexGranularity=8;
       
    59 const TInt KMsvOperationDataArrayGranularity=4;
       
    60 const TInt KMsvMtmRefCountArrayGranularity=4;
       
    61 
       
    62 _LIT(KMsvClientPanicString, "MSGS Client");
       
    63 
       
    64 //**********************************
       
    65 // TMtmGroupRefCount
       
    66 //**********************************
       
    67 
       
    68 TMtmGroupRefCount::TMtmGroupRefCount(TUid aMtmTypeUid)
       
    69 : iMtmTypeUid(aMtmTypeUid), iRefCount(0)
       
    70 	{}
       
    71 
       
    72 //**********************************
       
    73 // CMsvOperationData
       
    74 //**********************************
       
    75 
       
    76 CMsvOperationData::CMsvOperationData(TMsvOp aOpId)
       
    77 : iOpId(aOpId)
       
    78 	{
       
    79 	__DECLARE_NAME(_S("CMsvOperationData"));
       
    80 	}
       
    81 
       
    82 CMsvOperationData::~CMsvOperationData()
       
    83 	{
       
    84 	delete iBuffer;
       
    85 	}
       
    86 
       
    87 //**********************************
       
    88 // CMsvServerSession
       
    89 //**********************************
       
    90 
       
    91 CMsvServerSession::CMsvServerSession(CMsvServer& aServer)
       
    92 :   CSession2(),
       
    93 	iMsvServer(aServer),
       
    94 	iOperations(KMsvOperationIndexGranularity),
       
    95 	iMtmGroupRefCountArray(KMsvMtmRefCountArrayGranularity),
       
    96 	iOperationDataArray(KMsvOperationDataArrayGranularity),
       
    97 	iReceiveEntryEvents(ETrue)
       
    98 	{
       
    99 	__DECLARE_NAME(_S("CMsvServerSession"));
       
   100 	iSessionId = iMsvServer.SessionId();
       
   101 	}
       
   102 
       
   103 CMsvServerSession* CMsvServerSession::NewL(CMsvServer& aServer, const RMessage2 &aMessage)
       
   104 	{
       
   105 	CMsvServerSession* self = new(ELeave) CMsvServerSession(aServer);
       
   106 	CleanupStack::PushL(self);
       
   107 	self->ConstructL(aMessage);
       
   108 	CleanupStack::Pop();
       
   109 	return self;
       
   110 	}
       
   111 
       
   112 
       
   113 void CMsvServerSession::ConstructL(const RMessage2 &aMessage)
       
   114 	{
       
   115 	iChangeBuffer = CMsvChangeBuffer::NewL();
       
   116 	iBuffer = HBufC8::NewL(KMsvSessionBufferLength);
       
   117 	iChildrenSelection = new(ELeave) CArrayPtrSeg<const TMsvEntry>(16);
       
   118 	iChildrenSelectionIds = new(ELeave) CMsvEntrySelection;
       
   119 	
       
   120 	// if the index is already loaded, tell the client
       
   121 	if (iMsvServer.HasContext() && iMsvServer.Context().State()==TMsvIndexLoadProgress::EIndexComplete)
       
   122 		{
       
   123 		TMsvNotifBuffer buffer;
       
   124 		TMsvPackedChangeNotification package(buffer);
       
   125 		package.Pack(EMsvIndexLoaded, 0, 0, 0);
       
   126 		NotifyChangedL(buffer);
       
   127 
       
   128 		// Send disk status notifications
       
   129 		if (iMsvServer.StartupState() != EMsvNullNotification)
       
   130 			{
       
   131 			package.Pack(iMsvServer.StartupState(), KMsvNullIndexEntryId, iMsvServer.Context().Config().iDrive, 0);
       
   132 			NotifyChangedL(buffer);
       
   133 			}
       
   134 	
       
   135 	#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   136 			// if we have unsupported drives, notify the client
       
   137 		if(FoundUnSupportedDrives())
       
   138 			{
       
   139 			package.Pack(EMsvMessageStoreNotSupported, 0, 0, 0);
       
   140 			NotifyChangedL(buffer);
       
   141 			}
       
   142 	#endif
       
   143 		}
       
   144 
       
   145 	RThread thread;
       
   146 	aMessage.Client(thread);
       
   147 	iProcessName = thread.Name();
       
   148 	thread.Close();
       
   149 	}
       
   150 
       
   151 
       
   152 CMsvServerSession::~CMsvServerSession()
       
   153 	{
       
   154 	// releasing locks
       
   155 	__ASSERT_DEBUG(iLockedStores.Count()==0, PanicClient(iQueuedMessage, EMsvLockedStoresOnExit));
       
   156 	TInt count = iLockedStores.Count();
       
   157 	while (count--)
       
   158 		{
       
   159 		iMsvServer.IndexAdapter().ReleaseStore(iLockedStores.At(count)); // ignore any errors
       
   160 		}
       
   161 
       
   162 
       
   163 	// deleting outstanding operations
       
   164 	__ASSERT_DEBUG(iOperations.Count()==0, PanicClient(iQueuedMessage, EMsvOutstandingOperationsOnExit));
       
   165 	count=iOperations.Count();
       
   166 	while (count--)
       
   167 		{
       
   168 		delete iOperations.At(count); // operation are deleted last in first out order
       
   169 		iOperations.Delete(count);
       
   170 		}
       
   171 
       
   172 	iOperationDataArray.ResetAndDestroy();
       
   173 	iMtmGroupRefCountArray.Reset();
       
   174 
       
   175 	// Set request queued flag to false so we're not notified to close the session
       
   176 	iRequestQueued = EFalse;
       
   177 
       
   178 	iMsvServer.ClosingSession(iSessionId);
       
   179 
       
   180 	delete iChildrenSelection;
       
   181 	delete iChildrenSelectionIds;
       
   182 	if(iChangeBuffer != NULL)
       
   183 		{
       
   184 		delete iChangeBuffer;
       
   185 		}
       
   186 	if(iBuffer != NULL)
       
   187 		{
       
   188 		delete iBuffer;
       
   189 		
       
   190 		}
       
   191 	}
       
   192 
       
   193 void CMsvServerSession::ServiceL(const RMessage2& aMessage)
       
   194 //
       
   195 //
       
   196 //
       
   197 	{
       
   198 	if ((!iMsvServer.HasContext() || iMsvServer.Context().State()!=TMsvIndexLoadProgress::EIndexComplete) && aMessage.Function()!=EMsvNotifySessionEvent && aMessage.Function()!=EMsvCancelSessionEventNotification)
       
   199 		aMessage.Complete(KErrNotReady);
       
   200 	else
       
   201 		{
       
   202 		TRAPD(error, DoServiceL(aMessage));
       
   203 		if (error)
       
   204 			aMessage.Complete(error);
       
   205 		}
       
   206 	}
       
   207 
       
   208 void CMsvServerSession::DoServiceL(const RMessage2& aMessage)
       
   209 //
       
   210 // service a client request; test the opcode and then do appropriate servicing
       
   211 //
       
   212 	{
       
   213 	// all functions called should ensure that all synchronous messages have been completed
       
   214 	switch (aMessage.Function())
       
   215 		{
       
   216 		case EMsvNotifySessionEvent:
       
   217 			QueueSessionEventRequestL(aMessage);
       
   218 			break;
       
   219 		case EMsvCancelSessionEventNotification:
       
   220 			CancelSessionEventRequest(aMessage);
       
   221 			break;
       
   222 		case EMsvOperationData:
       
   223 			CopyOperationDataL(aMessage);
       
   224 			break;
       
   225 		case EMsvCommandData:
       
   226 			CopyCommandDataL(aMessage);
       
   227 			break;
       
   228 		case EMsvCreateEntry:
       
   229 			CreateEntryL(aMessage);
       
   230 			break;
       
   231 		case EMsvGetEntry:
       
   232 			GetEntryL(aMessage);
       
   233 			break;
       
   234 		case EMsvChangeEntry:
       
   235 			ChangeEntryL(aMessage);
       
   236 			break;
       
   237 		case EMsvGetChildren:
       
   238 			GetChildrenL(aMessage);
       
   239 			break;
       
   240 		case EMsvGetRemainingChildren:
       
   241 			GetRemainingChildrenL(aMessage);
       
   242 			break;
       
   243 		case EMsvDeleteEntries:
       
   244 			DeleteEntriesL(aMessage);
       
   245 			break;
       
   246 		case EMsvLockEntry:
       
   247 			LockEntryL(aMessage);
       
   248 			break;
       
   249 		case EMsvReleaseEntry:
       
   250 			ReleaseEntryL(aMessage);
       
   251 			break;
       
   252 		case EMsvReadStore:
       
   253 			ReadStoreL(aMessage);
       
   254 			break;
       
   255 		case EMsvLockStore:
       
   256 			LockStoreL(aMessage);
       
   257 			break;
       
   258 		case EMsvReleaseStore:
       
   259 			ReleaseStoreL(aMessage);
       
   260 			break;
       
   261 		case EMsvCancelOperation:
       
   262 			CancelOperationL(aMessage);
       
   263 			break;
       
   264 		case EMsvOperationCompletion:
       
   265 			OperationCompletionL(aMessage);
       
   266 			break;
       
   267 		case EMsvOperationProgress:
       
   268 			OperationProgressL(aMessage);
       
   269 			break;
       
   270 		case EMsvOperationSystemProgress:
       
   271 			OperationSystemProgressL(aMessage);
       
   272 			break;
       
   273 		case EMsvOperationMtm:
       
   274 			OperationMtmL(aMessage);
       
   275 			break;
       
   276 		case EMsvMoveEntries:
       
   277 			MoveEntriesL(aMessage);
       
   278 			break;
       
   279 		case EMsvCopyEntries:
       
   280 			CopyEntriesL(aMessage);
       
   281 			break;
       
   282 		case EMsvMtmCommand:
       
   283 			TransferCommandL(aMessage);
       
   284 			break;
       
   285 		case EMsvFillRegisteredMtmDllArray:
       
   286 			FillRegisteredMtmDllArray(aMessage);
       
   287 			break;
       
   288 		case EMsvInstallMtmGroup:
       
   289 			MtmGroupL(aMessage, ETrue);
       
   290 			break;
       
   291 		case EMsvDeInstallMtmGroup:
       
   292 			MtmGroupL(aMessage, EFalse);
       
   293 			break;
       
   294 		case EMsvUseMtmGroup:
       
   295 			UseMtmGroup(aMessage);
       
   296 			break;
       
   297 		case EMsvReleaseMtmGroup:
       
   298 			ReleaseMtmGroup(aMessage);
       
   299 			break;
       
   300 		case EMsvGetMtmGroupData:
       
   301 			GetMtmGroupDataL(aMessage);
       
   302 			break;
       
   303 		case EMsvGetMtmRequiredCapabilities:
       
   304 			GetMtmRequiredCapabilitiesL(aMessage);
       
   305 			break;
       
   306 		case EMsvCloseServer:
       
   307 			iMsvServer.CloseServer(aMessage);
       
   308 			break;
       
   309 		case EMsvStopService:
       
   310 			iMsvServer.StopServiceL(aMessage);
       
   311 			break;
       
   312 		case EMsvServiceActive:
       
   313 			iMsvServer.ServiceActive(aMessage);
       
   314 			break;
       
   315 		case EMsvServiceProgress:
       
   316 			ServiceProgressL(aMessage);
       
   317 			break;
       
   318 		case EMsvRemoveEntry:
       
   319 			RemoveEntry(aMessage);
       
   320 			break;
       
   321 		case EMsvGetMessageDirectory:
       
   322 			MessageFolderL(aMessage);
       
   323 			break;
       
   324 		case EMsvSlotAvailable:
       
   325 			if (iOperations.Count()<KMsvMaxSlotsAvailable)
       
   326 				aMessage.Complete(KErrNone);
       
   327 			else
       
   328 				aMessage.Complete(KErrServerBusy);
       
   329 			break;
       
   330 		case EMsvSetSessionAsObserver:
       
   331 			iObserverOnly=ETrue;
       
   332 			aMessage.Complete(KErrNone);
       
   333 			break;
       
   334 		case EMsvSetFailure:
       
   335 			iMsvServer.SetFailure((TMsvFailure)aMessage.Int0(), aMessage.Int1(), aMessage.Int2(), aMessage.Int3());
       
   336 			aMessage.Complete(KErrNone);
       
   337 			break;
       
   338 		case EMsvChangeAttributes:
       
   339 			ChangeAttributesL(aMessage);
       
   340 			break;
       
   341 		case EMsvGetChildIds:
       
   342 			GetChildIdsL(aMessage);
       
   343 			break;
       
   344 		case EMsvChangeDrive:
       
   345 			ChangeDriveL(aMessage);
       
   346 			break;
       
   347 		case EMsvOutstandingOperations:
       
   348 			OutstandingOperationsL(aMessage);
       
   349 			break;
       
   350 		case EMsvGetNotifySequence:
       
   351 			GetNotifySequenceL(aMessage);
       
   352 			break;
       
   353 		case EMsvSetReceiveEntyEvents:
       
   354 			SetReceiveEntryEvents(aMessage);
       
   355 			break;
       
   356 		case EMsvDecStoreReaderCount:
       
   357 			DecStoreReaderCountL(aMessage);
       
   358 			break;
       
   359 		case EMsvGetMessageDrive:
       
   360 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   361 			MessageDrive(aMessage);
       
   362 #else
       
   363 			aMessage.Complete(iMsvServer.Context().Config().iDrive);
       
   364 #endif
       
   365 			break;
       
   366 		case EMsvCreateAttachmentForWrite:
       
   367 			CreateAttachmentForWriteL(aMessage);
       
   368 			break;
       
   369 		case EMsvReplaceAttachmentForWrite:
       
   370 			ReplaceAttachmentForWriteL(aMessage);
       
   371 			break;
       
   372 		case EMsvOpenAttachment:
       
   373 			OpenAttachmentL(aMessage);
       
   374 			break;
       
   375 		case EMsvOpenAttachmentForWrite:
       
   376 			OpenAttachmentForWriteL(aMessage);
       
   377 			break;
       
   378 		case EMsvDeleteAttachment:
       
   379 			DeleteAttachmentL(aMessage);
       
   380 			break;
       
   381 		case EMsvRenameAttachment:
       
   382 			RenameAttachmentL(aMessage);
       
   383 			break;
       
   384 		case EMsvFileExists :
       
   385 			FileExistsL(aMessage);
       
   386 			break;
       
   387 		case EMsvGetAttachmentFilePath:
       
   388 			GetAttachmentFilePathL(aMessage);
       
   389 			break;
       
   390 		case EMsvOpenFileStoreForRead:
       
   391 			OpenFileStoreForReadL(aMessage);
       
   392 			break;
       
   393 		case EMsvOpenTempStoreFile:
       
   394 			OpenTempStoreFileL(aMessage);
       
   395 			break;
       
   396 		case EMsvReplaceFileStore:
       
   397 			ReplaceFileStoreL(aMessage);
       
   398 			break;
       
   399 		case EMsvDeleteFileStore:
       
   400 			DeleteFileStoreL(aMessage);
       
   401 			break;
       
   402 		case EMsvFileStoreExists:
       
   403 			FileStoreExistsL(aMessage);
       
   404 			break;
       
   405 		case EMsvGetAndClearIndexCorruptFlag:
       
   406 			aMessage.Complete(iMsvServer.Context().GetAndClearIndexCorruptFlagL());
       
   407 			break;
       
   408 		case EMsvCopyStore:
       
   409 			CopyStoreL(aMessage);
       
   410 			break;
       
   411 		case EMsvDeleteStore:
       
   412 			DeleteStoreL(aMessage);
       
   413 			break;
       
   414 		case EMsvDriveContainsStore:
       
   415 			aMessage.Complete(MessageServer::DriveContainsStore(iMsvServer.FileSession(),aMessage.Int0()));
       
   416 			break;
       
   417 		case EMsvMessageStoreDrivePresent:
       
   418 			aMessage.Complete(MessageServer::IsMessageStoreDrivePresentL(iMsvServer.FileSession()));			
       
   419 			break;
       
   420 		case EMsvGetBodyTextFilePath:
       
   421 			 BodyTextFilePathL(aMessage);
       
   422 			 break;
       
   423 		case EMsvOpenTextFileForRead:
       
   424 			 OpenPlainTextFileL(aMessage);
       
   425 			 break;
       
   426 		case EMsvCreatePlainTextFile:
       
   427 			 CreatePlainTextFileL(aMessage);
       
   428 			 break;
       
   429 		case EMsvDeletePlainTextFile:
       
   430 			DeletePlainTextFileL(aMessage); 
       
   431 			break;
       
   432 		case EMsvReplacePlainTextFile:
       
   433 			ReplacePlainTextFileL(aMessage);
       
   434 			break;
       
   435 
       
   436 		case EMsvGetNonOperationMtmData:
       
   437 			{
       
   438 			GetNonOperationMtmDataL(aMessage);
       
   439 			break;
       
   440 			}
       
   441 		case EMsvSearchSortOperation: // On HEADER AND BODY
       
   442 			SearchSortOnHeaderAndBodytMsgL(aMessage);
       
   443 			break;
       
   444 	
       
   445 		case EMsvSearchSortOnIndexEntry: //On INDEX ENTRY.
       
   446 			SearchSortOnIndexEntryL(aMessage);
       
   447 			break;
       
   448 
       
   449 		case EMsvGetResult ://Index entry result.
       
   450 			SendSearchSortIndexEntryResultL(aMessage);
       
   451 			break;
       
   452 		
       
   453 		case EMsvGetIdsOrResult://header result.
       
   454 			SendResultOrIdsToSearchL(aMessage);
       
   455 			break;
       
   456 		
       
   457 		case EMsvGetResultCount:
       
   458 			GetSearchSortResultCountL(aMessage);
       
   459 			break;
       
   460 			
       
   461 		case EMsvGetNextId:
       
   462 			GetResultInIteratorL(aMessage);
       
   463 			break;
       
   464 		
       
   465 		case EMsvGetNextEntry:
       
   466 			GetNextEntryInIteratorL(aMessage);
       
   467 			break;
       
   468 		
       
   469 		case EMsvGetQueryId:
       
   470 			GetQueryIDL(aMessage);
       
   471 			break;
       
   472 	
       
   473 		case EMsvUnmarQueryId:
       
   474 			QueryUnMarkedL(aMessage);
       
   475 			break;
       
   476 
       
   477 		case EMsvIdWithSortFiled:
       
   478 			UpdateSearchSortCacheWithSortFiledL(aMessage);
       
   479 			break;
       
   480 	
       
   481 		case EMsvSearchSortQueryId:
       
   482 			GetResultForQueryIDL(aMessage);
       
   483 			break;
       
   484 
       
   485 		case EMsvQueryData:
       
   486 			CopyQueryDataL(aMessage);
       
   487 			break;
       
   488 			
       
   489 		case EMsvGetSearchSortProgress:
       
   490 			GetSearchSortProgressInfoL(aMessage);
       
   491 			break;
       
   492 			
       
   493 		case EMsvCancelSearchSortOp:
       
   494 			SearchSortOperationCancelL(aMessage);
       
   495 			break;
       
   496 			
       
   497 		case EMsvUpdateAndSort:
       
   498 			UpdateSearchSortResultsAndSortByEntryL(aMessage);
       
   499 			break;
       
   500 
       
   501 // Code changes for PREQ 557.	   
       
   502 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   503 		case EMsvGetChildrenALL:
       
   504 			GetChildrenAllL(aMessage);
       
   505 			break;
       
   506 		case EMsvGetChildIdsALL:
       
   507 			GetChildIdsAllL(aMessage);
       
   508 			break;
       
   509 		case EMsvGetCurrentDriveInfo:
       
   510 			CurrentDriveInfoL(aMessage);
       
   511 			break;
       
   512 		case EMsvGetDriveList:
       
   513 			DriveListL(aMessage);	   
       
   514 			break;
       
   515 		case EMsvGetAvailableDriveList:
       
   516 			AvailableDriveListL(aMessage);
       
   517 			break;
       
   518 		case EMsvAddDriveToDriveList:
       
   519 			AddDriveL(aMessage);
       
   520 			break;
       
   521 		case EMsvRemoveDriveFromDriveList:
       
   522 			RemoveDriveL(aMessage); 
       
   523 			break;
       
   524 		case EMsvUpdateDrivePriority:
       
   525 			UpdateDrivePriorityL(aMessage);
       
   526 			break;
       
   527 #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
       
   528 		case EMsvResetRepository:
       
   529 			ResetRepositoryL(aMessage);
       
   530 			break;
       
   531 		case EMsvPrintCache:
       
   532 			PrintCache(aMessage);
       
   533 			break;
       
   534 #endif	  // #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
       
   535 #endif	  // #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
   536 
       
   537 
       
   538 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   539 		case EMsvCreateStore:
       
   540 			CreateHeaderTableL(aMessage);
       
   541 			break;
       
   542 		case EMsvCheckStoreExists:
       
   543 			DoesStoreExistsL(aMessage);
       
   544 			break;
       
   545 		case EMsvLastErrorMessage:
       
   546 			LastErrorMessageL(aMessage);
       
   547 			break;
       
   548 		case EMsvCreateHeaderEntry:
       
   549 			CreateHeaderEntryL(aMessage);
       
   550 			break;
       
   551 		case EMsvLoadHeaderEntry:
       
   552 			LoadHeaderEntryL(aMessage);
       
   553 			break;
       
   554 		case EMsvUpdateHeaderEntry:
       
   555 			UpdateHeaderEntryL(aMessage);
       
   556 			break;
       
   557 		case EMsvDeleteHeaderEntry:
       
   558 			DeleteHeaderEntryL(aMessage);
       
   559 			break;							  
       
   560 		case EMsvCheckAnyStoreExists:
       
   561 			DoesAnyStoreExists(aMessage);
       
   562 			break;
       
   563 		case EMsvCheckHeaderTableExist:
       
   564 			{
       
   565 			DoesHeaderTableExist(aMessage);
       
   566 			break;
       
   567 			}
       
   568 		case EMsvGetConvertibleDriveList:
       
   569 			GetConvertibleDriveListL(aMessage);
       
   570 			break;
       
   571 		case EMsvConvertMessageStore:
       
   572 			ConvertMessageStoreL(aMessage);
       
   573 			break;
       
   574 		case EMsvGetConversionStatus:
       
   575 			GetConversionStatus(aMessage);
       
   576 			break;
       
   577 		case EMsvCancelConversionRequest:
       
   578 			CancelConversionRequestL(aMessage);
       
   579 			break;
       
   580 #endif	  // #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   581 		case EMsvChangeEntries:
       
   582 		     ChangeEntriesL(aMessage);
       
   583 		     break;
       
   584 		default:
       
   585 			PanicClient(aMessage, EMsvBadRequest);
       
   586 			break;
       
   587 		}
       
   588 	}
       
   589 
       
   590 
       
   591 void CMsvServerSession::QueueSessionEventRequestL(const RMessage2 &aMessage)
       
   592 //
       
   593 // The client is requesting notifcation of any changes
       
   594 //
       
   595 	{
       
   596 	if (iRequestQueued)
       
   597 		{
       
   598 		PanicClient(aMessage, EMsvDuplicatedChangeRequest);
       
   599 		return;
       
   600 		}
       
   601 
       
   602 	if (iChangeBuffer->IsEmpty())
       
   603 		{
       
   604 		// queue this request until a change occurs
       
   605 		iQueuedMessage = aMessage;
       
   606 		iRequestQueued = ETrue;
       
   607 		}
       
   608 	else
       
   609 		{
       
   610 		// inform client of change which has been queued
       
   611 		SendNotificationL(aMessage);
       
   612 		}
       
   613 	}
       
   614 
       
   615 void CMsvServerSession::SendNotificationL(const RMessage2& aMessage)
       
   616 	{
       
   617 	// inform client of change which has been queued
       
   618 	TPckgBuf<TUint32> sequence;
       
   619 	aMessage.WriteL(0, iChangeBuffer->Next(sequence()));
       
   620 
       
   621 	// Tell the client the notification sequence number
       
   622 	aMessage.WriteL(1, sequence);
       
   623 
       
   624 #ifndef _NO_SERVER_LOGGING_
       
   625 	iMsvServer.Log(_L("Sending notification sequence %d"), sequence());
       
   626 #endif
       
   627 
       
   628 	aMessage.Complete(KErrNone);
       
   629 	iChangeBuffer->Out();
       
   630 	}
       
   631 
       
   632 void CMsvServerSession::CancelSessionEventRequest(const RMessage2 &aMessage)
       
   633 //
       
   634 // The client is cancelling the outstanding request
       
   635 //
       
   636 	{
       
   637 	if (iRequestQueued)
       
   638 		{
       
   639 		iQueuedMessage.Complete(KErrNone);
       
   640 		iRequestQueued = EFalse;
       
   641 		}
       
   642 	aMessage.Complete(KErrNone);
       
   643 	}
       
   644 
       
   645 
       
   646 
       
   647 void CMsvServerSession::ReadBufferL(const RMessage2& aMessage, TInt aParam, HBufC8*& aBuffer)
       
   648 //
       
   649 // Copies a buffer from the client
       
   650 // Only fails if there is not enough memory to increase the buffer size (if needed)
       
   651 //
       
   652 	{
       
   653 	TInt desLen = aMessage.GetDesLength(aParam);
       
   654 
       
   655 	if(desLen >= 0)
       
   656 		{
       
   657 		TBool alloced=EFalse;
       
   658 		HBufC8* localBuffer=NULL;
       
   659 		
       
   660 		if (aBuffer==NULL)
       
   661 			{
       
   662 			localBuffer = HBufC8::NewLC(desLen);
       
   663 			alloced=ETrue;
       
   664 			}
       
   665 		else if (desLen > aBuffer->Des().MaxLength())
       
   666 			{
       
   667 			// we have to increase the size of iBuffer
       
   668 			aBuffer->Des().SetLength(0); // to avoid copying the contents
       
   669 			localBuffer = aBuffer->ReAlloc(desLen);
       
   670 			if (localBuffer==NULL)
       
   671 				{
       
   672 				User::Leave(KErrNoMemory); // unable to create buffer large enough
       
   673 				}
       
   674 			}
       
   675 		
       
   676 		if(localBuffer)
       
   677 			{
       
   678 			TPtr8 desPtr = localBuffer->Des();
       
   679 			aMessage.ReadL(aParam, desPtr);
       
   680 				
       
   681 			if (alloced)
       
   682 				{
       
   683 				CleanupStack::Pop(); // localBuffer
       
   684 				}
       
   685 			
       
   686 			aBuffer = localBuffer;  
       
   687 			}
       
   688 		//use aBuffer
       
   689 		else
       
   690 			{
       
   691 			TPtr8 desPtr = aBuffer->Des();
       
   692 			aMessage.ReadL(aParam, desPtr); 
       
   693 			}
       
   694 		}
       
   695 	else
       
   696 		{
       
   697 		// desLen is negative leave with an error.
       
   698 		User::Leave(KErrArgument);
       
   699 		}
       
   700 	}
       
   701 
       
   702 void CMsvServerSession::WriteBufferL(const RMessage2& aMessage, TInt aParam)
       
   703 //
       
   704 // Copies the packed entry buffer from the client
       
   705 // Only fails if the client buffer is not large enough
       
   706 //
       
   707 	{
       
   708 	TInt desLen = aMessage.GetDesMaxLength(aParam);
       
   709 	if (desLen < iBuffer->Des().Length())
       
   710 		User::Leave(KErrOverflow);
       
   711 	aMessage.WriteL(aParam, iBuffer->Des());
       
   712 	}
       
   713 
       
   714 
       
   715 void CMsvServerSession::WriteL(const RMessage2& aMessage, TInt aParam, const TDesC8& aDes)
       
   716 //
       
   717 // Write a descriptor to the client thread; if unsuccessful,leave so that client can handle it.
       
   718 //
       
   719 	{
       
   720 	TInt error = aMessage.Write(aParam, aDes);
       
   721 	if (error)
       
   722 		{
       
   723 		User::Leave(error);
       
   724 		}
       
   725 	}
       
   726 
       
   727 
       
   728 void CMsvServerSession::ReadL(const RMessage2& aMessage, TInt aParam, TDes8& aDes)
       
   729 //
       
   730 // Reads a descriptor from the client thread; if unsuccessful,leave so that client can handle it
       
   731 //
       
   732 	{
       
   733 	TInt error = aMessage.Read(aParam, aDes);
       
   734 	if (error)
       
   735 		{
       
   736 		User::Leave(error);
       
   737 		}
       
   738 	}
       
   739 
       
   740 
       
   741 
       
   742 void CMsvServerSession::CopyOperationDataL(const RMessage2 &aMessage)
       
   743 //
       
   744 // Copies operation data from the client and stores for the asynchronous operation request
       
   745 //
       
   746 	{
       
   747 	TMsvOp operationId = aMessage.Int0();
       
   748 	CMsvOperationData* opData = new (ELeave) CMsvOperationData(operationId);
       
   749 	CleanupStack::PushL(opData);
       
   750 	ReadBufferL(aMessage, 1, opData->iBuffer);
       
   751 	iOperationDataArray.AppendL(opData);
       
   752 	CleanupStack::Pop(); // opData
       
   753 	aMessage.Complete(KErrNone);
       
   754 	}
       
   755 
       
   756 void CMsvServerSession::CopyCommandDataL(const RMessage2 &aMessage)
       
   757 //
       
   758 // Copies operation data from the client and stores for the asynchronous operation request
       
   759 //
       
   760 	{
       
   761 	TMsvOp operationId = aMessage.Int0();
       
   762 	// operation data
       
   763 	CMsvOperationData* opData = new (ELeave) CMsvOperationData(operationId);
       
   764 	CleanupStack::PushL(opData);
       
   765 	ReadBufferL(aMessage, 1, opData->iBuffer);
       
   766 
       
   767 	// This is to check if the buffer is a valid , before it is added to 
       
   768 	// the operationData array
       
   769 	TMsvPackedOperation packedOperation(opData->iBuffer);
       
   770 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
   771 	CleanupStack::PushL(selection);
       
   772 	TInt command, temp;
       
   773 	packedOperation.UnpackL(*selection, command, temp);
       
   774 	CleanupStack::PopAndDestroy(selection);
       
   775 
       
   776 	iOperationDataArray.AppendL(opData);
       
   777 	
       
   778 	// additional parameter
       
   779 	CMsvOperationData* opParam = new (ELeave) CMsvOperationData(operationId);
       
   780 	CleanupStack::PushL(opParam);
       
   781 	ReadBufferL(aMessage, 2, opParam->iBuffer);
       
   782 	iOperationDataArray.AppendL(opParam);
       
   783 	CleanupStack::Pop(2, opData); // opParam, opData
       
   784 	//
       
   785 	aMessage.Complete(KErrNone);
       
   786 	}
       
   787 
       
   788 
       
   789 HBufC8* CMsvServerSession::RecoverOperationData(TMsvOp aOpId)
       
   790 //
       
   791 // Returns the operation data previously copied from the client
       
   792 // NOTE the calling function is responsible for deleting the returned HBufC
       
   793 //
       
   794 	{
       
   795 	// find the data
       
   796 	TInt count = 0;
       
   797 	TInt totalCount=iOperationDataArray.Count();
       
   798 	for (; count<totalCount; count++)
       
   799 		{
       
   800 		if (iOperationDataArray.At(count)->OperationId()==aOpId)
       
   801 			break;
       
   802 		}
       
   803 	// Panic during debug if cannot find data
       
   804 	__ASSERT_DEBUG(count<iOperationDataArray.Count(), PanicServer(EMsvEntryDataNotFound));
       
   805 	// At runtime, return NULL.
       
   806 	if(count >= iOperationDataArray.Count())
       
   807 		{
       
   808 		return NULL;
       
   809 		}
       
   810 	// return the data to the caller, and delete the container object
       
   811 	HBufC8* opData = iOperationDataArray.At(count)->iBuffer;
       
   812 	iOperationDataArray.At(count)->iBuffer = NULL;
       
   813 	delete iOperationDataArray.At(count);
       
   814 	iOperationDataArray.Delete(count);
       
   815 	return opData;
       
   816 	}
       
   817 
       
   818 
       
   819 void CMsvServerSession::CreateEntryL(const RMessage2 &aMessage)
       
   820 //
       
   821 // Create a entry in the index
       
   822 //
       
   823 	{
       
   824 	// Recover the operation data
       
   825 	TMsvOp operationId = aMessage.Int0();
       
   826 	HBufC8* opData = RecoverOperationData(operationId);
       
   827 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
   828 	if(opData == NULL)
       
   829 		{
       
   830 		aMessage.Complete(KErrArgument);
       
   831 		return;
       
   832 		}
       
   833 	
       
   834 	CleanupStack::PushL(opData);
       
   835 	// Unpack the data
       
   836 	TMsvPackedEntry packedEntry(opData);
       
   837 	TMsvEntry entry;
       
   838 	packedEntry.UnpackEntry(entry);
       
   839 
       
   840 	// Check the content of the entry are conforming to policy
       
   841 	if (!MsvUtils::ValidEntry(entry, ETrue))
       
   842 		{
       
   843 		PanicClient(aMessage, EMsvIncorrectEntry);
       
   844 		User::Leave(KErrNotSupported);
       
   845 		}
       
   846 
       
   847 	// Check if the entry is local or the entry is a service
       
   848 	TBool local=ETrue;
       
   849 	// Police request - client must be able to create the entry.
       
   850 	iMsvServer.PoliceCreateEntryL(aMessage, entry, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CreateEntryL"));
       
   851 
       
   852 	// For purpose of creating a service entry, it is considered local as an MTM
       
   853 	// is not required to do the work.
       
   854 	if( entry.iType == KUidMsvServiceEntry )
       
   855 		local = ETrue;
       
   856 
       
   857 	// start the change for local or remote entries
       
   858 	if (local)
       
   859 		{
       
   860 		TSecureId ownerId = aMessage.Int1();
       
   861 
       
   862 		DoCreateLocalEntryL(entry, operationId, aMessage, ownerId);
       
   863 		}
       
   864 	else
       
   865 		DoCreateRemoteEntryL(entry, operationId, aMessage);
       
   866 
       
   867 	CleanupStack::PopAndDestroy(); // opData
       
   868 	}
       
   869 
       
   870 void CMsvServerSession::DoCreateLocalEntryL(const TMsvEntry& aEntry, TMsvOp aOpId, const RMessage2 &aMessage, TSecureId aOwnerId)
       
   871 //
       
   872 // Create a local entry in the index
       
   873 //
       
   874 	{
       
   875 	CMsvLocalCreateOperation* operation = new(ELeave) CMsvLocalCreateOperation(aMessage, aOpId, aEntry, iMsvServer);
       
   876 	CleanupStack::PushL(operation);
       
   877 	iOperations.AppendL(operation);
       
   878 	CleanupStack::Pop(operation);
       
   879 	operation->Start(aOwnerId);
       
   880 	}
       
   881 
       
   882 void CMsvServerSession::DoCreateRemoteEntryL(const TMsvEntry& aEntry, TMsvOp aOpId, const RMessage2 &aMessage)
       
   883 //
       
   884 // Create a remote entry in the index
       
   885 //
       
   886 	{
       
   887 	// make sure that the operation can be added to the list
       
   888 	iOperations.SetReserveL(iOperations.Count()+1);
       
   889 
       
   890 	// create the operation and pass it to the server for starting/queuing
       
   891 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, aEntry.iMtm, aEntry.iServiceId, iSessionId, iMsvServer);
       
   892 	CleanupStack::PushL(operation);
       
   893 	operation->CreateL(aEntry);
       
   894 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, ETrue);
       
   895 	iOperations.AppendL(operation); // will not fail - see start of function
       
   896 	CleanupStack::Pop(); // operation
       
   897 	}
       
   898 
       
   899 
       
   900 void CMsvServerSession::ChangeEntryL(const RMessage2 &aMessage)
       
   901 //
       
   902 // Changes the entry
       
   903 //
       
   904 	{
       
   905 	// Recover the operation data
       
   906 	TMsvOp operationId = aMessage.Int0();
       
   907 	HBufC8* opData = RecoverOperationData(operationId);
       
   908 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
   909 	if(opData == NULL)
       
   910 		{
       
   911 		aMessage.Complete(KErrArgument);
       
   912 		return;
       
   913 		}
       
   914 		
       
   915 	CleanupStack::PushL(opData);
       
   916 	// Unpack the data
       
   917 	TMsvPackedEntry packedEntry(opData);
       
   918 	TMsvEntry entry;
       
   919 	packedEntry.UnpackEntry(entry);
       
   920 
       
   921 	// Check the content of the entry are conforming to policy
       
   922 	__ASSERT_DEBUG(MsvUtils::ValidEntry(entry), PanicClient(aMessage, EMsvIncorrectEntry));
       
   923 	if (!MsvUtils::ValidEntry(entry))
       
   924 		User::Leave(KErrNotSupported);
       
   925 
       
   926 	// Check if the entry is local or the entry is a service
       
   927 	TBool local=ETrue;
       
   928 	// Police request - client must be able to modify the entry.
       
   929 	iMsvServer.PoliceModifyEntryL(aMessage, entry, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ChangeEntryL"));
       
   930 
       
   931 	// For purpose of changing a service entry, it is considered local as an MTM
       
   932 	// is not required to do the work.
       
   933 	if( entry.iType == KUidMsvServiceEntry )
       
   934 		local = ETrue;
       
   935 
       
   936 	// start the change for local or remote entries
       
   937 	if (local)
       
   938 		{
       
   939 		// Extract the owner ID from the message.
       
   940 		TSecureId ownerId = aMessage.Int1();
       
   941 
       
   942 		DoChangeLocalEntryL(entry, operationId, aMessage, ownerId);
       
   943 		}
       
   944 	else
       
   945 		DoChangeRemoteEntryL(entry, operationId, aMessage);
       
   946 
       
   947 	CleanupStack::PopAndDestroy(); // opData
       
   948 	}
       
   949 
       
   950 //
       
   951 // Changes the selection of id.
       
   952 //
       
   953 
       
   954 void CMsvServerSession::ChangeEntriesL(const RMessage2 &aMessage)
       
   955     {
       
   956      // Recover the operation data
       
   957      TMsvOp operationId = aMessage.Int0();
       
   958      HBufC8* opData = RecoverOperationData(operationId);
       
   959      // Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
   960      if(opData == NULL)
       
   961          {
       
   962          aMessage.Complete(KErrArgument);
       
   963          return;
       
   964          }
       
   965      CleanupStack::PushL(opData);
       
   966 
       
   967      // unpack the data
       
   968      TMsvPackedOperation packedOperation(opData);
       
   969      
       
   970      CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
   971      CleanupStack::PushL(selection);
       
   972      TInt target,temp;
       
   973      packedOperation.UnpackL(*selection, target, temp);
       
   974 
       
   975      if (selection->Count() == 0)
       
   976          {
       
   977          PanicClient(aMessage, EMsvNoEntriesInChangeSelection);
       
   978          aMessage.Complete(KErrNotFound);
       
   979          return;
       
   980          }
       
   981      // Find the first entry in the selection which exists
       
   982      TInt count=selection->Count();
       
   983      while (count--)
       
   984          {
       
   985          TBool entryExsists = EFalse;
       
   986          entryExsists = iMsvServer.IndexAdapter().EntryExists(selection->At(count));
       
   987          if (entryExsists)
       
   988              break;
       
   989          }
       
   990  
       
   991        // Check if the entry is local or the entry is a service
       
   992       TBool local=ETrue;
       
   993       TMsvEntry* entry=NULL;
       
   994       User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(selection->At(0), entry));
       
   995      
       
   996       // Police request - client must be able to modify the entry.
       
   997       iMsvServer.PoliceModifyEntryL(aMessage, *entry, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ChangeEntryL"));
       
   998              
       
   999       // For purpose of changing a service entry, it is considered local as an MTM
       
  1000       // is not required to do the work.
       
  1001       if( entry->iType == KUidMsvServiceEntry )
       
  1002           local = ETrue;
       
  1003 
       
  1004       // start the change for local or remote entries
       
  1005       if (local)
       
  1006           {
       
  1007           // Extract the owner ID from the message.
       
  1008           TSecureId ownerId = aMessage.Int1();
       
  1009 
       
  1010           DoChangeLocalEntriesL(selection, operationId, aMessage, ownerId, target);
       
  1011           }
       
  1012       else
       
  1013           DoChangeRemoteEntriesL(selection, operationId, aMessage,target);
       
  1014 
       
  1015       CleanupStack::PopAndDestroy(); // opData
       
  1016     }
       
  1017 
       
  1018 void CMsvServerSession::DoChangeLocalEntriesL(CMsvEntrySelection*& aSelection, TMsvOp aOpId, const RMessage2 &aMessage, TSecureId aOwnerId, TInt mark)
       
  1019     {
       
  1020     CMsvLocalChangeEntriesOperation* operation = new(ELeave) CMsvLocalChangeEntriesOperation(aMessage, aOpId, aSelection, iMsvServer,mark);
       
  1021     CleanupStack::Pop(); // selection
       
  1022     CleanupStack::PushL(operation);
       
  1023    
       
  1024     TBool forcedUpdate = (aOwnerId != aMessage.SecureId());
       
  1025     operation->StartL(aOwnerId, forcedUpdate);
       
  1026 
       
  1027     iOperations.AppendL(operation);
       
  1028     CleanupStack::Pop(); // operation
       
  1029 
       
  1030     
       
  1031     }
       
  1032 
       
  1033 void CMsvServerSession::DoChangeRemoteEntriesL(CMsvEntrySelection*& aSelection, TMsvOp aOpId, const RMessage2 &aMessage,TInt mark)
       
  1034 //
       
  1035 // Change a selection of entry under a remote service
       
  1036 //
       
  1037     {
       
  1038      // make sure that the operation can be added to the list
       
  1039      iOperations.SetReserveL(iOperations.Count()+1);
       
  1040 
       
  1041      TMsvEntry* entry=NULL;
       
  1042      User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aSelection->At(0), entry));
       
  1043  
       
  1044      // create the operation
       
  1045      CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, entry->iMtm, entry->iServiceId, iSessionId, iMsvServer);
       
  1046      CleanupStack::Pop(); // aSelection
       
  1047      CleanupStack::PushL(operation);
       
  1048      operation->ChangeEntriesL(aSelection,mark);
       
  1049      
       
  1050      iMsvServer.StartOperationL(*operation, iSessionId, aMessage, ETrue);
       
  1051      iOperations.AppendL(operation); // will not fail - see start of function
       
  1052      CleanupStack::Pop(); // operation
       
  1053 	}
       
  1054 
       
  1055 
       
  1056 void CMsvServerSession::DoChangeLocalEntryL(const TMsvEntry& aEntry, TMsvOp aOpId, const RMessage2 &aMessage, TSecureId aOwnerId)
       
  1057 //
       
  1058 // Create a local entry in the index
       
  1059 //
       
  1060 	{
       
  1061 	CMsvLocalChangeOperation* operation = new(ELeave) CMsvLocalChangeOperation(aMessage, aOpId, aEntry, iMsvServer);
       
  1062 	CleanupStack::PushL(operation);
       
  1063 	// Check the given owner ID - if NULL then this is not a forced update, but
       
  1064 	// need to set the ID to that of the requesting process.
       
  1065 	TBool forcedUpdate = (aOwnerId != aMessage.SecureId());
       
  1066 
       
  1067 	operation->StartL(aOwnerId, forcedUpdate);
       
  1068 	iOperations.AppendL(operation);
       
  1069 	CleanupStack::Pop(); //operation
       
  1070 	}
       
  1071 
       
  1072 
       
  1073 void CMsvServerSession::DoChangeRemoteEntryL(const TMsvEntry& aEntry, TMsvOp aOpId, const RMessage2 &aMessage)
       
  1074 //
       
  1075 // Change a entry under a remote service
       
  1076 //
       
  1077 	{
       
  1078 	// make sure that the operation can be added to the list
       
  1079 	iOperations.SetReserveL(iOperations.Count()+1);
       
  1080 
       
  1081 	// create the operation
       
  1082 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, aEntry.iMtm, aEntry.iServiceId, iSessionId, iMsvServer);
       
  1083 	CleanupStack::PushL(operation);
       
  1084 	operation->ChangeL(aEntry);
       
  1085 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, ETrue);
       
  1086 	iOperations.AppendL(operation); // will not fail - see start of function
       
  1087 	CleanupStack::Pop(); // operation
       
  1088 	}
       
  1089 
       
  1090 
       
  1091 void CMsvServerSession::PackEntryAndWriteBufferL(const RMessage2 &aMessage, const TInt aParam, const TMsvEntry& aEntry, const TMsvId& aServiceId)
       
  1092 //
       
  1093 //
       
  1094 	{
       
  1095 	// package the entry and service id in same buffer
       
  1096 	TMsvPackedEntry packedEntry(iBuffer);
       
  1097 	TInt error = packedEntry.PackEntryAndService(aEntry, aServiceId);
       
  1098 	while(error!=KErrNone)
       
  1099 		{
       
  1100 		// increase the size of the buffer and try again
       
  1101 		iBuffer->Des().SetLength(0); // to avoid copying contents
       
  1102 		iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  1103 		error = packedEntry.PackEntryAndService(aEntry, aServiceId);
       
  1104 		}
       
  1105 	// max destination length is passed from client
       
  1106 	TInt maxDesLen = aMessage.Int2();
       
  1107     if (maxDesLen < iBuffer->Des().Length())
       
  1108 		{
       
  1109         User::Leave(KErrOverflow);
       
  1110 		}
       
  1111 
       
  1112     aMessage.WriteL(aParam, iBuffer->Des());
       
  1113 	}
       
  1114 
       
  1115 void CMsvServerSession::GetEntryL(const RMessage2 &aMessage)
       
  1116 //
       
  1117 // Returns the index entry for the given id
       
  1118 //
       
  1119 	{
       
  1120 	// copy across the entry id to get
       
  1121 	TMsvId id = aMessage.Int0();
       
  1122 	TMsvEntry* entryPtr;
       
  1123 	TSecureId ownerId;
       
  1124 	TInt error = KErrNone;
       
  1125 	error = iMsvServer.IndexAdapter().GetEntry(id, entryPtr, ownerId);
       
  1126 	if (error==KErrNone)
       
  1127 		{
       
  1128 		// Police request - client must be able to read the entry.
       
  1129 		iMsvServer.PoliceReadEntryL(aMessage, ownerId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetEntryL"));
       
  1130 
       
  1131 		// get the owning service and write that back
       
  1132 		TMsvId service;
       
  1133 		if (id == KMsvRootIndexEntryId)
       
  1134 			service = KMsvRootIndexEntryId;
       
  1135 		else
       
  1136 			{
       
  1137 			iMsvServer.IndexAdapter().OwningService(id, service); // error ignore as the entry exists
       
  1138 			}
       
  1139 		// write the entry back
       
  1140 		PackEntryAndWriteBufferL(aMessage, 1, *entryPtr, service);
       
  1141 		}
       
  1142 
       
  1143 	aMessage.Complete(error);
       
  1144 	}
       
  1145 
       
  1146 void CMsvServerSession::OutstandingOperationsL(const RMessage2& aMessage)
       
  1147 	{
       
  1148 	TPckgBuf<TInt> outstanding;
       
  1149 	outstanding() = iMsvServer.OutstandingOperations() > 0;
       
  1150 	WriteL(aMessage, 0, outstanding);
       
  1151 	aMessage.Complete(KErrNone);
       
  1152 	}
       
  1153 
       
  1154 void CMsvServerSession::GetNotifySequenceL(const RMessage2& aMessage)
       
  1155 	{
       
  1156 	TPckgBuf<TUint32> sequence;
       
  1157 	sequence() = iChangeBuffer->NotifySequence();
       
  1158 	WriteL(aMessage, 0, sequence);
       
  1159 	aMessage.Complete(KErrNone);
       
  1160 	}
       
  1161 
       
  1162 void CMsvServerSession::GetChildrenL(const RMessage2 &aMessage)
       
  1163 //
       
  1164 // Gets the children of an entry
       
  1165 //
       
  1166 	{
       
  1167 	// reset
       
  1168 	iChildrenSelection->Reset();
       
  1169 	iChildrenSelectionIds->Reset();
       
  1170 
       
  1171 	// copy across the children details structure
       
  1172 	TPckgBuf<TMsvChildrenDetails> children;
       
  1173 	aMessage.ReadL(0, children);
       
  1174 
       
  1175 	// Check that the children details arguments are empty. Panic in debug mode but try to handle it gracefully in
       
  1176 	// release code.
       
  1177 	__ASSERT_DEBUG( children().iTotalNumberChildren==0 &&
       
  1178 					children().iNumberChildrenInArray==0, PanicServer(EMsvChildrenDetailsNotEmpty2));
       
  1179 
       
  1180 	if( children().iTotalNumberChildren != 0 || children().iNumberChildrenInArray != 0 )
       
  1181 		{
       
  1182 		aMessage.Complete(KErrArgument);
       
  1183 		return;
       
  1184 		}
       
  1185 		
       
  1186 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
  1187 	// Return error, if the passed parent-id 
       
  1188 	// is a non-current standard id.
       
  1189 	if( (IsStandardId(children().iParentId)) &&
       
  1190 		(KCurrentDriveId != GetDriveId(children().iParentId))
       
  1191 	  )
       
  1192 		{
       
  1193 		aMessage.Complete(KErrArgument);
       
  1194 		return;
       
  1195 		}	   
       
  1196 #endif
       
  1197 
       
  1198 	// copy across the sort order
       
  1199 	TPckgBuf<TMsvSelectionOrdering> order;
       
  1200 	aMessage.ReadL(1, order);
       
  1201 
       
  1202 	// get the children as a selection
       
  1203 	// Need to filter the list via the client secure ID if the client is not
       
  1204 	// trusted with Read User Data.
       
  1205 	TBool filterByOwnerId = !aMessage.HasCapability(ECapabilityReadUserData);
       
  1206 	iMsvServer.IndexAdapter().GetChildrenL(children().iParentId, *iChildrenSelection, order(), KUidMsvNullEntry, filterByOwnerId, aMessage.SecureId());
       
  1207 	// return number of children
       
  1208 	children().iTotalNumberChildren = iChildrenSelection->Count();
       
  1209 
       
  1210 	// package up the entries
       
  1211 	iBuffer->Des().SetMax();
       
  1212 	TMsvPackedEntryArray packedEntryArray(iBuffer);
       
  1213 	TInt count=0;
       
  1214 	TInt error=KErrNone;
       
  1215 	TInt totalCount=iChildrenSelection->Count();
       
  1216 	for (; count<totalCount; count++)
       
  1217 		{
       
  1218 		error = packedEntryArray.PackEntry(*iChildrenSelection->At(count));
       
  1219 		if (error)
       
  1220 			{
       
  1221 			children().iLastEntryInArray = count;
       
  1222 			break;
       
  1223 			}
       
  1224 		}
       
  1225 	// return number of children in the array
       
  1226 	children().iNumberChildrenInArray = count;
       
  1227 
       
  1228 	// Try to write the buffer to the client (if any entries are in the array)
       
  1229     if (children().iNumberChildrenInArray)
       
  1230     	{
       
  1231         TRAPD(bufferError, WriteL(aMessage, 2, iBuffer->Des()));
       
  1232         if(bufferError!=KErrNone)
       
  1233         	{
       
  1234         	// Writing data into client buffer is failed, we should not send incorrect count to client.
       
  1235 			error = bufferError;
       
  1236         	children().iNumberChildrenInArray = 0;
       
  1237         	children().iLastEntryInArray = 0;
       
  1238         	}
       
  1239         }
       
  1240 
       
  1241 	// write the children to client
       
  1242 	WriteL(aMessage, 0, children);
       
  1243 
       
  1244 	if (error==KErrNone)
       
  1245 		{
       
  1246 		// reset the member data
       
  1247 		iChildrenSelection->Reset();
       
  1248 		}
       
  1249 	else
       
  1250 		{
       
  1251 		// keep an list of the ids separatelyin case they are deleted by another client
       
  1252 		TInt totalCount=iChildrenSelection->Count();
       
  1253 		for (count=0; count<totalCount; count++)
       
  1254 			iChildrenSelectionIds->AppendL(iChildrenSelection->At(count)->Id());
       
  1255 		iChildrenDetails = children();
       
  1256 		}
       
  1257 
       
  1258 	// signal the client and finished with selection
       
  1259 	aMessage.Complete(error);
       
  1260 	}
       
  1261 
       
  1262 
       
  1263 
       
  1264 
       
  1265 void CMsvServerSession::GetRemainingChildrenL(const RMessage2 &aMessage)
       
  1266 //
       
  1267 // Gets the remaining children of an entry when the buffer is to small
       
  1268 //
       
  1269 	{
       
  1270 	// Check the arguments. Panic in debug mode but try to handle it gracefully in
       
  1271 	// release code.
       
  1272 	__ASSERT_DEBUG(iChildrenSelection->Count()!=0, PanicServer(EMsvChildrenSelectionNull));
       
  1273 	__ASSERT_DEBUG(iChildrenSelection->Count() == iChildrenSelectionIds->Count(), PanicServer(EMsvChildrenSelectionCountsMismatch));
       
  1274 
       
  1275 	if( (iChildrenSelection->Count()==0) || (iChildrenSelection->Count() != iChildrenSelectionIds->Count()) )
       
  1276 		{
       
  1277 		aMessage.Complete(KErrArgument);
       
  1278 		return;
       
  1279 		}
       
  1280 
       
  1281 	// copy across the children details structure
       
  1282 	TPckgBuf<TMsvChildrenDetails> pDetails;
       
  1283 	aMessage.ReadL(0, pDetails);
       
  1284 
       
  1285 	// Check the arguments. Panic in debug mode but try to handle it gracefully in
       
  1286 	// release code.
       
  1287 	__ASSERT_DEBUG( iChildrenDetails.iParentId == pDetails().iParentId &&
       
  1288 					iChildrenDetails.iTotalNumberChildren == pDetails().iTotalNumberChildren &&
       
  1289 					iChildrenDetails.iNumberChildrenInArray == pDetails().iNumberChildrenInArray, PanicServer(EMsvChildrenDetailsNotEmpty1));
       
  1290 
       
  1291 	if( iChildrenDetails.iParentId != pDetails().iParentId ||
       
  1292 		iChildrenDetails.iTotalNumberChildren != pDetails().iTotalNumberChildren ||
       
  1293 		iChildrenDetails.iNumberChildrenInArray != pDetails().iNumberChildrenInArray )
       
  1294 		{
       
  1295 		aMessage.Complete(KErrArgument);
       
  1296 		return;
       
  1297 		}
       
  1298 
       
  1299 	iChildrenDetails=pDetails();
       
  1300 	// Make a local copy of details, this needs to be used when the client buffer is not sufficient enough to
       
  1301 	// pack data.
       
  1302 	TMsvChildrenDetails localCopy = pDetails();
       
  1303 	
       
  1304 	// package up the entries
       
  1305 	iBuffer->Des().SetMax();
       
  1306 	TMsvPackedEntryArray packedEntryArray(iBuffer);
       
  1307 	TInt error=KErrNone;
       
  1308 	TInt count=iChildrenDetails.iLastEntryInArray;
       
  1309 	iChildrenDetails.iLastEntryInArray=-1;
       
  1310 
       
  1311 	TInt childCount=iChildrenSelection->Count();
       
  1312 	TInt missingCount = 0;
       
  1313 
       
  1314 	for (; count<childCount; count++)
       
  1315 		{
       
  1316 		// The iChildrenSelection contains pointers to TMsvEntry objects. If one of those
       
  1317 		// objects has been deleted then the pointer will no longer be valid so we need
       
  1318 		// to get the entry again using the ID from iChildrenSelectionIds.
       
  1319 		TMsvEntry* entryPtr;
       
  1320 		TInt err = KErrNone;
       
  1321 		err = iMsvServer.IndexAdapter().GetEntry(iChildrenSelectionIds->At(count), entryPtr);
       
  1322 		if (err != KErrNotFound)
       
  1323 			{
       
  1324 #ifndef _NO_SERVER_LOGGING_
       
  1325 			if (entryPtr != iChildrenSelection->At(count))
       
  1326 				{
       
  1327 				iMsvServer.Log(_L("GetRemainingChildrenL() - Ptr mismatch for id %d (%x %x)"), iChildrenSelectionIds->At(count), iChildrenSelection->At(count), entryPtr);
       
  1328 				}
       
  1329 #endif
       
  1330 
       
  1331 			error = packedEntryArray.PackEntry(*entryPtr);
       
  1332 
       
  1333 			if (error)
       
  1334 				{
       
  1335 				// the buffer is not large enough to pack all the entries
       
  1336 				iChildrenDetails.iLastEntryInArray = count;
       
  1337 				if ((count - missingCount - pDetails().iLastEntryInArray) == 0)
       
  1338 					{
       
  1339 					// Couldn't fit entry in buffer
       
  1340 					// Increase size of buffer - client will do this as well
       
  1341 					iBuffer->Des().SetLength(0);
       
  1342 					iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  1343 					}
       
  1344 				break;
       
  1345 
       
  1346 				}
       
  1347 			}
       
  1348 		else
       
  1349 			{
       
  1350 #ifndef _NO_SERVER_LOGGING_
       
  1351 			iMsvServer.Log(_L("GetRemainingChildrenL() - Ignore missing id %d"), iChildrenSelectionIds->At(count));
       
  1352 #endif
       
  1353 
       
  1354 			++missingCount;
       
  1355 			}
       
  1356 		}
       
  1357 
       
  1358 	// return number of children in the array
       
  1359 	iChildrenDetails.iNumberChildrenInArray = count - missingCount - pDetails().iLastEntryInArray;
       
  1360 
       
  1361 	// write the array to the client (if any entries are in the array)
       
  1362 	TRAPD(err, WriteBufferL(aMessage, 2));
       
  1363 	if(err)
       
  1364 		{
       
  1365 		if(err == KErrOverflow)
       
  1366 		 {
       
  1367 		 localCopy.iNumberChildrenInArray = 0;
       
  1368 		 iChildrenDetails = localCopy;
       
  1369 		 pDetails() = iChildrenDetails;
       
  1370 		 WriteL(aMessage, 0, pDetails);
       
  1371 		 User::Leave(KErrOverflow);
       
  1372 		 }
       
  1373 	 else
       
  1374 		 {
       
  1375 		 User::Leave(err);
       
  1376 		 }   
       
  1377 	 }   
       
  1378 			 
       
  1379 
       
  1380 	// write the details to client
       
  1381 	pDetails() = iChildrenDetails;
       
  1382 	WriteL(aMessage, 0, pDetails);
       
  1383 
       
  1384 	if (error==KErrNone)
       
  1385 		{
       
  1386 		// reset the member data
       
  1387 		iChildrenDetails = TMsvChildrenDetails();
       
  1388 		iChildrenSelection->Reset();
       
  1389 		iChildrenSelectionIds->Reset();
       
  1390 		}
       
  1391 
       
  1392 	// signal the client and finished with selection
       
  1393 	aMessage.Complete(error);
       
  1394 	}
       
  1395 
       
  1396 
       
  1397 void CMsvServerSession::DeleteEntriesL(const RMessage2 &aMessage)
       
  1398 //
       
  1399 // Deleting entries
       
  1400 //
       
  1401 	{
       
  1402 	// Recover the operation data
       
  1403 	TMsvOp operationId = aMessage.Int0();
       
  1404 	HBufC8* opData = RecoverOperationData(operationId);
       
  1405 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
  1406 	if(opData == NULL)
       
  1407 		{
       
  1408 		aMessage.Complete(KErrArgument);
       
  1409 		return;
       
  1410 		}
       
  1411 	
       
  1412 	CleanupStack::PushL(opData);
       
  1413 	// unpack the data
       
  1414 	TMsvPackedOperation packedOperation(opData);
       
  1415 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
  1416 	CleanupStack::PushL(selection);
       
  1417 	TInt temp1, temp2;
       
  1418 	packedOperation.UnpackL(*selection, temp1, temp2);
       
  1419 
       
  1420 /**
       
  1421 Added code to begin transaction for bulk deletion.
       
  1422 */
       
  1423 	iMsvServer.IndexAdapter().GetDbAdapter()->BeginTransactionL();
       
  1424 
       
  1425 	if (selection->Count())
       
  1426 		{
       
  1427 		// Check if the entries are local (inc services) or remote
       
  1428 		TBool local;
       
  1429 		TMsvEntry* entry=NULL;
       
  1430 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(selection->At(0), entry));
       
  1431 		// Police request - client must be able to modify the entry.
       
  1432 		iMsvServer.PoliceModifyEntryL(aMessage, *entry, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DeleteEntriesL"));
       
  1433 		// start the move for local or remote messages
       
  1434 		if (local || entry->iType==KUidMsvServiceEntry)
       
  1435 			{
       
  1436 			DoDeleteLocalEntriesL(selection, operationId, aMessage);
       
  1437 			TMsgType aType(EDeletedMsg);
       
  1438 			if(CMSvSearchSortCacheManager::Instance()->iManagerEntry != NULL)
       
  1439 				{
       
  1440 				if(CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count()>0)
       
  1441 					{
       
  1442 					TInt count=selection->Count();
       
  1443 					TInt i=0;
       
  1444 					while(i < count)
       
  1445 						{
       
  1446 						CMsvSearchSortDeltaCache::Instance()->EntryInDeltaCache(selection->At(i),aType);
       
  1447 						i++;	
       
  1448 						}
       
  1449 					}
       
  1450 				}
       
  1451 			}
       
  1452 		else
       
  1453 			{
       
  1454 			DoDeleteRemoteEntriesL(selection, operationId, aMessage);
       
  1455 			TMsgType aType(EDeletedMsg);
       
  1456 			if(CMSvSearchSortCacheManager::Instance()->iManagerEntry != NULL)
       
  1457 				{
       
  1458 				if(CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count()>0)
       
  1459 					{
       
  1460 					TInt count=selection->Count();
       
  1461 					TInt i=0;
       
  1462 					while(i < count)
       
  1463 						{
       
  1464 						CMsvSearchSortDeltaCache::Instance()->EntryInDeltaCache(selection->At(i),aType);
       
  1465 						i++;	
       
  1466 						}
       
  1467 					}
       
  1468 				}
       
  1469 			}
       
  1470 		}
       
  1471 	else
       
  1472 		{
       
  1473 		PanicClient(aMessage, EMsvNoEntriesInDeleteSelection);
       
  1474 		aMessage.Complete(KErrNotFound);
       
  1475 		}
       
  1476 
       
  1477 	CleanupStack::PopAndDestroy(); // opData
       
  1478 	}
       
  1479 
       
  1480 
       
  1481 void CMsvServerSession::DoDeleteLocalEntriesL(CMsvEntrySelection*& aSelection, TMsvOp aOpId, const RMessage2 &aMessage)
       
  1482 //
       
  1483 //
       
  1484 //
       
  1485 	{
       
  1486 	CMsvLocalDeleteOperation* operation = new(ELeave) CMsvLocalDeleteOperation(aMessage, aOpId, aSelection, iMsvServer);
       
  1487 	CleanupStack::Pop(); // selection
       
  1488 	CleanupStack::PushL(operation);
       
  1489 	operation->StartL();
       
  1490 	iOperations.AppendL(operation);
       
  1491 	CleanupStack::Pop(); // operation
       
  1492 	}
       
  1493 
       
  1494 
       
  1495 void CMsvServerSession::DoDeleteRemoteEntriesL(CMsvEntrySelection*& aSelection, TMsvOp aOpId, const RMessage2 &aMessage)
       
  1496 //
       
  1497 //
       
  1498 //
       
  1499 	{
       
  1500 	// make sure that the operation can be added to the list
       
  1501 	iOperations.SetReserveL(iOperations.Count()+1);
       
  1502 
       
  1503 	// find the first entry being acted on
       
  1504 	TMsvEntry* entry=NULL;
       
  1505 	User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aSelection->At(0), entry));
       
  1506 	// create the operation
       
  1507 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, entry->iMtm, entry->iServiceId, iSessionId, iMsvServer);
       
  1508 	CleanupStack::Pop();
       
  1509 	CleanupStack::PushL(operation);
       
  1510 
       
  1511 	// set up the operation type and pass the data
       
  1512 	operation->DeleteAll(aSelection);
       
  1513 
       
  1514 	// either start the operation or queue it
       
  1515 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, ETrue);
       
  1516 	iOperations.AppendL(operation); // will not fail - see start of function
       
  1517 	CleanupStack::Pop(); // operation
       
  1518 	}
       
  1519 
       
  1520 
       
  1521 void CMsvServerSession::LockEntryL(const RMessage2 &aMessage)
       
  1522 //
       
  1523 // Locks an entry in the index
       
  1524 //
       
  1525 	{
       
  1526 	TMsvId id = aMessage.Int0();
       
  1527 	aMessage.Complete(iMsvServer.IndexAdapter().LockEntry(id));
       
  1528 	}
       
  1529 
       
  1530 
       
  1531 void CMsvServerSession::ReleaseEntryL(const RMessage2 &aMessage)
       
  1532 //
       
  1533 // Releases the lock on an entry in the index
       
  1534 //
       
  1535 	{
       
  1536 	TMsvId id = aMessage.Int0();
       
  1537 	aMessage.Complete(iMsvServer.IndexAdapter().ReleaseEntry(id));
       
  1538 	}
       
  1539 
       
  1540 void CMsvServerSession::ReadStoreL(const RMessage2 &aMessage)
       
  1541 //
       
  1542 // Can only read from a store that has nnot been locked
       
  1543 //
       
  1544 	{
       
  1545 	// Fail now if the index says it's not available
       
  1546 	User::LeaveIfError(iMsvServer.IndexAdapter().ErrorState());
       
  1547 	TMsvId id = aMessage.Int0();
       
  1548 
       
  1549 	// Police request - client must be able to read the entry.
       
  1550 	iMsvServer.PoliceReadEntryL(aMessage, id, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ReadStoreL"));
       
  1551 
       
  1552 	TBool locked;
       
  1553 	TInt error = KErrNone;
       
  1554 	error = iMsvServer.IndexAdapter().IsStoreLocked(id, locked);
       
  1555 	if (error==KErrNone && locked)
       
  1556 		error = KErrAccessDenied;
       
  1557 	if(error==KErrNone)
       
  1558 		{
       
  1559 		iMsvServer.IndexAdapter().IncStoreReaderCount(id);
       
  1560 		}
       
  1561 
       
  1562 	aMessage.Complete(error);
       
  1563 	}
       
  1564 
       
  1565 
       
  1566 void CMsvServerSession::LockStoreL(const RMessage2 &aMessage)
       
  1567 //
       
  1568 // Tries to locks the store
       
  1569 // Adds the id to the list of locked entries
       
  1570 //
       
  1571 	{
       
  1572 	// Fail now if the index says it's not available
       
  1573 	User::LeaveIfError(iMsvServer.IndexAdapter().ErrorState());
       
  1574 	TMsvId id = aMessage.Int0();
       
  1575 
       
  1576 	// Police request - client must be able to modify the entry.
       
  1577 	iMsvServer.PoliceModifyEntryL(aMessage, id, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::LockStoreL"));
       
  1578 
       
  1579 	iLockedStores.AppendL(id); // ensure that the entry cannot be locked but not added to the list
       
  1580 	TInt error = KErrNone;
       
  1581 	error = iMsvServer.IndexAdapter().LockStore(id);
       
  1582 	if (error)
       
  1583 		iLockedStores.Delete(iLockedStores.Count()-1);
       
  1584 
       
  1585 	aMessage.Complete(error);
       
  1586 	}
       
  1587 
       
  1588 
       
  1589 void CMsvServerSession::ReleaseStoreL(const RMessage2 &aMessage)
       
  1590 //
       
  1591 // Releases the lock on a store
       
  1592 // Removes the id from the list of locked entries
       
  1593 //
       
  1594 	{
       
  1595 	TMsvId id = aMessage.Int0();
       
  1596 
       
  1597 	// Police request - client must be able to modify the entry.
       
  1598 	iMsvServer.PoliceModifyEntryL(aMessage, id, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ReleaseStoreL"));
       
  1599 	TInt error = KErrNone;
       
  1600 	error = iMsvServer.IndexAdapter().ReleaseStore(id);
       
  1601 	TInt count = iLockedStores.Count();
       
  1602 	while (count--)
       
  1603 		{
       
  1604 		if (iLockedStores.At(count)==id)
       
  1605 			{
       
  1606 			iLockedStores.Delete(count);
       
  1607 			break;
       
  1608 			}
       
  1609 		}
       
  1610 
       
  1611 	__ASSERT_DEBUG(count>=0, PanicClient(aMessage, EMsvReleasingUnknownStore));
       
  1612 
       
  1613 	aMessage.Complete(error);
       
  1614 	}
       
  1615 
       
  1616 
       
  1617 void CMsvServerSession::DecStoreReaderCountL(const RMessage2 &aMessage)
       
  1618 //
       
  1619 // Decrements the reader count on a store
       
  1620 //
       
  1621 	{
       
  1622 	TMsvId id = aMessage.Int0();
       
  1623 
       
  1624 	// Police request - client must be able to read the entry.
       
  1625 	iMsvServer.PoliceReadEntryL(aMessage, id, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DecStoreReaderCountL"));
       
  1626 
       
  1627 	TInt error = KErrNone;
       
  1628 	error = iMsvServer.IndexAdapter().DecStoreReaderCount(id);
       
  1629 	aMessage.Complete(error);
       
  1630 	}
       
  1631 
       
  1632 void CMsvServerSession::NotifyChangedL(TMsvNotifBuffer& aChange, TBool aQueue)
       
  1633 //
       
  1634 // This session is being informed that a change has occured
       
  1635 // Will only leave if a write to a client fails
       
  1636 //
       
  1637 	{
       
  1638 	// queue the change in FIFO buffer
       
  1639 	iChangeBuffer->InL(aChange);
       
  1640 
       
  1641 #ifndef _NO_SERVER_LOGGING_
       
  1642 	iMsvServer.Log(_L("Queued notification sequence %d"), iChangeBuffer->NotifySequence());
       
  1643 #endif
       
  1644 
       
  1645 	// Only actually send the notification when we have a context
       
  1646 	if (iRequestQueued && !aQueue &&  iQueuedMessage.Handle())
       
  1647 		{
       
  1648 		// inform client of change
       
  1649 		SendNotificationL(iQueuedMessage);
       
  1650 		iRequestQueued = EFalse;
       
  1651 		}
       
  1652 	}
       
  1653 
       
  1654 
       
  1655 TBool CMsvServerSession::IsInUse(TUid aMtmTypeUid)
       
  1656 	{
       
  1657 	TBool isinuse=EFalse;
       
  1658 	TInt index=0;
       
  1659 	TInt count=iMtmGroupRefCountArray.Count();
       
  1660 	for (; (index<count) && !isinuse; index++)
       
  1661 		if (iMtmGroupRefCountArray[index].iMtmTypeUid==aMtmTypeUid)
       
  1662 			isinuse=ETrue;
       
  1663 	return isinuse;
       
  1664 	}
       
  1665 
       
  1666 void CMsvServerSession::CancelOperationL(const RMessage2 &aMessage)
       
  1667 //
       
  1668 // Cancels an operation
       
  1669 //
       
  1670 	{
       
  1671 	TMsvOp op = aMessage.Int0();
       
  1672 
       
  1673 	TInt error=KErrNotFound;
       
  1674 	for (TInt count=0; count<iOperations.Count(); count++)
       
  1675 		{
       
  1676 		if (iOperations.At(count)->Id()==op)
       
  1677 			{
       
  1678 			error=KErrNone;
       
  1679 
       
  1680 			iOperations.At(count)->Cancel();
       
  1681 
       
  1682 			if (iOperations.At(count)->State()!=EMsvOperationQueued)
       
  1683 				{
       
  1684 				TPtrC8 desPtr = iOperations.At(count)->Progress();
       
  1685 				if (desPtr.Length() > KMsvProgressBufferLength)
       
  1686 					{
       
  1687 					PanicClient(aMessage, EMsvProgressBufferExceeds256);
       
  1688 					error = KErrOverflow;
       
  1689 					}
       
  1690 				else
       
  1691 					{
       
  1692 					WriteL(aMessage, 1, desPtr);
       
  1693 					error = desPtr.Length();
       
  1694 					}
       
  1695 				}
       
  1696 			else
       
  1697 				{
       
  1698 				error=KErrNotReady;
       
  1699 				}
       
  1700 
       
  1701 			delete iOperations.At(count);
       
  1702 			iOperations.Delete(count);
       
  1703 			break;
       
  1704 			}
       
  1705 		}
       
  1706 
       
  1707 	aMessage.Complete(error);
       
  1708 	}
       
  1709 
       
  1710 
       
  1711 void CMsvServerSession::OperationCompletionL(const RMessage2 &aMessage)
       
  1712 //
       
  1713 // Gets the final progress of an operation and deletes all objects
       
  1714 //
       
  1715 	{
       
  1716 	TMsvOp op = aMessage.Int0();
       
  1717 
       
  1718 	TInt error=KErrNotFound;
       
  1719 	for (TInt count=0; count<iOperations.Count(); count++)
       
  1720 		{
       
  1721 		if (iOperations.At(count)->Id()==op)
       
  1722 			{
       
  1723 			__ASSERT_DEBUG(iOperations.At(count)->State() == EMsvOperationCompleted || iOperations.At(count)->State() == EMsvOperationFailed, PanicServer(EMsvOperationNotCompleted));
       
  1724 			if (iOperations.At(count)->State() == EMsvOperationFailed)
       
  1725 				{
       
  1726 				// there will be no progress available
       
  1727 				error=KErrNone;
       
  1728 				}
       
  1729 			else
       
  1730 				{
       
  1731 				TPtrC8 desPtr = iOperations.At(count)->Progress();
       
  1732 				if (desPtr.Length() > KMsvProgressBufferLength)
       
  1733 					{
       
  1734 					PanicClient(aMessage, EMsvProgressBufferExceeds256);
       
  1735 					error = KErrOverflow;
       
  1736 					}
       
  1737 				else
       
  1738 					{
       
  1739 					WriteL(aMessage, 1, desPtr);
       
  1740 					error = desPtr.Length();
       
  1741 					}
       
  1742 				}
       
  1743 			delete iOperations.At(count);
       
  1744 			iOperations.Delete(count);
       
  1745 			break;
       
  1746 			}
       
  1747 		}
       
  1748 
       
  1749 	aMessage.Complete(error);
       
  1750 	}
       
  1751 
       
  1752 
       
  1753 void CMsvServerSession::OperationProgressL(const RMessage2 &aMessage)
       
  1754 //
       
  1755 // Gets the progress of an operation
       
  1756 //
       
  1757 	{
       
  1758 	TMsvOp op = aMessage.Int0();
       
  1759 
       
  1760 	TInt error=KErrNotFound;
       
  1761 	for (TInt count=0; count<iOperations.Count(); count++)
       
  1762 		{
       
  1763 		if (iOperations.At(count)->Id()==op)
       
  1764 			{
       
  1765 			if (iOperations.At(count)->State() == EMsvOperationQueued)
       
  1766 				{
       
  1767 				// the operation has not started
       
  1768 				error = KErrNotReady;
       
  1769 				}
       
  1770 			else
       
  1771 				{
       
  1772 				// get the progress from the running operation
       
  1773 				TPtrC8 desPtr = iOperations.At(count)->Progress();
       
  1774 				if (desPtr.Length() > KMsvProgressBufferLength)
       
  1775 					{
       
  1776 					PanicClient(aMessage, EMsvProgressBufferExceeds256);
       
  1777 					error = KErrOverflow;
       
  1778 					}
       
  1779 				else
       
  1780 					{
       
  1781 					WriteL(aMessage, 1, desPtr);
       
  1782 					error = desPtr.Length();
       
  1783 					}
       
  1784 				break;
       
  1785 				}
       
  1786 			}
       
  1787 		}
       
  1788 	aMessage.Complete(error);
       
  1789 	}
       
  1790 
       
  1791 void CMsvServerSession::OperationSystemProgressL(const RMessage2 &aMessage)
       
  1792 //
       
  1793 // Get the progress of a system operation
       
  1794 //
       
  1795 	{
       
  1796 	TMsvOp op = aMessage.Int0();
       
  1797 	TInt error=KErrNotFound;
       
  1798 	for (TInt count=0; count<iOperations.Count(); count++)
       
  1799 		{
       
  1800 		if (iOperations.At(count)->Id()==op)
       
  1801 			{
       
  1802 			if (iOperations.At(count)->State() == EMsvOperationQueued)
       
  1803 				{
       
  1804 				// the operation has not started
       
  1805 				error = KErrNotReady;
       
  1806 				}
       
  1807 			else
       
  1808 				{
       
  1809 				// get the progress from the running operation
       
  1810 				TPckgBuf<TMsvSystemProgress> systemProgress;
       
  1811 				error = iOperations.At(count)->SystemProgress(systemProgress());
       
  1812 				WriteL(aMessage, 1, systemProgress);
       
  1813 				break;
       
  1814 				}
       
  1815 			}
       
  1816 		}
       
  1817 	aMessage.Complete(error);
       
  1818 	}
       
  1819 
       
  1820 void CMsvServerSession::OperationMtmL(const RMessage2 &aMessage)
       
  1821 //
       
  1822 // Returns the MTM which will perform the operation using the two entries
       
  1823 //
       
  1824 	{
       
  1825 	// read the two ids
       
  1826 	TMsvId id1 = aMessage.Int0();
       
  1827 	TMsvId id2 = aMessage.Int1();
       
  1828 
       
  1829 	// the uid to be writen back
       
  1830 	TPckgBuf<TUid> uid;
       
  1831 	TPckgBuf<TMsvId> service;
       
  1832 
       
  1833 	// get the first entries
       
  1834 	TBool local1;
       
  1835 	TMsvEntry* entry1=NULL;
       
  1836 	User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(id1, entry1));
       
  1837 	User::LeaveIfError(iMsvServer.IndexAdapter().IsLocal(id1, local1));
       
  1838 	if (id1==id2)
       
  1839 		{
       
  1840 		// single entry either under local or a remote service
       
  1841 		if (local1)
       
  1842 			{
       
  1843 			uid() = KUidMsvLocalServiceMtm;
       
  1844 			service() = KMsvLocalServiceIndexEntryId;
       
  1845 			}
       
  1846 		else
       
  1847 			{
       
  1848 			uid() = entry1->iMtm;
       
  1849 			service() = entry1->iServiceId;
       
  1850 			}
       
  1851 		}
       
  1852 	else
       
  1853 		{
       
  1854 		// get the second entry
       
  1855 		TBool local2;
       
  1856 		TMsvEntry* entry2=NULL;
       
  1857 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(id2, entry2));
       
  1858 		User::LeaveIfError(iMsvServer.IndexAdapter().IsLocal(id2, local2));
       
  1859 		// work out the responsible MTM
       
  1860 		if (local1 && local2)
       
  1861 			{
       
  1862 			// both entries under the local service
       
  1863 			uid() = KUidMsvLocalServiceMtm;
       
  1864 			service() = KMsvLocalServiceIndexEntryId;
       
  1865 			}
       
  1866 		else if (entry1->iMtm == entry2->iMtm)
       
  1867 			{
       
  1868 			__ASSERT_DEBUG(entry1->iMtm!=KUidMsvLocalServiceMtm, PanicServer(EMsvOperationMtm3));
       
  1869 			// both entries use the same MTM
       
  1870 			uid() = entry1->iMtm;
       
  1871 			service() = entry1->iServiceId;
       
  1872 			}
       
  1873 		else if (entry1->iMtm == KUidMsvLocalServiceMtm)
       
  1874 			{
       
  1875 			__ASSERT_DEBUG(entry2->iMtm!=KUidMsvLocalServiceMtm, PanicServer(EMsvOperationMtm1));
       
  1876 			// entry1 is a local entry - hence entry 2 must be MTM dependent
       
  1877 			uid() = entry2->iMtm;
       
  1878 			service() = entry2->iServiceId;
       
  1879 			}
       
  1880 		else
       
  1881 			{
       
  1882 #ifdef _DEBUG
       
  1883 			if (entry2->iMtm != KUidMsvLocalServiceMtm)
       
  1884 				{
       
  1885 				// Neither entry belongs to local mtm, check they have the same technology type
       
  1886 				__ASSERT_DEBUG(iMsvServer.Registry().TechnologyTypeUid(entry1->iMtm) == iMsvServer.Registry().TechnologyTypeUid(entry2->iMtm), PanicServer(EMsvOperationMtm2));
       
  1887 				}
       
  1888 #endif
       
  1889 
       
  1890 			// entry1 is not a local entry - assume entry 2 is local
       
  1891 			uid() = entry1->iMtm;
       
  1892 			service() = entry1->iServiceId;
       
  1893 			}
       
  1894 		}
       
  1895 
       
  1896 	WriteL(aMessage, 2, uid);
       
  1897 	WriteL(aMessage, 3, service);
       
  1898 	aMessage.Complete(KErrNone);
       
  1899 	}
       
  1900 
       
  1901 
       
  1902 
       
  1903 void CMsvServerSession::MoveEntriesL(const RMessage2 &aMessage)
       
  1904 //
       
  1905 // Moving entries
       
  1906 //
       
  1907 	{
       
  1908 	// Recover the operation data
       
  1909 	TMsvOp operationId = aMessage.Int0();
       
  1910 	HBufC8* opData = RecoverOperationData(operationId);
       
  1911 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
  1912 	if(opData == NULL)
       
  1913 		{
       
  1914 		aMessage.Complete(KErrArgument);
       
  1915 		return;
       
  1916 		}
       
  1917 	
       
  1918 	CleanupStack::PushL(opData);
       
  1919 	// unpack the data
       
  1920 	TMsvPackedOperation packedOperation(opData);
       
  1921 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
  1922 	CleanupStack::PushL(selection);
       
  1923 	TInt target, temp;
       
  1924 	packedOperation.UnpackL(*selection, target, temp);
       
  1925 
       
  1926 	TInt count = selection->Count();
       
  1927 	if ( count == 0)
       
  1928 		{
       
  1929 		PanicClient(aMessage, EMsvNoEntriesInMoveSelection);
       
  1930 		aMessage.Complete(KErrNotFound);
       
  1931 		return;
       
  1932 		}
       
  1933 
       
  1934 	// Find the first entry in the selection which exists
       
  1935 	TInt pos=-1;
       
  1936 	TMsvId source = KMsvNullIndexEntryIdValue;
       
  1937 	while (++pos<count)
       
  1938 		{
       
  1939 		TMsvEntry* entryPtr;
       
  1940 		TInt error = KErrNone;
       
  1941 		error = iMsvServer.IndexAdapter().GetEntry(selection->At(pos), entryPtr);
       
  1942 		if( error == KErrNone )
       
  1943 			{
       
  1944 			source = entryPtr->Parent();
       
  1945 			break;
       
  1946 			}
       
  1947 		}
       
  1948 	if (pos==count)
       
  1949 		pos = 0;
       
  1950 
       
  1951 	// Check if the target and source are local or remote
       
  1952 	TBool targetLocal=EFalse;
       
  1953 	TBool sourceLocal=EFalse;
       
  1954 	TBool hasCapability=EFalse;
       
  1955 	// Police request - client must be able to move the entries.
       
  1956 #if (defined SYMBIAN_USER_PROMPT_SERVICE)
       
  1957 	TRAPD(err, iMsvServer.PoliceMoveEntriesL(aMessage, *selection, target, source, targetLocal, sourceLocal, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::MoveEntriesL")));
       
  1958 	if(err == KErrNone)
       
  1959 		{
       
  1960 		hasCapability = ETrue;
       
  1961 		}
       
  1962 	else if((err != KErrNone) && (targetLocal && sourceLocal))
       
  1963 		{
       
  1964 		User::LeaveIfError(err);
       
  1965 		}
       
  1966 #else
       
  1967 	iMsvServer.PoliceMoveEntriesL(aMessage, *selection, target, source, targetLocal, sourceLocal, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::MoveEntriesL"));
       
  1968 #endif
       
  1969 	
       
  1970 	// start the move for local or remote messages
       
  1971 	if (targetLocal && sourceLocal)
       
  1972 		DoMoveLocalEntriesL(selection, target, operationId, aMessage);
       
  1973 	else
       
  1974 		DoMoveRemoteEntriesL(selection, target, operationId, aMessage, sourceLocal, targetLocal, hasCapability);
       
  1975 
       
  1976 	CleanupStack::PopAndDestroy(); // opData
       
  1977 	}
       
  1978 
       
  1979 void CMsvServerSession::DoMoveLocalEntriesL(CMsvEntrySelection*& aSelection, TMsvId aTarget, TMsvOp aOpId, const RMessage2 &aMessage)
       
  1980 //
       
  1981 // NOTE aSelection is the top item on the cleanupstack when the function is called
       
  1982 //
       
  1983 	{
       
  1984 	CMsvLocalMoveOperation* operation = new(ELeave) CMsvLocalMoveOperation(aMessage, aOpId, aSelection, aTarget, iMsvServer);
       
  1985 	CleanupStack::Pop(); // selection
       
  1986 	CleanupStack::PushL(operation);
       
  1987 	operation->StartL();
       
  1988 	iOperations.AppendL(operation);
       
  1989 	CleanupStack::Pop(); // operation
       
  1990 	}
       
  1991 
       
  1992 
       
  1993 void CMsvServerSession::DoMoveRemoteEntriesL(CMsvEntrySelection*& aSelection, TMsvId aTarget, TMsvOp aOpId, const RMessage2 &aMessage, TBool aSourceLocal, TBool aTargetLocal, TBool aHasCapability)
       
  1994 //
       
  1995 // NOTE aSelection is the top item on the cleanupstack when the function is called
       
  1996 //
       
  1997 	{
       
  1998 	// make sure that the operation can be added to the list
       
  1999 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2000 
       
  2001 	TMsvEntry* entry=NULL;
       
  2002 	if (!aTargetLocal)
       
  2003 		{
       
  2004 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aTarget, entry));
       
  2005 		}
       
  2006 	else
       
  2007 		{
       
  2008 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aSelection->At(0), entry));
       
  2009 		}
       
  2010 
       
  2011 
       
  2012 	// create the operation
       
  2013 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, entry->iMtm, entry->iServiceId, iSessionId, iMsvServer);
       
  2014 	CleanupStack::Pop();
       
  2015 	CleanupStack::PushL(operation);
       
  2016 
       
  2017 	// set up the operation type and pass the data
       
  2018 	if (!(aSourceLocal || aTargetLocal))
       
  2019 		operation->MoveWithinService(aSelection, aTarget);
       
  2020 	else if (aSourceLocal)
       
  2021 		operation->MoveFromLocal(aSelection, aTarget);
       
  2022 	else
       
  2023 		operation->MoveToLocal(aSelection, aTarget);
       
  2024 
       
  2025 	// either start the operation or queue it
       
  2026 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, aHasCapability);
       
  2027 	iOperations.AppendL(operation); // will not fail - see start of function
       
  2028 	CleanupStack::Pop(); // operation
       
  2029 	}
       
  2030 
       
  2031 
       
  2032 void CMsvServerSession::CopyEntriesL(const RMessage2 &aMessage)
       
  2033 //
       
  2034 // Moving entries
       
  2035 //
       
  2036 	{
       
  2037 	// Recover the operation data
       
  2038 	TMsvOp operationId = aMessage.Int0();
       
  2039 	HBufC8* opData = RecoverOperationData(operationId);
       
  2040 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
  2041 	if(opData == NULL)
       
  2042 		{
       
  2043 		aMessage.Complete(KErrArgument);
       
  2044 		return;
       
  2045 		}
       
  2046 	
       
  2047 	CleanupStack::PushL(opData);
       
  2048 	// unpack the data
       
  2049 	TMsvPackedOperation packedOperation(opData);
       
  2050 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
  2051 	CleanupStack::PushL(selection);
       
  2052 	TInt target,temp;
       
  2053 	packedOperation.UnpackL(*selection, target, temp);
       
  2054 
       
  2055 	if (selection->Count() == 0)
       
  2056 		{
       
  2057 		PanicClient(aMessage, EMsvNoEntriesInCopySelection);
       
  2058 		aMessage.Complete(KErrNotFound);
       
  2059 		return;
       
  2060 		}
       
  2061 
       
  2062 	// Find the first entry in the selection which exists
       
  2063 	TInt pos=-1;
       
  2064 	TInt count=selection->Count();
       
  2065 	while (++pos<count)
       
  2066 		{
       
  2067 		TBool entryExsists = EFalse;
       
  2068 		entryExsists = iMsvServer.IndexAdapter().EntryExists(selection->At(pos));
       
  2069 		if (entryExsists)
       
  2070 			break;
       
  2071 		}
       
  2072 	if (pos==count)
       
  2073 		pos = 0;
       
  2074 
       
  2075 	// Check if the target and source are local or remote
       
  2076 	TBool targetLocal=EFalse;
       
  2077 	TBool sourceLocal=EFalse;
       
  2078 	TBool hasCapability = EFalse;
       
  2079 #if (defined SYMBIAN_USER_PROMPT_SERVICE)
       
  2080 	// Police request - client must be able to copy the entries.
       
  2081 	TRAPD(err, iMsvServer.PoliceCopyEntriesL(aMessage, *selection, target, targetLocal, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CopyEntriesL")));
       
  2082 	
       
  2083 	if(err == KErrNone)
       
  2084 		{
       
  2085 		hasCapability = ETrue;
       
  2086 		}
       
  2087 #else
       
  2088 	iMsvServer.PoliceCopyEntriesL(aMessage, *selection, target, targetLocal, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CopyEntriesL"));
       
  2089 #endif
       
  2090 	TInt error = KErrNone;
       
  2091 	// what happens about the rest? Inconsistent behaviour
       
  2092 	error = iMsvServer.IndexAdapter().IsLocal(selection->At(pos), sourceLocal);
       
  2093 	
       
  2094 #if (defined SYMBIAN_USER_PROMPT_SERVICE)   
       
  2095 	if((err != KErrNone) && (targetLocal && sourceLocal))
       
  2096 		{
       
  2097 		User::LeaveIfError(err);
       
  2098 		}
       
  2099 #endif
       
  2100 		
       
  2101 	if (error)
       
  2102 		{
       
  2103 		CleanupStack::PopAndDestroy(2); // selection & opData
       
  2104 		aMessage.Complete(error);
       
  2105 		return;
       
  2106 		}
       
  2107 
       
  2108 
       
  2109 	// start the move for local or remote messages
       
  2110 	if (targetLocal && sourceLocal)
       
  2111 		DoCopyLocalEntriesL(selection, target, operationId, aMessage);
       
  2112 	else
       
  2113 		DoCopyRemoteEntriesL(selection, target, operationId, aMessage, sourceLocal, targetLocal, hasCapability);
       
  2114 
       
  2115 	CleanupStack::PopAndDestroy(); // opData
       
  2116 	}
       
  2117 
       
  2118 void CMsvServerSession::DoCopyLocalEntriesL(CMsvEntrySelection*& aSelection, TMsvId aTarget, TMsvOp aOpId, const RMessage2 &aMessage)
       
  2119 //
       
  2120 // NOTE aSelection is the top item on the cleanupstack when the function is called
       
  2121 //
       
  2122 	{
       
  2123 	CMsvLocalCopyOperation* operation = new(ELeave) CMsvLocalCopyOperation(aMessage, aOpId, aSelection, aTarget, iMsvServer);
       
  2124 	CleanupStack::Pop(); // selection
       
  2125 	CleanupStack::PushL(operation);
       
  2126 
       
  2127 	operation->StartL();
       
  2128 
       
  2129 	iOperations.AppendL(operation);
       
  2130 	CleanupStack::Pop(); // operation
       
  2131 	}
       
  2132 
       
  2133 void CMsvServerSession::DoCopyRemoteEntriesL(CMsvEntrySelection*& aSelection, TMsvId aTarget, TMsvOp aOpId, const RMessage2 &aMessage, TBool aSourceLocal, TBool aTargetLocal, TBool aHasCapability)
       
  2134 //
       
  2135 // NOTE aSelection is the top item on the cleanupstack when the function is called
       
  2136 //
       
  2137 	{
       
  2138 	// make sure that the operation can be added to the list
       
  2139 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2140 
       
  2141 	TMsvEntry* entry=NULL;
       
  2142 	if (!aTargetLocal)
       
  2143 		{
       
  2144 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aTarget, entry));
       
  2145 		}
       
  2146 
       
  2147 	else
       
  2148 		{
       
  2149 		User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(aSelection->At(0), entry));
       
  2150 		}
       
  2151 
       
  2152 	// create the operation
       
  2153 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, aOpId, entry->iMtm, entry->iServiceId, iSessionId, iMsvServer);
       
  2154 	CleanupStack::Pop(); // aSelection
       
  2155 	CleanupStack::PushL(operation);
       
  2156 
       
  2157 	// set up the operation type and pass the data
       
  2158 	if (!(aSourceLocal || aTargetLocal))
       
  2159 		operation->CopyWithinService(aSelection, aTarget);
       
  2160 	else if (aSourceLocal)
       
  2161 		operation->CopyFromLocal(aSelection, aTarget);
       
  2162 	else
       
  2163 		operation->CopyToLocal(aSelection, aTarget);
       
  2164 
       
  2165 	// either start the operation or queue it
       
  2166 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, aHasCapability);
       
  2167 	iOperations.AppendL(operation); // will not fail - see start of function
       
  2168 	CleanupStack::Pop(); // operation
       
  2169 	}
       
  2170 
       
  2171 
       
  2172 
       
  2173 void CMsvServerSession::TransferCommandL(const RMessage2 &aMessage)
       
  2174 //
       
  2175 //
       
  2176 //
       
  2177 	{
       
  2178 	// Recover the operation data and parameter
       
  2179 	TMsvOp operationId = aMessage.Int0();
       
  2180 	HBufC8* opData = RecoverOperationData(operationId);
       
  2181 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
  2182 	if(opData == NULL)
       
  2183 		{
       
  2184 		aMessage.Complete(KErrArgument);
       
  2185 		return;
       
  2186 		}
       
  2187 	
       
  2188 	HBufC8* opParam = RecoverOperationData(operationId);
       
  2189 	// Check for NULL data entry to be changed, must have been given incorrect id for argument.
       
  2190 	if(opParam == NULL)
       
  2191 		{
       
  2192 		delete opData;
       
  2193 		aMessage.Complete(KErrArgument);
       
  2194 		return;
       
  2195 		}
       
  2196 	
       
  2197 	CleanupStack::PushL(opData);
       
  2198 	CleanupStack::PushL(opParam);
       
  2199 
       
  2200 	// Unpack the data
       
  2201 	TMsvPackedOperation packedOperation(opData);
       
  2202 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
  2203 	CleanupStack::PushL(selection);
       
  2204 	TInt command, temp;
       
  2205 	packedOperation.UnpackL(*selection, command, temp);
       
  2206 
       
  2207 	// make sure that the operation can be added to the list
       
  2208 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2209 
       
  2210 	// find the first entry being acted on
       
  2211 	TMsvEntry* entry=NULL;
       
  2212 	User::LeaveIfError(iMsvServer.IndexAdapter().GetEntry(selection->At(0), entry));
       
  2213 	TBool hasCapability = EFalse;
       
  2214 	// Police request - client must be able to access the MTM functionality.
       
  2215 #if (defined SYMBIAN_USER_PROMPT_SERVICE)
       
  2216 	TRAPD(err, iMsvServer.PoliceMtmTransferCommandL(aMessage, entry->iMtm, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::TransferCommandL")));
       
  2217 	
       
  2218 	if(err == KErrNone)
       
  2219 		{
       
  2220 		hasCapability = ETrue;
       
  2221 		}
       
  2222 	else if(err != KErrPermissionDenied)
       
  2223 		{
       
  2224 		User::LeaveIfError(err);
       
  2225 		}
       
  2226 #else
       
  2227 	iMsvServer.PoliceMtmTransferCommandL(aMessage, entry->iMtm, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::TransferCommandL"));
       
  2228 #endif
       
  2229 
       
  2230 	// create the operation
       
  2231 	CMsvMtmOperation* operation = CMsvMtmOperation::NewL(aMessage, operationId, entry->iMtm, entry->iServiceId, iSessionId, iMsvServer);
       
  2232 	CleanupStack::Pop(); // selection
       
  2233 	CleanupStack::Pop(); // opParam
       
  2234 	CleanupStack::PushL(operation);
       
  2235 
       
  2236 	// set up the operation type and pass the data
       
  2237 	operation->StartCommand(selection, command, opParam);
       
  2238 
       
  2239 	// either start the operation or queue it
       
  2240 	iMsvServer.StartOperationL(*operation, iSessionId, aMessage, hasCapability);
       
  2241 	iOperations.AppendL(operation); // will not fail - see start of function
       
  2242 	CleanupStack::Pop(); // operation
       
  2243 	CleanupStack::PopAndDestroy(); // opParam
       
  2244 	}
       
  2245 
       
  2246 
       
  2247 void CMsvServerSession::FillRegisteredMtmDllArray(const RMessage2 &aMessage)
       
  2248 	{
       
  2249 	TRAPD(error,DoFillRegisteredMtmDllArrayL(aMessage));
       
  2250 	aMessage.Complete(error);
       
  2251 	}
       
  2252 
       
  2253 void CMsvServerSession::DoFillRegisteredMtmDllArrayL(const RMessage2 &aMessage)
       
  2254 	{
       
  2255 	CRegisteredMtmDllArray* registeredMtmDllArray = new(ELeave) CRegisteredMtmDllArray;
       
  2256 	CleanupStack::PushL(registeredMtmDllArray);
       
  2257 
       
  2258 	TUid mtmdlltypeuid = {aMessage.Int0()};
       
  2259 	TInt error=iMsvServer.FillRegisteredMtmDllArray(mtmdlltypeuid,*registeredMtmDllArray);
       
  2260 	User::LeaveIfError(error);
       
  2261 
       
  2262 	TPtr8 bufferPtr = iBuffer->Des();
       
  2263 	bufferPtr.Zero();
       
  2264 	RDesWriteStream writeStream(bufferPtr);
       
  2265 	TMsvPackedRegisteredMtmDllArray::PackRegisteredMtmDllArrayL(writeStream, *registeredMtmDllArray);
       
  2266 	writeStream.CommitL();
       
  2267 
       
  2268 	WriteBufferL(aMessage, 1);
       
  2269 	CleanupStack::PopAndDestroy(); // registeredMtmDllArray
       
  2270 	}
       
  2271 
       
  2272 
       
  2273 void CMsvServerSession::MtmGroupL(const RMessage2 &aMessage, TBool aInstall)
       
  2274 	{
       
  2275 	TFullName fullname;
       
  2276 	TInt  desLen = aMessage.GetDesLengthL(0);
       
  2277 	fullname.SetLength(desLen);
       
  2278 	TInt error = aMessage.Read(0,fullname);
       
  2279 	if (error)
       
  2280 		{
       
  2281 		PanicClient(aMessage, EMsvBadDescriptorRead);
       
  2282 		User::Leave(error);
       
  2283 		}
       
  2284 	TUid mtmtypeuid=KNullUid;
       
  2285 	if (aInstall)
       
  2286 		{
       
  2287 		User::LeaveIfError(iMsvServer.InstallMtmGroup(fullname,mtmtypeuid));
       
  2288 		iMsvServer.NotifyChanged(EMsvMtmGroupInstalled,mtmtypeuid);
       
  2289 		}
       
  2290 	else
       
  2291 		{
       
  2292 		User::LeaveIfError(iMsvServer.DeInstallMtmGroup(fullname,mtmtypeuid));
       
  2293 		iMsvServer.NotifyChanged(EMsvMtmGroupDeInstalled,mtmtypeuid);
       
  2294 		}
       
  2295 	aMessage.Complete(KErrNone);
       
  2296 	}
       
  2297 
       
  2298 
       
  2299 void CMsvServerSession::UseMtmGroup(const RMessage2 &aMessage)
       
  2300 	{
       
  2301 	TUid mtmtypeuid = {aMessage.Int0()};
       
  2302 	TInt index=0;
       
  2303 	TInt count=iMtmGroupRefCountArray.Count();
       
  2304 	for (; (index<count) && (mtmtypeuid!=iMtmGroupRefCountArray[index].iMtmTypeUid); index++)
       
  2305 		{
       
  2306 		}
       
  2307 	TInt error=KErrNone;
       
  2308 	if (index==count)
       
  2309 		{
       
  2310 		TMtmGroupRefCount mtmgrouprefcount(mtmtypeuid);
       
  2311 		TRAP(error,iMtmGroupRefCountArray.AppendL(mtmgrouprefcount));
       
  2312 		}
       
  2313 	if (error==KErrNone)
       
  2314 		iMtmGroupRefCountArray[index].iRefCount++;
       
  2315 	aMessage.Complete(error);
       
  2316 	}
       
  2317 
       
  2318 void CMsvServerSession::ReleaseMtmGroup(const RMessage2 &aMessage)
       
  2319 	{
       
  2320 	TUid mtmtypeuid = {aMessage.Int0()};
       
  2321 	TInt index=0;
       
  2322 	TInt count=iMtmGroupRefCountArray.Count();
       
  2323 	for (; (index<count) && (mtmtypeuid!=iMtmGroupRefCountArray[index].iMtmTypeUid); index++)
       
  2324 		{
       
  2325 		}
       
  2326 	TInt error=KErrNone;
       
  2327 	if (index==count)
       
  2328 		error=KErrNotFound;
       
  2329 	else
       
  2330 		{
       
  2331 		iMtmGroupRefCountArray[index].iRefCount--;
       
  2332 		if (iMtmGroupRefCountArray[index].iRefCount==0)
       
  2333 			iMtmGroupRefCountArray.Delete(index);
       
  2334 		}
       
  2335 	aMessage.Complete(error);
       
  2336 	}
       
  2337 
       
  2338 void CMsvServerSession::GetMtmGroupDataL(const RMessage2 &aMessage)
       
  2339 	{
       
  2340 	TUid mtmtypeuid = {aMessage.Int0()};
       
  2341 	CMtmGroupData* mtmgroupdata=iMsvServer.GetMtmGroupDataL(mtmtypeuid);
       
  2342 	CleanupStack::PushL(mtmgroupdata);
       
  2343 	TPtr8 bufferPtr = iBuffer->Des();
       
  2344 	bufferPtr.Zero();
       
  2345 	RDesWriteStream writeStream(bufferPtr);
       
  2346 	writeStream << *mtmgroupdata;
       
  2347 	writeStream.CommitL();
       
  2348 
       
  2349 	WriteBufferL(aMessage, 1);
       
  2350 	CleanupStack::PopAndDestroy();
       
  2351 	aMessage.Complete(KErrNone);
       
  2352 	}
       
  2353 
       
  2354 
       
  2355 void CMsvServerSession::GetMtmRequiredCapabilitiesL(const RMessage2& aMessage)
       
  2356 	{
       
  2357 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  2358 	TCapabilitySet mtmRequiredCaps;
       
  2359 	iMsvServer.GetMtmRequiredCapabilitiesL(mtmTypeUid,mtmRequiredCaps);
       
  2360 	TPtr8 ptr = iBuffer->Des();
       
  2361 	ptr.Zero();
       
  2362 	RDesWriteStream writeStream(ptr);
       
  2363 	MsvSecurityCapabilitySetUtils::ExternalizeL(writeStream,mtmRequiredCaps);
       
  2364 	writeStream.CommitL();
       
  2365 	WriteBufferL(aMessage, 1);
       
  2366 	aMessage.Complete(KErrNone);
       
  2367 	}
       
  2368 
       
  2369 
       
  2370 void CMsvServerSession::PanicClient(const RMessage2& aMessage, TMsvClientPanic aPanic) const
       
  2371 //
       
  2372 // Panic the client
       
  2373 //
       
  2374 	{
       
  2375 	aMessage.Panic(KMsvClientPanicString, aPanic);
       
  2376 	}
       
  2377 
       
  2378 
       
  2379 void CMsvServerSession::StopOperations(TMsvId aServiceId)
       
  2380 //
       
  2381 // Cancels all operations which use the service (the service is being stopped)
       
  2382 //
       
  2383 	{
       
  2384 	TInt count=iOperations.Count();
       
  2385 	while (count--)
       
  2386 		{
       
  2387 		if (iOperations.At(count)->ServiceId() == aServiceId)
       
  2388 			{
       
  2389 			delete iOperations.At(count);
       
  2390 			iOperations.Delete(count);
       
  2391 			}
       
  2392 		}
       
  2393 	}
       
  2394 
       
  2395 
       
  2396 void CMsvServerSession::ServiceProgressL(const RMessage2 &aMessage)
       
  2397 //
       
  2398 // Returns the progress from the server MTM
       
  2399 //
       
  2400 	{
       
  2401 	TPtrC8 desPtr = iMsvServer.ServiceProgressL(aMessage.Int0());
       
  2402 	TInt desLength = aMessage.GetDesMaxLength(1);
       
  2403 	if (desLength < desPtr.Length())
       
  2404 		aMessage.Complete(KErrOverflow);
       
  2405 	else
       
  2406 		{
       
  2407 		WriteL(aMessage, 1, desPtr);
       
  2408 		aMessage.Complete(desPtr.Length());
       
  2409 		}
       
  2410 	}
       
  2411 
       
  2412 void CMsvServerSession::RemoveEntry(const RMessage2& aMessage)
       
  2413 //
       
  2414 // Removes the entry from the index. Client not interested in result.
       
  2415 //
       
  2416 	{
       
  2417 	TMsvId id = aMessage.Int0();
       
  2418 
       
  2419 	TBool local;
       
  2420 	// Police request - client must be able to modify the entry.
       
  2421 	TRAPD(error, iMsvServer.PoliceModifyEntryL(aMessage, id, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::RemoveEntry")));
       
  2422 
       
  2423 	if( error == KErrPermissionDenied )
       
  2424 		{
       
  2425 		// The request was denied - complete with this error code.
       
  2426 		aMessage.Complete(KErrPermissionDenied);
       
  2427 		return;
       
  2428 		}
       
  2429 	else if( error == KErrNone )
       
  2430 		{
       
  2431 		if (local)
       
  2432 			iMsvServer.RemoveEntry(id);
       
  2433 		else
       
  2434 			{
       
  2435 			TMsvId service;
       
  2436 			iMsvServer.IndexAdapter().OwningService(id, service); // error ignored
       
  2437 			if (service==id)
       
  2438 				iMsvServer.RemoveEntry(id);
       
  2439 			else
       
  2440 				PanicClient(aMessage, EMsvRemovingNonLocalEntry);
       
  2441 			}
       
  2442 		}
       
  2443 
       
  2444 	aMessage.Complete(KErrNone);
       
  2445 	}
       
  2446 
       
  2447 void CMsvServerSession::MessageFolderL(const RMessage2 &aMessage)
       
  2448 //
       
  2449 //
       
  2450 //
       
  2451 	{
       
  2452 	aMessage.WriteL(0, iMsvServer.Context().MessageFolder());
       
  2453 	aMessage.Complete(KErrNone);
       
  2454 	}
       
  2455 
       
  2456 void CMsvServerSession::ChangeAttributesL(const RMessage2& aMessage)
       
  2457 //
       
  2458 //
       
  2459 //
       
  2460 	{
       
  2461 	HBufC8* buffer = NULL;
       
  2462 	ReadBufferL(aMessage, 0, buffer);
       
  2463 	CleanupStack::PushL(buffer);
       
  2464 
       
  2465 	TMsvPackedOperation packedOperation(buffer);
       
  2466 
       
  2467 	CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
       
  2468 	CleanupStack::PushL(selection);
       
  2469 
       
  2470 	TInt setAttributes, clearAttributes;
       
  2471 	packedOperation.UnpackL(*selection, setAttributes, clearAttributes);
       
  2472 
       
  2473 	if (selection->Count() == 0)
       
  2474 		{
       
  2475 		PanicClient(aMessage, EMsvNoEntriesInChangeAttributesSelection);
       
  2476 		aMessage.Complete(KErrNotFound);
       
  2477 		return;
       
  2478 		}
       
  2479 
       
  2480 	// get a copy of the selection
       
  2481 	CMsvEntrySelection* changedEntries = selection->CopyL();
       
  2482 	CleanupStack::PushL(changedEntries);
       
  2483 
       
  2484 	// create a selection for the later notification
       
  2485 	CMsvEntrySelection* notify = new(ELeave)CMsvEntrySelection;
       
  2486 	CleanupStack::PushL(notify);
       
  2487 	notify->SetReserveL(selection->Count());
       
  2488 
       
  2489 	TInt error = KErrNone;
       
  2490 
       
  2491 	// lock all the selection
       
  2492 	TInt count1 = selection->Count();
       
  2493 	while (count1--)
       
  2494 		{
       
  2495 		error = iMsvServer.IndexAdapter().LockEntry(selection->At(count1));
       
  2496 		if (error)
       
  2497 			break;
       
  2498 		}
       
  2499 
       
  2500 	// change the attributes if all were locked
       
  2501 	if (error == KErrNone)
       
  2502 		{
       
  2503 		error = iMsvServer.IndexAdapter().ChangeAttributes(*changedEntries, setAttributes, clearAttributes);
       
  2504 		}
       
  2505 
       
  2506 
       
  2507 	// release all that were locked
       
  2508 	TInt count2 = selection->Count();
       
  2509 	while (--count2 > count1)
       
  2510 		{
       
  2511 		iMsvServer.IndexAdapter().ReleaseEntry(selection->At(count2));
       
  2512 		}
       
  2513 
       
  2514 
       
  2515 	if (error == KErrNone)
       
  2516 		{
       
  2517 		// Note: Code in the following loop shouldn't leave
       
  2518 		while(changedEntries->Count())
       
  2519 			{
       
  2520 			TMsvId id = changedEntries->At(0);
       
  2521 			changedEntries->Delete(0);
       
  2522 
       
  2523 			// Get the index entry associated with this entry - Shouldn't fail
       
  2524 		
       
  2525 			TInt err = KErrNone;
       
  2526 			CMsvCacheEntry* entry = NULL;
       
  2527 			err = iMsvServer.IndexAdapter().GetInternalEntry(id, entry);
       
  2528 			if (err != KErrNone)
       
  2529 				continue;
       
  2530 
       
  2531 			// Get the parent of this entry. It will be notified that its children have changed
       
  2532 			TMsvId parent = entry->Entry().Parent();
       
  2533 			notify->AppendL(id);
       
  2534 
       
  2535 			// Find other entries that have the same parent
       
  2536 			TInt count = changedEntries->Count();
       
  2537 			while(count--)
       
  2538 				{
       
  2539 				iMsvServer.IndexAdapter().GetInternalEntry(changedEntries->At(count), entry);
       
  2540 				if (entry && entry->Entry().Parent() == parent)
       
  2541 					{
       
  2542 					// Add entry to list - Shouldn't fail as we've already reserved space
       
  2543 					notify->AppendL(changedEntries->At(count));
       
  2544 					changedEntries->Delete(count);
       
  2545 					}
       
  2546 				}
       
  2547 
       
  2548 			// Do the notification
       
  2549 			iMsvServer.NotifyChanged(EMsvEntriesChanged, *notify, parent);
       
  2550 			notify->Reset();
       
  2551 			}
       
  2552 		}
       
  2553 
       
  2554 	aMessage.Complete(error);
       
  2555 	CleanupStack::PopAndDestroy(4); // notify, changedEntries, selection, buffer
       
  2556 	}
       
  2557 
       
  2558 void CMsvServerSession::GetChildIdsL(const RMessage2& aMessage)
       
  2559 	{
       
  2560 	TMsvId id = aMessage.Int1();
       
  2561 
       
  2562 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
  2563 	// Return error, if the passed parent-id 
       
  2564 	// is a non-current standard id.
       
  2565 	if( (IsStandardId(id)) &&
       
  2566 		(KCurrentDriveId != GetDriveId(id))
       
  2567 	  )
       
  2568 		{
       
  2569 		aMessage.Complete(KErrArgument);		
       
  2570 		return;
       
  2571 		}
       
  2572 #endif
       
  2573 	
       
  2574 	CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection;
       
  2575 	CleanupStack::PushL(selection);
       
  2576 
       
  2577 	HBufC8* buffer = NULL;
       
  2578 	ReadBufferL(aMessage, 0, buffer);
       
  2579 	CleanupStack::PushL(buffer);
       
  2580 
       
  2581 	CMsvEntryFilter* filter = CMsvEntryFilter::NewLC();
       
  2582 	TMsvPackedEntryFilter package(buffer);
       
  2583 	package.UnpackFilter(*filter);
       
  2584 
       
  2585 	// Need to filter the list via the client secure ID if the client is not
       
  2586 	// trusted with Read User Data.
       
  2587 	TBool filterByOwnerId = !aMessage.HasCapability(ECapabilityReadUserData);
       
  2588 
       
  2589 	iMsvServer.IndexAdapter().GetChildrenId(id, *filter, *selection, filterByOwnerId, aMessage.SecureId());
       
  2590 	TMsvPackedOperation op(iBuffer);
       
  2591 
       
  2592 	TInt error = op.Pack(*selection, 0, 0);
       
  2593 	while (error != KErrNone)
       
  2594 		{
       
  2595 		// increase the size of the buffer and try again
       
  2596 		iBuffer->Des().SetLength(0); // to avoid copying contents
       
  2597 		iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  2598 		error = op.Pack(*selection, 0, 0);
       
  2599 		}
       
  2600 
       
  2601 	WriteBufferL(aMessage, 0);
       
  2602 
       
  2603 	aMessage.Complete(KErrNone);
       
  2604 	CleanupStack::PopAndDestroy(3); // selection, buffer, filter
       
  2605 	}
       
  2606 
       
  2607 
       
  2608 
       
  2609 void CMsvServerSession::ChangeDriveL(const RMessage2 &aMessage)
       
  2610 //
       
  2611 // Change the drive containing the Message Store
       
  2612 //
       
  2613 	{
       
  2614 	// Not allowed to do this if operations are outstanding
       
  2615 	if (iMsvServer.OutstandingOperations() > 0)
       
  2616 		User::Leave(KErrServerBusy);
       
  2617 
       
  2618 	// make sure that the operation can be added to the list
       
  2619 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2620 
       
  2621 	// Start the operation
       
  2622 	CMsvChangeDriveOperation* operation = new(ELeave)CMsvChangeDriveOperation(aMessage, aMessage.Int0(), aMessage.Int1(), iMsvServer);
       
  2623 	CleanupStack::PushL(operation);
       
  2624 	User::LeaveIfError(operation->Start());
       
  2625 
       
  2626 	iOperations.AppendL(operation);
       
  2627 	CleanupStack::Pop(); // operation
       
  2628 	}
       
  2629 
       
  2630 
       
  2631 
       
  2632 
       
  2633 void CMsvServerSession::CopyStoreL(const RMessage2 &aMessage)
       
  2634 //
       
  2635 // Copy the Message Store to another location
       
  2636 //
       
  2637 	{
       
  2638 	// Not allowed to do this if operations are outstanding
       
  2639 	if (iMsvServer.OutstandingOperations() > 0)
       
  2640 		User::Leave(KErrServerBusy);
       
  2641 
       
  2642 	// make sure that the operation can be added to the list
       
  2643 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2644 
       
  2645 	// Start the operation
       
  2646 	CMsvCopyStoreOperation* operation = CMsvCopyStoreOperation::NewL(aMessage, iMsvServer);
       
  2647 	CleanupStack::PushL(operation);
       
  2648 	operation->StartL();
       
  2649 
       
  2650 	iOperations.AppendL(operation);
       
  2651 	CleanupStack::Pop(); // operation
       
  2652 	}
       
  2653 
       
  2654 void CMsvServerSession::DeleteStoreL(const RMessage2 &aMessage)
       
  2655 //
       
  2656 // Delete the Message Store from the specified location
       
  2657 //
       
  2658 	{
       
  2659 	// Not allowed to do this if operations are outstanding
       
  2660 	if (iMsvServer.OutstandingOperations() > 0)
       
  2661 		User::Leave(KErrServerBusy);
       
  2662 
       
  2663 	// make sure that the operation can be added to the list
       
  2664 	iOperations.SetReserveL(iOperations.Count()+1);
       
  2665 
       
  2666 	// Start the operation
       
  2667 	CMsvDeleteStoreOperation* operation = new(ELeave)CMsvDeleteStoreOperation(aMessage, iMsvServer);
       
  2668 	CleanupStack::PushL(operation);
       
  2669 	operation->StartL();
       
  2670 
       
  2671 	iOperations.AppendL(operation);
       
  2672 	CleanupStack::Pop(); // operation
       
  2673 	}
       
  2674 
       
  2675 
       
  2676 
       
  2677 void CMsvServerSession::SetReceiveEntryEvents(const RMessage2 &aMessage)
       
  2678 //
       
  2679 // Request/UnRequest Entry Events
       
  2680 //
       
  2681 	{
       
  2682 	iReceiveEntryEvents=aMessage.Int0();
       
  2683 	aMessage.Complete(KErrNone);
       
  2684 	}
       
  2685 
       
  2686 
       
  2687 void CMsvServerSession::CreateAttachmentForWriteL(const RMessage2 &aMessage)
       
  2688 	{
       
  2689 	// Get the Message Id from slot 0
       
  2690 	TMsvId msgId = aMessage.Int0();
       
  2691 
       
  2692 	// Police request - client must be able to modify the entry.
       
  2693 	TBool local;
       
  2694 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CreateAttachmentForWriteL"));
       
  2695 
       
  2696 	if( local )
       
  2697 		{
       
  2698 		// Update the owner ID of the entry. NOTE - doesn't matter if actually
       
  2699 		// attachment creation fails after this - safer that owner ID is updated
       
  2700 		// at very least.
       
  2701 		UpdateOwnerIdL(msgId, aMessage.SecureId());
       
  2702 		}
       
  2703 
       
  2704 	// Get the file name from slot 1
       
  2705 	TFileName fileName;
       
  2706 	aMessage.ReadL(1, fileName);
       
  2707 
       
  2708 	RFs fs;
       
  2709 	ConnectAndShareFileSessionLC(fs);
       
  2710 
       
  2711 	// Set the CMsvServer and file session
       
  2712 	TMsvServerStoreManager storemanager;
       
  2713 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2714 
       
  2715 	RFile file;
       
  2716 	TBool fileNameChanged = storemanager.CreateAttachmentForWriteL(msgId, fileName, file);
       
  2717 	CleanupClosePushL(file);
       
  2718 
       
  2719 	// Write the sub session handle (RFile) in slot 2
       
  2720 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2721 	aMessage.WriteL(2,pckgSubSessionHandle);
       
  2722 
       
  2723 	// Write the file changed status in slot 3
       
  2724 	TPckg<TBool> pckgFileNameChanged(fileNameChanged);
       
  2725 	aMessage.WriteL(3,pckgFileNameChanged);
       
  2726 
       
  2727 	// Write back the file path to the client.
       
  2728 	TInt desLen = aMessage.GetDesMaxLength(1);
       
  2729 	if( desLen < fileName.Length() )
       
  2730 		User::Leave(KErrOverflow);
       
  2731 	aMessage.WriteL(1, fileName);
       
  2732 
       
  2733 	// Takes care of completing with session (RFs),
       
  2734 	// SendReceieve returns session handle at client side
       
  2735 	User::LeaveIfError(file.TransferToClient(aMessage,2));
       
  2736 
       
  2737 	CleanupStack::PopAndDestroy(2, &fs); // fs , file
       
  2738 	}
       
  2739 
       
  2740 void CMsvServerSession::ReplaceAttachmentForWriteL(const RMessage2 &aMessage)
       
  2741 	{
       
  2742 	// Get the Message Id from slot 0
       
  2743 	TMsvId msgId = aMessage.Int0();
       
  2744 
       
  2745 	// Police request - client must be able to modify the entry.
       
  2746 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ReplaceAttachmentForWriteL"));
       
  2747 
       
  2748 	// Get the file name from slot 1
       
  2749 	TFileName fileName;
       
  2750 	aMessage.ReadL(1, fileName);
       
  2751 
       
  2752 	RFs fs;
       
  2753 	ConnectAndShareFileSessionLC(fs);
       
  2754 
       
  2755 	// Set the CMsvServer and file session
       
  2756 	TMsvServerStoreManager storemanager;
       
  2757 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2758 
       
  2759 	RFile file;
       
  2760 	storemanager.ReplaceAttachmentForWriteL(msgId, fileName, file);
       
  2761 	CleanupClosePushL(file);
       
  2762 
       
  2763 	// Write the sub session handle (RFile) in slot 2
       
  2764 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2765 	aMessage.WriteL(2,pckgSubSessionHandle);
       
  2766 
       
  2767 	// Write back the file path to the client.
       
  2768 	TInt desLen = aMessage.GetDesMaxLength(1);
       
  2769 	if( desLen < fileName.Length() )
       
  2770 		User::Leave(KErrOverflow);
       
  2771 	aMessage.WriteL(1, fileName);
       
  2772 
       
  2773 	// Takes care of completing with session (RFs),
       
  2774 	// SendReceieve returns session handle at client side
       
  2775 	User::LeaveIfError(file.TransferToClient(aMessage,2));
       
  2776 
       
  2777 	CleanupStack::PopAndDestroy(2, &fs); // fs , file
       
  2778 	}
       
  2779 
       
  2780 void CMsvServerSession::OpenAttachmentL(const RMessage2 &aMessage)
       
  2781 	{
       
  2782 	// Get the Message Id from slot 0
       
  2783 	TMsvId msgId = aMessage.Int0();
       
  2784 
       
  2785 	// Police request - client must be able to read the entry.
       
  2786 	iMsvServer.PoliceReadEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::OpenAttachmentL"));
       
  2787 
       
  2788 	// Get the file name from slot 1
       
  2789 	TFileName filePath;
       
  2790 	aMessage.ReadL(1, filePath);
       
  2791 
       
  2792 	RFs fs;
       
  2793 	ConnectAndShareFileSessionLC(fs);
       
  2794 
       
  2795 	// Set the CMsvServer and file session
       
  2796 	TMsvServerStoreManager storemanager;
       
  2797 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2798 
       
  2799 	RFile file;
       
  2800 	storemanager.OpenAttachmentL(msgId, filePath, file);
       
  2801 	CleanupClosePushL(file);
       
  2802 
       
  2803 	// Write the sub session handle (RFile) in slot 2
       
  2804 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2805 	aMessage.WriteL(2,pckgSubSessionHandle);
       
  2806 
       
  2807 	// Takes care of completing with session (RFs),
       
  2808 	// SendReceieve returns session handle at client side
       
  2809 	User::LeaveIfError(file.TransferToClient(aMessage,2));
       
  2810 
       
  2811 	CleanupStack::PopAndDestroy(2,&fs); // fs, file
       
  2812 	}
       
  2813 
       
  2814 void CMsvServerSession::OpenAttachmentForWriteL(const RMessage2 &aMessage)
       
  2815 	{
       
  2816 	// Get the Message Id from slot 0
       
  2817 	TMsvId msgId = aMessage.Int0();
       
  2818 
       
  2819 	// Police request - client must be able to read the entry.
       
  2820 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::OpenAttachmentForWriteL"));
       
  2821 
       
  2822 	// Get the file name from slot 1
       
  2823 	TFileName filePath;
       
  2824 	aMessage.ReadL(1, filePath);
       
  2825 
       
  2826 	RFs fs;
       
  2827 	ConnectAndShareFileSessionLC(fs);
       
  2828 
       
  2829 	// Set the CMsvServer and file session
       
  2830 	TMsvServerStoreManager storemanager;
       
  2831 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2832 
       
  2833 	RFile file;
       
  2834 	storemanager.OpenAttachmentForWriteL(msgId, filePath, file);
       
  2835 	CleanupClosePushL(file);
       
  2836 
       
  2837 	// Write the sub session handle (RFile) in slot 2
       
  2838 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2839 	aMessage.WriteL(2,pckgSubSessionHandle);
       
  2840 
       
  2841 	// Takes care of completing with session (RFs),
       
  2842 	// SendReceieve returns session handle at client side
       
  2843 	User::LeaveIfError(file.TransferToClient(aMessage,2));
       
  2844 
       
  2845 	CleanupStack::PopAndDestroy(2,&fs); // fs, file
       
  2846 	}
       
  2847 
       
  2848 void CMsvServerSession::DeleteAttachmentL(const RMessage2 &aMessage)
       
  2849 	{
       
  2850 	// Get the Message Id from slot 0
       
  2851 	TMsvId msgId = aMessage.Int0();
       
  2852 
       
  2853 	// Police request - client must be able to modify the entry.
       
  2854 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DeleteAttachmentL"));
       
  2855 
       
  2856 	// Get the file name from slot 1
       
  2857 	TFileName filePath;
       
  2858 	aMessage.ReadL(1, filePath);
       
  2859 
       
  2860 	// Set the CMsvServer and file session
       
  2861 	TMsvServerStoreManager storemanager;
       
  2862 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  2863 
       
  2864 	TInt error = storemanager.DeleteAttachment(msgId, filePath);
       
  2865 	aMessage.Complete(error);
       
  2866 	}
       
  2867 
       
  2868 void CMsvServerSession::RenameAttachmentL(const RMessage2 &aMessage)
       
  2869 	{
       
  2870 	// Get the Message Id from slot 0
       
  2871 	TMsvId msgId = aMessage.Int0();
       
  2872 
       
  2873 	// Police request - client must be able to modify the entry.
       
  2874 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::RenameAttachmentL"));
       
  2875 
       
  2876 	// Get the old file name from slot 1
       
  2877 	TFileName oldFileName;
       
  2878 	aMessage.ReadL(1, oldFileName);
       
  2879 
       
  2880 	// Get the new file name from slot 2
       
  2881 	TFileName newFileName;
       
  2882 	aMessage.ReadL(2, newFileName);
       
  2883 
       
  2884 	// Set the CMsvServer and file session
       
  2885 	TMsvServerStoreManager storemanager;
       
  2886 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  2887 
       
  2888 	TInt error = storemanager.RenameAttachment(msgId, oldFileName, newFileName);
       
  2889 	aMessage.Complete(error);
       
  2890 	}
       
  2891 
       
  2892 void CMsvServerSession::FileExistsL(const RMessage2 &aMessage)
       
  2893 	{
       
  2894 	// Get the file name from slot 10
       
  2895 	TFileName filePath;
       
  2896 	aMessage.ReadL(0, filePath);
       
  2897 
       
  2898 	// Set the CMsvServer and file session
       
  2899 	TMsvServerStoreManager storemanager;
       
  2900 	storemanager.SetMsvServerAndFileSession(iMsvServer, iMsvServer.FileSession());
       
  2901 
       
  2902 	TInt err = KErrNotFound;
       
  2903 	if( storemanager.FileExistsL(filePath) )
       
  2904 		{
       
  2905 		err = KErrNone;
       
  2906 		}
       
  2907 
       
  2908 	aMessage.Complete(err);
       
  2909 	}
       
  2910 
       
  2911 void CMsvServerSession::GetAttachmentFilePathL(const RMessage2& aMessage)
       
  2912 	{
       
  2913 	// Get the Message Id from slot 0
       
  2914 	TMsvId msgId = aMessage.Int0();
       
  2915 
       
  2916 	// Get the file path buffer from slot 1
       
  2917 	TFileName filePath;
       
  2918 	aMessage.ReadL(1, filePath);
       
  2919 
       
  2920 	// Set the CMsvServer and file session
       
  2921 	TMsvServerStoreManager storeManager;
       
  2922 	storeManager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  2923 	storeManager.AttachmentFilePathL(msgId, filePath);
       
  2924 
       
  2925 	// Write the attachment file path back to slot 1
       
  2926 	TInt desLen = aMessage.GetDesMaxLength(1);
       
  2927 	if( desLen < filePath.Length() )
       
  2928 		{
       
  2929 		User::Leave(KErrOverflow);
       
  2930 		}
       
  2931 
       
  2932 	aMessage.WriteL(1, filePath);
       
  2933 	aMessage.Complete(KErrNone);
       
  2934 	}
       
  2935 
       
  2936 void CMsvServerSession::OpenFileStoreForReadL(const RMessage2 &aMessage)
       
  2937 	{
       
  2938 	// Get the Message Id from slot 0
       
  2939 	TMsvId msgId = aMessage.Int0();
       
  2940 
       
  2941 	// Police request - client must be able to read the entry.
       
  2942 	iMsvServer.PoliceReadEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::OpenFileStoreForReadL"));
       
  2943 
       
  2944 	RFs fs;
       
  2945 	ConnectAndShareFileSessionLC(fs);
       
  2946 
       
  2947 	// Set the CMsvServer and file session
       
  2948 	TMsvServerStoreManager storemanager;
       
  2949 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2950 
       
  2951 	RFile file;
       
  2952 	User::LeaveIfError( storemanager.OpenFileStoreForRead(msgId,file));
       
  2953 	CleanupClosePushL(file);
       
  2954 
       
  2955 	// Write the sub session handle (RFile) in slot 1
       
  2956 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2957 	aMessage.WriteL(1,pckgSubSessionHandle);
       
  2958 
       
  2959 	// Takes care of completing with session (RFs),
       
  2960 	// SendReceieve returns session handle at client side
       
  2961 	User::LeaveIfError(file.TransferToClient(aMessage,1));
       
  2962 
       
  2963 	CleanupStack::PopAndDestroy(2,&fs); // fs, file
       
  2964 	}
       
  2965 
       
  2966 void CMsvServerSession::OpenTempStoreFileL(const RMessage2 &aMessage)
       
  2967 	{
       
  2968 	// Get the Message Id from slot 0
       
  2969 	TMsvId msgId = aMessage.Int0();
       
  2970 
       
  2971 	// Police request - client must be able to modify the entry.
       
  2972 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::OpenTempStoreFileL"));
       
  2973 
       
  2974 	RFs fs;
       
  2975 	ConnectAndShareFileSessionLC(fs);
       
  2976 
       
  2977 	// Set the CMsvServer and file session
       
  2978 	TMsvServerStoreManager storemanager;
       
  2979 	storemanager.SetMsvServerAndFileSession(iMsvServer,fs);
       
  2980 
       
  2981 	RFile file;
       
  2982 	storemanager.OpenTempStoreFileL(msgId,file);
       
  2983 	CleanupClosePushL(file);
       
  2984 
       
  2985 	// Write the sub session handle (RFile) in slot 1
       
  2986 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle());
       
  2987 	aMessage.WriteL(1,pckgSubSessionHandle);
       
  2988 
       
  2989 	// Takes care of completing with session (RFs),
       
  2990 	// SendReceieve returns session handle at client side
       
  2991 	User::LeaveIfError(file.TransferToClient(aMessage,1));
       
  2992 
       
  2993 	CleanupStack::PopAndDestroy(2,&fs); // fs, file
       
  2994 	}
       
  2995 
       
  2996 void CMsvServerSession::ReplaceFileStoreL(const RMessage2 &aMessage)
       
  2997 	{
       
  2998 	// Get the Message Id from slot 0
       
  2999 	TMsvId msgId = aMessage.Int0();
       
  3000 
       
  3001 	// Police request - client must be able to modify the entry.
       
  3002 	TBool local;
       
  3003 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ReplaceFileStoreL"));
       
  3004 
       
  3005 	if( local )
       
  3006 		{
       
  3007 		// Update the owner ID of the entry. NOTE - doesn't matter if actually
       
  3008 		// attachment creation fails after this - safer that owner ID is updated
       
  3009 		// at very least.
       
  3010 		UpdateOwnerIdL(msgId, aMessage.SecureId());
       
  3011 		}
       
  3012 
       
  3013 	// Set the CMsvServer and file session
       
  3014 	TMsvServerStoreManager storemanager;
       
  3015 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  3016 
       
  3017 	storemanager.ReplaceFileStoreL(msgId);
       
  3018 	aMessage.Complete(KErrNone);
       
  3019 	}
       
  3020 
       
  3021 void CMsvServerSession::DeleteFileStoreL(const RMessage2 &aMessage)
       
  3022 	{
       
  3023 	// Get the Message Id from slot 0
       
  3024 	TMsvId msgId = aMessage.Int0();
       
  3025 
       
  3026 	// Police request - client must be able to modify the entry.
       
  3027 	iMsvServer.PoliceModifyEntryL(aMessage, msgId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DeleteFileStoreL"));
       
  3028 
       
  3029 	// Set the CMsvServer and file session
       
  3030 	TMsvServerStoreManager storemanager;
       
  3031 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  3032 
       
  3033 	storemanager.DeleteFileStoreL(msgId);
       
  3034 	aMessage.Complete(KErrNone);
       
  3035 	}
       
  3036 
       
  3037 void CMsvServerSession::FileStoreExistsL(const RMessage2 &aMessage) const
       
  3038 	{
       
  3039 	// Get the Message Id from slot 0
       
  3040 	TMsvId msgId = aMessage.Int0();
       
  3041 
       
  3042 	// Set the CMsvServer and file session
       
  3043 	TMsvServerStoreManager storemanager;
       
  3044 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession());
       
  3045 
       
  3046 	TInt storeExists = storemanager.FileStoreExistsL(msgId);
       
  3047 	aMessage.Complete(storeExists);
       
  3048 	}
       
  3049 
       
  3050 void CMsvServerSession::ConnectAndShareFileSessionLC(RFs& aFs )
       
  3051 	{
       
  3052 	User::LeaveIfError(aFs.Connect());
       
  3053 	CleanupClosePushL(aFs);
       
  3054 	User::LeaveIfError(aFs.ShareProtected());
       
  3055 	}
       
  3056 
       
  3057 void CMsvServerSession::UpdateOwnerIdL(TMsvId aId, TSecureId aOwnerId)
       
  3058 	{
       
  3059 	User::LeaveIfError(iMsvServer.IndexAdapter().LockEntry(aId));
       
  3060 	TMsvEntry* entry;
       
  3061 	iMsvServer.IndexAdapter().GetEntry(aId, entry); // error ignored
       
  3062 	User::LeaveIfError(iMsvServer.IndexAdapter().ChangeEntry(*entry, aOwnerId, ETrue));
       
  3063 	iMsvServer.IndexAdapter().ReleaseEntry(aId);		// error ignored
       
  3064 	}
       
  3065 
       
  3066 
       
  3067 /**
       
  3068 Gets the path for the file in message store for which the message Id is passed in RMessage2.
       
  3069 @param aMessage RMessage2 encapsulating client request and data.
       
  3070 @return none.
       
  3071 */
       
  3072 void CMsvServerSession::BodyTextFilePathL(const RMessage2 &aMessage)
       
  3073 	{
       
  3074 	// Get the Message Id from slot 0
       
  3075 	TMsvId bodyTextId = aMessage.Int0();
       
  3076 	
       
  3077 	// Get the file name from slot 1
       
  3078 	TFileName filePath;
       
  3079 	aMessage.ReadL(1, filePath);
       
  3080 		
       
  3081 	// Set the CMsvServer and file session 
       
  3082 	TMsvServerStoreManager storemanager; 
       
  3083 	storemanager.SetMsvServerAndFileSession(iMsvServer, iMsvServer.FileSession());
       
  3084 	
       
  3085 	storemanager.BodyTextFilePathL(bodyTextId, filePath);
       
  3086 	aMessage.WriteL(1, filePath);   
       
  3087 	aMessage.Complete(KErrNone);
       
  3088 	}
       
  3089 
       
  3090 
       
  3091 /**
       
  3092 Open the RFile located in filepath encapsulted in RMessage2 in Read mode.
       
  3093 @param aMessage RMessage2 encapsulating client request and data.
       
  3094 @return none.
       
  3095 */
       
  3096 void CMsvServerSession::OpenPlainTextFileL(const RMessage2 &aMessage)
       
  3097 	{
       
  3098 	TMsvId bodyTextId = aMessage.Int0();
       
  3099 	
       
  3100 	TFileName filePath;
       
  3101 	aMessage.ReadL(1, filePath);
       
  3102 	iMsvServer.PoliceReadEntryL(aMessage, bodyTextId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::OpenPlainTextFileL"));
       
  3103 	
       
  3104 	RFs fs;
       
  3105 	ConnectAndShareFileSessionLC(fs);
       
  3106 	RFile file;
       
  3107 	CleanupClosePushL(file);
       
  3108 		
       
  3109 	// Set the CMsvServer and file session 
       
  3110 	TMsvServerStoreManager storemanager;
       
  3111 	storemanager.SetMsvServerAndFileSession(iMsvServer, fs); 
       
  3112 	storemanager.OpenBodyTextFileForReadL(file, bodyTextId, filePath);
       
  3113 
       
  3114 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle()); 
       
  3115 	aMessage.WriteL(2,pckgSubSessionHandle);
       
  3116 	User::LeaveIfError(file.TransferToClient(aMessage, 2));
       
  3117 	CleanupStack::PopAndDestroy(2, &fs);
       
  3118 	}
       
  3119 
       
  3120 
       
  3121 /**
       
  3122 Creates the RFile in location specified by filepath encapsulted in RMessage2.
       
  3123 @param aMessage RMessage2 encapsulating client request and data.
       
  3124 @return none.
       
  3125 */  
       
  3126 void CMsvServerSession::CreatePlainTextFileL(const RMessage2 &aMessage)
       
  3127 	{
       
  3128 	TMsvId bodyTextId = aMessage.Int0();
       
  3129 	
       
  3130 	iMsvServer.PoliceModifyEntryL(aMessage, bodyTextId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CreatePlainTextFileL")); 
       
  3131 	
       
  3132 	RFs fs;
       
  3133 	ConnectAndShareFileSessionLC(fs);
       
  3134 	
       
  3135 	RFile file;
       
  3136 	CleanupClosePushL(file);
       
  3137 		
       
  3138 	// Set the CMsvServer and file session 
       
  3139 	TMsvServerStoreManager storemanager;
       
  3140 	storemanager.SetMsvServerAndFileSession(iMsvServer, fs); 
       
  3141 	storemanager.CreatePlainTextFileL(file, bodyTextId);
       
  3142 	
       
  3143 	TPckg<TInt> pckgSubSessionHandle(file.SubSessionHandle()); 
       
  3144 	aMessage.WriteL(1,pckgSubSessionHandle);
       
  3145 	User::LeaveIfError(file.TransferToClient(aMessage,1));
       
  3146 	CleanupStack::PopAndDestroy(2, &fs);
       
  3147 	}
       
  3148 
       
  3149 
       
  3150 /**
       
  3151 Deletes the RFile located in filepath encapsulted in RMessage2
       
  3152 @param aMessage RMessage2 encapsulating client request and data.
       
  3153 @return none.
       
  3154 */
       
  3155 void CMsvServerSession::DeletePlainTextFileL(const RMessage2& aMessage)
       
  3156 	{
       
  3157 	TMsvServerStoreManager storemanager;
       
  3158 	storemanager.SetMsvServerAndFileSession(iMsvServer, iMsvServer.FileSession()); 
       
  3159 	TMsvId bodyTextId = aMessage.Int0();
       
  3160 
       
  3161 	// Police request - client must be able to modify the entry.
       
  3162 	iMsvServer.PoliceModifyEntryL(aMessage, bodyTextId, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DeletePlainTextFileL"));
       
  3163 	storemanager.DeletePlainTextFileL(bodyTextId);
       
  3164 	}
       
  3165 
       
  3166 /**
       
  3167 Replace the RFile for the message Id encapsulted in RMessage2.
       
  3168 @param aMessage RMessage2 encapsulating client request and data.
       
  3169 @return none.
       
  3170 */  
       
  3171 void CMsvServerSession::ReplacePlainTextFileL(const RMessage2 &aMessage)
       
  3172 	{
       
  3173 	// Get the Message Id from slot 0
       
  3174 	TMsvId bodyTextId = aMessage.Int0();
       
  3175 	
       
  3176 	// Police request - client must be able to modify the entry.
       
  3177 	TBool local;
       
  3178 	iMsvServer.PoliceModifyEntryL(aMessage, bodyTextId, local, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ReplacePlainTextFileL")); 
       
  3179 
       
  3180 	if( local )
       
  3181 		{
       
  3182 		// Update the owner ID of the entry. 
       
  3183 		UpdateOwnerIdL(bodyTextId, aMessage.SecureId());
       
  3184 		}
       
  3185 
       
  3186 	// Set the CMsvServer and file session 
       
  3187 	TMsvServerStoreManager storemanager;
       
  3188 	storemanager.SetMsvServerAndFileSession(iMsvServer,iMsvServer.FileSession()); 
       
  3189 		
       
  3190 	storemanager.ReplacePlainTextFileL(bodyTextId);
       
  3191 	aMessage.Complete(KErrNone);
       
  3192 	}
       
  3193 
       
  3194 /**
       
  3195 Gets data from a server MTM that is not related to any operation being performed on
       
  3196 that MTM.
       
  3197 
       
  3198 @param aMessage Received message
       
  3199 */
       
  3200 void CMsvServerSession::GetNonOperationMtmDataL(const RMessage2 &aMessage)
       
  3201 	{
       
  3202 	TPtrC8 desPtr;
       
  3203 
       
  3204 	iMsvServer.GetNonOperationMtmDataL(static_cast<TMsvId>(aMessage.Int0()), static_cast<TNonOperationMtmDataType>(aMessage.Int1()), desPtr);
       
  3205 
       
  3206 	TInt desLength = aMessage.GetDesMaxLength(2);
       
  3207 	if (desLength < desPtr.Length())
       
  3208 		{
       
  3209 		aMessage.Complete(KErrOverflow);
       
  3210 		}
       
  3211 	else
       
  3212 		{
       
  3213 		WriteL(aMessage, 2, desPtr);
       
  3214 		aMessage.Complete(KErrNone);
       
  3215 		}
       
  3216 	}
       
  3217 
       
  3218 
       
  3219 /*****************************************
       
  3220  * SearchSortOnHeaderAndBodytMsgL() :
       
  3221  * Get the Query data from  client to make Search-Sort on HEADER abd BODY
       
  3222  * in meassage server.
       
  3223  * 
       
  3224  * @param aMessage Received message
       
  3225  ****************************************/ 
       
  3226 void CMsvServerSession::SearchSortOnHeaderAndBodytMsgL(const RMessage2& aMessage)
       
  3227 	{
       
  3228 	//For Simultaneously query
       
  3229 	if(CMSvSearchSortCacheManager::Instance()->OutstandingSOSOperations() > 0)
       
  3230        		{
       
  3231 			if(CMSvSearchSortCacheManager::Instance()->iProgress != KMsvSearchSortOpCompleted)
       
  3232 				{
       
  3233 				User::Leave(KErrServerBusy); // One is SOS request is under proress.
       
  3234 				}
       
  3235        		}
       
  3236 	CMSvSearchSortCacheManager::Instance()->AddOutstandingSOSOperation();
       
  3237 
       
  3238 	//Header and body.
       
  3239 	TMsvOp operationId = aMessage.Int0();
       
  3240 		
       
  3241 	HBufC8* buffer = NULL;
       
  3242 	ReadBufferL(aMessage, 1, buffer);
       
  3243 	CleanupStack::PushL(buffer);
       
  3244 
       
  3245 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::SearchSortOnHeaderAndBodytMsgL"));
       
  3246 	
       
  3247 	CMsvSearchSortQuery* query= CMsvSearchSortQuery::NewL() ;
       
  3248 	CleanupStack::PushL(query);
       
  3249 
       
  3250 	TMsvPackQuery packedQuery(buffer);
       
  3251 	packedQuery.UnpackQuery(query);
       
  3252 		
       
  3253 	TBool markQuery = aMessage.Int2();
       
  3254 	
       
  3255 	CMsvSearchSortCacheEntry *aEntry = CMsvSearchSortCacheEntry::CreateQueryEntryL(query, markQuery);
       
  3256 	CleanupStack::PushL(aEntry);
       
  3257 	
       
  3258 	TInt indexCount =CMSvSearchSortCacheManager::Instance()->QueryExists(*aEntry);
       
  3259 	//Check the query is exist or not.
       
  3260 	
       
  3261 	if(CMSvSearchSortCacheManager::Instance()->QueryExists(*aEntry)<0)
       
  3262 		{
       
  3263 	
       
  3264 		//NEW Query
       
  3265 		if(!aEntry->IsSortQuery())
       
  3266 			{
       
  3267 			CMSvSearchSortCacheManager::Instance()->TypeOfSearchQuery(*aEntry);
       
  3268 			}
       
  3269 		else
       
  3270 			{
       
  3271 			CMSvSearchSortCacheManager::Instance()->TypeOfSortQuery(*aEntry);
       
  3272 			}
       
  3273 		//Do process query.
       
  3274 		CMSvSearchSortCacheManager::Instance()->DoProcessQueryL(*aEntry);
       
  3275 		}
       
  3276 	else 
       
  3277 		{
       
  3278 		//Existing Query
       
  3279 		CMSvSearchSortCacheManager::Instance()->DoProcessQueryL(indexCount);
       
  3280 		}
       
  3281 	CleanupStack::Pop();//  aEntry
       
  3282 	CleanupStack::PopAndDestroy(2); //  query, buffer
       
  3283 	aMessage.Complete(KErrNone);
       
  3284 	}
       
  3285 	
       
  3286 
       
  3287 /*****************************************
       
  3288  * SearchSortOnIndexEntry() :
       
  3289  * Get the Query data from  client to make Search-Sort on INDEX ENTRY
       
  3290  * in meassage server.
       
  3291  * 
       
  3292  * @param aMessage Received message
       
  3293  ****************************************/ 
       
  3294 
       
  3295 void CMsvServerSession::SearchSortOnIndexEntryL(const RMessage2& aMessage)
       
  3296 	{
       
  3297   	//For Simultaneously query
       
  3298    	if(CMSvSearchSortCacheManager::Instance()->OutstandingSOSOperations() > 0)
       
  3299        	{
       
  3300        	if(CMSvSearchSortCacheManager::Instance()->iProgress != KMsvSearchSortOpCompleted)
       
  3301 			{
       
  3302             User::Leave(KErrServerBusy); // One is SOS request is under proress.
       
  3303 			}
       
  3304        	}
       
  3305  	CMSvSearchSortCacheManager::Instance()->AddOutstandingSOSOperation();
       
  3306 
       
  3307 	//Search sort on index entry.
       
  3308 	// Recover the operation data
       
  3309 	TMsvOp operationId = aMessage.Int0();
       
  3310 	
       
  3311 	HBufC8* buffer = NULL;
       
  3312 	ReadBufferL(aMessage, 1, buffer);
       
  3313 	CleanupStack::PushL(buffer);
       
  3314 	
       
  3315 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::SearchSortOnIndexEntryL"));
       
  3316 
       
  3317 	CMsvSearchSortQuery* query= CMsvSearchSortQuery::NewL() ;
       
  3318 	CleanupStack::PushL(query);
       
  3319 
       
  3320 	TMsvPackQuery packedQuery(buffer);
       
  3321 	packedQuery.UnpackQuery(query);
       
  3322 
       
  3323 		
       
  3324 	TBool markQuery = aMessage.Int2();
       
  3325 	TInt  iteratorCount = aMessage.Int3();
       
  3326 	
       
  3327 	CMsvSearchSortCacheEntry *aEntry = CMsvSearchSortCacheEntry::CreateQueryEntryL(query, markQuery,iteratorCount);
       
  3328 	CleanupStack::PushL(aEntry);
       
  3329 	
       
  3330 	TInt indexCount =CMSvSearchSortCacheManager::Instance()->QueryExists(*aEntry);
       
  3331 	//Query Exist or not
       
  3332 	if(CMSvSearchSortCacheManager::Instance()->QueryExists(*aEntry)<0)
       
  3333 		{
       
  3334 		//NEW Query
       
  3335 		if(!aEntry->IsSortQuery())
       
  3336 			{
       
  3337 			CMSvSearchSortCacheManager::Instance()->TypeOfSearchQuery(*aEntry);
       
  3338 			}
       
  3339 		else
       
  3340 			{
       
  3341 			CMSvSearchSortCacheManager::Instance()->TypeOfSortQuery(*aEntry);
       
  3342 			}
       
  3343 		//Do process query.
       
  3344 		CMSvSearchSortCacheManager::Instance()->DoProcessQueryL(*aEntry,iteratorCount);
       
  3345 		}
       
  3346 	else 
       
  3347 		{
       
  3348 		//Existing Query
       
  3349 		CMSvSearchSortCacheManager::Instance()->DoProcessQueryL(indexCount);
       
  3350 		}
       
  3351 	
       
  3352 	CleanupStack::Pop();		// aEntry
       
  3353 	CleanupStack::PopAndDestroy(2, buffer); // buffer, CmsvSearchSortQuery
       
  3354 	aMessage.Complete(KErrNone);
       
  3355 	}
       
  3356 
       
  3357 void CMsvServerSession::SendSearchSortIndexEntryResultL(const RMessage2 &aMessage)
       
  3358 	{
       
  3359 	TBool resultType = aMessage.Int0();
       
  3360 	
       
  3361 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::SendSearchSortIndexEntryResultL"));
       
  3362 	//id's
       
  3363 	if(resultType) // EResultAsTMsvID
       
  3364 		{
       
  3365 		TMsvPackedIdOperation op(iBuffer);
       
  3366 		TInt error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3367 		while (error != KErrNone)
       
  3368 			{
       
  3369 			// increase the size of the buffer and try again
       
  3370 			iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3371 			iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3372 			error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3373 			}
       
  3374 		}
       
  3375 	else  // EResultAsTMsvEntry
       
  3376 		{
       
  3377 		//As of now it takes TMsvId.
       
  3378 		}
       
  3379 	WriteBufferL(aMessage, 1);
       
  3380 	CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray.Reset();
       
  3381 	CMSvSearchSortCacheManager::Instance()->iToFindResultAsIdArray.Reset();
       
  3382 	CMSvSearchSortCacheManager::Instance()->iMsvIdWithSortFieldArray.Reset();
       
  3383 	aMessage.Complete(KErrNone);
       
  3384 	}
       
  3385 
       
  3386 
       
  3387 
       
  3388 //sending resultas
       
  3389 void CMsvServerSession::SendResultOrIdsToSearchL(const RMessage2& aMessage)
       
  3390 	{
       
  3391 	// result type (is it a Final result, Partial Result or New query)
       
  3392 	TPckgBuf<TInt> resultType;
       
  3393 	TInt errorMem = KErrNone;
       
  3394 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::SendResultOrIdsToSearchL"));   
       
  3395 	//resuttype
       
  3396 	resultType = CMSvSearchSortCacheManager::Instance()->iReturnResultType;
       
  3397 	
       
  3398 	if(CMSvSearchSortCacheManager::Instance()->iReturnResultType == KMsvSearchSortQueryIdNotFound)
       
  3399 		{
       
  3400 		WriteL(aMessage, 1, resultType);
       
  3401 		}
       
  3402 	else
       
  3403 		{
       
  3404 		// need to send data to client according resultType 
       
  3405 		// result type is KFinalResult, KNewQuery or KPartilaResult
       
  3406 		TInt error = KErrNone;
       
  3407 		
       
  3408 		TMsvPackedIdOperation op(iBuffer);
       
  3409 		
       
  3410 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
  3411 		error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3412 		while (error != KErrNone)
       
  3413 			{
       
  3414 			// increase the size of the buffer and try again
       
  3415 			iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3416 			iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3417 			error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3418 			}
       
  3419 
       
  3420 #else   // else SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB	
       
  3421 	
       
  3422 		if(CMSvSearchSortCacheManager::Instance()->iReturnResultType == KFinalResult)
       
  3423 			{
       
  3424 			CMSvSearchSortCacheManager::Instance()->iSearchSortDeltaCache->iIsHeaderSearchEnabled = EFalse;
       
  3425 			error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3426 			
       
  3427 			while (error != KErrNone)
       
  3428 				{
       
  3429 				// increase the size of the buffer and try again
       
  3430 				iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3431 				iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3432 				error = op.Pack(CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray);
       
  3433 				}
       
  3434 			}
       
  3435 		else if(CMSvSearchSortCacheManager::Instance()->iReturnResultType == KNewQuery)
       
  3436 			{
       
  3437 			error = op.Pack(CMSvSearchSortCacheManager::Instance()->iToFindResultAsIdArray);
       
  3438 			while (error != KErrNone)
       
  3439 				{
       
  3440 				// increase the size of the buffer and try again
       
  3441 				iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3442 				iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3443 				error = op.Pack(CMSvSearchSortCacheManager::Instance()->iToFindResultAsIdArray);
       
  3444 				}
       
  3445 			}
       
  3446 		else // for KPartialResult
       
  3447 			{
       
  3448 			error = op.Pack(CMSvSearchSortCacheManager::Instance()->iDeltaCacheIdArray);
       
  3449 			while (error != KErrNone)
       
  3450 				{
       
  3451 				// increase the size of the buffer and try again
       
  3452 				iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3453 				iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3454 				error = op.Pack(CMSvSearchSortCacheManager::Instance()->iDeltaCacheIdArray);
       
  3455 				}
       
  3456 			}
       
  3457 #endif // SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB
       
  3458 			
       
  3459 		// send Id's in buffer
       
  3460 		TRAP(errorMem,WriteBufferL(aMessage,0));
       
  3461 			
       
  3462 		//send resultType to client, whether it's final result, partial result or newQuery.
       
  3463 		WriteL(aMessage,1,resultType);
       
  3464 		}
       
  3465 	
       
  3466 	//needs to reset RArray
       
  3467 	if(errorMem==KErrNone)
       
  3468 		{
       
  3469 		CMSvSearchSortCacheManager::Instance()->iFinalResultAsIdArray.Reset();
       
  3470 		CMSvSearchSortCacheManager::Instance()->iToFindResultAsIdArray.Reset();
       
  3471 		CMSvSearchSortCacheManager::Instance()->iMsvIdWithSortFieldArray.Reset();
       
  3472 		}
       
  3473 
       
  3474 	aMessage.Complete(errorMem);
       
  3475 	}
       
  3476 
       
  3477 void CMsvServerSession::GetSearchSortResultCountL(const RMessage2& aMessage)
       
  3478 	{
       
  3479 	TPckgBuf<TInt> resultCount;
       
  3480 	
       
  3481 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetSearchSortResultCountL"));  
       
  3482 		
       
  3483 	TInt  index = CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count();
       
  3484 	CMSvSearchSortCacheManager::Instance()->ResultCountL(index-1);
       
  3485 	
       
  3486 	resultCount() = CMSvSearchSortCacheManager::Instance()->iFinalResultCount;//Contain the result.
       
  3487 	WriteL(aMessage, 0, resultCount);
       
  3488 	CMSvSearchSortCacheManager::Instance()->iFinalResultCount = 0;
       
  3489 	aMessage.Complete(KErrNone);
       
  3490 	}
       
  3491 	
       
  3492 	
       
  3493 void CMsvServerSession::GetResultInIteratorL(const RMessage2& aMessage)
       
  3494 	{
       
  3495 	TPckgBuf<TMsvId> messageId;
       
  3496 	TPckgBuf<TInt> count;
       
  3497 	
       
  3498 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetResultInIteratorL"));   
       
  3499 		
       
  3500 	TInt  index = CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count();
       
  3501 	CMSvSearchSortCacheManager::Instance()->NextResultForInteraratorL(index-1);
       
  3502 	messageId() = CMSvSearchSortCacheManager::Instance()->iIteratorId;
       
  3503 	count() = CMSvSearchSortCacheManager::Instance()->iIteratorRemainingResultCount;
       
  3504 	
       
  3505 	//result as TMsvId
       
  3506 	WriteL(aMessage, 0, messageId);
       
  3507 	//for remaing count
       
  3508 	WriteL(aMessage, 1, count);
       
  3509 	
       
  3510 	CMSvSearchSortCacheManager::Instance()->iIteratorId = 0;
       
  3511 	aMessage.Complete(KErrNone);
       
  3512 	}
       
  3513 	
       
  3514 void CMsvServerSession::GetNextEntryInIteratorL(const RMessage2& aMessage)
       
  3515 	{
       
  3516 	//need this varible to send remaining count to client
       
  3517 	TPckgBuf<TInt> count;
       
  3518 	
       
  3519 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetNextEntryInIteratorL"));	
       
  3520 	
       
  3521 	TInt  index = CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count();
       
  3522 	CMSvSearchSortCacheManager::Instance()->NextResultForInteraratorL(index-1);
       
  3523 	
       
  3524 	// package the entry
       
  3525 	TMsvPackedEntry packedEntry(iBuffer);
       
  3526 	TInt error = packedEntry.PackEntry(CMSvSearchSortCacheManager::Instance()->iIteratorEntry);
       
  3527 	while(error!=KErrNone)
       
  3528 		{
       
  3529 		// increase the size of the buffer and try again
       
  3530 		iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3531 		iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3532 		error = packedEntry.PackEntry(CMSvSearchSortCacheManager::Instance()->iIteratorEntry);
       
  3533 		}
       
  3534 	//needs fill the remaing count
       
  3535 	count() =  CMSvSearchSortCacheManager::Instance()->iIteratorRemainingResultCount;
       
  3536 	
       
  3537 	//result as TMsvEntry
       
  3538 	WriteBufferL(aMessage, 0);
       
  3539 	//for remaing count
       
  3540 	WriteL(aMessage, 1, count);
       
  3541 	
       
  3542 	aMessage.Complete(KErrNone);
       
  3543 	}
       
  3544 	
       
  3545 
       
  3546 void CMsvServerSession::GetQueryIDL(const RMessage2& aMessage)
       
  3547 	{
       
  3548 	TPckgBuf<TInt> queryId;
       
  3549 	
       
  3550 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetQueryIDL"));	
       
  3551 	
       
  3552 	queryId() = CMSvSearchSortCacheManager::Instance()->QueryID();
       
  3553 	
       
  3554 	WriteL(aMessage, 0, queryId);
       
  3555 	aMessage.Complete(KErrNone);
       
  3556 	}
       
  3557 	
       
  3558 void CMsvServerSession::UpdateSearchSortCacheWithSortFiledL(const RMessage2& aMessage)
       
  3559 	{
       
  3560 	TInt  index = CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count();
       
  3561 	
       
  3562 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::UpdateSearchSortCacheWithSortFiledL"));	
       
  3563 	
       
  3564 	// get the length
       
  3565 	TInt desLen = aMessage.GetDesLength(1);
       
  3566 	if(desLen == 0)
       
  3567 		{
       
  3568 		aMessage.Complete(KErrArgument);
       
  3569 		return;
       
  3570 		}
       
  3571 
       
  3572 	// allocate buffer copy the data
       
  3573 	CBufFlat* buffer = CBufFlat::NewL(desLen);
       
  3574 	CleanupStack::PushL(buffer);
       
  3575 	buffer->ExpandL(0, desLen);
       
  3576 	RBufReadStream readStream(*buffer);
       
  3577 	CleanupClosePushL (readStream);
       
  3578 	TPtr8 desPtr = buffer->Ptr(0);
       
  3579 	
       
  3580 	TRAPD(err,  aMessage.ReadL(1, desPtr));
       
  3581 	User::LeaveIfError(err);
       
  3582 	// object of TMsvPackedIdAndMessagePart 
       
  3583 	TMsvPackedIdAndMessagePart packIdAndMessagePart;
       
  3584 	
       
  3585 	//extract TMsvId with Sort field
       
  3586 	packIdAndMessagePart.InternalizeL(readStream, CMSvSearchSortCacheManager::Instance()->iMsvIdWithSortFieldArray);
       
  3587 	
       
  3588 	//Manager class update the Db.
       
  3589 	CMSvSearchSortCacheManager::Instance()->StoreSortResultL(index,CMSvSearchSortCacheManager::Instance()->iMsvIdWithSortFieldArray);
       
  3590 	
       
  3591 	CleanupStack::PopAndDestroy(2, buffer);
       
  3592 	aMessage.Complete(KErrNone);
       
  3593 	}
       
  3594 	
       
  3595 void CMsvServerSession::QueryUnMarkedL(const RMessage2& aMessage)
       
  3596 	{
       
  3597 	
       
  3598 	TInt  queryID = aMessage.Int0();
       
  3599 	
       
  3600 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::PoliceSearchSortQueryReadRequestL"));  
       
  3601 	
       
  3602 	TInt index =  CMSvSearchSortCacheManager::Instance()->QueryExists(queryID);
       
  3603 	if(index>0)
       
  3604 		{
       
  3605 		CMSvSearchSortCacheManager::Instance()->UnMarkedQuery(index);
       
  3606 		}
       
  3607 	else
       
  3608 		{
       
  3609 		aMessage.Complete(KErrNotFound);	
       
  3610 		}   
       
  3611 	aMessage.Complete(KErrNone);
       
  3612 	}
       
  3613 
       
  3614 void CMsvServerSession::GetResultForQueryIDL(const RMessage2& aMessage)
       
  3615 	{
       
  3616     //For Simultaneously query
       
  3617     if(CMSvSearchSortCacheManager::Instance()->OutstandingSOSOperations() > 0)
       
  3618         {
       
  3619 		if(CMSvSearchSortCacheManager::Instance()->iProgress != KMsvSearchSortOpCompleted )
       
  3620 			{
       
  3621 			User::Leave(KErrServerBusy); // One is SOS request is under proress.
       
  3622 			}
       
  3623          }
       
  3624     CMSvSearchSortCacheManager::Instance()->AddOutstandingSOSOperation();
       
  3625 	
       
  3626 	TInt operationId = aMessage.Int0();
       
  3627 	TInt queryID = aMessage.Int1();
       
  3628 	
       
  3629 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetResultForQueryIDL"));   
       
  3630 	
       
  3631 	TInt index =  CMSvSearchSortCacheManager::Instance()->QueryExists(queryID);
       
  3632 	if(index>=0)
       
  3633 		{
       
  3634 		CMSvSearchSortCacheManager::Instance()->DoProcessQueryL(index);
       
  3635 		}
       
  3636 	else
       
  3637 		{
       
  3638 		//Invalid query id.
       
  3639 		CMSvSearchSortCacheManager::Instance()->iReturnResultType = KMsvSearchSortQueryIdNotFound;
       
  3640 		}
       
  3641 	
       
  3642 	aMessage.Complete(KErrNone);
       
  3643 	}
       
  3644 
       
  3645 
       
  3646 void CMsvServerSession::GetSearchSortProgressInfoL(const RMessage2 &aMessage)
       
  3647 	{
       
  3648 	TInt operationId = aMessage.Int0();
       
  3649 	TPckg<TInt> progress(KMsvSearchSortOpNone);
       
  3650 	
       
  3651 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetSearchSortProgressInfoL")); 
       
  3652 	
       
  3653 	progress() = CMSvSearchSortCacheManager::Instance()->ReturnProgressInfo();
       
  3654 	
       
  3655 	WriteL(aMessage, 1, progress);
       
  3656 	aMessage.Complete(KErrNone);
       
  3657 	}
       
  3658 	
       
  3659 void CMsvServerSession::SearchSortOperationCancelL(const RMessage2& aMessage)
       
  3660 	{
       
  3661 	TInt operationId = aMessage.Int0();
       
  3662 	
       
  3663 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::SearchSortOperationCancel"));  
       
  3664 	
       
  3665 	CMSvSearchSortCacheManager::Instance()->CancelSearchSortOperation();
       
  3666 	//cancel the current oeration and delete the query and correspnding entry from DB.
       
  3667 	aMessage.Complete(KErrNone);
       
  3668 	}
       
  3669 
       
  3670 //Update search sort results to DB, and sort by TMsvEntry fields invalid id's
       
  3671 void CMsvServerSession::UpdateSearchSortResultsAndSortByEntryL(const RMessage2& aMessage)
       
  3672 	{
       
  3673 	
       
  3674 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::UpdateSearchSortResultsAndSortByEntryL")); 
       
  3675 	
       
  3676 	TInt  index = CMSvSearchSortCacheManager::Instance()->iManagerEntry->Count();
       
  3677 
       
  3678 	HBufC8* buffer = NULL;
       
  3679 	ReadBufferL(aMessage, 1, buffer);
       
  3680 	CleanupStack::PushL(buffer);
       
  3681 
       
  3682 	// Unpack the entries from the buffer
       
  3683 	TMsvPackedIdOperation packedIdOperation(buffer);
       
  3684 	packedIdOperation.UnpackL(CMSvSearchSortCacheManager::Instance()->iUpdateIdsToCacheArray);
       
  3685 	
       
  3686 	// Update DB and sort by TMsvEnty field with existing partil query
       
  3687 	// Invalid ID need to delete.
       
  3688 	CMSvSearchSortCacheManager::Instance()->StoreResultL(index,CMSvSearchSortCacheManager::Instance()->iUpdateIdsToCacheArray);
       
  3689 	
       
  3690 	CleanupStack::PopAndDestroy(buffer); // buffer
       
  3691 	
       
  3692 	aMessage.Complete(KErrNone);
       
  3693 	}
       
  3694 
       
  3695 void CMsvServerSession::CopyQueryDataL(const RMessage2& aMessage)
       
  3696 	{
       
  3697 	TInt operationId = aMessage.Int0();
       
  3698 	TInt queryId = aMessage.Int1();
       
  3699 	
       
  3700 	iMsvServer.PoliceSearchSortQueryReadRequestL(aMessage,__PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CopyQueryDataL")); 
       
  3701 	
       
  3702 	CMsvSearchSortQuery* searchSortQuery= CMsvSearchSortQuery::NewL() ;
       
  3703 	CleanupStack::PushL(searchSortQuery);
       
  3704 	
       
  3705 	TInt index =  CMSvSearchSortCacheManager::Instance()->QueryExists(queryId);
       
  3706 	if(index>=0)
       
  3707 		{
       
  3708 		//This below function will return  TMsvSearchSortQuery object .
       
  3709 		CMSvSearchSortCacheManager::Instance()->RetrunQuery(index, searchSortQuery);
       
  3710 		}
       
  3711 	else
       
  3712 		{
       
  3713 		//Query id not found.
       
  3714 		CleanupStack::PopAndDestroy(searchSortQuery); // searchSortQuery
       
  3715 		aMessage.Complete(KErrNotFound);
       
  3716 		return;
       
  3717 		}
       
  3718 	
       
  3719 	TMsvPackQuery packedQuery(iBuffer);
       
  3720 	
       
  3721 	TInt error = KErrNone;
       
  3722 	error = packedQuery.PackQuery(searchSortQuery);
       
  3723 	
       
  3724 	WriteBufferL(aMessage, 2);
       
  3725 	CleanupStack::PopAndDestroy(searchSortQuery); // searchSortQuery
       
  3726 	aMessage.Complete(error);
       
  3727 	}
       
  3728 
       
  3729 
       
  3730 #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
  3731 /**
       
  3732  * GetChildrenAllL()
       
  3733  *
       
  3734  * @param RMessage2.
       
  3735  *
       
  3736  * Code changes for PREQ 557.
       
  3737  * Service request EMsvGetChildrenALL.
       
  3738  * If the parent id is a standard folder the function fetches
       
  3739  * the child entries from all drives in the preferred drive list
       
  3740  * as maintained by server.
       
  3741  */
       
  3742  void CMsvServerSession::GetChildrenAllL(const RMessage2 &aMessage)
       
  3743 	{
       
  3744 	// Reset internal datastructure.
       
  3745 	iChildrenSelection->Reset();
       
  3746 	iChildrenSelectionIds->Reset();
       
  3747 
       
  3748 	// Copy across the children details structure.
       
  3749 	TPckgBuf<TMsvChildrenDetails> children;
       
  3750 	aMessage.ReadL(0, children);
       
  3751 
       
  3752 	// Check that the children details arguments are empty. 
       
  3753 	// Panic in debug mode but try to handle it gracefully 
       
  3754 	// in release code.
       
  3755 	__ASSERT_DEBUG( children().iTotalNumberChildren==0 &&
       
  3756 					children().iNumberChildrenInArray==0, PanicServer(EMsvChildrenDetailsNotEmpty2));
       
  3757 
       
  3758 	if( children().iTotalNumberChildren != 0 || children().iNumberChildrenInArray != 0 )
       
  3759 		{
       
  3760 		aMessage.Complete(KErrArgument);
       
  3761 		return;
       
  3762 		}
       
  3763 	
       
  3764 	// The function is allowed only for following standard 
       
  3765 	// folders of current drive:
       
  3766 	// Inbox, Outbox, Draft, Sent and Deleted.
       
  3767 	if( (KCurrentDriveId != GetDriveId(children().iParentId)) ||
       
  3768 		( KMsvLocalServiceIndexEntryId >= UnmaskTMsvId(children().iParentId) ||
       
  3769 		  KMsvUnknownServiceIndexEntryId <= UnmaskTMsvId(children().iParentId) )
       
  3770 	  )
       
  3771 		{
       
  3772 		aMessage.Complete(KErrArgument);
       
  3773 		return;
       
  3774 		}
       
  3775 		
       
  3776 	// Copy across the sort order.
       
  3777 	TPckgBuf<TMsvSelectionOrdering> order;
       
  3778 	aMessage.ReadL(1, order);
       
  3779 
       
  3780 	// Get the children as a selection. Need to 
       
  3781 	// filter the list via the client secure ID 
       
  3782 	// if the client is not trusted with Read User Data.
       
  3783 	TBool filterByOwnerId = !aMessage.HasCapability(ECapabilityReadUserData);
       
  3784 	
       
  3785 	iMsvServer.IndexAdapter().GetChildrenAllL(children().iParentId, *iChildrenSelection, order(), KUidMsvNullEntry, filterByOwnerId, aMessage.SecureId());
       
  3786 
       
  3787 	// Return number of children.
       
  3788 	children().iTotalNumberChildren = iChildrenSelection->Count();
       
  3789 
       
  3790 	// Package up the entries.
       
  3791 	iBuffer->Des().SetMax();
       
  3792 	TMsvPackedEntryArray packedEntryArray(iBuffer);
       
  3793 	
       
  3794 	TInt count=0;
       
  3795 	TInt error=KErrNone;
       
  3796 	TInt totalCount=iChildrenSelection->Count();
       
  3797 	for (; count<totalCount; count++)
       
  3798 		{
       
  3799 		error = packedEntryArray.PackEntry(*iChildrenSelection->At(count));
       
  3800 		if (error)
       
  3801 			{
       
  3802 			children().iLastEntryInArray = count;
       
  3803 			break;
       
  3804 			}
       
  3805 		}
       
  3806 	// return number of children in the array
       
  3807 	children().iNumberChildrenInArray = count;
       
  3808 
       
  3809 	// write the children to client
       
  3810 	WriteL(aMessage, 0, children);
       
  3811 	
       
  3812 	// write the array to the client (if any entries are in the array)
       
  3813 	if (children().iNumberChildrenInArray)
       
  3814 		WriteL(aMessage, 2, iBuffer->Des());
       
  3815 
       
  3816 	if (error==KErrNone)
       
  3817 		{
       
  3818 		// reset the member data
       
  3819 		iChildrenSelection->Reset();
       
  3820 		}
       
  3821 	else
       
  3822 		{
       
  3823 		// keep an list of the ids separatelyin case they are deleted by another client
       
  3824 		TInt totalCount=iChildrenSelection->Count();
       
  3825 		for (count=0; count<totalCount; count++)
       
  3826 			iChildrenSelectionIds->AppendL(iChildrenSelection->At(count)->Id());
       
  3827 		iChildrenDetails = children();
       
  3828 		}
       
  3829 
       
  3830 	// signal the client and finished with selection
       
  3831 	aMessage.Complete(error);
       
  3832 	}
       
  3833 
       
  3834 
       
  3835 
       
  3836 /** 
       
  3837  * GetChildIdsAll()
       
  3838  *
       
  3839  * Gets the children of a parent entry specified as first argument.
       
  3840  * If the passed parent is a standard folder the function will fetch 
       
  3841  * entries from all drives currently present in the preferred drive list.
       
  3842  */
       
  3843 void CMsvServerSession::GetChildIdsAllL(const RMessage2& aMessage)
       
  3844 	{
       
  3845 	TMsvId id = aMessage.Int1();
       
  3846 
       
  3847 	// The function is allowed only for following standard 
       
  3848 	// folders of current drive:
       
  3849 	// Inbox, Outbox, Draft, Sent and Deleted.
       
  3850 	if( (KCurrentDriveId != GetDriveId(id)) ||
       
  3851 		(KMsvLocalServiceIndexEntryId >= UnmaskTMsvId(id)) ||
       
  3852 		(KMsvUnknownServiceIndexEntryId <= UnmaskTMsvId(id))
       
  3853 	  )
       
  3854 		{
       
  3855 		aMessage.Complete(KErrArgument);
       
  3856 		return;
       
  3857 		}
       
  3858 
       
  3859 	CMsvEntrySelection* selection = new(ELeave)CMsvEntrySelection;
       
  3860 	CleanupStack::PushL(selection);
       
  3861 	HBufC8* buffer = NULL;
       
  3862 	ReadBufferL(aMessage, 0, buffer);
       
  3863 	CleanupStack::PushL(buffer);
       
  3864 
       
  3865 	CMsvEntryFilter* filter = CMsvEntryFilter::NewLC();
       
  3866 	TMsvPackedEntryFilter package(buffer);
       
  3867 	package.UnpackFilter(*filter);
       
  3868 
       
  3869 	// Need to filter the list via the client secure ID if the client is not
       
  3870 	// trusted with Read User Data.
       
  3871 	TBool filterByOwnerId = !aMessage.HasCapability(ECapabilityReadUserData);
       
  3872 
       
  3873 	TInt error = iMsvServer.IndexAdapter().GetChildrenIdAll(id, *filter, *selection, filterByOwnerId, aMessage.SecureId());
       
  3874 	if(KErrNone != error)
       
  3875 		{
       
  3876 		aMessage.Complete(error);
       
  3877 		CleanupStack::PopAndDestroy(3); // selection, buffer, filter
       
  3878 		}
       
  3879 		
       
  3880 	TMsvPackedOperation op(iBuffer);
       
  3881 
       
  3882 	error = op.Pack(*selection, 0, 0);
       
  3883 	while (error != KErrNone)
       
  3884 		{
       
  3885 		// increase the size of the buffer and try again
       
  3886 		iBuffer->Des().SetLength(0); // to avoid copying contents
       
  3887 		iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  3888 		error = op.Pack(*selection, 0, 0);
       
  3889 		}
       
  3890 
       
  3891 	WriteBufferL(aMessage, 0);
       
  3892 
       
  3893 	aMessage.Complete(KErrNone);
       
  3894 	CleanupStack::PopAndDestroy(3); // selection, buffer, filter
       
  3895 	}
       
  3896 	
       
  3897 	
       
  3898 
       
  3899 
       
  3900 /**
       
  3901  * MessageDrive()
       
  3902  *
       
  3903  * @param RMessage2.
       
  3904  *
       
  3905  * Code changes for PREQ 557.
       
  3906  * Service request EMsvGetMessageDrive.
       
  3907  */
       
  3908 void CMsvServerSession::MessageDrive(const RMessage2 &aMessage)
       
  3909 	{
       
  3910 	aMessage.Complete(CMsvPreferredDriveList::GetDriveList()->CurrentDriveNumber());		
       
  3911 	}
       
  3912 
       
  3913 
       
  3914 
       
  3915 
       
  3916 /**
       
  3917  * CurrentDriveInfoL()
       
  3918  *
       
  3919  * @param RMessage2.
       
  3920  *
       
  3921  * Code changes for PREQ 557.
       
  3922  * Service request EMsvGetCurrentDriveInfo.
       
  3923  */	 
       
  3924 void CMsvServerSession::CurrentDriveInfoL(const RMessage2 &aMessage)
       
  3925 	{
       
  3926 	TMsvPreferredDrive driveInfo;
       
  3927 	TUint currentDriveIndex = CMsvPreferredDriveList::GetDriveList()->CurrentDriveIndex();
       
  3928 	TRAPD(err, CMsvPreferredDriveList::GetDriveList()->DriveInfoL(currentDriveIndex, driveInfo));
       
  3929 	if(KErrNone == err)
       
  3930 		{
       
  3931 		TPckgBuf<TDriveNumber> driveNum;
       
  3932 		TPckgBuf<TUint> priority;
       
  3933 		
       
  3934 		driveNum() = driveInfo.driveNum;
       
  3935 		priority() = currentDriveIndex + 1;
       
  3936 		
       
  3937 		WriteL(aMessage, 0, driveNum);
       
  3938 		WriteL(aMessage, 1, priority);
       
  3939 		}
       
  3940 	aMessage.Complete(err);
       
  3941 	}
       
  3942 	
       
  3943 
       
  3944 
       
  3945 /**
       
  3946  * DriveListL()
       
  3947  *
       
  3948  * @param RMessage2.
       
  3949  *
       
  3950  * Code changes for PREQ 557.
       
  3951  * Service request EMsvGetDriveList.
       
  3952  */	 
       
  3953 void CMsvServerSession::DriveListL(const RMessage2 &aMessage)
       
  3954 	{
       
  3955 	CMsvPreferredDriveList *driveList = CMsvPreferredDriveList::GetDriveList();
       
  3956 	RArray<TDriveNumber> driveNumList;
       
  3957 	CleanupClosePushL(driveNumList);
       
  3958 	
       
  3959 	for(TInt index=0; index<driveList->Count(); index++)
       
  3960 		{
       
  3961 		driveNumList.AppendL((*driveList)[index].driveNum);	 
       
  3962 		}
       
  3963 	
       
  3964 	TMsvPackedDriveIdOperation driveOp(iBuffer);
       
  3965 	User::LeaveIfError(driveOp.Pack(driveNumList));
       
  3966 	WriteBufferL(aMessage, 0);
       
  3967 	
       
  3968 	CleanupStack::PopAndDestroy();	  // driveNumList
       
  3969 	aMessage.Complete(KErrNone);
       
  3970 	}
       
  3971 	
       
  3972 
       
  3973 
       
  3974 /**
       
  3975  * AvailableDriveListL()
       
  3976  *
       
  3977  * @param RMessage2.
       
  3978  *
       
  3979  * Code changes for PREQ 557.
       
  3980  * Service request EMsvGetAvailableDriveList.
       
  3981  */ 
       
  3982 void CMsvServerSession::AvailableDriveListL(const RMessage2 &aMessage)
       
  3983 	{
       
  3984 	CMsvPreferredDriveList *driveList = CMsvPreferredDriveList::GetDriveList();
       
  3985 	RArray<TDriveNumber> driveNumList;
       
  3986 	CleanupClosePushL(driveNumList);
       
  3987 	
       
  3988 	for(TInt index=0; index<driveList->Count(); index++)
       
  3989 		{
       
  3990 		if(EMsvMessageStoreAvailableStatus == (*driveList)[index].status)
       
  3991 			{
       
  3992 			driveNumList.AppendL((*driveList)[index].driveNum);	 
       
  3993 			}
       
  3994 		}
       
  3995 	
       
  3996 	TMsvPackedDriveIdOperation driveOp(iBuffer);
       
  3997 	User::LeaveIfError(driveOp.Pack(driveNumList));
       
  3998 	WriteBufferL(aMessage, 0);
       
  3999 	
       
  4000 	CleanupStack::PopAndDestroy();	  // driveNumList
       
  4001 	aMessage.Complete(KErrNone);
       
  4002 	}
       
  4003 	
       
  4004 	
       
  4005 	
       
  4006 
       
  4007 /**
       
  4008  * AddDriveL()
       
  4009  *
       
  4010  * @param RMessage2.
       
  4011  *
       
  4012  * Code changes for PREQ 557.
       
  4013  * Service request EMsvAddDriveToDriveList.
       
  4014  */	 
       
  4015 void CMsvServerSession::AddDriveL(const RMessage2 &aMessage)
       
  4016 	{
       
  4017 	TDriveNumber driveNumber = (TDriveNumber) aMessage.Int0();
       
  4018 	TUint priority = (TUint) aMessage.Int1();
       
  4019 
       
  4020 	TRAPD(err, iMsvServer.AddDriveToListL(driveNumber, priority, this));
       
  4021 	if(KErrNone == err)
       
  4022 		{
       
  4023 		TPckgBuf<TUint> priorityBuf;
       
  4024 		priorityBuf() = priority;
       
  4025 		WriteL(aMessage, 2, priorityBuf);
       
  4026 		}
       
  4027 	aMessage.Complete(err);
       
  4028 	}
       
  4029 	
       
  4030 	
       
  4031 
       
  4032 /**
       
  4033  * RemoveDriveL()
       
  4034  *
       
  4035  * @param RMessage2.
       
  4036  *
       
  4037  * Code changes for PREQ 557.
       
  4038  * Service request EMsvRemoveDriveFromDriveList.
       
  4039  */ 
       
  4040 void CMsvServerSession::RemoveDriveL(const RMessage2 &aMessage)
       
  4041 	{
       
  4042 	TDriveNumber driveNumber = (TDriveNumber) aMessage.Int0();
       
  4043 	TRAPD(err, iMsvServer.RemoveDriveFromListL(driveNumber));
       
  4044 	aMessage.Complete(err);
       
  4045 	}
       
  4046 	
       
  4047 	
       
  4048 
       
  4049 /**
       
  4050  * UpdateDrivePriorityL()
       
  4051  *
       
  4052  * @param RMessage2.
       
  4053  *
       
  4054  * Code changes for PREQ 557.
       
  4055  * Service request EMsvUpdateDrivePriority.
       
  4056  */	 
       
  4057 void CMsvServerSession::UpdateDrivePriorityL(const RMessage2 &aMessage)
       
  4058 	{
       
  4059 	TDriveNumber driveNumber = (TDriveNumber) aMessage.Int0();
       
  4060 	TUint priority = (TUint) aMessage.Int1();
       
  4061 
       
  4062 	TRAPD(err, iMsvServer.UpdateDrivePriorityL(driveNumber, priority));
       
  4063 	if(KErrNone == err)
       
  4064 		{
       
  4065 		TPckgBuf<TUint> priorityBuf;
       
  4066 		priorityBuf() = priority;
       
  4067 		WriteL(aMessage, 2, priorityBuf);
       
  4068 		}
       
  4069 	aMessage.Complete(err);
       
  4070 	}
       
  4071 	
       
  4072 	
       
  4073 /**
       
  4074  * ResetRepositoryL()
       
  4075  *
       
  4076  * @param RMessage2.
       
  4077  *
       
  4078  * Code changes for PREQ 557.
       
  4079  * Service request EMsvResetRepository.
       
  4080  */ 
       
  4081 #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
       
  4082 void CMsvServerSession::ResetRepositoryL(const RMessage2 &aMessage)
       
  4083 	{
       
  4084 	TRAPD(err, iMsvServer.ResetRepositoryL());
       
  4085 	aMessage.Complete(err);
       
  4086 	}
       
  4087 
       
  4088 
       
  4089 void CMsvServerSession::PrintCache(const RMessage2 &aMessage)
       
  4090 	{
       
  4091 	#ifdef _DEBUG
       
  4092 		iMsvServer.Context().IndexAdapter()->PrintL();
       
  4093 	#endif
       
  4094 	aMessage.Complete(KErrNone);
       
  4095 	}
       
  4096 
       
  4097 #endif	  // #if (defined SYMBIAN_MESSAGESTORE_UNIT_TESTCODE)
       
  4098 
       
  4099 #endif		  // #if (defined SYMBIAN_MSGS_ENHANCED_REMOVABLE_MEDIA_SUPPORT)
       
  4100 
       
  4101 
       
  4102 
       
  4103 
       
  4104 
       
  4105 
       
  4106 
       
  4107 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
  4108 
       
  4109 /*
       
  4110  * CreateHeaderTableL()
       
  4111  *
       
  4112  * The function creates the header table in the message store.
       
  4113  */
       
  4114 void CMsvServerSession::CreateHeaderTableL(const RMessage2 &aMessage)
       
  4115 	{
       
  4116 	// Check for capability.
       
  4117 	if(!aMessage.HasCapability(ECapabilityWriteDeviceData))
       
  4118 		{
       
  4119 		// Client missing capabilities - emit diagnostics and leave...
       
  4120 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityWriteDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CreateHeaderTableL")));
       
  4121 		}
       
  4122 
       
  4123 	// Capability check is fine. Proceed.
       
  4124 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4125 	ReadBufferL(aMessage, 1, iBuffer);
       
  4126 	
       
  4127 	// Read the header structure from the buffer.
       
  4128 	RPointerArray<CFieldPair> fieldDetails;
       
  4129 	CleanupClosePushL(fieldDetails);
       
  4130 	TMsvPackedHeaderStructure headerStruct(iBuffer);
       
  4131 			
       
  4132 	headerStruct.UnpackL(fieldDetails);
       
  4133 	
       
  4134 	// Create the header table and handle error.
       
  4135 	TRAPD(err, iMsvServer.MessageDBAdapter().CreateHeaderTableL(mtmTypeUid, fieldDetails, iLastDBErrorMessage));
       
  4136 	fieldDetails.ResetAndDestroy();
       
  4137 	CleanupStack::PopAndDestroy();		  // fieldDetails
       
  4138 	aMessage.Complete(err);
       
  4139 	}
       
  4140 
       
  4141 
       
  4142 
       
  4143 
       
  4144 
       
  4145 /*
       
  4146  * DoesStoreExistsL()
       
  4147  *
       
  4148  * The function checks if a header table for a MTM Id already exists in message store.
       
  4149  */
       
  4150 void CMsvServerSession::DoesStoreExistsL(const RMessage2 &aMessage)
       
  4151 	{
       
  4152 	// Check for capability.
       
  4153 	if(!aMessage.HasCapability(ECapabilityReadDeviceData))
       
  4154 		{
       
  4155 		// Client missing capabilities - emit diagnostics and leave...
       
  4156 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityReadDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DoesStoreExistsL")));
       
  4157 		}
       
  4158 
       
  4159 	// Capability check is fine. Proceed.
       
  4160 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4161 	
       
  4162 	TBool isStoreExists = iMsvServer.MessageDBAdapter().IsHeaderTableExistsL(mtmTypeUid);
       
  4163 
       
  4164 	TPckgBuf<TBool> storeExists;
       
  4165 	storeExists() = isStoreExists;
       
  4166 	WriteL(aMessage, 1, storeExists);
       
  4167 	aMessage.Complete(KErrNone);
       
  4168 	}
       
  4169 	
       
  4170 	
       
  4171 
       
  4172 
       
  4173 
       
  4174 /*
       
  4175  * LastErrorMessageL()
       
  4176  *
       
  4177  * This function is mainly used after the header table creation.
       
  4178  * The function returns the error message text, if the header table
       
  4179  * creation fails.
       
  4180  */ 
       
  4181 void CMsvServerSession::LastErrorMessageL(const RMessage2 &aMessage)
       
  4182 	{
       
  4183 	TInt desLen = iLastDBErrorMessage.Size();   
       
  4184 	if (Align4(desLen+4) > aMessage.GetDesMaxLength(0))
       
  4185 		{
       
  4186 		User::Leave(KErrOverflow);
       
  4187 		}
       
  4188 	
       
  4189 	iBuffer->Des().SetLength(desLen+4);
       
  4190 	TInt* ptr = (TInt*) CONST_CAST(TUint8*, iBuffer->Ptr());
       
  4191 	*ptr++ = desLen;
       
  4192 	Mem::Copy((void*)ptr, iLastDBErrorMessage.Ptr(), desLen);
       
  4193 
       
  4194 	WriteBufferL(aMessage, 0);
       
  4195 	aMessage.Complete(KErrNone);
       
  4196 	}
       
  4197 
       
  4198 
       
  4199 
       
  4200 
       
  4201 
       
  4202 
       
  4203 /*
       
  4204  * CreateHeaderEntryL()
       
  4205  *
       
  4206  * This function creates a new header entry in the database.
       
  4207  */ 
       
  4208 void CMsvServerSession::CreateHeaderEntryL(const RMessage2 &aMessage)
       
  4209 	{
       
  4210 	// Check for capability.
       
  4211 	if(!aMessage.HasCapability(ECapabilityWriteUserData))
       
  4212 		{
       
  4213 		// Client missing capabilities - emit diagnostics and leave...
       
  4214 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityWriteUserData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::CreateHeaderEntryL")));
       
  4215 		}
       
  4216 
       
  4217 	// Capability check is fine. Proceed.
       
  4218 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4219 	TMsvId entryId = aMessage.Int1();
       
  4220 	
       
  4221 	ReadBufferL(aMessage, 2, iBuffer);
       
  4222 		
       
  4223 	RPointerArray<CHeaderFields> fieldPairList;
       
  4224 	CleanupClosePushL(fieldPairList);
       
  4225 	
       
  4226 	TMsvPackedHeaderData headerData(iBuffer);
       
  4227 	headerData.UnpackL(fieldPairList);
       
  4228 	
       
  4229 	TRAPD(err, iMsvServer.MessageDBAdapter().CreateHeaderEntryL(mtmTypeUid, entryId, fieldPairList));
       
  4230 	fieldPairList.ResetAndDestroy();
       
  4231 	CleanupStack::PopAndDestroy();
       
  4232 	aMessage.Complete(err); 
       
  4233 	}
       
  4234 	
       
  4235 	
       
  4236 	
       
  4237 	
       
  4238 
       
  4239 
       
  4240 /*
       
  4241  * LoadHeaderEntryL()
       
  4242  *
       
  4243  * This function loads the header entry from the database
       
  4244  * and returns to the client.
       
  4245  */ 
       
  4246 void CMsvServerSession::LoadHeaderEntryL(const RMessage2 &aMessage)
       
  4247 	{
       
  4248 	// Check for capability.
       
  4249 	if(!aMessage.HasCapability(ECapabilityReadUserData))
       
  4250 		{
       
  4251 		// Client missing capabilities - emit diagnostics and leave...
       
  4252 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityReadUserData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::LoadHeaderEntryL")));
       
  4253 		}
       
  4254 
       
  4255 	// Capability check is fine. Proceed.
       
  4256 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4257 	TMsvId entryId = aMessage.Int1();
       
  4258 	
       
  4259 	RPointerArray<CHeaderFields> fieldPairList;
       
  4260 	CleanupClosePushL(fieldPairList);
       
  4261 	
       
  4262 	TRAPD(err, iMsvServer.MessageDBAdapter().LoadHeaderEntryL(mtmTypeUid, entryId, fieldPairList));
       
  4263 	if(KErrNone == err)
       
  4264 		{
       
  4265 		TMsvPackedHeaderData headerData(iBuffer);
       
  4266 		err = headerData.Pack(fieldPairList);
       
  4267 		while (err != KErrNone)
       
  4268 			{
       
  4269 			// increase the size of the buffer and try again
       
  4270 			iBuffer->Des().SetLength(0); // to avoid copying contents
       
  4271 			iBuffer = iBuffer->ReAllocL(iBuffer->Des().MaxSize() + KMsvSessionBufferLength);
       
  4272 			err = headerData.Pack(fieldPairList);
       
  4273 			}
       
  4274 		WriteBufferL(aMessage, 2);
       
  4275 		}
       
  4276 	fieldPairList.ResetAndDestroy();
       
  4277 	CleanupStack::PopAndDestroy();
       
  4278 
       
  4279 	aMessage.Complete(err);
       
  4280 	}
       
  4281 	
       
  4282 	
       
  4283 	
       
  4284 	
       
  4285 	
       
  4286 	
       
  4287 /*
       
  4288  * DeleteHeaderEntryL()
       
  4289  *
       
  4290  * This function deletes the header entry from the database.
       
  4291  */	 
       
  4292 void CMsvServerSession::DeleteHeaderEntryL(const RMessage2 &aMessage)
       
  4293 	{
       
  4294 	// Check for capability.
       
  4295 	if(!aMessage.HasCapability(ECapabilityWriteUserData))
       
  4296 		{
       
  4297 		// Client missing capabilities - emit diagnostics and leave...
       
  4298 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityWriteUserData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::DeleteHeaderEntryL")));
       
  4299 		}
       
  4300 
       
  4301 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4302 	TMsvId entryId = aMessage.Int1();
       
  4303 	
       
  4304 	TRAPD(err, iMsvServer.MessageDBAdapter().DeleteHeaderEntryL(mtmTypeUid, entryId));
       
  4305 	aMessage.Complete(err);
       
  4306 	}
       
  4307 
       
  4308 
       
  4309 
       
  4310 	
       
  4311 	
       
  4312 	
       
  4313 /*
       
  4314  * UpdateHeaderEntryL()
       
  4315  *
       
  4316  * This function udpates the header entry in the database.
       
  4317  */ 
       
  4318 void CMsvServerSession::UpdateHeaderEntryL(const RMessage2 &aMessage)
       
  4319 	{
       
  4320 	// Check for capability.
       
  4321 	if(!aMessage.HasCapability(ECapabilityWriteUserData))
       
  4322 		{
       
  4323 		// Client missing capabilities - emit diagnostics and leave...
       
  4324 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityWriteUserData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::UpdateHeaderEntryL")));
       
  4325 		}
       
  4326 
       
  4327 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4328 	TMsvId entryId = aMessage.Int1();
       
  4329 	
       
  4330 	ReadBufferL(aMessage, 2, iBuffer);
       
  4331 		
       
  4332 	RPointerArray<CHeaderFields> fieldPairList;
       
  4333 	CleanupClosePushL(fieldPairList);
       
  4334 	
       
  4335 	TMsvPackedHeaderData headerData(iBuffer);
       
  4336 	headerData.UnpackL(fieldPairList);
       
  4337 	
       
  4338 	TRAPD(err, iMsvServer.MessageDBAdapter().UpdateHeaderEntryL(mtmTypeUid, entryId, fieldPairList));
       
  4339 	fieldPairList.ResetAndDestroy();
       
  4340 	CleanupStack::PopAndDestroy();
       
  4341 	aMessage.Complete(err);
       
  4342 	}
       
  4343 
       
  4344 
       
  4345 
       
  4346 
       
  4347 
       
  4348 
       
  4349 /*
       
  4350  * DoesAnyStoreExists()
       
  4351  *
       
  4352  * This function checks if the store (header/body) exists 
       
  4353  * for a give metadata entry.
       
  4354  */ 
       
  4355 void CMsvServerSession::DoesAnyStoreExists(const RMessage2 &aMessage)
       
  4356 	{
       
  4357 	TMsvId entryId = aMessage.Int0();
       
  4358 	TUid mtmTypeUid = TUid::Uid(aMessage.Int1());
       
  4359 	
       
  4360 	TBool isStoreExists = EFalse;
       
  4361 	TRAPD(err, isStoreExists = iMsvServer.MessageDBAdapter().DoesAnyStoreExistsL(entryId, mtmTypeUid));
       
  4362 	if(err)
       
  4363 		{
       
  4364 		aMessage.Complete(EFalse);
       
  4365 		}
       
  4366 	else
       
  4367 		{
       
  4368 		aMessage.Complete(isStoreExists);
       
  4369 		}
       
  4370 	}
       
  4371 
       
  4372 void CMsvServerSession::DoesHeaderTableExist(const RMessage2 aMessage)
       
  4373 	{
       
  4374 	TUid mtmTypeUid = TUid::Uid(aMessage.Int0());
       
  4375 	
       
  4376 	TBool doesHeaderExists = EFalse;
       
  4377 	TRAPD(err, doesHeaderExists = iMsvServer.MessageDBAdapter().IsHeaderTableExistsL(mtmTypeUid));
       
  4378 	if(err)
       
  4379 		{
       
  4380 		aMessage.Complete(EFalse);
       
  4381 		}
       
  4382 	else
       
  4383 		{
       
  4384 		aMessage.Complete(doesHeaderExists);
       
  4385 		}
       
  4386 	}
       
  4387 
       
  4388 /***************************************Converter API's***************************/
       
  4389 /*
       
  4390  GetConvertibleDriveListL()
       
  4391  Fetches a list of drives with message store unsupported	
       
  4392  
       
  4393  @param aMessage: RMessage2 representing client request and containing request data.
       
  4394  @return None
       
  4395  */
       
  4396 void CMsvServerSession::GetConvertibleDriveListL(const RMessage2 &aMessage)
       
  4397 	{
       
  4398 	// capability check
       
  4399 	if(!aMessage.HasCapability(ECapabilityReadDeviceData))
       
  4400 		{
       
  4401 		// Client missing capabilities - emit diagnostics and leave...
       
  4402 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityReadDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::GetConvertibleDriveListL")));
       
  4403 		}
       
  4404 	
       
  4405 	
       
  4406 	CMsvPreferredDriveList *driveList = CMsvPreferredDriveList::GetDriveList();
       
  4407 	RArray<TDriveNumber> driveNumList;
       
  4408 	CleanupClosePushL(driveNumList);
       
  4409 	
       
  4410 	for(TInt index=0; index<driveList->Count(); index++)
       
  4411 		{
       
  4412 		if(EMsvMessageStoreNotSupportedStatus == (*driveList)[index].status)
       
  4413 			{
       
  4414 			driveNumList.AppendL((*driveList)[index].driveNum);	 
       
  4415 			}
       
  4416 		}
       
  4417 	
       
  4418 	TMsvPackedDriveIdOperation driveOp(iBuffer);
       
  4419 	User::LeaveIfError(driveOp.Pack(driveNumList));
       
  4420 	WriteBufferL(aMessage, 0);
       
  4421 	
       
  4422 	CleanupStack::PopAndDestroy();	  // driveNumList
       
  4423 	aMessage.Complete(KErrNone);
       
  4424 	}
       
  4425 
       
  4426 /*
       
  4427  ConvertMessageStoreL()
       
  4428  Initiates message store conversion on a drive. if the conversion is active on a drive
       
  4429  than this request is queued and completed later.
       
  4430 
       
  4431  @param aMessage: RMessage2 representing client request and containing request data.
       
  4432  @return None
       
  4433  */
       
  4434 void CMsvServerSession::ConvertMessageStoreL(const RMessage2 &aMessage)
       
  4435 	{
       
  4436 	// capability check
       
  4437 	if(!aMessage.HasCapability(ECapabilityWriteDeviceData))
       
  4438 		{
       
  4439 		// Client missing capabilities - emit diagnostics and leave...
       
  4440 		User::LeaveIfError(PlatSec::CapabilityCheckFail(aMessage, ECapabilityWriteDeviceData, __PLATSEC_DIAGNOSTIC_STRING("Checked by CMsvServerSession::ConvertMessageStoreL")));
       
  4441 		}
       
  4442 	
       
  4443 	/*Instantiate the converter waiter thread. If it is already active, than the existing instance is returned
       
  4444 	  Else a new instance is created and returned. Singleton Pattern   */
       
  4445 	  
       
  4446 	iConverterWaiter=CMsvConverterWaiter::InstanceL(&iMsvServer);
       
  4447 		
       
  4448 	if(!iConverterWaiter->isRunningMessageStoreConverter()) 
       
  4449 		{
       
  4450 		iConverterWaiter->StartMessageStoreConversionL(aMessage,EFalse);
       
  4451 		}
       
  4452 	else 
       
  4453 		{
       
  4454 		// Queue the request if the drive is already not present
       
  4455 		iConverterWaiter->QueueConversionRequestL(aMessage);
       
  4456 		}
       
  4457 	}
       
  4458 
       
  4459 /*
       
  4460  CancelConversionRequestL()
       
  4461  Cancels conversion request for a drive.
       
  4462 
       
  4463  @param aMessage: RMessage2 representing client request and containing request data.
       
  4464  @return None
       
  4465  */
       
  4466 void CMsvServerSession::CancelConversionRequestL(const RMessage2 &aMessage)
       
  4467 	{
       
  4468 	if(iConverterWaiter)
       
  4469 		{
       
  4470 		iConverterWaiter->CancelConversionL(aMessage);
       
  4471 		}
       
  4472 	else
       
  4473 		{
       
  4474 		aMessage.Complete(KErrNotFound);
       
  4475 		}
       
  4476 	}
       
  4477 
       
  4478 /*
       
  4479  GetConversionStatus()
       
  4480  Gets the conversion status for a drive.
       
  4481  
       
  4482  @param aMessage: RMessage2 representing client request and containing request data.
       
  4483  @return None
       
  4484  */ 
       
  4485 void CMsvServerSession::GetConversionStatus(const RMessage2 &aMessage)
       
  4486 	{
       
  4487 	if(iConverterWaiter)
       
  4488 		{
       
  4489 		iConverterWaiter->GetConversionStatus(aMessage);
       
  4490 		}
       
  4491 	else
       
  4492 		{
       
  4493 		aMessage.Complete(KErrNotFound);
       
  4494 		}
       
  4495 	}
       
  4496 
       
  4497 TBool CMsvServerSession::FoundUnSupportedDrives()
       
  4498 	{
       
  4499 	CMsvPreferredDriveList *driveList = CMsvPreferredDriveList::GetDriveList();
       
  4500 	for(TInt index=0; index<driveList->Count(); index++)
       
  4501 		{
       
  4502 		if(EMsvMessageStoreNotSupportedStatus == (*driveList)[index].status)
       
  4503 			{
       
  4504 			return ETrue;
       
  4505 			}
       
  4506 		}
       
  4507 	return EFalse;
       
  4508 	
       
  4509 	}
       
  4510 #endif	  // #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
  4511 
       
  4512 
       
  4513 
       
  4514 
       
  4515 
       
  4516