memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp
branchRCL_3
changeset 59 8ad140f3dd41
parent 49 7fdc9a71d314
equal deleted inserted replaced
49:7fdc9a71d314 59:8ad140f3dd41
    17 
    17 
    18 #include "MemSpyEngineServer.h"
    18 #include "MemSpyEngineServer.h"
    19 
    19 
    20 // System includes
    20 // System includes
    21 #include <e32svr.h>
    21 #include <e32svr.h>
    22 #include <w32std.h>
       
    23 #include <APGTASK.H>
       
    24 #include <APGWGNAM.H>  
       
    25 
    22 
    26 // User includes
    23 // User includes
    27 #include <memspy/engine/memspyengine.h>
    24 #include <memspy/engine/memspyengine.h>
    28 #include <memspy/engine/memspyenginelogger.h>
    25 #include <memspy/engine/memspyenginelogger.h>
    29 #include <memspyengineclientinterface.h>
    26 #include <memspyengineclientinterface.h>
    39 #include <memspy/engine/memspyenginehelperfilesystem.h>
    36 #include <memspy/engine/memspyenginehelperfilesystem.h>
    40 #include <memspy/engine/memspyenginehelperram.h>
    37 #include <memspy/engine/memspyenginehelperram.h>
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    38 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
    42 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    39 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
    43 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    40 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
    44 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
    41 
    45 #include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
       
    46 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
       
    47 #include <memspy/engine/memspyenginehelperserver.h>
       
    48 #include <memspy/engine/memspyenginehelperecom.h>
       
    49 
       
    50 #include <memspy/engine/memspyprocessdata.h>
       
    51 #include <memspy/engine/memspythreaddata.h>
       
    52 #include <memspy/engine/memspykernelobjectdata.h>
       
    53 #include <memspy/engine/memspythreadinfoitemdata.h>
       
    54 #include <memspy/engine/memspymemorytrackingcycledata.h>
       
    55 #include <memspy/engine/memspyengineoutputsink.h>
       
    56 #include <memspy/engine/memspyenginehelperactiveobject.h>
       
    57 #include <memspy/engine/memspyserverdata.h>
       
    58 #include <memspysession.h>
       
    59 #include <memspy/engine/memspyecomdata.h>
       
    60 
       
    61 inline CShutdown::CShutdown() :CTimer(-1)
       
    62     {
       
    63     CActiveScheduler::Add(this);
       
    64     }
       
    65 
       
    66 inline void CShutdown::ConstructL()
       
    67     {
       
    68     CTimer::ConstructL();
       
    69     }
       
    70 
       
    71 inline void CShutdown::Start()
       
    72     {
       
    73     After(KMyShutdownDelay);
       
    74     }
       
    75 
       
    76 void CShutdown::RunL()
       
    77     //
       
    78     // Initiate server exit when the timer expires
       
    79     //
       
    80     {
       
    81     CActiveScheduler::Stop();
       
    82     }
       
    83 
    42 
    84 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    43 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
    85 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    44 :   CServer2( EPriorityNormal ), iEngine( aEngine )
    86     {
    45     {
    87     }
    46     }
    93 
    52 
    94 
    53 
    95 void CMemSpyEngineServer::ConstructL()
    54 void CMemSpyEngineServer::ConstructL()
    96     {
    55     {
    97     StartL( KMemSpyServerName );
    56     StartL( KMemSpyServerName );
    98         
       
    99     iShutdown.ConstructL();
       
   100     // ensure that the server still exits even if the 1st client fails to connect
       
   101     iShutdown.Start();
       
   102     }
    57     }
   103 
    58 
   104 
    59 
   105 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
    60 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
   106     {
    61     {
   122     //
    77     //
   123     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
    78     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
   124 	return session;
    79 	return session;
   125     }
    80     }
   126 
    81 
   127 void CMemSpyEngineServer::AddSession(TBool aCliRequest)
       
   128     {
       
   129     if (aCliRequest)
       
   130         {
       
   131         iCliConnected = ETrue;
       
   132         }
       
   133     else
       
   134         {
       
   135         ++iSessionCount;
       
   136         }
       
   137     iShutdown.Cancel();
       
   138     }
       
   139 
       
   140 void CMemSpyEngineServer::DropSession(TBool aCliRequest)
       
   141     {
       
   142     if (!aCliRequest)
       
   143         {
       
   144         --iSessionCount;
       
   145         }
       
   146     
       
   147     if (iSessionCount == 0 && !iCliConnected)
       
   148         {
       
   149         iShutdown.Start();
       
   150         }
       
   151     }
       
   152 
       
   153 
       
   154 
    82 
   155 
    83 
   156 
    84 
   157 
    85 
   158 
    86 
   190 
   118 
   191     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   119     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
   192 #endif
   120 #endif
   193 
   121 
   194     delete iClientThreadName;
   122     delete iClientThreadName;
   195         
       
   196     Server().DropSession(iIsCliRequest);
       
   197     }
   123     }
   198 
   124 
   199 
   125 
   200 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   126 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
   201     {
   127     {
   210     const TFullName threadName( thread.FullName() );
   136     const TFullName threadName( thread.FullName() );
   211     iClientThreadName = threadName.AllocL();
   137     iClientThreadName = threadName.AllocL();
   212     iClientThreadId = thread.Id();
   138     iClientThreadId = thread.Id();
   213 
   139 
   214     CleanupStack::PopAndDestroy( &thread );
   140     CleanupStack::PopAndDestroy( &thread );
   215     
   141 
   216     const TUid KCliUid3 = { 0x2002129D };
       
   217     iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3);
       
   218     
       
   219     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   142     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
   220     }
   143     }
   221 
   144 
   222 void CMemSpyEngineSession::CreateL()
       
   223     {   
       
   224     Server().AddSession(iIsCliRequest);
       
   225     }
       
   226 
   145 
   227 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   146 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
   228     {
   147     {
   229     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   148     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
   230     CleanupStack::PushL( self );
   149     CleanupStack::PushL( self );
   241     TRAPD( error, DoServiceL( aMessage ) );
   160     TRAPD( error, DoServiceL( aMessage ) );
   242     if  ( error != KErrNone )
   161     if  ( error != KErrNone )
   243         {
   162         {
   244         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   163         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
   245         }
   164         }
   246     
   165     aMessage.Complete( error );
   247     if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone)
       
   248     	{
       
   249 		aMessage.Complete( error );
       
   250     	}
       
   251 
   166 
   252     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   167     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
   253 	}
   168 	}
   254 
   169 
   255 // ---------------------------------------------------------
   170 
   256 // DoServiceL( const RMessage2& aMessage )
       
   257 // ---------------------------------------------------------
       
   258 //
       
   259 void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
   171 void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
   260 	{
       
   261 	TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
       
   262 	if (function >= EMemSpyClientServerOpMarkerUiFirst && 
       
   263 		function < EMemSpyClientServerOpMarkerUiLast)
       
   264 		
       
   265 		DoUiServiceL(aMessage);
       
   266 	else
       
   267 		DoCmdServiceL(aMessage);
       
   268 	}
       
   269 // ---------------------------------------------------------
       
   270 // DoUiServiceL( const RMessage2& aMessage )
       
   271 // ---------------------------------------------------------
       
   272 //
       
   273 void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
       
   274     {
       
   275 	switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
       
   276 		{
       
   277 	    case EMemSpyClientServerOpGetOutputSink:
       
   278 	        {
       
   279 	        TMemSpySinkType sink = iEngine.SinkType();
       
   280 	        TPckgBuf<TMemSpySinkType> type( sink );
       
   281 	        
       
   282 	        aMessage.WriteL( 0, type );
       
   283 	        break;
       
   284 	        }
       
   285 		case EMemSpyClientServerOpGetProcessCount:
       
   286 			{
       
   287 			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
       
   288 			break;
       
   289 			}
       
   290 		case EMemSpyClientServerOpGetProcesses:
       
   291 			{
       
   292 			CMemSpyEngineObjectContainer& list = iEngine.Container();
       
   293 			
       
   294 			TPckgBuf<TInt> a0;
       
   295 			aMessage.ReadL(0, a0);
       
   296 			TInt realCount = Min(a0(), list.Count());
       
   297 			
       
   298 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
       
   299 				{
       
   300 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   301 				TMemSpyProcessData data;
       
   302 				data.iIsDead = process.IsDead();
       
   303 				data.iId = process.Id();
       
   304 				data.iName.Copy(process.Name().Left(KMaxFullName));
       
   305 				data.iThreadCount = process.Count();
       
   306 				data.iPriority = process.Priority();
       
   307 				data.iExitType = process.ExitType();
       
   308 				data.iExitReason = process.ExitReason();
       
   309 				data.iExitCategory = process.ExitCategory();
       
   310 				data.iSID = process.SID();
       
   311 				
       
   312 				TPckgBuf<TMemSpyProcessData> buffer(data);
       
   313 				aMessage.WriteL(1, buffer, offset);
       
   314 				}
       
   315 			
       
   316 			a0 = list.Count();
       
   317 			aMessage.WriteL(0, a0);
       
   318 
       
   319 			break;
       
   320 			}
       
   321 		case EMemSpyClienServerOpGetProcessIdByName:
       
   322 			{
       
   323 			TFullName processName;
       
   324 			aMessage.ReadL(0, processName);
       
   325 			
       
   326 			TBool found(EFalse);
       
   327 			
       
   328 			for (TInt i=0; i<iEngine.Container().Count(); i++)
       
   329 				{
       
   330 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   331 				if (process.Name().FindF(processName) >= 0)
       
   332 					{
       
   333 					found = ETrue;
       
   334 					TPckgBuf<TProcessId> procId(process.Id());
       
   335 					aMessage.WriteL(1, procId);
       
   336 					}
       
   337 				}
       
   338 			
       
   339 			if (!found)
       
   340 				{
       
   341 				User::Leave(KErrNotFound);
       
   342 				}
       
   343 			
       
   344 			break;
       
   345 			}
       
   346 		case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
       
   347 			{
       
   348 			TBool ret = EFalse;
       
   349 			TPckgBuf<TProcessId> id;
       
   350 			aMessage.ReadL( 0, id );
       
   351 			
       
   352 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   353 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   354 			
       
   355 			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
       
   356 				{
       
   357 				ret = ETrue;
       
   358 				}
       
   359 			TPckgBuf<TBool> retBuf( ret );
       
   360 			aMessage.WriteL( 1, retBuf );
       
   361 			
       
   362 			break;
       
   363 			}
       
   364 		case EMemSpyClientServerOpEndProcess:
       
   365 			{
       
   366 			TPckgBuf<TProcessId> id;
       
   367 			aMessage.ReadL( 0, id );
       
   368 			TPckgBuf<TMemSpyEndType> type;
       
   369 			aMessage.ReadL( 1, type );
       
   370 					
       
   371 			CMemSpyEngineObjectContainer& container = iEngine.Container();			
       
   372 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   373 									
       
   374 			switch ( type() )
       
   375 				{
       
   376 				case ETerminate:
       
   377 					{
       
   378 					process.TerminateL();
       
   379 					break;
       
   380 					}
       
   381 				case EPanic:
       
   382 					{
       
   383 					process.PanicL();
       
   384 					break;
       
   385 					}
       
   386 				case EKill:
       
   387 					{
       
   388 					process.KillL();
       
   389 					break;
       
   390 					}
       
   391 				}																
       
   392 			break;
       
   393 			}
       
   394 		case EMemSpyClientServerOpSwitchToProcess:
       
   395 			{/*
       
   396 			TInt wgCount;
       
   397 			RWsSession wsSession;
       
   398 			User::LeaveIfError( wsSession.Connect() );
       
   399 			CleanupClosePushL( wsSession );
       
   400 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   401 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   402 			CleanupClosePushL( wgArray );
       
   403 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   404 			TApaTask task( wsSession );
       
   405 			TBool brought( EFalse );
       
   406 			TInt wgId( KErrNotFound );
       
   407 			TThreadId threadId;
       
   408 			
       
   409 			TPckgBuf<TProcessId> id;
       
   410 			aMessage.ReadL( 0, id );
       
   411 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   412 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   413 			
       
   414 			// loop trough threads in a process
       
   415 			for ( TInt i = 0; i < process.MdcaCount(); i++ )
       
   416 				{
       
   417 				TInt wgCountLocal = wgCount;
       
   418 							
       
   419 				// loop trough all window groups and see if a thread id matches
       
   420 				while( !brought && wgCountLocal-- )
       
   421 					{
       
   422 					wgId = wgArray[wgCountLocal].iId;
       
   423 					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   424 					if ( threadId == process.At( i ).Id() )
       
   425 						{
       
   426 						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   427 						task.SetWgId( wgId );
       
   428 						if ( !wgName->Hidden() && task.Exists() )
       
   429 							{
       
   430 							task.BringToForeground();
       
   431 							brought = ETrue;                        
       
   432 							}
       
   433 						CleanupStack::PopAndDestroy( wgName );
       
   434 						}
       
   435 					}
       
   436 				}
       
   437 			
       
   438 			TPckgBuf<TBool> ret( brought );
       
   439 			aMessage.WriteL( 1, ret );
       
   440 			
       
   441 			break;*/
       
   442 			}
       
   443 		case EMemSpyClientServerOpGetThreadCount:
       
   444 			{
       
   445 			TPckgBuf<TProcessId> pid;
       
   446 			aMessage.ReadL(1, pid);
       
   447 			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
       
   448 			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
       
   449 			break;
       
   450 			}
       
   451 		case EMemSpyClientServerOpGetThreads:
       
   452 			{
       
   453 			TPckgBuf<TProcessId> pid;
       
   454 			aMessage.ReadL(2, pid);
       
   455 			
       
   456 			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
       
   457 			
       
   458 			TPckgBuf<TInt> a0;
       
   459 			aMessage.ReadL(0, a0);
       
   460 			TInt realCount = Min(a0(), list.Count());
       
   461 						
       
   462 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
       
   463 				{
       
   464 				CMemSpyThread& thread = list.At(i);
       
   465 				
       
   466 				TMemSpyThreadData data;
       
   467 				data.iId = thread.Id();
       
   468 				data.iName.Copy(thread.Name().Left(KMaxFullName));
       
   469 				data.iThreadPriority = thread.Priority();
       
   470 				
       
   471 				TPckgBuf<TMemSpyThreadData> buffer(data);
       
   472 				aMessage.WriteL(1, buffer, offset);
       
   473 				}
       
   474 			
       
   475 			a0 = list.Count();
       
   476 			aMessage.WriteL(0, a0);
       
   477 
       
   478 			break;
       
   479 			}
       
   480 		case EMemSpyClientServerOpSetThreadPriority:
       
   481 			{
       
   482 			TPckgBuf<TThreadId> tid;
       
   483 			TPckgBuf<TInt> priority;
       
   484 			aMessage.ReadL(0, tid);
       
   485 			aMessage.ReadL(1, priority);
       
   486 			
       
   487 			CMemSpyProcess* process = NULL;
       
   488 			CMemSpyThread* thread = NULL; 
       
   489 			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
       
   490 			
       
   491 			if (thread)
       
   492 				{				
       
   493 				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
       
   494 				}					
       
   495 			break;
       
   496 			}
       
   497 		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
       
   498 			{
       
   499 			TPckgBuf<TThreadId> id;
       
   500 			aMessage.ReadL( 0, id );
       
   501 			
       
   502 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   503 			CMemSpyProcess* process = NULL;
       
   504 			CMemSpyThread* thread = NULL; 
       
   505 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   506 			
       
   507 			TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() );
       
   508 			
       
   509 			TPckgBuf<TBool> retBuf( ret );
       
   510 			aMessage.WriteL( 1, retBuf );
       
   511 							
       
   512 			break;
       
   513 			}
       
   514 		case EMemSpyClientServerOpEndThread:
       
   515 			{
       
   516 			TPckgBuf<TThreadId> id;
       
   517 			aMessage.ReadL( 0, id );
       
   518 			TPckgBuf<TMemSpyEndType> type;
       
   519 			aMessage.ReadL( 1, type );
       
   520 			
       
   521 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   522 			CMemSpyProcess* process = NULL;
       
   523 			CMemSpyThread* thread = NULL; 
       
   524 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   525 			
       
   526 			if( thread )
       
   527 				{
       
   528 				switch ( type() )
       
   529 					{
       
   530 					case ETerminate:
       
   531 						{
       
   532 						thread->TerminateL();
       
   533 						break;
       
   534 						}
       
   535 					case EPanic:
       
   536 						{
       
   537 						thread->PanicL();
       
   538 						break;
       
   539 						}
       
   540 					case EKill:
       
   541 						{
       
   542 						thread->KillL();
       
   543 						break;
       
   544 						}
       
   545 					}				
       
   546 				}			
       
   547 			break;
       
   548 			}
       
   549 		case EMemSpyClientServerOpSwitchToThread:
       
   550 			{
       
   551 			TInt wgCount;
       
   552 			RWsSession wsSession;
       
   553 			User::LeaveIfError( wsSession.Connect() );
       
   554 			CleanupClosePushL( wsSession );
       
   555 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   556 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   557 			CleanupClosePushL( wgArray );
       
   558 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   559 			TApaTask task( wsSession );
       
   560 			TBool brought( EFalse );
       
   561 			TInt wgId( KErrNotFound );
       
   562 			TThreadId threadId;
       
   563 					
       
   564 			TPckgBuf<TThreadId> id;
       
   565 			aMessage.ReadL( 0, id );
       
   566 					
       
   567 			// loop trough all window groups and see if a thread id matches
       
   568 			while( !brought && wgCount-- )
       
   569 				{
       
   570 				wgId = wgArray[wgCount].iId;
       
   571 				User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   572 				if ( threadId == id() )
       
   573 					{
       
   574 					CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   575 					task.SetWgId( wgId );
       
   576 					if ( !wgName->Hidden() && task.Exists() )
       
   577 						{
       
   578 						task.BringToForeground();
       
   579 						brought = ETrue;                        
       
   580 						}
       
   581 					CleanupStack::PopAndDestroy( wgName );
       
   582 					}
       
   583 				}			
       
   584 			TPckgBuf<TBool> ret( brought );
       
   585 			aMessage.WriteL( 1, ret );															
       
   586 					
       
   587 			break;
       
   588 			}		
       
   589 		case EMemSpyClientServerOpGetInfoItemType:
       
   590 			{
       
   591 			
       
   592 			TPckgBuf<TInt> index;
       
   593 			aMessage.ReadL( 0, index );			
       
   594 			TPckgBuf<TThreadId> id;
       
   595 			aMessage.ReadL( 1, id);
       
   596 								
       
   597 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   598 			CMemSpyProcess* process = NULL; //not needed
       
   599 			CMemSpyThread* thread = NULL; 
       
   600 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   601 		            
       
   602 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
       
   603 			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
       
   604 			
       
   605 			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
       
   606 			aMessage.WriteL( 2, ret );			
       
   607 			
       
   608 			break;
       
   609 			}
       
   610 		case EMemSpyClientServerOpGetThreadInfoItemsCount:
       
   611 			{
       
   612 			TPckgBuf<TThreadId> id;
       
   613 			aMessage.ReadL( 0, id );
       
   614 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   615 			aMessage.ReadL( 1, type );					 
       
   616 			
       
   617 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   618 			CMemSpyProcess* process = NULL;
       
   619 			CMemSpyThread* thread = NULL; 
       
   620 			
       
   621 			container.ProcessAndThreadByThreadId( id(), process, thread );
       
   622 			
       
   623 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
       
   624 								
       
   625 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
       
   626 				    
       
   627 			TInt count = threadInfoItemBase.MdcaCount();		    
       
   628 			TPckgBuf<TInt> tempret( count );
       
   629 			aMessage.WriteL( 2, tempret );
       
   630 		
       
   631 			break;
       
   632 			}		
       
   633 		case EMemSpyClientServerOpGetThreadInfoItems:
       
   634 			{
       
   635 			TPckgBuf<TInt> count;
       
   636 			aMessage.ReadL( 0, count );						
       
   637 			TPckgBuf<TThreadId> id;
       
   638 			aMessage.ReadL( 1, id );
       
   639 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   640 			aMessage.ReadL( 2, type );			
       
   641 			
       
   642 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   643 			CMemSpyProcess* process = NULL;
       
   644 			CMemSpyThread* thread = NULL; 
       
   645 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   646 							  
       
   647 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   648 
       
   649 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
       
   650 			
       
   651 			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
       
   652 								
       
   653 			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
       
   654 				{
       
   655 				TMemSpyThreadInfoItemData data;
       
   656 				
       
   657 				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
       
   658 				TInt tabPos = caption.Locate('\t');
       
   659 				if (tabPos != KErrNotFound)
       
   660 					caption.Set(caption.Left(tabPos));
       
   661 				
       
   662 				TPtrC value(threadInfoItemBase.MdcaPoint(i));
       
   663 				tabPos = value.LocateReverse('\t');
       
   664 				if (tabPos != KErrNotFound)
       
   665 					value.Set(value.Mid(tabPos + 1));
       
   666 												
       
   667 				data.iCaption.Copy( caption.Left(64) );
       
   668 				data.iValue.Copy( value.Left(32) );
       
   669 							
       
   670 				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
       
   671 				aMessage.WriteL(3, buffer, offset);				
       
   672 				}			
       
   673 			aMessage.WriteL(0, count);
       
   674 					
       
   675 			break;
       
   676 			}
       
   677 			
       
   678 		case EMemSpyClientServerOpGetProcessIdByThreadId:
       
   679 			{
       
   680 			TPckgBuf<TThreadId> tid;
       
   681 			aMessage.ReadL( 1, tid );					
       
   682 			
       
   683 			CMemSpyProcess* process = NULL;
       
   684 			CMemSpyThread* thread = NULL;
       
   685 			//
       
   686 			const TInt error = iEngine.Container().ProcessAndThreadByThreadId( tid(), process, thread );
       
   687 			
       
   688 			TProcessId pid = process->Id();
       
   689 			
       
   690 			TPckgBuf<TProcessId> ret(pid);
       
   691 			aMessage.WriteL( 0, ret );
       
   692 									
       
   693 			break;
       
   694 			}
       
   695 			
       
   696 		// --- KernelObjects related functions ---
       
   697 		case EMemSpyClientServerOpGetKernelObjectCount:
       
   698 			{
       
   699 			TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst + 1;
       
   700 			TPckgBuf<TInt> ret( iCount );
       
   701 			aMessage.WriteL(0, ret);			
       
   702 			break;
       
   703 			}
       
   704 		case EMemSpyClientServerOpGetKernelObjects:
       
   705 			{
       
   706 			TPckgBuf<TInt> count;
       
   707 			aMessage.ReadL(0, count);
       
   708 			
       
   709 			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
       
   710 			CleanupStack::PushL( model );
       
   711 			
       
   712 			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
       
   713 				{
       
   714 				TMemSpyKernelObjectData data;
       
   715 				
       
   716 				TPtrC name(model->At(i).Name().Mid(1));
       
   717 				TInt tabPos = name.Locate('\t');
       
   718 				if (tabPos != KErrNotFound)
       
   719 					name.Set(name.Left(tabPos));
       
   720 												
       
   721 				data.iName.Copy(name);
       
   722 				data.iType = model->At(i).Type();
       
   723 				data.iCount = model->At(i).Count();											
       
   724 				data.iSize = model->At(i).Count() * model->At(i).Count();
       
   725 
       
   726 				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
       
   727 				aMessage.WriteL(1, buffer, offset);
       
   728 				}			
       
   729 			aMessage.WriteL(0, count);
       
   730 			CleanupStack::PopAndDestroy( model );
       
   731 			break;
       
   732 			}
       
   733 		case EMemSpyClientServerOpGetKernelObjectItemCount:
       
   734 			{
       
   735 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   736 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   737 			TMemSpyDriverContainerType type = tempType();
       
   738 			
       
   739 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   740 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );			
       
   741 			
       
   742 			TInt count = iObjectList->Count();
       
   743 			TPckgBuf<TInt> ret( count );
       
   744 			aMessage.WriteL( 0, ret );
       
   745 						
       
   746 			break;
       
   747 			}
       
   748 		case EMemSpyClientServerOpGetKernelObjectItems:
       
   749 			{
       
   750 			TPckgBuf<TInt> count;
       
   751 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   752 			aMessage.ReadL( 0, count ); //get count of items
       
   753 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   754 			TInt c = count();
       
   755 						
       
   756 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   757 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );			
       
   758 			
       
   759 			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
       
   760 				{
       
   761 				TMemSpyDriverHandleInfoGeneric data;								
       
   762 															
       
   763 				data = iObjectList->At( i );
       
   764 				
       
   765 				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
       
   766 				aMessage.WriteL(2, buffer, offset);
       
   767 				}			
       
   768 					
       
   769 			break;
       
   770 			}
       
   771 			
       
   772 		case EMemSpyClientServerOpOutputAllContainerContents:
       
   773 			{
       
   774 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   775 			CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
       
   776 			
       
   777 			model->OutputL( iEngine.Sink() );
       
   778 
       
   779 			break;
       
   780 			}
       
   781 			
       
   782 		case EMemSpyClientServerOpDumpKernelHeap:
       
   783 			{
       
   784 		    iEngine.HelperHeap().OutputHeapDataKernelL();
       
   785 			
       
   786 			break;
       
   787 			}
       
   788 			
       
   789 		case EMemSpyClientServerOpOutputInfoHandles:
       
   790 			{
       
   791 			TPckgBuf<TThreadId> id;
       
   792 			aMessage.ReadL(0, id);
       
   793 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   794 			CMemSpyProcess* process = NULL;
       
   795 			CMemSpyThread* thread = NULL; 
       
   796 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   797 										  
       
   798 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
       
   799 			
       
   800 			threadInfoContainer.PrintL();
       
   801 			
       
   802 			break;
       
   803 			}
       
   804 			
       
   805 		case EMemSpyClientServerOpOutputAOList:
       
   806 			{
       
   807 			TPckgBuf<TThreadId> id;
       
   808 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   809 			aMessage.ReadL(0, id);
       
   810 			aMessage.ReadL(1, type);
       
   811 			
       
   812 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   813 			CMemSpyProcess* process = NULL;
       
   814 			CMemSpyThread* thread = NULL; 
       
   815 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   816 										  
       
   817 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   818 
       
   819 			CMemSpyThreadInfoItemBase* threadInfoItem = &threadInfoContainer.Item( type() );
       
   820 						
       
   821 			CMemSpyThreadInfoActiveObjects* activeObjectArray = static_cast< CMemSpyThreadInfoActiveObjects* >( threadInfoItem );			
       
   822 						
       
   823 		    // Begin a new data stream
       
   824 		    _LIT( KMemSpyContext, "Active Object List - " );
       
   825 		    _LIT( KMemSpyFolder, "Active Objects" );
       
   826 		    iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder );
       
   827 		    		    
       
   828 		    // Set prefix for overall listing
       
   829 		    iEngine.Sink().OutputPrefixSetLC( KMemSpyContext );
       
   830 
       
   831 		    // Create header
       
   832 		    CMemSpyEngineActiveObjectArray::OutputDataColumnsL( iEngine );
       
   833 		    
       
   834 		    // List items
       
   835 		    const TInt count = activeObjectArray->Array().Count();
       
   836 		    for(TInt i=0; i<count; i++)
       
   837 		        {
       
   838 		        const CMemSpyEngineActiveObject& object = activeObjectArray->Array().At( i );
       
   839 		        //
       
   840 		        object.OutputDataL( iEngine );
       
   841 		        }
       
   842 
       
   843 		    // Tidy up
       
   844 		    CleanupStack::PopAndDestroy(); // prefix
       
   845 
       
   846 		    // End data stream		    		    
       
   847 		    iEngine.Sink().DataStreamEndL();		    
       
   848 			
       
   849 			break;
       
   850 			}
       
   851 			
       
   852 		// --- Kernel Heap related functions ---
       
   853 		case EMemSpyClientServerOpGetHeap:
       
   854 			{
       
   855 			TMemSpyHeapInfo heapInfo;			
       
   856 			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
       
   857 			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
       
   858 			
       
   859 			TPckgBuf<TMemSpyHeapData> buffer(data);
       
   860 			aMessage.WriteL(0, buffer);
       
   861 			
       
   862 			break;
       
   863 			}
       
   864 			
       
   865 		case EMemSpyClientServerOpGetServerCount:
       
   866             {
       
   867             CMemSpyEngineServerList* list = iEngine.HelperServer().ServerListL();
       
   868             CleanupStack::PushL(list);
       
   869             // TODO: cache it between calls
       
   870             aMessage.WriteL(0, TPckgBuf<TInt>(list->MdcaCount()));
       
   871             
       
   872             CleanupStack::PopAndDestroy(list);
       
   873             break;
       
   874             }
       
   875         // --- Servers related functions
       
   876         case EMemSpyClientServerOpGetServers:
       
   877             {
       
   878             CMemSpyEngineServerList* list = iEngine.HelperServer().ServerListL();
       
   879             CleanupStack::PushL(list);
       
   880             
       
   881             TPckgBuf<TInt> a0;
       
   882             aMessage.ReadL(0, a0);
       
   883             TInt realCount = Min(a0(), list->MdcaCount());
       
   884             
       
   885             for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyServerData))
       
   886                 {
       
   887                 const CMemSpyEngineServerEntry& server = list->At(i);
       
   888                 TMemSpyServerData data;
       
   889                 
       
   890                 CMemSpyProcess* process = NULL;
       
   891                 CMemSpyThread* thread = NULL;
       
   892                 TInt error = iEngine.Container().ProcessAndThreadByThreadId( server.Id(), process, thread );
       
   893                 if (error == KErrNone && thread)
       
   894                     {
       
   895                     data.iId = thread->Process().Id();
       
   896                     }
       
   897                 data.iName.Copy(server.Name().Left(KMaxFullName));
       
   898                 data.iSessionCount = server.SessionCount();
       
   899                 
       
   900                 TPckgBuf<TMemSpyServerData> buffer(data);
       
   901                 aMessage.WriteL(1, buffer, offset);
       
   902                 }
       
   903             
       
   904             a0 = list->Count();
       
   905             aMessage.WriteL(0, a0);
       
   906             
       
   907             CleanupStack::PopAndDestroy(list);
       
   908 
       
   909             break;
       
   910             }
       
   911             
       
   912         case EMemSpyClientServerOpGetSortedServers:
       
   913         	{
       
   914         	CMemSpyEngineServerList* list = iEngine.HelperServer().ServerListL();
       
   915         	CleanupStack::PushL(list);
       
   916         	
       
   917         	TPckgBuf<TSortType> a2;
       
   918         	aMessage.ReadL( 2, a2 );
       
   919         	
       
   920         	//sort the list of the servers
       
   921         	if( a2() == ESortServByName )
       
   922         		list->SortByNameL();
       
   923         	else
       
   924         		list->SortBySessionCountL();
       
   925         	
       
   926         	TPckgBuf<TInt> a0;        	
       
   927         	aMessage.ReadL(0, a0);        	        	        
       
   928         	
       
   929         	TInt realCount = Min(a0(), list->MdcaCount());
       
   930         	            
       
   931         	for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyServerData))
       
   932         		{
       
   933 				const CMemSpyEngineServerEntry& server = list->At(i);
       
   934 				TMemSpyServerData data;
       
   935         	                
       
   936 				data.iId = server.Id();
       
   937 				data.iName.Copy(server.Name().Left(KMaxFullName));
       
   938 				data.iSessionCount = server.SessionCount();
       
   939         	                
       
   940 				TPckgBuf<TMemSpyServerData> buffer(data);
       
   941 				aMessage.WriteL(1, buffer, offset);
       
   942         		}        	           
       
   943 			a0 = list->Count();
       
   944 			aMessage.WriteL(0, a0);
       
   945         	            
       
   946 			CleanupStack::PopAndDestroy(list);
       
   947 			break;
       
   948         	}
       
   949           
       
   950         case EMemSpyClientServerOpServerListOutputGeneric:
       
   951         	{
       
   952             TPckgBuf<TBool> a0;
       
   953             aMessage.ReadL(0, a0);
       
   954         	
       
   955             CMemSpyEngineServerList* list;            
       
   956             list = iEngine.HelperServer().ServerListL();
       
   957             CleanupStack::PushL(list);
       
   958             
       
   959             _LIT( KMemSpyContext, "Server List - " );
       
   960             _LIT( KMemSpyFolder, "Servers" );
       
   961             iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder );
       
   962 
       
   963             // Set prefix for overall listing
       
   964             iEngine.Sink().OutputPrefixSetLC( KMemSpyContext );
       
   965 
       
   966             // Create header
       
   967             CMemSpyEngineServerList::OutputDataColumnsL( iEngine, a0() );
       
   968                
       
   969             // List items
       
   970             const TInt count = list->Count();
       
   971             for(TInt i=0; i<count; i++)
       
   972             	{
       
   973 				const CMemSpyEngineServerEntry& server = list->At( i );
       
   974 				//
       
   975 				server.OutputDataL( iEngine.HelperServer(), a0() );
       
   976             	}
       
   977 
       
   978             // Tidy up
       
   979             CleanupStack::PopAndDestroy(); // prefix
       
   980             
       
   981             // End data stream
       
   982             iEngine.Sink().DataStreamEndL();
       
   983             
       
   984             CleanupStack::PopAndDestroy(list);        	
       
   985         	break;
       
   986         	}        	
       
   987         	
       
   988 		case EMemSpyClientServerOpGetMemoryTrackingCycleCount:
       
   989 			{
       
   990 			TInt count = iEngine.HelperSysMemTracker().CompletedCycles().Count();
       
   991 			TPckgBuf<TInt> ret( count );
       
   992 			aMessage.WriteL( 0, ret );			
       
   993 			break;
       
   994 			}		
       
   995 			
       
   996 		case EMemSpyClientServerOpGetMemoryTrackingCycles:
       
   997 			{
       
   998 			const RPointerArray<CMemSpyEngineHelperSysMemTrackerCycle>& list = iEngine.HelperSysMemTracker().CompletedCycles();
       
   999 
       
  1000 			TPckgBuf<TInt> a0;
       
  1001 			aMessage.ReadL(0, a0);
       
  1002 			TInt realCount = Min(a0(), list.Count());
       
  1003 			
       
  1004 			for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyMemoryTrackingCycleData))
       
  1005 				{
       
  1006 				CMemSpyProcess& process = iEngine.Container().At(i);
       
  1007 				TMemSpyMemoryTrackingCycleData data;
       
  1008 				data.iCycleNumber = list[i]->CycleNumber();
       
  1009 				data.iCaption.Copy(list[i]->Caption().Left(KMaxFullName));
       
  1010 				data.iTime = list[i]->Time();
       
  1011 				data.iFreeMemory = list[i]->MemoryFree();
       
  1012 				data.iMemoryDelta = list[i]->MemoryDelta();
       
  1013 				data.iPreviousCycleDiff = list[i]->MemoryFreePreviousCycle();
       
  1014 				data.iChangeCount = list[i]->ChangeCount();
       
  1015 				
       
  1016 				TPckgBuf<TMemSpyMemoryTrackingCycleData> buffer(data);
       
  1017 				aMessage.WriteL(1, buffer, offset);
       
  1018 				}
       
  1019 			
       
  1020 			a0 = list.Count();
       
  1021 			aMessage.WriteL(0, a0);
       
  1022 
       
  1023 		break;
       
  1024 		}
       
  1025 
       
  1026 	case EMemSpyClientServerOpIsSwmtRunning:
       
  1027 		{
       
  1028 		TPckgBuf<TBool> running(iEngine.HelperSysMemTracker().IsActive());
       
  1029 		aMessage.WriteL(0, running);
       
  1030 		break;
       
  1031 		}
       
  1032 		
       
  1033 	case EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodGet:
       
  1034 	    {	    			   
       
  1035 	    // Get current config
       
  1036 	    TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1037 	    iEngine.HelperSysMemTracker().GetConfig( config );
       
  1038 	    TInt time = config.iTimerPeriod.Int();
       
  1039 	    TPckgBuf<TInt> tim(time);			            
       
  1040 	    aMessage.WriteL( 0, tim );
       
  1041 	    break;
       
  1042 	    }
       
  1043 	    
       
  1044 	case EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesGet:
       
  1045 		{
       
  1046 		// Get current config
       
  1047 		TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1048 		iEngine.HelperSysMemTracker().GetConfig( config );		
       
  1049 		TInt categories = config.iEnabledCategories;		
       
  1050 		TPckgBuf<TInt> ret( categories );
       
  1051 		aMessage.WriteL( 0, ret );						
       
  1052 		break;
       
  1053 		}
       
  1054 		
       
  1055 	case EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterGet:
       
  1056 		{
       
  1057 		TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1058 		iEngine.HelperSysMemTracker().GetConfig( config );                 
       
  1059 		TName threadNameFilter = config.iThreadNameFilter;
       
  1060 		TPckgBuf<TName> name(threadNameFilter);
       
  1061 		aMessage.WriteL( 0, name );
       
  1062 		
       
  1063 		break;
       
  1064 		}
       
  1065 		
       
  1066 	case EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpGet:
       
  1067 		{
       
  1068 		TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1069 		iEngine.HelperSysMemTracker().GetConfig( config );		           
       
  1070 		TBool heapDump = config.iDumpData;
       
  1071 		TPckgBuf<TBool> heap(heapDump);			            
       
  1072 		aMessage.WriteL( 0, heap );
       
  1073 		break;
       
  1074 		}
       
  1075 						
       
  1076 	case EMemSpyClientServerOpSystemWideMemoryTrackingModeGet:
       
  1077 		{
       
  1078 		TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1079 		iEngine.HelperSysMemTracker().GetConfig( config );	 		 
       
  1080 		TPckgBuf<TMemSpyEngineHelperSysMemTrackerConfig::TMemSpyEngineSysMemTrackerMode> mod(config.iMode);			             		            
       
  1081 		aMessage.WriteL(0, mod);	 			 		    
       
  1082 		break;
       
  1083 		}			
       
  1084 		
       
  1085 	case EMemSpyClientServerOpNotifyDeviceWideOperationProgress:
       
  1086 		{
       
  1087 		if (!Server().CurrentOperationTracker())
       
  1088 			{
       
  1089 			User::Leave(KErrNotReady);
       
  1090 			}
       
  1091 		
       
  1092 		Server().CurrentOperationTracker()->AddNotificationL(aMessage);
       
  1093 		break;
       
  1094 		}
       
  1095 		
       
  1096 	case EMemSpyClientServerOpCancelDeviceWideOperation:
       
  1097 		if (!Server().CurrentOperationTracker())
       
  1098 			{
       
  1099 			User::Leave(KErrNotReady);
       
  1100 			}
       
  1101 		
       
  1102 		Server().CurrentOperationTracker()->Cancel();
       
  1103 		break;
       
  1104 	
       
  1105 		
       
  1106 	case EMemSpyClientServerOpGetEComCategoryCount:
       
  1107 	    aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.HelperECom().MdcaCount()));
       
  1108 	    break;
       
  1109 	    
       
  1110 
       
  1111 	case EMemSpyClientServerOpGetEComCategories:
       
  1112 	    {
       
  1113 	    TPckgBuf<TInt> a0;
       
  1114         aMessage.ReadL(0, a0);
       
  1115         TInt realCount = Min(a0(), iEngine.HelperECom().MdcaCount());
       
  1116         
       
  1117         for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyEComCategoryData))
       
  1118             {
       
  1119             TMemSpyEComCategoryData data;
       
  1120             data.iId.iUid = i;
       
  1121             data.iName.Copy(iEngine.HelperECom().At(i).Name());
       
  1122             data.iInterfaceCount = iEngine.HelperECom().At(i).MdcaCount();
       
  1123             
       
  1124             TPckgBuf<TMemSpyEComCategoryData> buffer(data);
       
  1125             aMessage.WriteL(1, buffer, offset);
       
  1126 		}
       
  1127         
       
  1128         a0 = iEngine.HelperECom().MdcaCount();
       
  1129         aMessage.WriteL(0, a0);
       
  1130 	    break;
       
  1131     }
       
  1132 	    
       
  1133 	case EMemSpyClientServerOpGetEComInterfaceCount:
       
  1134 	    {
       
  1135 	    TPckgBuf<TUid> a1;
       
  1136         aMessage.ReadL(1, a1);
       
  1137         TInt index = a1().iUid;
       
  1138         
       
  1139         if (index < 0 || index >= iEngine.HelperECom().MdcaCount())
       
  1140             {
       
  1141             User::Leave(KErrArgument);
       
  1142             }
       
  1143         
       
  1144         aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.HelperECom().At(index).MdcaCount()));
       
  1145 	    break;
       
  1146 	    }
       
  1147 	            
       
  1148 	case EMemSpyClientServerOpGetEComInterfaces:
       
  1149 	    {
       
  1150 	    TPckgBuf<TInt> a0;
       
  1151         aMessage.ReadL(0, a0);
       
  1152         TInt realCount = Min(a0(), iEngine.HelperECom().MdcaCount());
       
  1153         
       
  1154         TPckgBuf<TUid> a1;
       
  1155         aMessage.ReadL(1, a1);
       
  1156         TInt categoryIndex = a1().iUid;
       
  1157         
       
  1158         if (categoryIndex < 0 || categoryIndex >= iEngine.HelperECom().MdcaCount())
       
  1159             {
       
  1160             User::Leave(KErrArgument);
       
  1161             }
       
  1162         
       
  1163         CMemSpyEngineEComCategory &category = iEngine.HelperECom().At(categoryIndex);
       
  1164         
       
  1165         for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyEComInterfaceData))
       
  1166             {
       
  1167             TMemSpyEComInterfaceData data;
       
  1168             data.iId.iUid = (TInt32) &category.At(i);
       
  1169             data.iCategoryId.iUid = categoryIndex;
       
  1170             data.iName.Copy(category.At(i).Name());
       
  1171             data.iImplementationCount = category.At(i).MdcaCount();
       
  1172             
       
  1173             TPckgBuf<TMemSpyEComInterfaceData> buffer(data);
       
  1174             aMessage.WriteL(2, buffer, offset);
       
  1175             }
       
  1176         
       
  1177         a0 = realCount;
       
  1178         aMessage.WriteL(0, a0);
       
  1179         
       
  1180         break;
       
  1181 	    }
       
  1182 	    
       
  1183 	case EMemSpyClientServerOpGetEComImplementationCount:
       
  1184 	    {
       
  1185 	    TPckgBuf<TUid> a1;
       
  1186         aMessage.ReadL(1, a1);
       
  1187         CMemSpyEngineEComInterface* interface = reinterpret_cast<CMemSpyEngineEComInterface*>(a1().iUid);
       
  1188         
       
  1189         // TODO: check if it really is valid interface 
       
  1190         
       
  1191         aMessage.WriteL(0, TPckgBuf<TInt>(interface->MdcaCount()));
       
  1192 	    break;
       
  1193 	    }
       
  1194 	                
       
  1195 	case EMemSpyClientServerOpGetEComImplementations:
       
  1196 	    {
       
  1197         TPckgBuf<TUid> a1;
       
  1198         aMessage.ReadL(1, a1);
       
  1199         CMemSpyEngineEComInterface* interface = reinterpret_cast<CMemSpyEngineEComInterface*>(a1().iUid);
       
  1200         
       
  1201         TPckgBuf<TInt> a0;
       
  1202         aMessage.ReadL(0, a0);
       
  1203         TInt realCount = Min(a0(), interface->MdcaCount());
       
  1204         
       
  1205         
       
  1206         for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyEComImplementationData))
       
  1207             {
       
  1208             TMemSpyEComImplementationData data;
       
  1209             data.iName.Copy(interface->At(i).Info().DisplayName());
       
  1210             data.iImplementationUid = interface->At(i).Info().ImplementationUid();
       
  1211             data.iVersion = interface->At(i).Info().Version();
       
  1212             data.iDataType.Copy(interface->At(i).Info().DataType());
       
  1213             data.iOpaqueData.Copy(interface->At(i).Info().OpaqueData());
       
  1214             data.iDrive = interface->At(i).Info().Drive();
       
  1215             data.iRomOnly = interface->At(i).Info().RomOnly();
       
  1216             data.iRomBased = interface->At(i).Info().RomBased();
       
  1217             data.iVendorId = interface->At(i).Info().VendorId();
       
  1218             data.iDisabled = interface->At(i).Info().Disabled();
       
  1219             
       
  1220             TPckgBuf<TMemSpyEComImplementationData> buffer(data);
       
  1221             aMessage.WriteL(2, buffer, offset);
       
  1222             }
       
  1223         
       
  1224         a0 = realCount;
       
  1225         aMessage.WriteL(0, a0);
       
  1226         
       
  1227         break;
       
  1228 	    }
       
  1229 	    
       
  1230 		}
       
  1231     }
       
  1232 
       
  1233 // ---------------------------------------------------------
       
  1234 // DoCmdServiceL( const RMessage2& aMessage )
       
  1235 // ---------------------------------------------------------
       
  1236 //
       
  1237 void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
       
  1238     {
   172     {
  1239     TInt error = KErrNone;
   173     TInt error = KErrNone;
  1240 
   174 
  1241     // Check function attributes
   175     // Check function attributes
  1242     const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
   176     const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
  1446 
   380 
  1447 
   381 
  1448 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
   382 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
  1449     {
   383     {
  1450     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
   384     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
  1451     
       
  1452     //
   385     //
  1453     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
   386     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
  1454         {
   387         {
  1455         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
   388         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
  1456         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
   389         iEngine.HelperHeap().OutputHeapInfoForDeviceL();
  1457         	{
       
  1458 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage);
       
  1459         	}
       
  1460         else
       
  1461         	{
       
  1462 			iEngine.HelperHeap().OutputHeapInfoForDeviceL();
       
  1463         	}
       
  1464         }
   390         }
  1465     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
   391     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
  1466         {
   392         {
  1467         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
   393         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
  1468         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
   394         iEngine.HelperStack().OutputStackInfoForDeviceL();
  1469 			{
       
  1470 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage);
       
  1471 			}
       
  1472 		else
       
  1473 			{
       
  1474 			iEngine.HelperStack().OutputStackInfoForDeviceL();
       
  1475 			}
       
  1476         }
   395         }
  1477     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
   396     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
  1478         {
   397         {
  1479         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
   398         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
  1480         iEngine.HelperSysMemTracker().StartL();
   399         iEngine.HelperSysMemTracker().StartL();
  1519         config.iEnabledCategories = aMessage.Int0();
   438         config.iEnabledCategories = aMessage.Int0();
  1520 
   439 
  1521         // And update config... which will leave if the config is invalid
   440         // And update config... which will leave if the config is invalid
  1522         iEngine.HelperSysMemTracker().SetConfigL( config );
   441         iEngine.HelperSysMemTracker().SetConfigL( config );
  1523         }
   442         }
  1524     
       
  1525     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet )
   443     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet )
  1526         {
   444         {
  1527         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") );
   445         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") );
  1528         // Get current config
   446         // Get current config
  1529         TMemSpyEngineHelperSysMemTrackerConfig config;
   447         TMemSpyEngineHelperSysMemTrackerConfig config;
  1558         config.iDumpData = aMessage.Int0();
   476         config.iDumpData = aMessage.Int0();
  1559         
   477         
  1560         // And update config... which will leave if the config is invalid
   478         // And update config... which will leave if the config is invalid
  1561         iEngine.HelperSysMemTracker().SetConfigL( config );
   479         iEngine.HelperSysMemTracker().SetConfigL( config );
  1562         }
   480         }
  1563     else if( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingModeSet)
       
  1564     	{
       
  1565 		TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1566 		iEngine.HelperSysMemTracker().GetConfig( config );
       
  1567 		
       
  1568 		TPckgBuf<TMemSpyEngineHelperSysMemTrackerConfig::TMemSpyEngineSysMemTrackerMode> mode;
       
  1569 		aMessage.ReadL( 0, mode );
       
  1570 		
       
  1571 		config.iMode = mode();
       
  1572 			
       
  1573 		// And update config... which will leave if the config is invalid
       
  1574 		iEngine.HelperSysMemTracker().SetConfigL( config );
       
  1575     	}
       
  1576     
       
  1577     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
   481     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
  1578         {
   482         {
  1579         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
   483         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
  1580         iEngine.InstallDebugSinkL();
   484         iEngine.InstallSinkL( ESinkTypeDebug );
  1581         }
   485         }
  1582     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
   486     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
  1583         {
   487         {
  1584         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
   488         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
  1585         // Read file name from message.
   489         iEngine.InstallSinkL( ESinkTypeFile );
  1586         TFileName fileName;
       
  1587         RBuf buf;
       
  1588 		buf.CleanupClosePushL();
       
  1589 		
       
  1590 		TInt len = aMessage.GetDesLength( 0 );
       
  1591 		if ( len > 0 )
       
  1592 			{
       
  1593 			buf.CreateL( len );
       
  1594 			aMessage.ReadL( 0, buf, 0 );
       
  1595 			
       
  1596 			iEngine.InstallFileSinkL( buf );           
       
  1597 			}
       
  1598 		else
       
  1599 			{
       
  1600 			iEngine.InstallFileSinkL( KNullDesC );
       
  1601 			}
       
  1602 		
       
  1603 		CleanupStack::PopAndDestroy( &buf );
       
  1604         
       
  1605         }
   490         }
  1606     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
   491     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
  1607         {
   492         {
  1608         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
   493         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
  1609 
   494 
  1630     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
   515     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
  1631         {
   516         {
  1632         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
   517         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
  1633         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
   518         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
  1634         }
   519         }
  1635     else if ( aFunction == EMemSpyClientServerOpSummaryInfo )
       
  1636     	{
       
  1637 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfo") );
       
  1638 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralSummary, aMessage);
       
  1639     	}
       
  1640     else if ( aFunction == EMemSpyClientServerOpSummaryInfoDetailed )
       
  1641 		{
       
  1642 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfoDetailed") );
       
  1643 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed, aMessage);
       
  1644 		}
       
  1645     else if ( aFunction == EMemSpyClientServerOpHeapInfo )
       
  1646 		{
       
  1647 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfo") );
       
  1648 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapInfo, aMessage);
       
  1649 		}
       
  1650     else if ( aFunction == EMemSpyClientServerOpHeapCellListing )
       
  1651 		{
       
  1652 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapCellListing") );
       
  1653 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapCellListing, aMessage);
       
  1654 		}
       
  1655     else if ( aFunction == EMemSpyClientServerOpHeapData )
       
  1656 		{
       
  1657 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapData") );
       
  1658 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapData, aMessage);
       
  1659 		}
       
  1660     else if ( aFunction == EMemSpyClientServerOpStackInfo )
       
  1661 		{
       
  1662 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfo") );
       
  1663 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackInfo, aMessage);
       
  1664 		}
       
  1665     else if ( aFunction == EMemSpyClientServerOpStackDataUser )
       
  1666 		{
       
  1667 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataUser") );
       
  1668 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataUser, aMessage);
       
  1669 		}
       
  1670     else if ( aFunction == EMemSpyClientServerOpStackDataKernel )
       
  1671 		{
       
  1672 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataKernel") );
       
  1673 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataKernel, aMessage);
       
  1674 		}
       
  1675     else
   520     else
  1676         {
   521         {
  1677         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
   522         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
  1678         iEngine.NotifyClientServerOperationRequestL( aFunction );
   523         iEngine.NotifyClientServerOperationRequestL( aFunction );
  1679         }
   524         }
  1680     //
   525     //
  1681     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
   526     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
  1682     }
   527     }
  1683 
   528 
  1684 void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage)
   529 
  1685 	{
   530 
  1686 	if (Server().CurrentOperationTracker())
   531 
  1687 		{
   532 
  1688 		User::Leave(KErrInUse);
       
  1689 		}
       
  1690 	
       
  1691 	Server().SetCurrentOperationTracker(CMemSpyDwOperationTracker::NewL(aOperation, aMessage, Server()));
       
  1692 	}
       
  1693 
       
  1694 
       
  1695 
       
  1696 
       
  1697 
       
  1698 
       
  1699 
       
  1700 
       
  1701 
       
  1702 CMemSpyDwOperationTracker* CMemSpyDwOperationTracker::NewL(CMemSpyDeviceWideOperations::TOperation aOperation, 
       
  1703 		const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer)
       
  1704 	{
       
  1705 	CMemSpyDwOperationTracker* self = new (ELeave) CMemSpyDwOperationTracker(aOperationMessage, aServer);
       
  1706 	CleanupStack::PushL( self );
       
  1707 	self->ConstructL(aOperation);
       
  1708 	CleanupStack::Pop( self );
       
  1709 	return self;
       
  1710 	}
       
  1711 	
       
  1712 CMemSpyDwOperationTracker::~CMemSpyDwOperationTracker()
       
  1713 	{
       
  1714 	delete iOperation;
       
  1715 	delete iPendingNotifications;
       
  1716 	}
       
  1717 
       
  1718 CMemSpyDwOperationTracker::CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) : 
       
  1719 		iOperationMessage(aOperationMessage),
       
  1720 		iServer(aServer),
       
  1721 		iPendingNotifications(0),
       
  1722 		iOperation(0),
       
  1723 		iProgress(0)
       
  1724 	{
       
  1725 	}
       
  1726 
       
  1727 
       
  1728 void CMemSpyDwOperationTracker::ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation)
       
  1729 	{
       
  1730 	iPendingNotifications = new (ELeave) CArrayFixFlat<RMessage2>(3);
       
  1731 	iOperation = CMemSpyDeviceWideOperations::NewL(iServer.Engine(), *this, aOperation);
       
  1732 	}
       
  1733 
       
  1734 void CMemSpyDwOperationTracker::AddNotificationL(const RMessage2& aMessage)
       
  1735 	{
       
  1736 	iPendingNotifications->AppendL(aMessage);
       
  1737 	}
       
  1738 
       
  1739 void CMemSpyDwOperationTracker::Cancel()
       
  1740 	{
       
  1741 	iOperation->Cancel();
       
  1742 	}
       
  1743 
       
  1744 void CMemSpyDwOperationTracker::HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2)
       
  1745 	{
       
  1746 	switch( aEvent )
       
  1747 		{
       
  1748 	case MMemSpyDeviceWideOperationsObserver::EOperationCompleted:
       
  1749 	case MMemSpyDeviceWideOperationsObserver::EOperationCancelled:
       
  1750 		iServer.SetCurrentOperationTracker(0);
       
  1751 		
       
  1752 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1753 			{
       
  1754 			iPendingNotifications->At(i).Complete(KErrCancel);
       
  1755 			}
       
  1756 		
       
  1757 		if (iOperationMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1758 			{
       
  1759 			iOperationMessage.Complete(
       
  1760 				aEvent == MMemSpyDeviceWideOperationsObserver::EOperationCompleted ? KErrNone : KErrCancel);
       
  1761 			}
       
  1762 		
       
  1763 		iPendingNotifications->Reset();
       
  1764 		
       
  1765 		delete this;
       
  1766 		break;
       
  1767 		
       
  1768 	case MMemSpyDeviceWideOperationsObserver::EOperationProgressEnd:
       
  1769 		{
       
  1770 		iProgress += aParam1;
       
  1771 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1772 			{
       
  1773 			TInt err;
       
  1774 			TRAP(err, iPendingNotifications->At(i).WriteL(0, TPckgBuf<TInt>( iProgress * 100 / iOperation->TotalOperationSize() )));
       
  1775 			TRAP(err, iPendingNotifications->At(i).WriteL(1, aParam2));
       
  1776 			if (err != KErrNone)
       
  1777 				{
       
  1778 				// TODO: iPendingProgressNotifications->At(i).Panic()
       
  1779 				}
       
  1780 			iPendingNotifications->At(i).Complete(KErrNone);
       
  1781 			}
       
  1782 		iPendingNotifications->Reset();
       
  1783 		break;
       
  1784 		}
       
  1785 		
       
  1786 		}
       
  1787 	
       
  1788 	}