sl@0: // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Responsible for dealing with process lists in the SM framework sl@0: // sl@0: sl@0: /** sl@0: * @file sl@0: * @internalComponent sl@0: * @prototype sl@0: */ sl@0: sl@0: #ifdef __LAUNCH_AS_EXTENSION__ sl@0: sl@0: #include sl@0: #include sl@0: #include "d_rmd_breakpoints.h" sl@0: sl@0: using namespace Debug; sl@0: sl@0: /** sl@0: * Stop Mode routine to retrieve the process list and place it in the response buffer sl@0: * @param aItem List item describing the list sl@0: * @return One of the system wide error codes sl@0: */ sl@0: TInt StopModeDebug::GetProcessList(const TListItem* aItem, bool aCheckConsistent) sl@0: { sl@0: Kern::Printf("\nDumping the process list"); sl@0: sl@0: if(aItem->iListScope != EScopeGlobal) sl@0: { sl@0: return KErrArgument; //No other scope makes sense for process list sl@0: } sl@0: sl@0: //Check that the process obj con lock is ok if required sl@0: DObjectCon* objCon = Kern::Containers()[EProcess]; sl@0: sl@0: if(aCheckConsistent && objCon->Lock()->iHoldCount) sl@0: { sl@0: return KErrNotReady; sl@0: } sl@0: sl@0: //Look at the buffer sl@0: TUint8* buffer = (TUint8*)aItem->iBufferAddress; sl@0: TUint8* bufferPos = Align4(buffer + sizeof(TListReturn)); sl@0: TUint8* bufferEnd = buffer + aItem->iBufferSize; sl@0: sl@0: TListReturn* listResp = (TListReturn*)buffer; sl@0: listResp->iReqNo = EProcess; sl@0: listResp->iNumberItems = 0; sl@0: listResp->iDataSize = 0; sl@0: sl@0: DProcess** firstProcess = (DProcess**)objCon->iObjects; sl@0: sl@0: TInt numProcesses = objCon->Count(); sl@0: for(TInt cnt = 0; cnt < numProcesses; cnt++) sl@0: { sl@0: //Get process and see if we want to list it sl@0: DProcess* proc = firstProcess[cnt]; sl@0: if(proc && (proc->iId >= aItem->iStartElement) ) sl@0: { sl@0: TUint32 sizeOfProc = 0; sl@0: TInt err = AppendProcessToBuffer(proc, bufferPos, bufferEnd, sizeOfProc); sl@0: if(KErrNone != err) sl@0: { sl@0: return err; sl@0: } sl@0: ++(listResp->iNumberItems); sl@0: listResp->iDataSize += sizeOfProc; sl@0: bufferPos += sizeOfProc; sl@0: } sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: * Writes the required process details to the stop mode response buffer in the form of a sl@0: * TProcessListEntry structure sl@0: * @param aProc Process to write sl@0: * @param aBuffer Buffer to write to sl@0: * @param aBufferEnd Where the buffer ends sl@0: * @return TInt KErrTooBig if there is no more space in buffer or one of the other system wide error codes sl@0: */ sl@0: TInt StopModeDebug::AppendProcessToBuffer(DProcess* aProc, TUint8* aBuffer, TUint8* aBufferEnd, TUint32& aProcSize) sl@0: { sl@0: TFullName procName; sl@0: GetObjectFullName(aProc, procName); sl@0: TUint32 dynamicNameLength = procName.Length(); sl@0: sl@0: DCodeSeg* codeSeg = aProc->iCodeSeg; sl@0: TUint16 fileNameLength = (codeSeg) ? (*codeSeg->iFileName).Length() : 0; sl@0: sl@0: //Struct size is unicode so the filenames are twice as long, plus the size of the struct minus one character that sl@0: //lives inside the struct itself. Also, this is word aligned sl@0: TUint32 structSize = Align4( (2*fileNameLength) + (2*dynamicNameLength) + sizeof(TProcessListEntry) - sizeof(TUint16)); sl@0: aProcSize = structSize; sl@0: sl@0: //Is there space to write this to the buffer sl@0: if(aBuffer + structSize < aBufferEnd) sl@0: { sl@0: TProcessListEntry& entry = *(TProcessListEntry*)(aBuffer); sl@0: sl@0: entry.iProcessId = (TUint64)aProc->iId; sl@0: entry.iFileNameLength = fileNameLength; sl@0: entry.iDynamicNameLength = dynamicNameLength; sl@0: entry.iUid3 = aProc->iUids.iUid[2].iUid; sl@0: entry.iAttributes = aProc->iAttributes; sl@0: sl@0: //Write the filename sl@0: if(codeSeg) sl@0: { sl@0: //create TPtr to where the file name should be written sl@0: TPtr name = TPtr((TUint8*)&(entry.iNames[0]), fileNameLength*2, fileNameLength*2); sl@0: sl@0: //copy the file name sl@0: TInt err = CopyAndExpandDes(*codeSeg->iFileName, name); sl@0: if(KErrNone != err) sl@0: { sl@0: return KErrGeneral; sl@0: } sl@0: } sl@0: sl@0: //create TPtr to where the dynamic name should be written sl@0: TPtr name = TPtr((TUint8*)(&(entry.iNames[0]) + fileNameLength), dynamicNameLength*2, dynamicNameLength*2); sl@0: sl@0: //copy the dynamic name sl@0: TInt err = CopyAndExpandDes(procName, name); sl@0: if(KErrNone != err) sl@0: { sl@0: return KErrGeneral; sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: else sl@0: { sl@0: return KErrTooBig; sl@0: } sl@0: } sl@0: sl@0: #endif sl@0: