memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp
changeset 20 a71a3e32a2ae
parent 0 a03f92240627
child 30 86a2e675b80a
--- a/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp	Mon May 03 13:58:41 2010 +0300
+++ b/memspy/Engine/Source/ClientServer/MemSpyEngineServer.cpp	Thu May 13 23:59:27 2010 +0300
@@ -19,6 +19,9 @@
 
 // System includes
 #include <e32svr.h>
+#include <w32std.h>
+#include <APGTASK.H>
+#include <APGWGNAM.H>  
 
 // User includes
 #include <memspy/engine/memspyengine.h>
@@ -38,6 +41,12 @@
 #include <memspy/engine/memspyenginehelpersysmemtracker.h>
 #include <memspy/engine/memspyenginehelpersysmemtrackerconfig.h>
 #include <memspy/engine/memspyenginehelperkernelcontainers.h>
+#include <memspy/engine/memspyengineobjectthreadinfocontainer.h>
+
+#include <memspy/engine/memspyprocessdata.h>
+#include <memspy/engine/memspythreaddata.h>
+#include <memspy/engine/memspykernelobjectdata.h>
+#include <memspy/engine/memspythreadinfoitemdata.h>
 
 
 CMemSpyEngineServer::CMemSpyEngineServer( CMemSpyEngine& aEngine )
@@ -167,8 +176,551 @@
     TRACE( RDebug::Print( _L("[MemSpy] CMemSpyEngineSession::ServiceL() - END - this: 0x%08x, fn: 0x%08x, id: %4d, client: %S"), this, aMessage.Function(), iClientThreadId, iClientThreadName ) );
 	}
 
+// ---------------------------------------------------------
+// DoServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+	{
+	TInt function = aMessage.Function() & KMemSpyOpFlagsTypeMask;
+	if (function >= EMemSpyClientServerOpMarkerUiFirst && 
+		function < EMemSpyClientServerOpMarkerUiLast)
+		
+		DoUiServiceL(aMessage);
+	else
+		DoCmdServiceL(aMessage);
+	}
 
-void CMemSpyEngineSession::DoServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+// DoUiServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoUiServiceL( const RMessage2& aMessage )
+    {
+	switch (aMessage.Function() & KMemSpyOpFlagsTypeMask)
+		{
+		case EMemSpyClientServerOpGetProcessCount:
+			{
+			aMessage.WriteL(0, TPckgBuf<TInt>(iEngine.Container().Count()));
+			break;
+			}
+		case EMemSpyClientServerOpGetProcesses:
+			{
+			CMemSpyEngineObjectContainer& list = iEngine.Container();
+			
+			TPckgBuf<TInt> a0;
+			aMessage.ReadL(0, a0);
+			TInt realCount = Min(a0(), list.Count());
+			
+			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyProcessData))
+				{
+				CMemSpyProcess& process = iEngine.Container().At(i);
+				TMemSpyProcessData data;
+				data.iId = process.Id();
+				data.iName.Copy(process.Name());
+				
+				TPckgBuf<TMemSpyProcessData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}
+			
+			a0 = list.Count();
+			aMessage.WriteL(0, a0);
+	
+			break;
+			}
+		case EMemSpyClienServerOpGetProcessIdByName:
+			{
+			TFullName processName;
+			aMessage.ReadL(0, processName);
+			
+			TBool found(EFalse);
+			
+			for (TInt i=0; i<iEngine.Container().Count(); i++)
+				{
+				CMemSpyProcess& process = iEngine.Container().At(i);
+				if (process.Name().FindF(processName) >= 0)
+					{
+					found = ETrue;
+					TPckgBuf<TProcessId> procId(process.Id());
+					aMessage.WriteL(1, procId);
+					}
+				}
+			
+			if (!found)
+				{
+				User::Leave(KErrNotFound);
+				}
+			
+			break;
+			}
+		case EMemSpyClientServerOpProcessSystemPermanentOrCritical:
+			{
+			TBool ret = EFalse;
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+			
+			process.Open();
+	
+			if  ( process.IsSystemPermanent() || process.IsSystemCritical() )
+				{
+				ret = ETrue;
+				}
+			TPckgBuf<TBool> retBuf( ret );
+			aMessage.WriteL( 1, retBuf );
+			
+			break;
+			}
+		case EMemSpyClientServerOpEndProcess:
+			{
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyEndType> type;
+			aMessage.ReadL( 1, type );
+					
+			CMemSpyEngineObjectContainer& container = iEngine.Container();			
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+									
+			switch ( type() )
+				{
+				case ETerminate:
+					{
+					process.TerminateL();
+					break;
+					}
+				case EPanic:
+					{
+					process.PanicL();
+					break;
+					}
+				case EKill:
+					{
+					process.KillL();
+					break;
+					}
+				}																
+			break;
+			}
+		case EMemSpyClientServerOpSwitchToProcess:
+			{/*
+			TInt wgCount;
+			RWsSession wsSession;
+			User::LeaveIfError( wsSession.Connect() );
+			CleanupClosePushL( wsSession );
+			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+			CleanupClosePushL( wgArray );
+			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+			TApaTask task( wsSession );
+			TBool brought( EFalse );
+			TInt wgId( KErrNotFound );
+			TThreadId threadId;
+			
+			TPckgBuf<TProcessId> id;
+			aMessage.ReadL( 0, id );
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess& process = container.ProcessByIdL( id() );
+			
+			// loop trough threads in a process
+			for ( TInt i = 0; i < process.MdcaCount(); i++ )
+				{
+				TInt wgCountLocal = wgCount;
+							
+				// loop trough all window groups and see if a thread id matches
+				while( !brought && wgCountLocal-- )
+					{
+					wgId = wgArray[wgCountLocal].iId;
+					User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+					if ( threadId == process.At( i ).Id() )
+						{
+						CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+						task.SetWgId( wgId );
+						if ( !wgName->Hidden() && task.Exists() )
+							{
+							task.BringToForeground();
+							brought = ETrue;                        
+							}
+						CleanupStack::PopAndDestroy( wgName );
+						}
+					}
+				}
+			
+			TPckgBuf<TBool> ret( brought );
+			aMessage.WriteL( 1, ret );
+			
+			break;*/
+			}
+		case EMemSpyClientServerOpGetThreadCount:
+			{
+			TPckgBuf<TProcessId> pid;
+			aMessage.ReadL(1, pid);
+			CMemSpyProcess& process = iEngine.Container().ProcessByIdL(pid());
+			process.Open();
+			aMessage.WriteL(0, TPckgBuf<TInt>(process.Count()));
+			process.Close();
+			break;
+			}
+		case EMemSpyClientServerOpGetThreads:
+			{
+			TPckgBuf<TProcessId> pid;
+			aMessage.ReadL(2, pid);
+			
+			CMemSpyProcess& list = iEngine.Container().ProcessByIdL(pid());
+			list.Open();
+			
+			TPckgBuf<TInt> a0;
+			aMessage.ReadL(0, a0);
+			TInt realCount = Min(a0(), list.Count());
+			
+			for(TInt i=0, offset = 0; i<realCount; i++, offset += sizeof(TMemSpyThreadData))
+				{
+				CMemSpyThread& thread = list.At(i);
+				thread.Open();
+				
+				TMemSpyThreadData data;
+				data.iId = thread.Id();
+				data.iName.Copy(thread.Name());
+				data.iThreadPriority = thread.Priority();
+				
+				TPckgBuf<TMemSpyThreadData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				
+				thread.Close();
+				}
+			
+			a0 = list.Count();
+			aMessage.WriteL(0, a0);
+			
+			list.Close();
+	
+			break;
+			}
+		case EMemSpyClientServerOpSetThreadPriority:
+			{
+			TPckgBuf<TThreadId> tid;
+			TPckgBuf<TInt> priority;
+			aMessage.ReadL(0, tid);
+			aMessage.ReadL(1, priority);
+			
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError(iEngine.Container().ProcessAndThreadByThreadId(tid(), process, thread));
+			
+			if (thread)
+				{				
+				thread->Open();
+				thread->SetPriorityL(static_cast<TThreadPriority>(priority()));				
+				thread->Close();
+				}					
+			break;
+			}
+		case EMemSpyClientServerOpThreadSystemPermanentOrCritical:
+			{
+			TBool ret = EFalse;
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+			
+			if ( thread )
+				{				
+				thread->Open();
+				
+				if  ( thread->IsSystemPermanent() || thread->IsSystemCritical() )
+					{			
+					ret = ETrue;					
+					}
+				thread->Close();
+				}
+			TPckgBuf<TBool> retBuf( ret );
+			aMessage.WriteL( 1, retBuf );
+							
+			break;
+			}
+		case EMemSpyClientServerOpEndThread:
+			{
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyEndType> type;
+			aMessage.ReadL( 1, type );
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+			
+			if( thread )
+				{
+				switch ( type() )
+					{
+					case ETerminate:
+						{
+						thread->TerminateL();
+						break;
+						}
+					case EPanic:
+						{
+						thread->PanicL();
+						break;
+						}
+					case EKill:
+						{
+						thread->KillL();
+						break;
+						}
+					}				
+				}			
+			break;
+			}
+		case EMemSpyClientServerOpSwitchToThread:
+			{
+			TInt wgCount;
+			RWsSession wsSession;
+			User::LeaveIfError( wsSession.Connect() );
+			CleanupClosePushL( wsSession );
+			User::LeaveIfError( wgCount = wsSession.NumWindowGroups() );
+			RArray<RWsSession::TWindowGroupChainInfo> wgArray;
+			CleanupClosePushL( wgArray );
+			User::LeaveIfError( wsSession.WindowGroupList( &wgArray ) );
+			TApaTask task( wsSession );
+			TBool brought( EFalse );
+			TInt wgId( KErrNotFound );
+			TThreadId threadId;
+					
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+					
+			// loop trough all window groups and see if a thread id matches
+			while( !brought && wgCount-- )
+				{
+				wgId = wgArray[wgCount].iId;
+				User::LeaveIfError( wsSession.GetWindowGroupClientThreadId( wgId, threadId ) );
+				if ( threadId == id() )
+					{
+					CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC( wsSession, wgId );
+					task.SetWgId( wgId );
+					if ( !wgName->Hidden() && task.Exists() )
+						{
+						task.BringToForeground();
+						brought = ETrue;                        
+						}
+					CleanupStack::PopAndDestroy( wgName );
+					}
+				}			
+			TPckgBuf<TBool> ret( brought );
+			aMessage.WriteL( 1, ret );															
+					
+			break;
+			}		
+		case EMemSpyClientServerOpGetInfoItemType:
+			{
+			TPckgBuf<TInt> index;
+			aMessage.ReadL( 0, index );			
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 1, id);
+								
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL; //not needed
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id(), process, thread ) );
+		            
+			thread->Open();
+			process->Open();
+		            
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                        
+			TMemSpyThreadInfoItemType retType = threadInfoContainer.Item( index() ).Type();
+			
+			TPckgBuf<TMemSpyThreadInfoItemType> ret( retType );
+			aMessage.WriteL( 2, ret );			
+			
+			thread->Close();
+			process->Close();			
+			
+			break;
+			}
+		case EMemSpyClientServerOpGetThreadInfoItemsCount:
+			{		
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 0, id );
+			TPckgBuf<TMemSpyThreadInfoItemType> type;
+			aMessage.ReadL( 1, type );					 
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			
+			container.ProcessAndThreadByThreadId( id(), process, thread );
+			
+			thread->Open();
+			process->Open();
+				    
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();                 
+								
+			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() );
+				    
+			TInt count = threadInfoItemBase.MdcaCount();		    
+			TPckgBuf<TInt> tempret( count );
+			aMessage.WriteL( 2, tempret );
+					
+			thread->Close();
+			process->Close();
+					
+			break;
+			}		
+		case EMemSpyClientServerOpGetThreadInfoItems:
+			{
+			TPckgBuf<TInt> count;
+			aMessage.ReadL( 0, count );						
+			TPckgBuf<TThreadId> id;
+			aMessage.ReadL( 1, id );
+			TPckgBuf<TMemSpyThreadInfoItemType> type;
+			aMessage.ReadL( 2, type );			
+			
+			CMemSpyEngineObjectContainer& container = iEngine.Container();            
+			CMemSpyProcess* process = NULL;
+			CMemSpyThread* thread = NULL; 
+			User::LeaveIfError( container.ProcessAndThreadByThreadId( id() , process, thread ) );
+							  
+			process->Open();
+			thread->Open();
+					
+			CMemSpyThreadInfoContainer& threadInfoContainer = thread->InfoContainerForceSyncronousConstructionL();      
+					
+			CMemSpyThreadInfoItemBase& threadInfoItemBase = threadInfoContainer.Item( type() ); //get ThreadInfoItemBaseByType
+			
+			TInt itemCount = Min(count(), threadInfoItemBase.MdcaCount());
+					
+			for( TInt i=0, offset = 0; i<itemCount; i++, offset += sizeof( TMemSpyThreadInfoItemData ) )
+				{
+				TMemSpyThreadInfoItemData data;
+				
+				TPtrC caption(threadInfoItemBase.MdcaPoint(i).Mid(1));
+				TInt tabPos = caption.Locate('\t');
+				if (tabPos != KErrNotFound)
+					caption.Set(caption.Left(tabPos));
+				
+				TPtrC value(threadInfoItemBase.MdcaPoint(i));
+				tabPos = value.LocateReverse('\t');
+				if (tabPos != KErrNotFound)
+					value.Set(value.Mid(tabPos + 1));
+												
+				data.iCaption.Copy( caption );
+				data.iValue.Copy( value );
+							
+				TPckgBuf<TMemSpyThreadInfoItemData> buffer(data);
+				aMessage.WriteL(3, buffer, offset);				
+				}			
+			aMessage.WriteL(0, count);						
+					
+			thread->Close();
+			process->Close();
+					
+			break;
+			}
+		// --- KernelObjects related functions ---
+		case EMemSpyClientServerOpGetKernelObjectCount:
+			{
+			TInt iCount = EMemSpyDriverContainerTypeLast - EMemSpyDriverContainerTypeFirst;
+			TPckgBuf<TInt> ret( iCount );
+			aMessage.WriteL(0, ret);			
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjects:
+			{
+			TPckgBuf<TInt> count;
+			aMessage.ReadL(0, count);
+			
+			CMemSpyEngineGenericKernelObjectContainer* model = iEngine.HelperKernelContainers().ObjectsAllL(); //contains all the objects
+			CleanupStack::PushL( model );
+			
+			for( TInt i=0, offset = 0; i<count(); i++, offset += sizeof( TMemSpyKernelObjectData ) )
+				{
+				TMemSpyKernelObjectData data;
+				
+				TPtrC name(model->At(i).Name().Mid(1));
+				TInt tabPos = name.Locate('\t');
+				if (tabPos != KErrNotFound)
+					name.Set(name.Left(tabPos));
+												
+				data.iName.Copy(name);
+				data.iType = model->At(i).Type();
+				data.iCount = model->At(i).Count();											
+				data.iSize = model->At(i).Count() * model->At(i).Count();
+	
+				TPckgBuf<TMemSpyKernelObjectData> buffer(data);
+				aMessage.WriteL(1, buffer, offset);
+				}			
+			aMessage.WriteL(0, count);
+			CleanupStack::PopAndDestroy( model );
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjectItemCount:
+			{
+			TPckgBuf<TMemSpyDriverContainerType> tempType;
+			aMessage.ReadL(1, tempType); //get type of kernel object
+			TMemSpyDriverContainerType type = tempType();
+			
+			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( type );
+			CleanupStack::PushL( iObjectList );
+			
+			TInt count = iObjectList->Count();
+			TPckgBuf<TInt> ret( count );
+			aMessage.WriteL( 0, ret );
+			
+			CleanupStack::PopAndDestroy( iObjectList );
+			break;
+			}
+		case EMemSpyClientServerOpGetKernelObjectItems:
+			{
+			TPckgBuf<TInt> count;
+			TPckgBuf<TMemSpyDriverContainerType> tempType;
+			aMessage.ReadL( 0, count ); //get count of items
+			aMessage.ReadL(1, tempType); //get type of kernel object
+			TInt c = count();
+			
+			CMemSpyEngineHelperKernelContainers& kernelContainerManager = iEngine.HelperKernelContainers();
+			CMemSpyEngineGenericKernelObjectList* iObjectList = kernelContainerManager.ObjectsForSpecificContainerL( tempType() );
+			CleanupStack::PushL( iObjectList );
+			
+			for( TInt i=0, offset = 0; i<c; i++, offset += sizeof( TMemSpyDriverHandleInfoGeneric ) )
+				{
+				TMemSpyDriverHandleInfoGeneric data;								
+															
+				data = iObjectList->At( i );
+				
+				TPckgBuf<TMemSpyDriverHandleInfoGeneric> buffer(data);
+				aMessage.WriteL(2, buffer, offset);
+				}			
+			
+			CleanupStack::PopAndDestroy( iObjectList );			
+			break;
+			}
+		// --- Kernel Heap related functions ---
+		case EMemSpyClientServerOpGetHeap:
+			{
+			TMemSpyHeapInfo heapInfo;			
+			iEngine.HelperHeap().GetHeapInfoKernelL( heapInfo );
+			TMemSpyHeapData data = iEngine.HelperHeap().NewHeapRawInfo( heapInfo );
+			
+			TPckgBuf<TMemSpyHeapData> buffer(data);
+			aMessage.WriteL(0, buffer);
+			
+			break;
+			}
+		}
+    }
+
+// ---------------------------------------------------------
+// DoCmdServiceL( const RMessage2& aMessage )
+// ---------------------------------------------------------
+//
+void CMemSpyEngineSession::DoCmdServiceL( const RMessage2& aMessage )
     {
     TInt error = KErrNone;