os/kernelhwsrv/kernel/eka/drivers/debug/smdebug/d_sm_process.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Responsible for dealing with process lists in the SM framework
    15 //
    16 
    17 /**
    18  * @file
    19  * @internalComponent
    20  * @prototype
    21  */
    22 
    23 #ifdef __LAUNCH_AS_EXTENSION__
    24 
    25 #include <rm_debug_api.h>
    26 #include <sm_debug_api.h>
    27 #include "d_rmd_breakpoints.h"
    28 
    29 using namespace Debug;
    30 
    31 /**
    32  * Stop Mode routine to retrieve the process list and place it in the response buffer
    33  * @param aItem List item describing the list
    34  * @return One of the system wide error codes
    35  */
    36 TInt StopModeDebug::GetProcessList(const TListItem* aItem, bool aCheckConsistent)
    37 	{
    38 	Kern::Printf("\nDumping the process list");
    39 
    40 	if(aItem->iListScope != EScopeGlobal)
    41 		{
    42 		return KErrArgument; //No other scope makes sense for process list
    43 		}
    44 
    45 	//Check that the process obj con lock is ok if required
    46 	DObjectCon* objCon = Kern::Containers()[EProcess];
    47 
    48 	if(aCheckConsistent && objCon->Lock()->iHoldCount)
    49 		{
    50 		return KErrNotReady;
    51 		}
    52 
    53 	//Look at the buffer
    54 	TUint8* buffer = (TUint8*)aItem->iBufferAddress;
    55 	TUint8* bufferPos = Align4(buffer + sizeof(TListReturn));
    56 	TUint8* bufferEnd = buffer + aItem->iBufferSize;
    57 
    58 	TListReturn* listResp = (TListReturn*)buffer;	
    59 	listResp->iReqNo = EProcess;
    60 	listResp->iNumberItems = 0;
    61 	listResp->iDataSize = 0;
    62 
    63 	DProcess** firstProcess = (DProcess**)objCon->iObjects;
    64 
    65 	TInt numProcesses = objCon->Count();
    66 	for(TInt cnt = 0; cnt < numProcesses; cnt++)
    67 		{
    68 		//Get process and see if we want to list it
    69 		DProcess* proc = firstProcess[cnt];
    70 		if(proc && (proc->iId >= aItem->iStartElement) )
    71 			{
    72 			TUint32 sizeOfProc = 0;
    73 			TInt err = AppendProcessToBuffer(proc, bufferPos, bufferEnd, sizeOfProc);
    74 			if(KErrNone != err)
    75 				{
    76 				return err;
    77 				}
    78 			++(listResp->iNumberItems);
    79 			listResp->iDataSize += sizeOfProc;
    80 			bufferPos += sizeOfProc;
    81 			}
    82 		}
    83 
    84 	return KErrNone;
    85 	}
    86 
    87 /**
    88  * Writes the required process details to the stop mode response buffer in the form of a 
    89  * TProcessListEntry structure
    90  * @param aProc Process to write
    91  * @param aBuffer Buffer to write to
    92  * @param aBufferEnd Where the buffer ends
    93  * @return TInt KErrTooBig if there is no more space in buffer or one of the other system wide error codes
    94  */
    95 TInt StopModeDebug::AppendProcessToBuffer(DProcess* aProc, TUint8* aBuffer, TUint8* aBufferEnd, TUint32& aProcSize)
    96 	{
    97 	TFullName procName;
    98 	GetObjectFullName(aProc, procName);
    99 	TUint32	dynamicNameLength = procName.Length();
   100 
   101 	DCodeSeg* codeSeg = aProc->iCodeSeg;
   102 	TUint16 fileNameLength = (codeSeg) ? (*codeSeg->iFileName).Length() : 0;
   103 
   104 	//Struct size is unicode so the filenames are twice as long, plus the size of the struct minus one character that 
   105 	//lives inside the struct itself. Also, this is word aligned
   106 	TUint32 structSize = Align4( (2*fileNameLength) + (2*dynamicNameLength) + sizeof(TProcessListEntry) - sizeof(TUint16));
   107 	aProcSize = structSize;
   108 
   109 	//Is there space to write this to the buffer
   110 	if(aBuffer + structSize < aBufferEnd)
   111 		{
   112 		TProcessListEntry& entry = *(TProcessListEntry*)(aBuffer);
   113 
   114 		entry.iProcessId = (TUint64)aProc->iId;
   115 		entry.iFileNameLength = fileNameLength;
   116 		entry.iDynamicNameLength = dynamicNameLength;
   117 		entry.iUid3 = aProc->iUids.iUid[2].iUid;
   118 		entry.iAttributes = aProc->iAttributes;
   119 
   120 		//Write the filename
   121 		if(codeSeg)
   122 			{
   123 			//create TPtr to where the file name should be written
   124 			TPtr name = TPtr((TUint8*)&(entry.iNames[0]), fileNameLength*2, fileNameLength*2);
   125 
   126 			//copy the file name
   127 			TInt err = CopyAndExpandDes(*codeSeg->iFileName, name);
   128 			if(KErrNone != err)
   129 				{
   130 				return KErrGeneral;
   131 				}
   132 			}
   133 
   134 		//create TPtr to where the dynamic name should be written
   135 		TPtr name = TPtr((TUint8*)(&(entry.iNames[0]) + fileNameLength), dynamicNameLength*2, dynamicNameLength*2);
   136 
   137 		//copy the dynamic name
   138 		TInt err = CopyAndExpandDes(procName, name);
   139 		if(KErrNone != err)
   140 			{
   141 			return KErrGeneral;
   142 			}	
   143 
   144 		return KErrNone;
   145 		}
   146 	else
   147 		{
   148 		return KErrTooBig;
   149 		}
   150 	}
   151 
   152 #endif
   153