Annotation of mstools/samples/sdktools/image/drwatson/process.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     process.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This code provides access to the task list.
        !            12: 
        !            13: Author:
        !            14: 
        !            15:     Wesley Witt (wesw) 16-June-1993
        !            16: 
        !            17: Environment:
        !            18: 
        !            19:     User Mode
        !            20: 
        !            21: --*/
        !            22: 
        !            23: #include <windows.h>
        !            24: #include <winperf.h>
        !            25: #include <stdio.h>
        !            26: #include <string.h>
        !            27: #include <stdlib.h>
        !            28: #include "drwatson.h"
        !            29: #include "proto.h"
        !            30: #include "messages.h"
        !            31: 
        !            32: //
        !            33: // task list structure returned from GetTaskList()
        !            34: //
        !            35: typedef struct _TASK_LIST {
        !            36:     DWORD   dwProcessId;
        !            37:     char    ProcessName[MAX_PATH];
        !            38: } TASK_LIST, *PTASK_LIST;
        !            39: 
        !            40: 
        !            41: //
        !            42: // defines
        !            43: //
        !            44: #define INITIAL_SIZE        51200
        !            45: #define EXTEND_SIZE         25600
        !            46: #define REGKEY_PERF         "software\\microsoft\\windows nt\\currentversion\\perflib"
        !            47: #define REGSUBKEY_COUNTERS  "counters"
        !            48: #define PROCESS_COUNTER     "process"
        !            49: #define PROCESSID_COUNTER   "id process"
        !            50: #define UNKNOWN_TASK        "unknown"
        !            51: 
        !            52: 
        !            53: //
        !            54: // prototypes
        !            55: //
        !            56: PTASK_LIST GetTaskList( LPDWORD pdwNumTasks );
        !            57: 
        !            58: 
        !            59: void
        !            60: LogTaskList( void )
        !            61: 
        !            62: /*++
        !            63: 
        !            64: Routine Description:
        !            65: 
        !            66:     This function gets the current task list and logs the process id &
        !            67:     process name to the log file.
        !            68: 
        !            69: Arguments:
        !            70: 
        !            71:     None.
        !            72: 
        !            73: Return Value:
        !            74: 
        !            75:     None.
        !            76: 
        !            77: --*/
        !            78: 
        !            79: {
        !            80:     PTASK_LIST   pTask;
        !            81:     PTASK_LIST   pTaskBegin;
        !            82:     DWORD        dwNumTasks;
        !            83: 
        !            84: 
        !            85:     lprintf( MSG_TASK_LIST );
        !            86: 
        !            87:     pTask = pTaskBegin = GetTaskList( &dwNumTasks );
        !            88: 
        !            89:     if (pTask == NULL) {
        !            90:         printf( "ERROR: could not get the task list\n" );
        !            91:     }
        !            92: 
        !            93:     while (dwNumTasks--) {
        !            94:         lprintfs("%4d %s\r\n",pTask->dwProcessId, pTask->ProcessName );
        !            95:         pTask++;
        !            96:     }
        !            97:     lprintfs( "\r\n" );
        !            98: 
        !            99:     free( pTaskBegin );
        !           100: }
        !           101: 
        !           102: void
        !           103: GetTaskName( ULONG pid, char *szTaskName, LPDWORD pdwSize )
        !           104: 
        !           105: /*++
        !           106: 
        !           107: Routine Description:
        !           108: 
        !           109:     Gets the task name for a given process id.
        !           110: 
        !           111: Arguments:
        !           112: 
        !           113:     pid              - Process id to look for.
        !           114:     szTaskName       - Buffer to put the task name into.
        !           115:     lpdwSize         - Pointer to a dword.  On entry it contains the
        !           116:                        size of the szTaskName buffer.  On exit it contains
        !           117:                        the number of characters in the buffer.
        !           118: 
        !           119: Return Value:
        !           120: 
        !           121:     None.
        !           122: 
        !           123: --*/
        !           124: 
        !           125: {
        !           126:     PTASK_LIST   pTask;
        !           127:     PTASK_LIST   pTaskBegin;
        !           128:     DWORD        dwNumTasks;
        !           129: 
        !           130: 
        !           131:     pTask = pTaskBegin = GetTaskList( &dwNumTasks );
        !           132: 
        !           133:     if (pTask == NULL) {
        !           134:         strcpy( szTaskName, "unknown" );
        !           135:         return;
        !           136:     }
        !           137: 
        !           138:     while (dwNumTasks--) {
        !           139:         if (pTask->dwProcessId == pid) {
        !           140:             if (szTaskName) {
        !           141:                 strncpy( szTaskName, pTask->ProcessName, *pdwSize );
        !           142:             }
        !           143:             *pdwSize = min( strlen(pTask->ProcessName), *pdwSize );
        !           144:             break;
        !           145:         }
        !           146:         pTask++;
        !           147:     }
        !           148: 
        !           149:     free( pTaskBegin );
        !           150: }
        !           151: 
        !           152: PTASK_LIST
        !           153: GetTaskList( LPDWORD pdwNumTasks )
        !           154: 
        !           155: /*++
        !           156: 
        !           157: Routine Description:
        !           158: 
        !           159:     Provides an API for getting a list of tasks running at the time of the
        !           160:     API call.  This function uses the registry performance data to get the
        !           161:     task list and is therefor straight WIN32 calls that anyone can call.
        !           162: 
        !           163: Arguments:
        !           164: 
        !           165:     ldwNumTasks      - pointer to a dword that will be set to the
        !           166:                        number of tasks returned.
        !           167: 
        !           168: Return Value:
        !           169: 
        !           170:     PTASK_LIST       - pointer to an array of TASK_LIST records.
        !           171: 
        !           172: --*/
        !           173: 
        !           174: {
        !           175:     DWORD                        rc;
        !           176:     HKEY                         hKeyNames;
        !           177:     DWORD                        dwType;
        !           178:     DWORD                        dwSize;
        !           179:     LPBYTE                       buf = NULL;
        !           180:     char                         szSubKey[1024];
        !           181:     LANGID                       lid;
        !           182:     LPSTR                        p;
        !           183:     LPSTR                        p2;
        !           184:     PPERF_DATA_BLOCK             pPerf;
        !           185:     PPERF_OBJECT_TYPE            pObj;
        !           186:     PPERF_INSTANCE_DEFINITION    pInst;
        !           187:     PPERF_COUNTER_BLOCK          pCounter;
        !           188:     PPERF_COUNTER_DEFINITION     pCounterDef;
        !           189:     DWORD                        i;
        !           190:     DWORD                        dwProcessIdTitle;
        !           191:     DWORD                        dwProcessIdCounter;
        !           192:     PTASK_LIST                   pTask;
        !           193:     PTASK_LIST                   pTaskReturn = NULL;
        !           194:     char                         szProcessName[MAX_PATH];
        !           195: 
        !           196: 
        !           197:     //
        !           198:     // set the number of tasks to zero until we get some
        !           199:     //
        !           200:     *pdwNumTasks = 0;
        !           201: 
        !           202:     //
        !           203:     // Look for the list of counters.  Always use the neutral
        !           204:     // English version, regardless of the local language.  We
        !           205:     // are looking for some particular keys, and we are always
        !           206:     // going to do our looking in English.  We are not going
        !           207:     // to show the user the counter names, so there is no need
        !           208:     // to go find the corresponding name in the local language.
        !           209:     //
        !           210:     lid = MAKELANGID( LANG_ENGLISH, SUBLANG_NEUTRAL );
        !           211:     sprintf( szSubKey, "%s\\%03x", REGKEY_PERF, lid );
        !           212:     rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
        !           213:                        szSubKey,
        !           214:                        0,
        !           215:                        KEY_READ,
        !           216:                        &hKeyNames
        !           217:                      );
        !           218:     if (rc != ERROR_SUCCESS) {
        !           219:         goto exit;
        !           220:     }
        !           221: 
        !           222:     //
        !           223:     // get the buffer size for the counter names
        !           224:     //
        !           225:     rc = RegQueryValueEx( hKeyNames,
        !           226:                           REGSUBKEY_COUNTERS,
        !           227:                           NULL,
        !           228:                           &dwType,
        !           229:                           NULL,
        !           230:                           &dwSize
        !           231:                         );
        !           232: 
        !           233:     if (rc != ERROR_SUCCESS) {
        !           234:         goto exit;
        !           235:     }
        !           236: 
        !           237:     //
        !           238:     // allocate the counter names buffer
        !           239:     //
        !           240:     buf = (LPBYTE) malloc( dwSize );
        !           241:     if (buf == NULL) {
        !           242:         goto exit;
        !           243:     }
        !           244:     memset( buf, 0, dwSize );
        !           245: 
        !           246:     //
        !           247:     // read the counter names from the registry
        !           248:     //
        !           249:     rc = RegQueryValueEx( hKeyNames,
        !           250:                           REGSUBKEY_COUNTERS,
        !           251:                           NULL,
        !           252:                           &dwType,
        !           253:                           buf,
        !           254:                           &dwSize
        !           255:                         );
        !           256: 
        !           257:     if (rc != ERROR_SUCCESS) {
        !           258:         goto exit;
        !           259:     }
        !           260: 
        !           261:     //
        !           262:     // now loop thru the counter names looking for the following counters:
        !           263:     //
        !           264:     //      1.  "Process"           process name
        !           265:     //      2.  "ID Process"        process id
        !           266:     //
        !           267:     // the buffer contains multiple null terminated strings and then
        !           268:     // finally null terminated at the end.  the strings are in pairs of
        !           269:     // counter number and counter name.
        !           270:     //
        !           271: 
        !           272:     p = buf;
        !           273:     while (*p) {
        !           274:         if (stricmp(p, PROCESS_COUNTER) == 0) {
        !           275:             //
        !           276:             // look backwards for the counter number
        !           277:             //
        !           278:             for( p2=p-2; isdigit(*p2); p2--) ;
        !           279:             strcpy( szSubKey, p2+1 );
        !           280:         }
        !           281:         else
        !           282:         if (stricmp(p, PROCESSID_COUNTER) == 0) {
        !           283:             //
        !           284:             // look backwards for the counter number
        !           285:             //
        !           286:             for( p2=p-2; isdigit(*p2); p2--) ;
        !           287:             dwProcessIdTitle = atol( p2+1 );
        !           288:         }
        !           289:         //
        !           290:         // next string
        !           291:         //
        !           292:         p += (strlen(p) + 1);
        !           293:     }
        !           294: 
        !           295:     //
        !           296:     // free the counter names buffer
        !           297:     //
        !           298:     free( buf );
        !           299: 
        !           300: 
        !           301:     //
        !           302:     // allocate the initial buffer for the performance data
        !           303:     //
        !           304:     dwSize = INITIAL_SIZE;
        !           305:     buf = malloc( dwSize );
        !           306:     if (buf == NULL) {
        !           307:         goto exit;
        !           308:     }
        !           309:     memset( buf, 0, dwSize );
        !           310: 
        !           311: 
        !           312:     while (TRUE) {
        !           313: 
        !           314:         rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
        !           315:                               szSubKey,
        !           316:                               NULL,
        !           317:                               &dwType,
        !           318:                               buf,
        !           319:                               &dwSize
        !           320:                             );
        !           321: 
        !           322:         pPerf = (PPERF_DATA_BLOCK) buf;
        !           323: 
        !           324:         //
        !           325:         // check for success and valid perf data block signature
        !           326:         //
        !           327:         if ((rc == ERROR_SUCCESS) &&
        !           328:             (dwSize > 0) &&
        !           329:             (pPerf)->Signature[0] == (WCHAR)'P' &&
        !           330:             (pPerf)->Signature[1] == (WCHAR)'E' &&
        !           331:             (pPerf)->Signature[2] == (WCHAR)'R' &&
        !           332:             (pPerf)->Signature[3] == (WCHAR)'F' ) {
        !           333:             break;
        !           334:         }
        !           335: 
        !           336:         //
        !           337:         // if buffer is not big enough, reallocate and try again
        !           338:         //
        !           339:         if (rc == ERROR_MORE_DATA) {
        !           340:             dwSize += EXTEND_SIZE;
        !           341:             buf = realloc( buf, dwSize );
        !           342:             memset( buf, 0, dwSize );
        !           343:         }
        !           344:         else {
        !           345:             goto exit;
        !           346:         }
        !           347:     }
        !           348: 
        !           349:     //
        !           350:     // set the perf_object_type pointer
        !           351:     //
        !           352:     pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerf + pPerf->HeaderLength);
        !           353: 
        !           354:     //
        !           355:     // loop thru the performance counter definition records looking
        !           356:     // for the process id counter and then save its offset
        !           357:     //
        !           358:     pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength);
        !           359:     for (i=0; i<(DWORD)pObj->NumCounters; i++) {
        !           360:         if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) {
        !           361:             dwProcessIdCounter = pCounterDef->CounterOffset;
        !           362:             break;
        !           363:         }
        !           364:         pCounterDef++;
        !           365:     }
        !           366: 
        !           367:     //
        !           368:     // allocate a buffer for the returned task list
        !           369:     //
        !           370:     dwSize = pObj->NumInstances * sizeof(TASK_LIST);
        !           371:     pTask = pTaskReturn = (PTASK_LIST) malloc( dwSize );
        !           372:     if (pTask == NULL) {
        !           373:         goto exit;
        !           374:     }
        !           375:     memset( pTask, 0, dwSize);
        !           376: 
        !           377:     //
        !           378:     // loop thru the performance instance data extracting each process name
        !           379:     // and process id
        !           380:     //
        !           381:     *pdwNumTasks = pObj->NumInstances;
        !           382:     pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength);
        !           383:     for (i=0; i<(DWORD)pObj->NumInstances; i++) {
        !           384:         //
        !           385:         // pointer to the process name
        !           386:         //
        !           387:         p = (LPSTR) ((DWORD)pInst + pInst->NameOffset);
        !           388: 
        !           389:         //
        !           390:         // convert it to ascii
        !           391:         //
        !           392:         rc = WideCharToMultiByte( CP_ACP,
        !           393:                                   0,
        !           394:                                   (LPCWSTR)p,
        !           395:                                   -1,
        !           396:                                   szProcessName,
        !           397:                                   sizeof(szProcessName),
        !           398:                                   NULL,
        !           399:                                   NULL
        !           400:                                 );
        !           401: 
        !           402:         if (!rc) {
        !           403:             //
        !           404:             // if we cant convert the string then use a bogus value
        !           405:             //
        !           406:             strcpy( pTask->ProcessName, UNKNOWN_TASK );
        !           407:         }
        !           408: 
        !           409:         if (strlen(szProcessName)+4 <= sizeof(pTask->ProcessName)) {
        !           410:             strcpy( pTask->ProcessName, szProcessName );
        !           411:             strcat( pTask->ProcessName, ".exe" );
        !           412:         }
        !           413: 
        !           414:         //
        !           415:         // get the process id
        !           416:         //
        !           417:         pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength);
        !           418:         pTask->dwProcessId = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter));
        !           419: 
        !           420:         //
        !           421:         // next process
        !           422:         //
        !           423:         pTask++;
        !           424:         pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter + pCounter->ByteLength);
        !           425:     }
        !           426: 
        !           427: exit:
        !           428:     if (buf) {
        !           429:         free( buf );
        !           430:     }
        !           431: 
        !           432:     RegCloseKey( hKeyNames );
        !           433: 
        !           434:     return pTaskReturn;
        !           435: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.