diff options
Diffstat (limited to 'private/windbg/newdm/user/process.c')
-rw-r--r-- | private/windbg/newdm/user/process.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/private/windbg/newdm/user/process.c b/private/windbg/newdm/user/process.c new file mode 100644 index 000000000..9c010eee9 --- /dev/null +++ b/private/windbg/newdm/user/process.c @@ -0,0 +1,335 @@ +/*++ + +Copyright (c) 1993 Microsoft Corporation + +Module Name: + + process.c + +Abstract: + + This code provides access to the task list. + +Author: + + Wesley Witt (wesw) 16-June-1993 + +Environment: + + User Mode + +--*/ + +#include "precomp.h" +#pragma hdrstop + + +#ifndef WIN32S + +#include <winperf.h> + + + +// +// defines +// +#define INITIAL_SIZE 51200 +#define EXTEND_SIZE 25600 +#define REGKEY_PERF "software\\microsoft\\windows nt\\currentversion\\perflib" +#define REGSUBKEY_COUNTERS "Counters" +#define PROCESS_COUNTER "process" +#define PROCESSID_COUNTER "id process" +#define UNKNOWN_TASK "unknown" + + + +VOID +GetTaskList( + PTASK_LIST pTask, + DWORD dwNumTasks + ) + +/*++ + +Routine Description: + + Provides an API for getting a list of tasks running at the time of the + API call. This function uses the registry performance data to get the + task list and is therefor straight WIN32 calls that anyone can call. + +Arguments: + + ldwNumTasks - pointer to a dword that will be set to the + number of tasks returned. + +Return Value: + + PTASK_LIST - pointer to an array of TASK_LIST records. + +--*/ + +{ + DWORD rc; + HKEY hKeyNames = NULL; + DWORD dwType; + DWORD dwSize; + LPBYTE buf = NULL; + CHAR szSubKey[1024]; + LANGID lid; + LPSTR p; + LPSTR p2; + PPERF_DATA_BLOCK pPerf; + PPERF_OBJECT_TYPE pObj; + PPERF_INSTANCE_DEFINITION pInst; + PPERF_COUNTER_BLOCK pCounter; + PPERF_COUNTER_DEFINITION pCounterDef; + DWORD i; + DWORD dwProcessIdTitle; + DWORD dwProcessIdCounter; + CHAR szProcessName[MAX_PATH]; + DWORD dwLimit = dwNumTasks - 1; + DWORD ThisPid = GetCurrentProcessId(); + + + + // + // Look for the list of counters. Always use the neutral + // English version, regardless of the local language. We + // are looking for some particular keys, and we are always + // going to do our looking in English. We are not going + // to show the user the counter names, so there is no need + // to go find the corresponding name in the local language. + // + lid = MAKELANGID( LANG_ENGLISH, SUBLANG_NEUTRAL ); + sprintf( szSubKey, "%s\\%03x", REGKEY_PERF, lid ); + rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE, + szSubKey, + 0, + KEY_READ, + &hKeyNames + ); + if (rc != ERROR_SUCCESS) { + goto exit; + } + + // + // get the buffer size for the counter names + // + rc = RegQueryValueEx( hKeyNames, + REGSUBKEY_COUNTERS, + NULL, + &dwType, + NULL, + &dwSize + ); + + if (rc != ERROR_SUCCESS) { + goto exit; + } + + // + // allocate the counter names buffer + // + buf = (LPBYTE) malloc( dwSize ); + if (buf == NULL) { + goto exit; + } + memset( buf, 0, dwSize ); + + // + // read the counter names from the registry + // + rc = RegQueryValueEx( hKeyNames, + REGSUBKEY_COUNTERS, + NULL, + &dwType, + buf, + &dwSize + ); + + if (rc != ERROR_SUCCESS) { + goto exit; + } + + // + // now loop thru the counter names looking for the following counters: + // + // 1. "Process" process name + // 2. "ID Process" process id + // + // the buffer contains multiple null terminated strings and then + // finally null terminated at the end. the strings are in pairs of + // counter number and counter name. + // + + p = buf; + while (*p) { + if (_stricmp(p, PROCESS_COUNTER) == 0) { + // + // look backwards for the counter number + // + for( p2=p-2; isdigit(*p2); p2--) ; + strcpy( szSubKey, p2+1 ); + } + else + if (_stricmp(p, PROCESSID_COUNTER) == 0) { + // + // look backwards for the counter number + // + for( p2=p-2; isdigit(*p2); p2--) ; + dwProcessIdTitle = atol( p2+1 ); + } + // + // next string + // + p += (strlen(p) + 1); + } + + // + // free the counter names buffer + // + free( buf ); + + + // + // allocate the initial buffer for the performance data + // + dwSize = INITIAL_SIZE; + buf = malloc( dwSize ); + if (buf == NULL) { + goto exit; + } + memset( buf, 0, dwSize ); + + + while (TRUE) { + + rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA, + szSubKey, + NULL, + &dwType, + buf, + &dwSize + ); + + pPerf = (PPERF_DATA_BLOCK) buf; + + // + // check for success and valid perf data block signature + // + if ((rc == ERROR_SUCCESS) && + (dwSize > 0) && + (pPerf)->Signature[0] == (WCHAR)'P' && + (pPerf)->Signature[1] == (WCHAR)'E' && + (pPerf)->Signature[2] == (WCHAR)'R' && + (pPerf)->Signature[3] == (WCHAR)'F' ) { + break; + } + + // + // if buffer is not big enough, reallocate and try again + // + if (rc == ERROR_MORE_DATA) { + dwSize += EXTEND_SIZE; + buf = realloc( buf, dwSize ); + memset( buf, 0, dwSize ); + } + else { + goto exit; + } + } + + // + // set the perf_object_type pointer + // + pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerf + pPerf->HeaderLength); + + // + // loop thru the performance counter definition records looking + // for the process id counter and then save its offset + // + pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength); + for (i=0; i<(DWORD)pObj->NumCounters; i++) { + if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) { + dwProcessIdCounter = pCounterDef->CounterOffset; + break; + } + pCounterDef++; + } + + dwNumTasks = min( dwLimit, (DWORD)pObj->NumInstances ); + + pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength); + + // + // loop thru the performance instance data extracting each process name + // and process id + // + for (i=0; i<dwNumTasks; i++) { + // + // pointer to the process name + // + p = (LPSTR) ((DWORD)pInst + pInst->NameOffset); + + // + // convert it to ascii + // + rc = WideCharToMultiByte( CP_ACP, + 0, + (LPCWSTR)p, + -1, + szProcessName, + sizeof(szProcessName), + NULL, + NULL + ); + + if (!rc) { + // + // if we cant convert the string then use a bogus value + // + strcpy( pTask->ProcessName, UNKNOWN_TASK ); + } + + if (strlen(szProcessName)+4 <= sizeof(pTask->ProcessName)) { + strcpy( pTask->ProcessName, szProcessName ); + strcat( pTask->ProcessName, ".exe" ); + } + + // + // get the process id + // + pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength); + pTask->dwProcessId = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter)); + if (pTask->dwProcessId == 0) { + pTask->dwProcessId = (DWORD)-2; + } + if (_stricmp(szProcessName,"csrss")==0) { + pTask->dwProcessId = (DWORD)-1; + } + + // + // next process + // + if (pTask->dwProcessId == ThisPid) { + ZeroMemory( pTask, sizeof(*pTask) ); + } else { + pTask++; + } + pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter + pCounter->ByteLength); + } + +exit: + if (buf) { + free( buf ); + } + + if (hKeyNames) { + RegCloseKey( hKeyNames ); + RegCloseKey( HKEY_PERFORMANCE_DATA ); + } + + return; +} + +#endif |