memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp
changeset 48 516af714ebb4
parent 45 185201be11b0
child 55 f2950aff7424
equal deleted inserted replaced
45:185201be11b0 48:516af714ebb4
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyEngineServer.h"
       
    19 
       
    20 // System includes
       
    21 #include <e32svr.h>
       
    22 #include <w32std.h>
       
    23 #include <APGTASK.H>
       
    24 #include <APGWGNAM.H>  
       
    25 
       
    26 // User includes
       
    27 #include <memspy/engine/memspyengine.h>
       
    28 #include <memspy/engine/memspyenginelogger.h>
       
    29 #include <memspyengineclientinterface.h>
       
    30 #include <memspy/engine/memspyengineobjectthread.h>
       
    31 #include <memspy/engine/memspyengineobjectprocess.h>
       
    32 #include <memspy/engine/memspyengineobjectcontainer.h>
       
    33 #include <memspy/engine/memspyenginehelperchunk.h>
       
    34 #include <memspy/engine/memspyenginehelpercodesegment.h>
       
    35 #include <memspy/engine/memspyenginehelperheap.h>
       
    36 #include <memspy/engine/memspyenginehelperstack.h>
       
    37 #include <memspy/engine/memspyenginehelperthread.h>
       
    38 #include <memspy/engine/memspyenginehelperprocess.h>
       
    39 #include <memspy/engine/memspyenginehelperfilesystem.h>
       
    40 #include <memspy/engine/memspyenginehelperram.h>
       
    41 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
       
    42 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
       
    43 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
       
    44 #include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
       
    45 #include <memspy/engine/memspyengineobjectthreadinfoobjects.h>
       
    46 #include <memspy/engine/memspyenginehelpersysmemtrackercycle.h>
       
    47 
       
    48 #include <memspy/engine/memspyprocessdata.h>
       
    49 #include <memspy/engine/memspythreaddata.h>
       
    50 #include <memspy/engine/memspykernelobjectdata.h>
       
    51 #include <memspy/engine/memspythreadinfoitemdata.h>
       
    52 #include <memspy/engine/memspymemorytrackingcycledata.h>
       
    53 #include <memspy/engine/memspyengineoutputsink.h>
       
    54 #include <memspy/engine/memspyenginehelperactiveobject.h>
       
    55 
       
    56 inline CShutdown::CShutdown() :CTimer(-1)
       
    57     {
       
    58     CActiveScheduler::Add(this);
       
    59     }
       
    60 
       
    61 inline void CShutdown::ConstructL()
       
    62     {
       
    63     CTimer::ConstructL();
       
    64     }
       
    65 
       
    66 inline void CShutdown::Start()
       
    67     {
       
    68     After(KMyShutdownDelay);
       
    69     }
       
    70 
       
    71 void CShutdown::RunL()
       
    72     //
       
    73     // Initiate server exit when the timer expires
       
    74     //
       
    75     {
       
    76     CActiveScheduler::Stop();
       
    77     }
       
    78 
       
    79 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
       
    80 :   CServer2( EPriorityNormal ), iEngine( aEngine )
       
    81     {
       
    82     }
       
    83 
       
    84 
       
    85 CMemSpyEngineServer::~CMemSpyEngineServer()
       
    86     {
       
    87     }
       
    88 
       
    89 
       
    90 void CMemSpyEngineServer::ConstructL()
       
    91     {
       
    92     StartL( KMemSpyServerName );
       
    93     
       
    94     iShutdown.ConstructL();
       
    95     // ensure that the server still exits even if the 1st client fails to connect
       
    96     iShutdown.Start();
       
    97     }
       
    98 
       
    99 
       
   100 CMemSpyEngineServer* CMemSpyEngineServer::NewL( CMemSpyEngine& aEngine )
       
   101     {
       
   102     CMemSpyEngineServer* self = new(ELeave) CMemSpyEngineServer( aEngine );
       
   103     CleanupStack::PushL( self );
       
   104     self->ConstructL();
       
   105     CleanupStack::Pop( self );
       
   106     return self;
       
   107     }
       
   108 
       
   109 
       
   110 CSession2* CMemSpyEngineServer::NewSessionL( const TVersion& aVersion, const RMessage2& aMessage ) const
       
   111     {
       
   112     if  ( aVersion.iMajor != KMemSpyClientServerVersion )
       
   113         {
       
   114         RDebug::Printf( "[MemSpy] CMemSpyEngineSession::NewSessionL() - BAD VERSION" );
       
   115         User::Leave( KErrNotSupported );
       
   116         }
       
   117     //
       
   118     CMemSpyEngineSession* session = CMemSpyEngineSession::NewL( iEngine, aMessage );
       
   119 	return session;
       
   120     }
       
   121 
       
   122 void CMemSpyEngineServer::AddSession(TBool aCliRequest)
       
   123     {
       
   124     if (aCliRequest)
       
   125         {
       
   126         iCliConnected = ETrue;
       
   127         }
       
   128     else
       
   129         {
       
   130         ++iSessionCount;
       
   131         }
       
   132     iShutdown.Cancel();
       
   133     }
       
   134 
       
   135 void CMemSpyEngineServer::DropSession(TBool aCliRequest)
       
   136     {
       
   137     if (!aCliRequest)
       
   138         {
       
   139         --iSessionCount;
       
   140         }
       
   141     
       
   142     if (iSessionCount == 0 && !iCliConnected)
       
   143         {
       
   144         iShutdown.Start();
       
   145         }
       
   146     }
       
   147 
       
   148 
       
   149 
       
   150 
       
   151 
       
   152 
       
   153 
       
   154 
       
   155 
       
   156 
       
   157 
       
   158 
       
   159 
       
   160 
       
   161 
       
   162 
       
   163 
       
   164 
       
   165 
       
   166 
       
   167 
       
   168 
       
   169 
       
   170 
       
   171 
       
   172 CMemSpyEngineSession::CMemSpyEngineSession( CMemSpyEngine& aEngine )
       
   173 :   iEngine( aEngine )
       
   174     {
       
   175     }
       
   176 
       
   177 
       
   178 CMemSpyEngineSession::~CMemSpyEngineSession()
       
   179     {
       
   180 #ifdef _DEBUG
       
   181     TPtrC pThreadName( KNullDesC );
       
   182     if  ( iClientThreadName )
       
   183         {
       
   184         pThreadName.Set( *iClientThreadName );
       
   185         }
       
   186 
       
   187     RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::~CMemSpyEngineSession() - DEAD SESSION - this: 0x%08x, id: %4d, name: %S"), this, iClientThreadId, iClientThreadName );
       
   188 #endif
       
   189 
       
   190     delete iClientThreadName;
       
   191     
       
   192     Server().DropSession(iIsCliRequest);
       
   193     }
       
   194 
       
   195 
       
   196 void CMemSpyEngineSession::ConstructL( const RMessage2& aMessage )
       
   197     {
       
   198 	RThread thread;
       
   199     const TInt error = aMessage.Client( thread );
       
   200     CleanupClosePushL( thread );
       
   201 
       
   202     TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::ConstructL() - this: 0x%08x - opening client thread - err: %d", this, error ) );
       
   203 
       
   204     User::LeaveIfError( error );
       
   205 
       
   206     const TFullName threadName( thread.FullName() );
       
   207     iClientThreadName = threadName.AllocL();
       
   208     iClientThreadId = thread.Id();
       
   209 
       
   210     CleanupStack::PopAndDestroy( &thread );
       
   211     
       
   212     const TUid KCliUid3 = { 0x2002129D };
       
   213     iIsCliRequest = aMessage.SecureId() == TSecureId(KCliUid3);
       
   214     
       
   215     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ConstructL() - NEW SESSION - this: 0x%08x, id: %4d, client: %S"), this, iClientThreadId, iClientThreadName ) );
       
   216     }
       
   217 
       
   218 void CMemSpyEngineSession::CreateL()
       
   219     {   
       
   220     Server().AddSession(iIsCliRequest);
       
   221     }
       
   222 
       
   223 CMemSpyEngineSession* CMemSpyEngineSession::NewL( CMemSpyEngine& aEngine, const RMessage2& aMessage )
       
   224     {
       
   225     CMemSpyEngineSession* self = new(ELeave) CMemSpyEngineSession( aEngine );
       
   226     CleanupStack::PushL( self );
       
   227     self->ConstructL( aMessage );
       
   228     CleanupStack::Pop( self );
       
   229     return self;
       
   230     }
       
   231 
       
   232 
       
   233 void CMemSpyEngineSession::ServiceL( const RMessage2& aMessage )
       
   234     {
       
   235     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - START - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
       
   236 
       
   237     TRAPD( error, DoServiceL( aMessage ) );
       
   238     if  ( error != KErrNone )
       
   239         {
       
   240         RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - SERVICE ERROR - this: 0x%08x, fn: %d, err: %d, client: %S"), this, aMessage.Function(), error, iClientThreadName );
       
   241         }
       
   242     
       
   243     if ((aMessage.Function() & KMemSpyOpFlagsAsyncOperation) == 0 || error != KErrNone)
       
   244     	{
       
   245 		aMessage.Complete( error );
       
   246     	}
       
   247 
       
   248     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
       
   249 	}
       
   250 
       
   251 // ---------------------------------------------------------
       
   252 // DoServiceL( const RMessage2& aMessage )
       
   253 // ---------------------------------------------------------
       
   254 //
       
   255 void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
       
   256 	{
       
   257 	TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
       
   258 	if (function >= EMemSpyClientServerOpMarkerUiFirst && 
       
   259 		function < EMemSpyClientServerOpMarkerUiLast)
       
   260 		
       
   261 		DoUiServiceL(aMessage);
       
   262 	else
       
   263 		DoCmdServiceL(aMessage);
       
   264 	}
       
   265 // ---------------------------------------------------------
       
   266 // DoUiServiceL( const RMessage2& aMessage )
       
   267 // ---------------------------------------------------------
       
   268 //
       
   269 void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
       
   270     {
       
   271 	switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
       
   272 		{
       
   273 		case EMemSpyClientServerOpGetProcessCount:
       
   274 			{
       
   275 			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
       
   276 			break;
       
   277 			}
       
   278 		case EMemSpyClientServerOpGetProcesses:
       
   279 			{
       
   280 			CMemSpyEngineObjectContainer& list = iEngine.Container();
       
   281 			
       
   282 			TPckgBuf<TInt> a0;
       
   283 			aMessage.ReadL(0, a0);
       
   284 			TInt realCount = Min(a0(), list.Count());
       
   285 			
       
   286 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
       
   287 				{
       
   288 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   289 				TMemSpyProcessData data;
       
   290 				data.iIsDead = process.IsDead();
       
   291 				data.iId = process.Id();
       
   292 				data.iName.Copy(process.Name().Left(KMaxFullName));
       
   293 				data.iThreadCount = process.Count();
       
   294 				data.iPriority = process.Priority();
       
   295 				data.iExitType = process.ExitType();
       
   296 				data.iExitReason = process.ExitReason();
       
   297 				data.iExitCategory = process.ExitCategory();
       
   298 				data.iSID = process.SID();
       
   299 				
       
   300 				TPckgBuf<TMemSpyProcessData> buffer(data);
       
   301 				aMessage.WriteL(1, buffer, offset);
       
   302 				}
       
   303 			
       
   304 			a0 = list.Count();
       
   305 			aMessage.WriteL(0, a0);
       
   306 
       
   307 			break;
       
   308 			}
       
   309 		case EMemSpyClienServerOpGetProcessIdByName:
       
   310 			{
       
   311 			TFullName processName;
       
   312 			aMessage.ReadL(0, processName);
       
   313 			
       
   314 			TBool found(EFalse);
       
   315 			
       
   316 			for (TInt i=0; i<iEngine.Container().Count(); i++)
       
   317 				{
       
   318 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   319 				if (process.Name().FindF(processName) >= 0)
       
   320 					{
       
   321 					found = ETrue;
       
   322 					TPckgBuf<TProcessId> procId(process.Id());
       
   323 					aMessage.WriteL(1, procId);
       
   324 					}
       
   325 				}
       
   326 			
       
   327 			if (!found)
       
   328 				{
       
   329 				User::Leave(KErrNotFound);
       
   330 				}
       
   331 			
       
   332 			break;
       
   333 			}
       
   334 		case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
       
   335 			{
       
   336 			TBool ret = EFalse;
       
   337 			TPckgBuf<TProcessId> id;
       
   338 			aMessage.ReadL( 0, id );
       
   339 			
       
   340 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   341 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   342 			
       
   343 			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
       
   344 				{
       
   345 				ret = ETrue;
       
   346 				}
       
   347 			TPckgBuf<TBool> retBuf( ret );
       
   348 			aMessage.WriteL( 1, retBuf );
       
   349 			
       
   350 			break;
       
   351 			}
       
   352 		case EMemSpyClientServerOpEndProcess:
       
   353 			{
       
   354 			TPckgBuf<TProcessId> id;
       
   355 			aMessage.ReadL( 0, id );
       
   356 			TPckgBuf<TMemSpyEndType> type;
       
   357 			aMessage.ReadL( 1, type );
       
   358 					
       
   359 			CMemSpyEngineObjectContainer& container = iEngine.Container();			
       
   360 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   361 									
       
   362 			switch ( type() )
       
   363 				{
       
   364 				case ETerminate:
       
   365 					{
       
   366 					process.TerminateL();
       
   367 					break;
       
   368 					}
       
   369 				case EPanic:
       
   370 					{
       
   371 					process.PanicL();
       
   372 					break;
       
   373 					}
       
   374 				case EKill:
       
   375 					{
       
   376 					process.KillL();
       
   377 					break;
       
   378 					}
       
   379 				}																
       
   380 			break;
       
   381 			}
       
   382 		case EMemSpyClientServerOpSwitchToProcess:
       
   383 			{/*
       
   384 			TInt wgCount;
       
   385 			RWsSession wsSession;
       
   386 			User::LeaveIfError( wsSession.Connect() );
       
   387 			CleanupClosePushL( wsSession );
       
   388 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   389 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   390 			CleanupClosePushL( wgArray );
       
   391 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   392 			TApaTask task( wsSession );
       
   393 			TBool brought( EFalse );
       
   394 			TInt wgId( KErrNotFound );
       
   395 			TThreadId threadId;
       
   396 			
       
   397 			TPckgBuf<TProcessId> id;
       
   398 			aMessage.ReadL( 0, id );
       
   399 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   400 			CMemSpyProcess& process = container.ProcessByIdL( id() );
       
   401 			
       
   402 			// loop trough threads in a process
       
   403 			for ( TInt i = 0; i < process.MdcaCount(); i++ )
       
   404 				{
       
   405 				TInt wgCountLocal = wgCount;
       
   406 							
       
   407 				// loop trough all window groups and see if a thread id matches
       
   408 				while( !brought && wgCountLocal-- )
       
   409 					{
       
   410 					wgId = wgArray[wgCountLocal].iId;
       
   411 					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   412 					if ( threadId == process.At( i ).Id() )
       
   413 						{
       
   414 						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   415 						task.SetWgId( wgId );
       
   416 						if ( !wgName->Hidden() && task.Exists() )
       
   417 							{
       
   418 							task.BringToForeground();
       
   419 							brought = ETrue;                        
       
   420 							}
       
   421 						CleanupStack::PopAndDestroy( wgName );
       
   422 						}
       
   423 					}
       
   424 				}
       
   425 			
       
   426 			TPckgBuf<TBool> ret( brought );
       
   427 			aMessage.WriteL( 1, ret );
       
   428 			
       
   429 			break;*/
       
   430 			}
       
   431 		case EMemSpyClientServerOpGetThreadCount:
       
   432 			{
       
   433 			TPckgBuf<TProcessId> pid;
       
   434 			aMessage.ReadL(1, pid);
       
   435 			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
       
   436 			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
       
   437 			break;
       
   438 			}
       
   439 		case EMemSpyClientServerOpGetThreads:
       
   440 			{
       
   441 			TPckgBuf<TProcessId> pid;
       
   442 			aMessage.ReadL(2, pid);
       
   443 			
       
   444 			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
       
   445 			
       
   446 			TPckgBuf<TInt> a0;
       
   447 			aMessage.ReadL(0, a0);
       
   448 			TInt realCount = Min(a0(), list.Count());
       
   449 						
       
   450 			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
       
   451 				{
       
   452 				CMemSpyThread& thread = list.At(i);
       
   453 				
       
   454 				TMemSpyThreadData data;
       
   455 				data.iId = thread.Id();
       
   456 				data.iName.Copy(thread.Name().Left(KMaxFullName));
       
   457 				data.iThreadPriority = thread.Priority();
       
   458 				
       
   459 				TPckgBuf<TMemSpyThreadData> buffer(data);
       
   460 				aMessage.WriteL(1, buffer, offset);
       
   461 				}
       
   462 			
       
   463 			a0 = list.Count();
       
   464 			aMessage.WriteL(0, a0);
       
   465 
       
   466 			break;
       
   467 			}
       
   468 		case EMemSpyClientServerOpSetThreadPriority:
       
   469 			{
       
   470 			TPckgBuf<TThreadId> tid;
       
   471 			TPckgBuf<TInt> priority;
       
   472 			aMessage.ReadL(0, tid);
       
   473 			aMessage.ReadL(1, priority);
       
   474 			
       
   475 			CMemSpyProcess* process = NULL;
       
   476 			CMemSpyThread* thread = NULL; 
       
   477 			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
       
   478 			
       
   479 			if (thread)
       
   480 				{				
       
   481 				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));
       
   482 				}					
       
   483 			break;
       
   484 			}
       
   485 		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
       
   486 			{
       
   487 			TPckgBuf<TThreadId> id;
       
   488 			aMessage.ReadL( 0, id );
       
   489 			
       
   490 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   491 			CMemSpyProcess* process = NULL;
       
   492 			CMemSpyThread* thread = NULL; 
       
   493 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   494 			
       
   495 			TBool ret = thread && ( thread->IsSystemPermanent() || thread->IsSystemCritical() );
       
   496 			
       
   497 			TPckgBuf<TBool> retBuf( ret );
       
   498 			aMessage.WriteL( 1, retBuf );
       
   499 							
       
   500 			break;
       
   501 			}
       
   502 		case EMemSpyClientServerOpEndThread:
       
   503 			{
       
   504 			TPckgBuf<TThreadId> id;
       
   505 			aMessage.ReadL( 0, id );
       
   506 			TPckgBuf<TMemSpyEndType> type;
       
   507 			aMessage.ReadL( 1, type );
       
   508 			
       
   509 			CMemSpyEngineObjectContainer& container = iEngine.Container();
       
   510 			CMemSpyProcess* process = NULL;
       
   511 			CMemSpyThread* thread = NULL; 
       
   512 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   513 			
       
   514 			if( thread )
       
   515 				{
       
   516 				switch ( type() )
       
   517 					{
       
   518 					case ETerminate:
       
   519 						{
       
   520 						thread->TerminateL();
       
   521 						break;
       
   522 						}
       
   523 					case EPanic:
       
   524 						{
       
   525 						thread->PanicL();
       
   526 						break;
       
   527 						}
       
   528 					case EKill:
       
   529 						{
       
   530 						thread->KillL();
       
   531 						break;
       
   532 						}
       
   533 					}				
       
   534 				}			
       
   535 			break;
       
   536 			}
       
   537 		case EMemSpyClientServerOpSwitchToThread:
       
   538 			{
       
   539 			TInt wgCount;
       
   540 			RWsSession wsSession;
       
   541 			User::LeaveIfError( wsSession.Connect() );
       
   542 			CleanupClosePushL( wsSession );
       
   543 			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
       
   544 			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
       
   545 			CleanupClosePushL( wgArray );
       
   546 			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
       
   547 			TApaTask task( wsSession );
       
   548 			TBool brought( EFalse );
       
   549 			TInt wgId( KErrNotFound );
       
   550 			TThreadId threadId;
       
   551 					
       
   552 			TPckgBuf<TThreadId> id;
       
   553 			aMessage.ReadL( 0, id );
       
   554 					
       
   555 			// loop trough all window groups and see if a thread id matches
       
   556 			while( !brought && wgCount-- )
       
   557 				{
       
   558 				wgId = wgArray[wgCount].iId;
       
   559 				User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
       
   560 				if ( threadId == id() )
       
   561 					{
       
   562 					CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
       
   563 					task.SetWgId( wgId );
       
   564 					if ( !wgName->Hidden() && task.Exists() )
       
   565 						{
       
   566 						task.BringToForeground();
       
   567 						brought = ETrue;                        
       
   568 						}
       
   569 					CleanupStack::PopAndDestroy( wgName );
       
   570 					}
       
   571 				}			
       
   572 			TPckgBuf<TBool> ret( brought );
       
   573 			aMessage.WriteL( 1, ret );															
       
   574 					
       
   575 			break;
       
   576 			}		
       
   577 		case EMemSpyClientServerOpGetInfoItemType:
       
   578 			{
       
   579 			
       
   580 			TPckgBuf<TInt> index;
       
   581 			aMessage.ReadL( 0, index );			
       
   582 			TPckgBuf<TThreadId> id;
       
   583 			aMessage.ReadL( 1, id);
       
   584 								
       
   585 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   586 			CMemSpyProcess* process = NULL; //not needed
       
   587 			CMemSpyThread* thread = NULL; 
       
   588 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
       
   589 		            
       
   590 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
       
   591 			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
       
   592 			
       
   593 			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
       
   594 			aMessage.WriteL( 2, ret );			
       
   595 			
       
   596 			break;
       
   597 			}
       
   598 		case EMemSpyClientServerOpGetThreadInfoItemsCount:
       
   599 			{
       
   600 			TPckgBuf<TThreadId> id;
       
   601 			aMessage.ReadL( 0, id );
       
   602 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   603 			aMessage.ReadL( 1, type );					 
       
   604 			
       
   605 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   606 			CMemSpyProcess* process = NULL;
       
   607 			CMemSpyThread* thread = NULL; 
       
   608 			
       
   609 			container.ProcessAndThreadByThreadId( id(), process, thread );
       
   610 			
       
   611 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
       
   612 								
       
   613 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
       
   614 				    
       
   615 			TInt count = threadInfoItemBase.MdcaCount();		    
       
   616 			TPckgBuf<TInt> tempret( count );
       
   617 			aMessage.WriteL( 2, tempret );
       
   618 		
       
   619 			break;
       
   620 			}		
       
   621 		case EMemSpyClientServerOpGetThreadInfoItems:
       
   622 			{
       
   623 			TPckgBuf<TInt> count;
       
   624 			aMessage.ReadL( 0, count );						
       
   625 			TPckgBuf<TThreadId> id;
       
   626 			aMessage.ReadL( 1, id );
       
   627 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   628 			aMessage.ReadL( 2, type );			
       
   629 			
       
   630 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   631 			CMemSpyProcess* process = NULL;
       
   632 			CMemSpyThread* thread = NULL; 
       
   633 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   634 							  
       
   635 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   636 
       
   637 			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
       
   638 			
       
   639 			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
       
   640 								
       
   641 			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
       
   642 				{
       
   643 				TMemSpyThreadInfoItemData data;
       
   644 				
       
   645 				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
       
   646 				TInt tabPos = caption.Locate('\t');
       
   647 				if (tabPos != KErrNotFound)
       
   648 					caption.Set(caption.Left(tabPos));
       
   649 				
       
   650 				TPtrC value(threadInfoItemBase.MdcaPoint(i));
       
   651 				tabPos = value.LocateReverse('\t');
       
   652 				if (tabPos != KErrNotFound)
       
   653 					value.Set(value.Mid(tabPos + 1));
       
   654 												
       
   655 				data.iCaption.Copy( caption.Left(64) );
       
   656 				data.iValue.Copy( value.Left(32) );
       
   657 							
       
   658 				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
       
   659 				aMessage.WriteL(3, buffer, offset);				
       
   660 				}			
       
   661 			aMessage.WriteL(0, count);
       
   662 					
       
   663 			break;
       
   664 			}
       
   665 		// --- KernelObjects related functions ---
       
   666 		case EMemSpyClientServerOpGetKernelObjectCount:
       
   667 			{
       
   668 			TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
       
   669 			TPckgBuf<TInt> ret( iCount );
       
   670 			aMessage.WriteL(0, ret);			
       
   671 			break;
       
   672 			}
       
   673 		case EMemSpyClientServerOpGetKernelObjects:
       
   674 			{
       
   675 			TPckgBuf<TInt> count;
       
   676 			aMessage.ReadL(0, count);
       
   677 			
       
   678 			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
       
   679 			CleanupStack::PushL( model );
       
   680 			
       
   681 			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
       
   682 				{
       
   683 				TMemSpyKernelObjectData data;
       
   684 				
       
   685 				TPtrC name(model->At(i).Name().Mid(1));
       
   686 				TInt tabPos = name.Locate('\t');
       
   687 				if (tabPos != KErrNotFound)
       
   688 					name.Set(name.Left(tabPos));
       
   689 												
       
   690 				data.iName.Copy(name);
       
   691 				data.iType = model->At(i).Type();
       
   692 				data.iCount = model->At(i).Count();											
       
   693 				data.iSize = model->At(i).Count() * model->At(i).Count();
       
   694 
       
   695 				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
       
   696 				aMessage.WriteL(1, buffer, offset);
       
   697 				}			
       
   698 			aMessage.WriteL(0, count);
       
   699 			CleanupStack::PopAndDestroy( model );
       
   700 			break;
       
   701 			}
       
   702 		case EMemSpyClientServerOpGetKernelObjectItemCount:
       
   703 			{
       
   704 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   705 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   706 			TMemSpyDriverContainerType type = tempType();
       
   707 			
       
   708 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   709 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
       
   710 			CleanupStack::PushL( iObjectList );
       
   711 			
       
   712 			TInt count = iObjectList->Count();
       
   713 			TPckgBuf<TInt> ret( count );
       
   714 			aMessage.WriteL( 0, ret );
       
   715 			
       
   716 			CleanupStack::PopAndDestroy( iObjectList );
       
   717 			break;
       
   718 			}
       
   719 		case EMemSpyClientServerOpGetKernelObjectItems:
       
   720 			{
       
   721 			TPckgBuf<TInt> count;
       
   722 			TPckgBuf<TMemSpyDriverContainerType> tempType;
       
   723 			aMessage.ReadL( 0, count ); //get count of items
       
   724 			aMessage.ReadL(1, tempType); //get type of kernel object
       
   725 			TInt c = count();
       
   726 						
       
   727 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   728 			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
       
   729 			CleanupStack::PushL( iObjectList );
       
   730 			
       
   731 			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
       
   732 				{
       
   733 				TMemSpyDriverHandleInfoGeneric data;								
       
   734 															
       
   735 				data = iObjectList->At( i );
       
   736 				
       
   737 				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
       
   738 				aMessage.WriteL(2, buffer, offset);
       
   739 				}			
       
   740 			
       
   741 			CleanupStack::PopAndDestroy( iObjectList );			
       
   742 			break;
       
   743 			}
       
   744 			
       
   745 		case EMemSpyClientServerOpOutputAllContainerContents:
       
   746 			{
       
   747 			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
       
   748 			CMemSpyEngineGenericKernelObjectContainer* model = kernelContainerManager.ObjectsAllL();
       
   749 			
       
   750 			model->OutputL( iEngine.Sink() );
       
   751 
       
   752 			break;
       
   753 			}
       
   754 			
       
   755 		case EMemSpyClientServerOpDumpKernelHeap:
       
   756 			{
       
   757 		    iEngine.HelperHeap().OutputHeapDataKernelL();
       
   758 			
       
   759 			break;
       
   760 			}
       
   761 			
       
   762 		case EMemSpyClientServerOpOutputInfoHandles:
       
   763 			{
       
   764 			TPckgBuf<TThreadId> id;
       
   765 			aMessage.ReadL(0, id);
       
   766 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   767 			CMemSpyProcess* process = NULL;
       
   768 			CMemSpyThread* thread = NULL; 
       
   769 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   770 										  
       
   771 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();
       
   772 			
       
   773 			threadInfoContainer.PrintL();
       
   774 			
       
   775 			break;
       
   776 			}
       
   777 			
       
   778 		case EMemSpyClientServerOpOutputAOList:
       
   779 			{
       
   780 			TPckgBuf<TThreadId> id;
       
   781 			TPckgBuf<TMemSpyThreadInfoItemType> type;
       
   782 			aMessage.ReadL(0, id);
       
   783 			aMessage.ReadL(1, type);
       
   784 			
       
   785 			CMemSpyEngineObjectContainer& container = iEngine.Container();            
       
   786 			CMemSpyProcess* process = NULL;
       
   787 			CMemSpyThread* thread = NULL; 
       
   788 			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
       
   789 										  
       
   790 			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
       
   791 
       
   792 			CMemSpyThreadInfoItemBase* threadInfoItem = &threadInfoContainer.Item( type() );
       
   793 						
       
   794 			CMemSpyThreadInfoActiveObjects* activeObjectArray = static_cast< CMemSpyThreadInfoActiveObjects* >( threadInfoItem );			
       
   795 						
       
   796 		    // Begin a new data stream
       
   797 		    _LIT( KMemSpyContext, "Active Object List - " );
       
   798 		    _LIT( KMemSpyFolder, "Active Objects" );
       
   799 		    iEngine.Sink().DataStreamBeginL( KMemSpyContext, KMemSpyFolder );
       
   800 		    		    
       
   801 		    // Set prefix for overall listing
       
   802 		    iEngine.Sink().OutputPrefixSetLC( KMemSpyContext );
       
   803 
       
   804 		    // Create header
       
   805 		    CMemSpyEngineActiveObjectArray::OutputDataColumnsL( iEngine );
       
   806 		    
       
   807 		    // List items
       
   808 		    const TInt count = activeObjectArray->Array().Count();
       
   809 		    for(TInt i=0; i<count; i++)
       
   810 		        {
       
   811 		        const CMemSpyEngineActiveObject& object = activeObjectArray->Array().At( i );
       
   812 		        //
       
   813 		        object.OutputDataL( iEngine );
       
   814 		        }
       
   815 
       
   816 		    // Tidy up
       
   817 		    CleanupStack::PopAndDestroy(); // prefix
       
   818 
       
   819 		    // End data stream		    		    
       
   820 		    iEngine.Sink().DataStreamEndL();		    
       
   821 			
       
   822 			break;
       
   823 			}
       
   824 			
       
   825 		// --- Kernel Heap related functions ---
       
   826 		case EMemSpyClientServerOpGetHeap:
       
   827 			{
       
   828 			TMemSpyHeapInfo heapInfo;			
       
   829 			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
       
   830 			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
       
   831 			
       
   832 			TPckgBuf<TMemSpyHeapData> buffer(data);
       
   833 			aMessage.WriteL(0, buffer);
       
   834 			
       
   835 			break;
       
   836 			}
       
   837 		
       
   838 		case EMemSpyClientServerOpGetMemoryTrackingCycleCount:
       
   839 			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.HelperSysMemTracker().CompletedCycles().Count()));
       
   840 			break;
       
   841 			
       
   842 		case EMemSpyClientServerOpGetMemoryTrackingCycles:
       
   843 			{
       
   844 			const RPointerArray<CMemSpyEngineHelperSysMemTrackerCycle>& list = iEngine.HelperSysMemTracker().CompletedCycles();
       
   845 
       
   846 			TPckgBuf<TInt> a0;
       
   847 			aMessage.ReadL(0, a0);
       
   848 			TInt realCount = Min(a0(), list.Count());
       
   849 			
       
   850 			for (TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyMemoryTrackingCycleData))
       
   851 				{
       
   852 				CMemSpyProcess& process = iEngine.Container().At(i);
       
   853 				TMemSpyMemoryTrackingCycleData data;
       
   854 				data.iCycleNumber = list[i]->CycleNumber();
       
   855 				data.iCaption.Copy(list[i]->Caption().Left(KMaxFullName));
       
   856 				data.iTime = list[i]->Time();
       
   857 				data.iFreeMemory = list[i]->MemoryFree();
       
   858 				data.iMemoryDelta = list[i]->MemoryDelta();
       
   859 				data.iPreviousCycleDiff = list[i]->MemoryFreePreviousCycle();
       
   860 				
       
   861 				TPckgBuf<TMemSpyMemoryTrackingCycleData> buffer(data);
       
   862 				aMessage.WriteL(1, buffer, offset);
       
   863 				}
       
   864 			
       
   865 			a0 = list.Count();
       
   866 			aMessage.WriteL(0, a0);
       
   867 
       
   868 		break;
       
   869 		}
       
   870 	case EMemSpyClientServerOpIsSwmtRunning:
       
   871 		{
       
   872 		TPckgBuf<TBool> running(iEngine.HelperSysMemTracker().IsActive());
       
   873 		aMessage.WriteL(0, running);
       
   874 		break;
       
   875 		}
       
   876 			
       
   877 		
       
   878 	case EMemSpyClientServerOpNotifyDeviceWideOperationProgress:
       
   879 		{
       
   880 		if (!Server().CurrentOperationTracker())
       
   881 			{
       
   882 			User::Leave(KErrNotReady);
       
   883 			}
       
   884 		
       
   885 		Server().CurrentOperationTracker()->AddNotificationL(aMessage);
       
   886 		break;
       
   887 		}
       
   888 		
       
   889 	case EMemSpyClientServerOpCancelDeviceWideOperation:
       
   890 		if (!Server().CurrentOperationTracker())
       
   891 			{
       
   892 			User::Leave(KErrNotReady);
       
   893 			}
       
   894 		
       
   895 		Server().CurrentOperationTracker()->Cancel();
       
   896 		break;
       
   897 		}
       
   898     }
       
   899 
       
   900 // ---------------------------------------------------------
       
   901 // DoCmdServiceL( const RMessage2& aMessage )
       
   902 // ---------------------------------------------------------
       
   903 //
       
   904 void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
       
   905     {
       
   906     TInt error = KErrNone;
       
   907 
       
   908     // Check function attributes
       
   909     const TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
       
   910     const TInt argSpec = aMessage.Function() & KMemSpyOpFlagsInclusionMask;
       
   911     const TBool byThreadId = ( argSpec == KMemSpyOpFlagsIncludesThreadId );
       
   912     const TBool byThreadName = ( argSpec == KMemSpyOpFlagsIncludesThreadName );
       
   913 
       
   914     TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - START - unmodified function: 0x%08x, opCode: %d [TID: %d, TN: %d]", aMessage.Function(), function, byThreadId, byThreadName ) );
       
   915 
       
   916     // Check function is supported and argument combination is valid
       
   917     error = ValidateFunction( function, byThreadId, byThreadName );
       
   918     TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - validation result: %d", error ) );
       
   919     
       
   920     // Process function request
       
   921     if  ( error == KErrNone )
       
   922         {
       
   923         if  ( byThreadId )
       
   924             {
       
   925             TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - [TID] thread-specific..." ) );
       
   926             
       
   927             const TThreadId threadId( aMessage.Int0() );
       
   928             HandleThreadSpecificOpL( function, threadId );
       
   929             }
       
   930         else if ( byThreadName )
       
   931             {
       
   932             TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - [TN] thread-specific..." ) );
       
   933 
       
   934             error = aMessage.GetDesLength( 0 /*slot 0*/ );
       
   935         
       
   936             if  ( error > 0 && error <= KMaxFullName )
       
   937                 {
       
   938                 TFullName* threadName = new(ELeave) TFullName();
       
   939                 CleanupStack::PushL( threadName );
       
   940                 aMessage.ReadL( 0, *threadName );
       
   941                 HandleThreadSpecificOpL( function, *threadName );
       
   942                 CleanupStack::PopAndDestroy( threadName );
       
   943                 }
       
   944             else
       
   945                 {
       
   946                 error = KErrArgument;
       
   947                 }
       
   948             }
       
   949         else
       
   950             {
       
   951             TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - thread-agnostic..." ) );
       
   952 
       
   953             HandleThreadAgnosticOpL( function, aMessage );
       
   954             }
       
   955         }
       
   956 
       
   957     User::LeaveIfError( error );
       
   958 
       
   959     TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::DoServiceL() - END" ) );
       
   960     }
       
   961 
       
   962 
       
   963 
       
   964 TInt CMemSpyEngineSession::ValidateFunction( TInt aFunction, TBool aIncludesThreadId, TBool aIncludesThreadName )
       
   965     {
       
   966     TInt err = KErrNotSupported;
       
   967     
       
   968     // Check the operation is within op-code range
       
   969     if  ( aFunction >= EMemSpyClientServerOpMarkerFirst && aFunction < EMemSpyClientServerOpMarkerLast )
       
   970         {
       
   971         // Check the operation doesn't include unnecessary or not supported information
       
   972         const TBool includesThreadIdentifier = ( aIncludesThreadId || aIncludesThreadName );
       
   973         if  ( includesThreadIdentifier && aFunction >= EMemSpyClientServerOpMarkerThreadAgnosticFirst )
       
   974             {
       
   975             // Passing a thread identifier to a thread agnostic operation
       
   976             err = KErrArgument;
       
   977             }
       
   978         else
       
   979             {
       
   980             err = KErrNone;
       
   981             }
       
   982         }
       
   983     //
       
   984     if  ( err != KErrNone )
       
   985         {
       
   986         RDebug::Printf( "[MemSpy] CMemSpyEngineSession::ValidateFunction() - function request did not validate - [withId: %d, withName: %d]", aIncludesThreadId, aIncludesThreadName );
       
   987         }
       
   988     //
       
   989     return err;
       
   990     }
       
   991 
       
   992 
       
   993 void CMemSpyEngineSession::HandleThreadSpecificOpL( TInt aFunction, const TThreadId& aThreadId )
       
   994     {
       
   995     TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadId: %d", aFunction, (TUint) aThreadId ) );
       
   996 
       
   997     ASSERT( (TUint) aThreadId != 0 );
       
   998     TInt error = KErrNone;
       
   999 
       
  1000     // Check if its a kernel thread identifier
       
  1001     const TBool isKernel = ( static_cast<TUint32>( aThreadId ) == KMemSpyClientServerThreadIdKernel );
       
  1002 
       
  1003     // Treat as thread specific operation
       
  1004     CMemSpyProcess* process = NULL;
       
  1005     CMemSpyThread* thread = NULL;
       
  1006     if  ( !isKernel )
       
  1007         {
       
  1008         error = iEngine.Container().ProcessAndThreadByThreadId( aThreadId, process, thread );
       
  1009         TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - search result: %d, proc: 0x%08x, thread: 0x%08x", error, process, thread ) );
       
  1010         }
       
  1011     else
       
  1012         {
       
  1013         // Kernel is only supported for a couple of operations
       
  1014         if  ( aFunction == EMemSpyClientServerOpHeapInfo || aFunction == EMemSpyClientServerOpHeapData )
       
  1015             {
       
  1016             }
       
  1017         else
       
  1018             {
       
  1019             TRACE( RDebug::Printf( "[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - trying to call unsupported function for kernel thread!" ) );
       
  1020             error = KErrArgument;
       
  1021             }
       
  1022         }
       
  1023 
       
  1024     // Must be no error so far and we must have a valid thread & process when performing a non-kernel op
       
  1025     // or then if we are performing a kernel op, we don't need the thread or process.
       
  1026     if  ( error == KErrNone && ( ( thread && process && !isKernel ) || ( isKernel ) ) )
       
  1027         {
       
  1028 #ifdef _DEBUG
       
  1029         if  ( thread )
       
  1030             {
       
  1031             HBufC* threadName = thread->FullName().AllocLC();
       
  1032             _LIT( KTrace2, "[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - thread: %S" );
       
  1033             RDebug::Print( KTrace2, threadName );
       
  1034             CleanupStack::PopAndDestroy( threadName );
       
  1035             }
       
  1036         else if ( isKernel )
       
  1037             {
       
  1038             _LIT( KTrace2, "[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - thread: Kernel" );
       
  1039             RDebug::Print( KTrace2 );
       
  1040             }
       
  1041 #endif
       
  1042 
       
  1043         // Got a valid thread object - now work out which operation to perform...
       
  1044         switch( aFunction )
       
  1045             {
       
  1046         case EMemSpyClientServerOpSummaryInfo:
       
  1047             iEngine.HelperProcess().OutputProcessInfoL( *process );
       
  1048             break;
       
  1049         case EMemSpyClientServerOpSummaryInfoDetailed:
       
  1050             iEngine.HelperProcess().OutputProcessInfoDetailedL( *process );
       
  1051             break;
       
  1052         case EMemSpyClientServerOpHeapInfo:
       
  1053             if  ( isKernel )
       
  1054                 {
       
  1055                 iEngine.HelperHeap().OutputHeapInfoKernelL();
       
  1056                 }
       
  1057             else
       
  1058                 {
       
  1059                 iEngine.HelperHeap().OutputHeapInfoUserL( *thread );
       
  1060                 }
       
  1061             break;
       
  1062         case EMemSpyClientServerOpHeapCellListing:
       
  1063             iEngine.HelperHeap().OutputCellListingUserL( *thread );
       
  1064             break;
       
  1065         case EMemSpyClientServerOpHeapData:
       
  1066             if  ( isKernel )
       
  1067                 {
       
  1068                 iEngine.HelperHeap().OutputHeapDataKernelL();
       
  1069                 }
       
  1070             else
       
  1071                 {
       
  1072                 iEngine.HelperHeap().OutputHeapDataUserL( *thread );
       
  1073                 }
       
  1074             break;
       
  1075         case EMemSpyClientServerOpStackInfo:
       
  1076             iEngine.HelperStack().OutputStackInfoL( *thread );
       
  1077             break;
       
  1078         case EMemSpyClientServerOpStackDataUser:
       
  1079             iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainUser, EFalse );
       
  1080             break;
       
  1081         case EMemSpyClientServerOpStackDataKernel:
       
  1082             iEngine.HelperStack().OutputStackDataL( *thread, EMemSpyDriverDomainKernel, EFalse );
       
  1083             break;
       
  1084         case EMemSpyClientServerOpOpenFiles:
       
  1085             iEngine.HelperFileSystem().ListOpenFilesL( aThreadId );
       
  1086             break;
       
  1087 
       
  1088         default:
       
  1089             error = KErrNotSupported;
       
  1090             break;
       
  1091             }
       
  1092         }
       
  1093 
       
  1094     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadId: %d, error: %d", aFunction, (TUint) aThreadId, error ) );
       
  1095     User::LeaveIfError( error );
       
  1096     }
       
  1097 
       
  1098 
       
  1099 void CMemSpyEngineSession::HandleThreadSpecificOpL( TInt aFunction, const TDesC& aThreadName )
       
  1100     {
       
  1101     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - START - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
       
  1102     //
       
  1103     CMemSpyProcess* process = NULL;
       
  1104     CMemSpyThread* thread = NULL;
       
  1105     TInt error = iEngine.Container().ProcessAndThreadByPartialName( aThreadName, process, thread );
       
  1106     User::LeaveIfError( error );
       
  1107     //
       
  1108     const TThreadId threadId( thread->Id() );
       
  1109     HandleThreadSpecificOpL( aFunction, threadId );
       
  1110     //
       
  1111     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::HandleThreadSpecificOpL() - END - aFunction: %d, aThreadName: %S"), aFunction, &aThreadName ) );
       
  1112     }
       
  1113 
       
  1114 
       
  1115 void CMemSpyEngineSession::HandleThreadAgnosticOpL( TInt aFunction, const RMessage2& aMessage )
       
  1116     {
       
  1117     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - START" ) );
       
  1118     
       
  1119     //
       
  1120     if  ( aFunction ==  EMemSpyClientServerOpHeapInfoCompact )
       
  1121         {
       
  1122         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfoCompact") );
       
  1123         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1124         	{
       
  1125 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceHeapInfoCompact, aMessage);
       
  1126         	}
       
  1127         else
       
  1128         	{
       
  1129 			iEngine.HelperHeap().OutputHeapInfoForDeviceL();
       
  1130         	}
       
  1131         }
       
  1132     else if ( aFunction ==  EMemSpyClientServerOpStackInfoCompact )
       
  1133         {
       
  1134         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfoCompact") );
       
  1135         if (aMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1136 			{
       
  1137 			StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EEntireDeviceStackInfoCompact, aMessage);
       
  1138 			}
       
  1139 		else
       
  1140 			{
       
  1141 			iEngine.HelperStack().OutputStackInfoForDeviceL();
       
  1142 			}
       
  1143         }
       
  1144     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart )
       
  1145         {
       
  1146         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStart") );
       
  1147         iEngine.HelperSysMemTracker().StartL();
       
  1148         }
       
  1149     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop )
       
  1150         {
       
  1151         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerStop") );
       
  1152         iEngine.HelperSysMemTracker().StopL();
       
  1153         }
       
  1154     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingReset )
       
  1155         {
       
  1156         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingReset") );
       
  1157         iEngine.HelperSysMemTracker().Reset();
       
  1158         }
       
  1159     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate )
       
  1160         {
       
  1161         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingForceUpdate") );
       
  1162         iEngine.HelperSysMemTracker().CheckForChangesNowL();
       
  1163         }
       
  1164     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet )
       
  1165         {
       
  1166         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingTimerPeriodSet") );
       
  1167         
       
  1168         // Get current config
       
  1169         TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1170         iEngine.HelperSysMemTracker().GetConfig( config );
       
  1171 
       
  1172         // Set new timer value
       
  1173         config.iTimerPeriod = aMessage.Int0();
       
  1174 
       
  1175         // And update config... which will leave if the config is invalid
       
  1176         iEngine.HelperSysMemTracker().SetConfigL( config );
       
  1177         }
       
  1178     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet )
       
  1179         {
       
  1180         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingCategoriesSet") );
       
  1181         // Get current config
       
  1182         TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1183         iEngine.HelperSysMemTracker().GetConfig( config );
       
  1184 
       
  1185         // Set new categories
       
  1186         config.iEnabledCategories = aMessage.Int0();
       
  1187 
       
  1188         // And update config... which will leave if the config is invalid
       
  1189         iEngine.HelperSysMemTracker().SetConfigL( config );
       
  1190         }
       
  1191     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet )
       
  1192         {
       
  1193         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSystemWideMemoryTrackingThreadNameFilterSet") );
       
  1194         // Get current config
       
  1195         TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1196         iEngine.HelperSysMemTracker().GetConfig( config );
       
  1197 
       
  1198         // Set new filter
       
  1199         RBuf buf;
       
  1200         buf.CleanupClosePushL();
       
  1201         TInt len = aMessage.GetDesLength( 0 );
       
  1202         if ( len > 0 )
       
  1203             {
       
  1204             buf.CreateL( len );
       
  1205             aMessage.ReadL( 0, buf, 0 );
       
  1206             config.iThreadNameFilter.Copy( buf );            
       
  1207             }
       
  1208         else
       
  1209             {
       
  1210             config.iThreadNameFilter.Zero();
       
  1211             }
       
  1212         CleanupStack::PopAndDestroy( &buf );
       
  1213 
       
  1214         // And update config... which will leave if the config is invalid
       
  1215         iEngine.HelperSysMemTracker().SetConfigL( config );
       
  1216         }
       
  1217     else if ( aFunction == EMemSpyClientServerOpSystemWideMemoryTrackingHeapDumpSet )
       
  1218         {
       
  1219         // Get current config
       
  1220         TMemSpyEngineHelperSysMemTrackerConfig config;
       
  1221         iEngine.HelperSysMemTracker().GetConfig( config );
       
  1222         
       
  1223         // Set new Heap Dump value
       
  1224         config.iDumpData = aMessage.Int0();
       
  1225         
       
  1226         // And update config... which will leave if the config is invalid
       
  1227         iEngine.HelperSysMemTracker().SetConfigL( config );
       
  1228         }
       
  1229     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkTrace )
       
  1230         {
       
  1231         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkTrace") );
       
  1232         iEngine.InstallDebugSinkL();
       
  1233         }
       
  1234     else if ( aFunction == EMemSpyClientServerOpSwitchOutputSinkFile )
       
  1235         {
       
  1236         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSwitchOutputSinkFile") );
       
  1237         // Read file name from message.
       
  1238         TFileName fileName;
       
  1239         RBuf buf;
       
  1240 		buf.CleanupClosePushL();
       
  1241 		
       
  1242 		TInt len = aMessage.GetDesLength( 0 );
       
  1243 		if ( len > 0 )
       
  1244 			{
       
  1245 			buf.CreateL( len );
       
  1246 			aMessage.ReadL( 0, buf, 0 );
       
  1247 			
       
  1248 			iEngine.InstallFileSinkL( buf );           
       
  1249 			}
       
  1250 		else
       
  1251 			{
       
  1252 			iEngine.InstallFileSinkL( KNullDesC );
       
  1253 			}
       
  1254 		
       
  1255 		CleanupStack::PopAndDestroy( &buf );
       
  1256         
       
  1257         }
       
  1258     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainer )
       
  1259         {
       
  1260         const TMemSpyDriverContainerType type = CMemSpyEngineHelperKernelContainers::MapToType( static_cast< TObjectType >( aMessage.Int0() ) );
       
  1261 
       
  1262         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainer - type: %d", type ) );
       
  1263 
       
  1264         CMemSpyEngineGenericKernelObjectList* model = iEngine.HelperKernelContainers().ObjectsForSpecificContainerL( type );
       
  1265         CleanupStack::PushL( model );
       
  1266         model->OutputL( iEngine.Sink() );
       
  1267         CleanupStack::PopAndDestroy( model );
       
  1268         }
       
  1269     else if ( aFunction == EMemSpyClientServerOpEnumerateKernelContainerAll )
       
  1270         {
       
  1271         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpEnumerateKernelContainerAll") );
       
  1272         CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL();
       
  1273         CleanupStack::PushL( model );
       
  1274         model->OutputL( iEngine.Sink() );
       
  1275         CleanupStack::PopAndDestroy( model );
       
  1276         }
       
  1277     else if ( aFunction == EMemSpyClientServerOpOpenFiles )
       
  1278         {
       
  1279         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpOpenFiles") );
       
  1280         iEngine.ListOpenFilesL();
       
  1281         }
       
  1282     else if ( aFunction == EMemSpyClientServerOpDisableAknIconCache )
       
  1283         {
       
  1284         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpDisableAknIconCache") );
       
  1285         iEngine.HelperRAM().SetAknIconCacheStatusL( EFalse );
       
  1286         }
       
  1287     else if ( aFunction == EMemSpyClientServerOpSummaryInfo )
       
  1288     	{
       
  1289 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfo") );
       
  1290 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralSummary, aMessage);
       
  1291     	}
       
  1292     else if ( aFunction == EMemSpyClientServerOpSummaryInfoDetailed )
       
  1293 		{
       
  1294 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpSummaryInfoDetailed") );
       
  1295 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityGeneralDetailed, aMessage);
       
  1296 		}
       
  1297     else if ( aFunction == EMemSpyClientServerOpHeapInfo )
       
  1298 		{
       
  1299 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapInfo") );
       
  1300 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapInfo, aMessage);
       
  1301 		}
       
  1302     else if ( aFunction == EMemSpyClientServerOpHeapCellListing )
       
  1303 		{
       
  1304 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapCellListing") );
       
  1305 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapCellListing, aMessage);
       
  1306 		}
       
  1307     else if ( aFunction == EMemSpyClientServerOpHeapData )
       
  1308 		{
       
  1309 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpHeapData") );
       
  1310 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityHeapData, aMessage);
       
  1311 		}
       
  1312     else if ( aFunction == EMemSpyClientServerOpStackInfo )
       
  1313 		{
       
  1314 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackInfo") );
       
  1315 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackInfo, aMessage);
       
  1316 		}
       
  1317     else if ( aFunction == EMemSpyClientServerOpStackDataUser )
       
  1318 		{
       
  1319 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataUser") );
       
  1320 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataUser, aMessage);
       
  1321 		}
       
  1322     else if ( aFunction == EMemSpyClientServerOpStackDataKernel )
       
  1323 		{
       
  1324 		TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - EMemSpyClientServerOpStackDataKernel") );
       
  1325 		StartDeviceWideOperationL(CMemSpyDeviceWideOperations::EPerEntityStackDataKernel, aMessage);
       
  1326 		}
       
  1327     else
       
  1328         {
       
  1329         TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - [device-wide operation] => invoking UI") );
       
  1330         iEngine.NotifyClientServerOperationRequestL( aFunction );
       
  1331         }
       
  1332     //
       
  1333     TRACE( RDebug::Printf("[MemSpy] CMemSpyEngineSession::HandleThreadAgnosticOpL() - END" ) );
       
  1334     }
       
  1335 
       
  1336 void CMemSpyEngineSession::StartDeviceWideOperationL(CMemSpyDeviceWideOperations::TOperation aOperation, const RMessage2& aMessage)
       
  1337 	{
       
  1338 	if (Server().CurrentOperationTracker())
       
  1339 		{
       
  1340 		User::Leave(KErrInUse);
       
  1341 		}
       
  1342 	
       
  1343 	Server().SetCurrentOperationTracker(CMemSpyDwOperationTracker::NewL(aOperation, aMessage, Server()));
       
  1344 	}
       
  1345 
       
  1346 
       
  1347 
       
  1348 
       
  1349 
       
  1350 
       
  1351 
       
  1352 
       
  1353 
       
  1354 CMemSpyDwOperationTracker* CMemSpyDwOperationTracker::NewL(CMemSpyDeviceWideOperations::TOperation aOperation, 
       
  1355 		const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer)
       
  1356 	{
       
  1357 	CMemSpyDwOperationTracker* self = new (ELeave) CMemSpyDwOperationTracker(aOperationMessage, aServer);
       
  1358 	CleanupStack::PushL( self );
       
  1359 	self->ConstructL(aOperation);
       
  1360 	CleanupStack::Pop( self );
       
  1361 	return self;
       
  1362 	}
       
  1363 	
       
  1364 CMemSpyDwOperationTracker::~CMemSpyDwOperationTracker()
       
  1365 	{
       
  1366 	delete iOperation;
       
  1367 	delete iPendingNotifications;
       
  1368 	}
       
  1369 
       
  1370 CMemSpyDwOperationTracker::CMemSpyDwOperationTracker(const RMessage2& aOperationMessage, CMemSpyEngineServer& aServer) : 
       
  1371 		iOperationMessage(aOperationMessage),
       
  1372 		iServer(aServer),
       
  1373 		iPendingNotifications(0),
       
  1374 		iOperation(0),
       
  1375 		iProgress(0)
       
  1376 	{
       
  1377 	}
       
  1378 
       
  1379 
       
  1380 void CMemSpyDwOperationTracker::ConstructL(CMemSpyDeviceWideOperations::TOperation aOperation)
       
  1381 	{
       
  1382 	iPendingNotifications = new (ELeave) CArrayFixFlat<RMessage2>(3);
       
  1383 	iOperation = CMemSpyDeviceWideOperations::NewL(iServer.Engine(), *this, aOperation);
       
  1384 	}
       
  1385 
       
  1386 void CMemSpyDwOperationTracker::AddNotificationL(const RMessage2& aMessage)
       
  1387 	{
       
  1388 	iPendingNotifications->AppendL(aMessage);
       
  1389 	}
       
  1390 
       
  1391 void CMemSpyDwOperationTracker::Cancel()
       
  1392 	{
       
  1393 	iOperation->Cancel();
       
  1394 	}
       
  1395 
       
  1396 void CMemSpyDwOperationTracker::HandleDeviceWideOperationEvent(TEvent aEvent, TInt aParam1, const TDesC& aParam2)
       
  1397 	{
       
  1398 	switch( aEvent )
       
  1399 		{
       
  1400 	case MMemSpyDeviceWideOperationsObserver::EOperationCompleted:
       
  1401 	case MMemSpyDeviceWideOperationsObserver::EOperationCancelled:
       
  1402 		iServer.SetCurrentOperationTracker(0);
       
  1403 		
       
  1404 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1405 			{
       
  1406 			iPendingNotifications->At(i).Complete(KErrCancel);
       
  1407 			}
       
  1408 		
       
  1409 		if (iOperationMessage.Function() & KMemSpyOpFlagsAsyncOperation)
       
  1410 			{
       
  1411 			iOperationMessage.Complete(
       
  1412 				aEvent == MMemSpyDeviceWideOperationsObserver::EOperationCompleted ? KErrNone : KErrCancel);
       
  1413 			}
       
  1414 		
       
  1415 		iPendingNotifications->Reset();
       
  1416 		
       
  1417 		delete this;
       
  1418 		break;
       
  1419 		
       
  1420 	case MMemSpyDeviceWideOperationsObserver::EOperationProgressEnd:
       
  1421 		{
       
  1422 		iProgress += aParam1;
       
  1423 		for (TInt i=0; i<iPendingNotifications->Count(); i++)
       
  1424 			{
       
  1425 			TInt err;
       
  1426 			TRAP(err, iPendingNotifications->At(i).WriteL(0, TPckgBuf<TInt>( iProgress * 100 / iOperation->TotalOperationSize() )));
       
  1427 			TRAP(err, iPendingNotifications->At(i).WriteL(1, aParam2));
       
  1428 			if (err != KErrNone)
       
  1429 				{
       
  1430 				// TODO: iPendingProgressNotifications->At(i).Panic()
       
  1431 				}
       
  1432 			iPendingNotifications->At(i).Complete(KErrNone);
       
  1433 			}
       
  1434 		iPendingNotifications->Reset();
       
  1435 		break;
       
  1436 		}
       
  1437 		
       
  1438 		}
       
  1439 	
       
  1440 	}