|
|
/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
ctrlist.c
Abstract:
Program to read the current perfmon counters and dump a list of objects and counters returned by the registry
Author:
Bob Watson (a-robw) 4 Dec 92
Revision History: HonWah Chan May 22, 93 - added more features HonWah Chan Oct 18, 93 - added check for perflib version. Old version --> get names from registry New version --> get names from PerfLib thru HKEY_PERFORMANCE_DATA Bob Watson (a-robw) 1 Dec 95 added new counter types
--*/ #define UNICODE 1
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <winperf.h>
#include <ntprfctr.h>
#include <wbemutil.h>
#define MAX_LEVEL 400
LPSTR DetailLevelStr[] = { "Novice", "Advanced", "Expert", "Wizard"}; // LPCWSTR lpwszDiskPerfKey = (LPCWSTR)L"SYSTEM\\CurrentControlSet\\Services\\Diskperf";
LPCWSTR NamesKey = (LPCWSTR)L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"; LPCWSTR DefaultLangId = (LPCWSTR)L"009"; LPCWSTR Counters = (LPCWSTR)L"Counters"; LPCWSTR Help = (LPCWSTR)L"Help"; LPCWSTR LastHelp = (LPCWSTR)L"Last Help"; LPCWSTR LastCounter = (LPCWSTR)L"Last Counter"; LPCWSTR Slash = (LPCWSTR)L"\\";
// the following strings are for getting texts from perflib
#define OLD_VERSION 0x010000
LPCWSTR VersionName = (LPCWSTR)L"Version"; LPCWSTR CounterName = (LPCWSTR)L"Counter "; LPCWSTR HelpName = (LPCWSTR)L"Explain ";
#define RESERVED 0L
#define INITIAL_SIZE (1024*64)
#define EXTEND_SIZE (1024*16)
#define LINE_LENGTH 80
#define WRAP_POINT LINE_LENGTH-12
typedef LPVOID LPMEMORY; typedef HGLOBAL HMEMORY;
#define MemoryAllocate(x) ((LPMEMORY)GlobalAlloc(GPTR, x))
#define MemoryFree(x) ((VOID)GlobalFree(x))
#define MemorySize(x) ((x != NULL) ? (DWORD)GlobalSize(x) : (DWORD)0)
#define MemoryResize(x,y) ((LPMEMORY)GlobalReAlloc(x,y,GMEM_MOVEABLE));
LPWSTR *lpCounterText; LPWSTR *lpDisplayText;
TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+1];
const CHAR PerfCounterCounter[] = "PERF_COUNTER_COUNTER"; const CHAR PerfCounterTimer[] = "PERF_COUNTER_TIMER"; const CHAR PerfCounterQueueLen[] = "PERF_COUNTER_QUEUELEN_TYPE"; const CHAR PerfCounterLargeQueueLen[] = "PERF_COUNTER_LARGE_QUEUELEN_TYPE"; const CHAR PerfCounterBulkCount[] = "PERF_COUNTER_BULK_COUNT"; const CHAR PerfCounterText[] = "PERF_COUNTER_TEXT"; const CHAR PerfCounterRawcount[] = "PERF_COUNTER_RAWCOUNT"; const CHAR PerfCounterRawcountHex[] = "PERF_COUNTER_RAWCOUNT_HEX"; const CHAR PerfCounterLargeRawcount[] = "PERF_COUNTER_LARGE_RAWCOUNT"; const CHAR PerfCounterLargeRawcountHex[] = "PERF_COUNTER_LARGE_RAWCOUNT_HEX"; const CHAR PerfSampleFraction[] = "PERF_SAMPLE_FRACTION"; const CHAR PerfSampleCounter[] = "PERF_SAMPLE_COUNTER"; const CHAR PerfCounterNodata[] = "PERF_COUNTER_NODATA"; const CHAR PerfCounterTimerInv[] = "PERF_COUNTER_TIMER_INV"; const CHAR PerfSampleBase[] = "PERF_SAMPLE_BASE"; const CHAR PerfAverageTimer[] = "PERF_AVERAGE_TIMER"; const CHAR PerfAverageBase[] = "PERF_AVERAGE_BASE"; const CHAR PerfAverageBulk[] = "PERF_AVERAGE_BULK"; const CHAR Perf100nsecTimer[] = "PERF_100NSEC_TIMER"; const CHAR Perf100nsecTimerInv[] = "PERF_100NSEC_TIMER_INV"; const CHAR PerfCounterMultiTimer[] = "PERF_COUNTER_MULTI_TIMER";
const CHAR PerfCounterMultiTimerInv[] = "PERF_COUNTER_MULTI_TIMER_INV"; const CHAR PerfCounterMultiBase[] = "PERF_COUNTER_MULTI_BASE"; const CHAR Perf100nsecMultiTimer[] = "PERF_100NSEC_MULTI_TIMER"; const CHAR Perf100nsecMultiTimerInv[] = "PERF_100NSEC_MULTI_TIMER_INV"; const CHAR PerfRawFraction[] = "PERF_RAW_FRACTION"; const CHAR PerfRawBase[] = "PERF_RAW_BASE"; const CHAR PerfElapsedTime[] = "PERF_ELAPSED_TIME"; const CHAR PerfCounterHistogramType[] = "PERF_COUNTER_HISTOGRAM_TYPE"; const CHAR PerfCounterDelta[] = "PERF_COUNTER_DELTA"; const CHAR PerfCounterLargeDelta[] = "PERF_COUNTER_LARGE_DELTA"; const CHAR NotDefineCounterType[] = " ";
const CHAR PerfCounter100NsQueLenType[] = "PERF_COUNTER_100NS_QUEUELEN_TYPE"; const CHAR PerfCounterObjTimeQueLenType[] = "PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE"; const CHAR PerfObjTimeTimer[] = "PERF_OBJ_TIME_TIMER"; const CHAR PerfLargeRawFraction[] = "PERF_LARGE_RAW_FRACTION"; const CHAR PerfLargeRawBase[] = "PERF_LARGE_RAW_BASE"; const CHAR PerfPrecisionSystemTimer[] = "PERF_PRECISION_SYSTEM_TIMER"; const CHAR PerfPrecision100NsTimer[] = "PERF_PRECISION_100NS_TIMER"; const CHAR PerfPrecisionObjectTimer[] = "PERF_PRECISION_OBJECT_TIMER";
BOOL bFormatCSV = FALSE; BOOL bFormatMOF = FALSE; BOOL bPrintMOFData = FALSE; BOOL bCheckCtrType = FALSE; //
// Object Record Fields are:
// Record Type = "O" for Object Record
// Object name string ID
// Object Name in selected language
// Object Detail Level string (in english)
// has Instance Records [1= yes, 0= no]
// Object Instance Code Page [0 = unicode]
// Help text ID
// Help text
//
const CHAR fmtObjectRecord[] = "\n\"O\",\"%d\",\"%ws\",\"%s\",\"%d\",\"%d\",\"%d\",\"%ws\""; //
// Counter Record Fields are:
// Record Type = "C" for Counter Record
// Object name string ID { these fields are used as links
// Object Name in selected language { to object info records
// Counter name string ID
// Counter name text in selected language
// Counter Detail Level string (in english)
// Counter Type value as a HEX string
// Counter Type Name
// Counter Data field size in bytes
// Counter Visibility [1= listed in list box, 0=hidden]
// Counter Help text ID
// Counter Help text
//
const CHAR fmtCounterRecord[] = "\n\"C\",\"%d\",\"%ws\",\"%d\",\"%ws\",\"%s\",\"0x%8.8x\",\"%s\",\"%d\",\"%d\",\"%d\",\"%ws\"";
__inline static PPERF_OBJECT_TYPE FirstObject ( PPERF_DATA_BLOCK pPerfData ) { return ((PPERF_OBJECT_TYPE) ((PBYTE) pPerfData + pPerfData->HeaderLength)); }
__inline static PPERF_OBJECT_TYPE NextObject ( PPERF_OBJECT_TYPE pObject ) { // NextObject
return ((PPERF_OBJECT_TYPE) ((PBYTE) pObject + pObject->TotalByteLength)); } // NextObject
__inline static PERF_COUNTER_DEFINITION * FirstCounter( PERF_OBJECT_TYPE *pObjectDef ) { return (PERF_COUNTER_DEFINITION *) ((PCHAR) pObjectDef + pObjectDef->HeaderLength); }
__inline static PERF_COUNTER_DEFINITION * NextCounter( PERF_COUNTER_DEFINITION *pCounterDef ) { return (PERF_COUNTER_DEFINITION *) ((PCHAR) pCounterDef + pCounterDef->ByteLength); }
__inline static BOOL ValidCtrSizeDef( PERF_COUNTER_DEFINITION *pThisCounter ) { #define PERF_COUNTER_SIZE_MASK 0x00000300
DWORD dwSizeValue = pThisCounter->CounterType & PERF_COUNTER_SIZE_MASK; BOOL bReturn = TRUE; if ((dwSizeValue == PERF_SIZE_DWORD) && (pThisCounter->CounterSize != sizeof(DWORD))) { bReturn = FALSE; } else if ((dwSizeValue == PERF_SIZE_LARGE) && (pThisCounter->CounterSize != sizeof(__int64))) { bReturn = FALSE; } else if ((dwSizeValue == PERF_SIZE_ZERO) && (pThisCounter->CounterSize != 0)) { bReturn = FALSE; } // else assume that the variable length value is valid
return bReturn; }
_inline static DWORD CtrTypeSize ( PERF_COUNTER_DEFINITION *pThisCounter ) { DWORD dwSizeValue = pThisCounter->CounterType & PERF_COUNTER_SIZE_MASK;
switch (dwSizeValue) { case PERF_SIZE_DWORD: return sizeof(DWORD);
case PERF_SIZE_LARGE: return sizeof(__int64);
case PERF_SIZE_ZERO: return 0;
default: return (pThisCounter->CounterSize); } }
__inline static PERF_INSTANCE_DEFINITION * FirstInstance( PERF_OBJECT_TYPE * pObjectDef) { return (PERF_INSTANCE_DEFINITION * ) ((PCHAR) pObjectDef + pObjectDef->DefinitionLength); }
__inline static PERF_INSTANCE_DEFINITION * NextInstance( PERF_INSTANCE_DEFINITION * pInstDef) { PERF_COUNTER_BLOCK *pCounterBlock;
pCounterBlock = (PERF_COUNTER_BLOCK *) ((PCHAR) pInstDef + pInstDef->ByteLength);
return (PERF_INSTANCE_DEFINITION * ) ((PCHAR) pCounterBlock + pCounterBlock->ByteLength); }
__inline static LPCWSTR GetInstanceName( PERF_INSTANCE_DEFINITION *pInstDef ) { static WCHAR szLocalName[MAX_PATH]; LPWSTR szSrc, szDest;
assert ((pInstDef->NameLength) < (MAX_PATH * sizeof(WCHAR))); szDest = &szLocalName[0]; szSrc = (LPWSTR) ((PCHAR) pInstDef + pInstDef->NameOffset);
while (*szSrc != 0) { switch (*szSrc) { case '\\': *szDest++ = *szSrc; *szDest++ = *szSrc++; break;
default: *szDest++ = *szSrc++; }; } *szDest++ = 0;
return (LPCWSTR)&szLocalName[0]; }
void PrintMofHeader () { WCHAR szPrintBuffer[8192]; DWORD dwLength = 8192; DWORD dwStatus;
dwStatus = GenerateMofHeader (szPrintBuffer, szComputerName, &dwLength);
if (dwStatus == ERROR_SUCCESS) { printf ("%ls", szPrintBuffer); } }
void PrintMofObject ( PERF_OBJECT_TYPE *pPerfObject, BOOL bRawDefinition, BOOL bCostlyObject, BOOL bDefaultObject ) { WCHAR szPrintBuffer[8192*2]; DWORD dwLength = 8192*2; DWORD dwStatus; DWORD dwFlags;
dwFlags = 0; dwFlags |= (bRawDefinition ? WM_GMO_RAW_DEFINITION : 0); dwFlags |= (bCostlyObject ? WM_GMO_COSTLY_OBJECT : 0); dwFlags |= (bDefaultObject ? WM_GMO_DEFAULT_OBJECT : 0);
dwStatus = GenerateMofObject ( szPrintBuffer, &dwLength, NULL, pPerfObject, lpCounterText, lpDisplayText, dwFlags);
if (dwStatus == ERROR_SUCCESS) { printf ("%ls", szPrintBuffer); } }
void PrintMofCounter ( PERF_COUNTER_DEFINITION *pPerfCounter, BOOL bRawDefinition, BOOL bDefaultCounter ) { WCHAR szPrintBuffer[8192*2]; DWORD dwLength = 8192*2; DWORD dwStatus; DWORD dwFlags;
dwFlags = 0; dwFlags |= (bRawDefinition ? WM_GMO_RAW_DEFINITION : 0); dwFlags |= (bDefaultCounter ? WM_GMO_DEFAULT_COUNTER : 0);
dwStatus = GenerateMofCounter ( szPrintBuffer, &dwLength, pPerfCounter, lpCounterText, lpDisplayText, dwFlags);
if (dwStatus == ERROR_SUCCESS) { printf ("%ls", szPrintBuffer); } }
void PrintMofInstances ( PERF_DATA_BLOCK * pPerfDataBlock, PERF_OBJECT_TYPE * pPerfObject, BOOL bRawDefinition ) { WCHAR szPrintBuffer[8192*2]; DWORD dwLength = 8192*2; DWORD dwStatus; DWORD dwFlags;
dwFlags = 0; dwFlags |= (bRawDefinition ? WM_GMO_RAW_DEFINITION : 0);
dwStatus = GenerateMofInstances ( szPrintBuffer, &dwLength, pPerfDataBlock, pPerfObject, lpCounterText, // name strings array
lpDisplayText, dwFlags);
if (dwStatus == ERROR_SUCCESS) { printf ("%ls", szPrintBuffer); } }
LPCSTR GetCounterType( DWORD CounterType ) { switch (CounterType) { case PERF_COUNTER_COUNTER: return (PerfCounterCounter);
case PERF_COUNTER_TIMER: return (PerfCounterTimer);
case PERF_COUNTER_QUEUELEN_TYPE: return (PerfCounterQueueLen);
case PERF_COUNTER_LARGE_QUEUELEN_TYPE: return (PerfCounterLargeQueueLen);
case PERF_COUNTER_100NS_QUEUELEN_TYPE: return (PerfCounter100NsQueLenType);
case PERF_COUNTER_OBJ_TIME_QUEUELEN_TYPE: return (PerfCounterObjTimeQueLenType);
case PERF_COUNTER_BULK_COUNT: return (PerfCounterBulkCount);
case PERF_COUNTER_TEXT: return (PerfCounterText);
case PERF_COUNTER_RAWCOUNT: return (PerfCounterRawcount);
case PERF_COUNTER_LARGE_RAWCOUNT: return (PerfCounterLargeRawcount);
case PERF_COUNTER_RAWCOUNT_HEX: return (PerfCounterRawcountHex);
case PERF_COUNTER_LARGE_RAWCOUNT_HEX: return (PerfCounterLargeRawcountHex);
case PERF_SAMPLE_FRACTION: return (PerfSampleFraction);
case PERF_SAMPLE_COUNTER: return (PerfSampleCounter);
case PERF_COUNTER_NODATA: return (PerfCounterNodata);
case PERF_COUNTER_TIMER_INV: return (PerfCounterTimerInv);
case PERF_SAMPLE_BASE: return (PerfSampleBase);
case PERF_AVERAGE_TIMER: return (PerfAverageTimer);
case PERF_AVERAGE_BASE: return (PerfAverageBase);
case PERF_AVERAGE_BULK: return (PerfAverageBulk); case PERF_OBJ_TIME_TIMER: return (PerfObjTimeTimer);
case PERF_100NSEC_TIMER: return (Perf100nsecTimer);
case PERF_100NSEC_TIMER_INV: return (Perf100nsecTimerInv);
case PERF_COUNTER_MULTI_TIMER: return (PerfCounterMultiTimer);
case PERF_COUNTER_MULTI_TIMER_INV: return (PerfCounterMultiTimerInv);
case PERF_COUNTER_MULTI_BASE: return (PerfCounterMultiBase);
case PERF_100NSEC_MULTI_TIMER: return (Perf100nsecMultiTimer);
case PERF_100NSEC_MULTI_TIMER_INV: return (Perf100nsecMultiTimerInv);
case PERF_RAW_FRACTION: return (PerfRawFraction);
case PERF_LARGE_RAW_FRACTION: return (PerfLargeRawFraction);
case PERF_RAW_BASE: return (PerfRawBase);
case PERF_LARGE_RAW_BASE: return (PerfLargeRawBase);
case PERF_ELAPSED_TIME: return (PerfElapsedTime);
case PERF_COUNTER_HISTOGRAM_TYPE: return (PerfCounterHistogramType);
case PERF_COUNTER_DELTA: return (PerfCounterDelta);
case PERF_COUNTER_LARGE_DELTA: return (PerfCounterLargeDelta);
case PERF_PRECISION_SYSTEM_TIMER: return (PerfPrecisionSystemTimer);
case PERF_PRECISION_100NS_TIMER: return (PerfPrecision100NsTimer);
case PERF_PRECISION_OBJECT_TIMER: return (PerfPrecisionObjectTimer);
default: return (NotDefineCounterType); } }
void DisplayUsage ( void ) {
printf("\nCtrList - Lists all the objects and counters installed in\n"); printf(" the system for the given language ID\n"); printf("\nUsage: ctrlist [-cmd] [LangID] [\\\\machine] > <filename>\n"); printf("\n -c prints data in a CSV format"); printf("\n -m prints data as a WBEM MOF"); printf("\n -d prints data as a WBEM MOF with perf data instances defined"); printf("\n (note: only one of the above command switches may be used"); printf("\n LangID - 009 for English (default)\n"); printf(" - 007 for German\n"); printf(" - 00A for Spanish\n"); printf(" - 00C for French\n"); printf(" \\\\machine may be specified to list counters on a\n"); printf(" remote system\n\n"); printf(" Example - \"ctrlist 00C > french.lst\" will get all the\n"); printf(" objects and counters for the French system and put\n"); printf(" them in the file french.lst\n");
return;
} /* DisplayUsage() */
LPWSTR *BuildNameTable( HKEY hKeyRegistry, // handle to registry db with counter names
LPWSTR lpszLangId, // unicode value of Language subkey
PDWORD pdwLastItem // size of array in elements
) /*++
BuildNameTable
Arguments:
hKeyRegistry Handle to an open registry (this can be local or remote.) and is the value returned by RegConnectRegistry or a default key.
lpszLangId The unicode id of the language to look up. (default is 409)
Return Value: pointer to an allocated table. (the caller must free it when finished!) the table is an array of pointers to zero terminated strings. NULL is returned if an error occured.
--*/ {
LPWSTR *lpReturnValue;
LPWSTR *lpCounterId; LPWSTR lpCounterNames; LPWSTR lpHelpText;
LPWSTR lpThisName;
LONG lWin32Status; DWORD dwLastError; DWORD dwValueType; DWORD dwArraySize; DWORD dwBufferSize; DWORD dwCounterSize; DWORD dwHelpSize; DWORD dwThisCounter; DWORD dwSystemVersion; DWORD dwLastId; DWORD dwLastHelpId; HKEY hKeyValue; HKEY hKeyNames;
LPWSTR lpValueNameString; WCHAR CounterNameBuffer [50]; WCHAR HelpNameBuffer [50];
lpValueNameString = NULL; //initialize to NULL
lpReturnValue = NULL; hKeyValue = NULL; hKeyNames = NULL; // check for null arguments and insert defaults if necessary
if (!lpszLangId) { lpszLangId = (LPWSTR)DefaultLangId; }
// open registry to get number of items for computing array size
lWin32Status = RegOpenKeyEx ( hKeyRegistry, NamesKey, RESERVED, KEY_READ, &hKeyValue); if (lWin32Status != ERROR_SUCCESS) { goto BNT_BAILOUT; }
// get number of items
dwBufferSize = sizeof (dwLastHelpId); lWin32Status = RegQueryValueEx ( hKeyValue, LastHelp, RESERVED, &dwValueType, (LPBYTE)&dwLastHelpId, &dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) { goto BNT_BAILOUT; }
// get number of items
dwBufferSize = sizeof (dwLastId); lWin32Status = RegQueryValueEx ( hKeyValue, LastCounter, RESERVED, &dwValueType, (LPBYTE)&dwLastId, &dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) { goto BNT_BAILOUT; }
if (dwLastId < dwLastHelpId) dwLastId = dwLastHelpId;
dwArraySize = dwLastId * sizeof(LPWSTR);
// get Perflib system version
dwBufferSize = sizeof (dwSystemVersion); lWin32Status = RegQueryValueEx ( hKeyValue, VersionName, RESERVED, &dwValueType, (LPBYTE)&dwSystemVersion, &dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) { dwSystemVersion = OLD_VERSION; }
if (dwSystemVersion == OLD_VERSION) { // get names from registry
lpValueNameString = MemoryAllocate ( lstrlen(NamesKey) * sizeof (WCHAR) + lstrlen(Slash) * sizeof (WCHAR) + lstrlen(lpszLangId) * sizeof (WCHAR) + sizeof (UNICODE_NULL)); if (!lpValueNameString) goto BNT_BAILOUT;
lstrcpy (lpValueNameString, NamesKey); lstrcat (lpValueNameString, Slash); lstrcat (lpValueNameString, lpszLangId);
lWin32Status = RegOpenKeyEx ( hKeyRegistry, lpValueNameString, RESERVED, KEY_READ, &hKeyNames); } else { if (szComputerName[0] == 0) { hKeyNames = HKEY_PERFORMANCE_DATA; } else { lWin32Status = RegConnectRegistry (szComputerName, HKEY_PERFORMANCE_DATA, &hKeyNames); } lstrcpy (CounterNameBuffer, CounterName); lstrcat (CounterNameBuffer, lpszLangId);
lstrcpy (HelpNameBuffer, HelpName); lstrcat (HelpNameBuffer, lpszLangId); }
// get size of counter names and add that to the arrays
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
dwBufferSize = 0; lWin32Status = RegQueryValueEx ( hKeyNames, dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer, RESERVED, &dwValueType, NULL, &dwBufferSize);
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
dwCounterSize = dwBufferSize;
// get size of counter names and add that to the arrays
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
dwBufferSize = 0; lWin32Status = RegQueryValueEx ( hKeyNames, dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer, RESERVED, &dwValueType, NULL, &dwBufferSize);
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT; dwHelpSize = dwBufferSize;
lpReturnValue = MemoryAllocate (dwArraySize + dwCounterSize + dwHelpSize);
if (!lpReturnValue) goto BNT_BAILOUT;
// initialize pointers into buffer
lpCounterId = lpReturnValue; lpCounterNames = (LPWSTR)((LPBYTE)lpCounterId + dwArraySize); lpHelpText = (LPWSTR)((LPBYTE)lpCounterNames + dwCounterSize);
// read counters into memory
dwBufferSize = dwCounterSize; lWin32Status = RegQueryValueEx ( hKeyNames, dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer, RESERVED, &dwValueType, (LPVOID)lpCounterNames, &dwBufferSize);
if (!lpReturnValue) goto BNT_BAILOUT; dwBufferSize = dwHelpSize; lWin32Status = RegQueryValueEx ( hKeyNames, dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer, RESERVED, &dwValueType, (LPVOID)lpHelpText, &dwBufferSize); if (!lpReturnValue) goto BNT_BAILOUT; // load counter array items
for (lpThisName = lpCounterNames; *lpThisName; lpThisName += (lstrlen(lpThisName)+1) ) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul (lpThisName, NULL, 10);
if (dwThisCounter == 0) goto BNT_BAILOUT; // bad entry
// point to corresponding counter name
lpThisName += (lstrlen(lpThisName)+1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
}
for (lpThisName = lpHelpText; *lpThisName; lpThisName += (lstrlen(lpThisName)+1) ) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul (lpThisName, NULL, 10);
if (dwThisCounter == 0) goto BNT_BAILOUT; // bad entry
// point to corresponding counter name
lpThisName += (lstrlen(lpThisName)+1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
} if (pdwLastItem) *pdwLastItem = dwLastId;
MemoryFree ((LPVOID)lpValueNameString); RegCloseKey (hKeyValue); // if (dwSystemVersion == OLD_VERSION)
RegCloseKey (hKeyNames);
return lpReturnValue;
BNT_BAILOUT: if (lWin32Status != ERROR_SUCCESS) { dwLastError = GetLastError(); }
if (lpValueNameString) { MemoryFree ((LPVOID)lpValueNameString); } if (lpReturnValue) { MemoryFree ((LPVOID)lpReturnValue); } if (hKeyValue) RegCloseKey (hKeyValue);
// if (dwSystemVersion == OLD_VERSION &&
// hKeyNames)
RegCloseKey (hKeyNames);
return NULL; }
LONG GetEnumPerfData ( IN HKEY hKeySystem, IN DWORD dwIndex, IN PPERF_DATA_BLOCK *pPerfData ) { // GetSystemPerfData
LONG lError ; DWORD Size; DWORD Type;
if (dwIndex >= 2) return !ERROR_SUCCESS;
if (*pPerfData == NULL) { *pPerfData = MemoryAllocate (INITIAL_SIZE); if (*pPerfData == NULL) { return ERROR_OUTOFMEMORY; } } #pragma warning ( disable : 4127 )
while (TRUE) { Size = MemorySize (*pPerfData); lError = RegQueryValueEx ( hKeySystem, dwIndex == 0 ? (LPCWSTR)L"Global" : (LPCWSTR)L"Costly", RESERVED, &Type, (LPBYTE)*pPerfData, &Size);
if ((!lError) && (Size > 0) && (*pPerfData)->Signature[0] == (WCHAR)'P' && (*pPerfData)->Signature[1] == (WCHAR)'E' && (*pPerfData)->Signature[2] == (WCHAR)'R' && (*pPerfData)->Signature[3] == (WCHAR)'F' ) {
return (ERROR_SUCCESS); }
if (lError == ERROR_MORE_DATA) { *pPerfData = MemoryResize ( *pPerfData, MemorySize (*pPerfData) + EXTEND_SIZE);
if (!*pPerfData) { return (lError); } } else { return (lError); } // else
} #pragma warning ( default : 4127 )
} // GetSystemPerfData
LONG PrintHelpText( DWORD Indent, DWORD dwID, LPWSTR szTextString ) { LPWSTR szThisChar;
BOOL bNewLine;
DWORD dwThisPos; DWORD dwLinesUsed;
szThisChar = szTextString; dwLinesUsed = 0;
// check arguments
if (!szTextString) { return dwLinesUsed; } if (Indent > WRAP_POINT) { return dwLinesUsed; // can't do this
}
// display id number
for (dwThisPos = 0; dwThisPos < Indent - 6; dwThisPos++) { putchar (' '); }
dwThisPos += printf ("[%3.3d] ", dwID); bNewLine = FALSE;
// print text
while (*szThisChar) {
if (bNewLine){ for (dwThisPos = 0; dwThisPos < Indent; dwThisPos++) { putchar (' '); }
bNewLine = FALSE; } if ((*szThisChar == L' ') && (dwThisPos >= WRAP_POINT)) { putchar ('\n'); bNewLine = TRUE; // go to next printable character
while (*szThisChar <= L' ') { szThisChar++; } dwLinesUsed++; } else { putchar (*szThisChar); szThisChar++; }
dwThisPos++; }
putchar ('\n'); bNewLine = TRUE; dwLinesUsed++;
return dwLinesUsed; }
#pragma warning ( disable : 4706 )
int __cdecl main( int argc, char *argv[] ) { int ArgNo;
DWORD dwLastElement;
DWORD dwIndex; DWORD dwDisplayLevel;
PPERF_DATA_BLOCK pDataBlock; // pointer to perfdata block
BOOL bError;
DWORD dwThisObject; DWORD dwThisCounter; CHAR LangID[10]; WCHAR wLangID[10]; BOOL UseDefaultID = FALSE; LPSTR szComputerNameArg = NULL; DWORD dwLoop; DWORD dwLoopEnd; DWORD dwErrorCount; DWORD dwStatus;
PPERF_OBJECT_TYPE pThisObject; PPERF_COUNTER_DEFINITION pThisCounter;
HKEY hKeyMachine = HKEY_LOCAL_MACHINE; HKEY hKeyPerformance = HKEY_PERFORMANCE_DATA;
dwDisplayLevel = PERF_DETAIL_WIZARD; // open key to registry or use default
if (argc >= 2) { if ((argv[1][0] == '-' || argv[1][0] == '/') && argv[1][1] == '?') { DisplayUsage(); return 0; }
if (argv[1][0] != '\\') { if ((argv[1][0] == '-') || (argv[1][0] == '/')) { // then this is a command switch
if ((argv[1][1] == 'c') || (argv[1][1] == 'C')) { // then format is a CSV
bFormatCSV = TRUE; } else if ((argv[1][1] == 'm') || (argv[1][1] == 'M')) { // then format is a MOF
bFormatMOF = TRUE; } else if ((argv[1][1] == 'd') || (argv[1][1] == 'D')) { // then format is a MOF w/ data
bFormatMOF = TRUE; bPrintMOFData = TRUE; } else if ((argv[1][1] == 'e') || (argv[1][1] == 'E')) { bCheckCtrType = TRUE; } ArgNo = 2; } else { ArgNo = 1; }
if (argc > ArgNo) { // get the lang ID
if (argv[ArgNo][0] != '\\') { LangID[0] = argv[ArgNo][0]; LangID[1] = argv[ArgNo][1]; LangID[2] = argv[ArgNo][2]; LangID[3] = '\0'; mbstowcs(wLangID, LangID, 4); ++ArgNo; } else { lstrcpyW (wLangID, (LPCWSTR)L"009"); }
if (argc > (ArgNo)) { // see if the next arg is a computer name
if (argv[ArgNo][0] == '\\') { mbstowcs (szComputerName, argv[ArgNo], MAX_COMPUTERNAME_LENGTH); szComputerNameArg = argv[ArgNo]; } else { szComputerName[0] = 0; } } } } else { // 1st arg is a computer name
mbstowcs (szComputerName, argv[1], MAX_COMPUTERNAME_LENGTH); szComputerNameArg = argv[1]; }
#if 0
// get user level from command line
if (argc > 2 && sscanf(argv[2], " %d", &dwDisplayLevel) == 1) { if (dwDisplayLevel <= PERF_DETAIL_NOVICE) { dwDisplayLevel = PERF_DETAIL_NOVICE; } else if (dwDisplayLevel <= PERF_DETAIL_ADVANCED) { dwDisplayLevel = PERF_DETAIL_ADVANCED; } else if (dwDisplayLevel <= PERF_DETAIL_EXPERT) { dwDisplayLevel = PERF_DETAIL_EXPERT; } else { dwDisplayLevel = PERF_DETAIL_WIZARD; } } else { dwDisplayLevel = PERF_DETAIL_WIZARD; } #endif
} else { UseDefaultID = TRUE; szComputerName[0] = 0; }
if (szComputerName[0] != 0) { if (RegConnectRegistry (szComputerName, HKEY_LOCAL_MACHINE, &hKeyMachine) != ERROR_SUCCESS) { printf ("\nUnable to connect to %s", szComputerNameArg); return 0; } dwStatus = RegConnectRegistry (szComputerName, HKEY_PERFORMANCE_DATA, &hKeyPerformance); if (dwStatus != ERROR_SUCCESS) { printf ("\nUnable to connect to %s", szComputerNameArg); return 0; } } else { // use default initializations
}
lpCounterText = BuildNameTable ( hKeyMachine, (LPWSTR)(DefaultLangId), // counter text is in ENGLISH always
&dwLastElement);
if (!lpCounterText) { printf("***FAILure*** Cannot open the registry\n"); return 0; }
lpDisplayText = BuildNameTable ( hKeyMachine, (LPWSTR)(UseDefaultID ? DefaultLangId : wLangID), &dwLastElement);
if (!lpDisplayText) { printf("***FAILure*** Cannot open the registry\n"); return 0; }
if (bFormatMOF) { // then print the header block
PrintMofHeader (); }
// get a performance data buffer with counters
pDataBlock = 0;
for (dwIndex = 0; (bError = GetEnumPerfData ( hKeyPerformance, dwIndex, &pDataBlock) == ERROR_SUCCESS); dwIndex++) {
for (dwThisObject = 0, pThisObject = FirstObject (pDataBlock); dwThisObject < pDataBlock->NumObjectTypes; dwThisObject++, pThisObject = NextObject(pThisObject)) {
if (bFormatMOF) { if (bPrintMOFData) { dwLoopEnd = 2; } else { dwLoopEnd = 1; } } else { dwLoopEnd = 0; }
dwLoop = 0; do { if (bFormatCSV) { printf (fmtObjectRecord, pThisObject->ObjectNameTitleIndex, lpDisplayText[pThisObject->ObjectNameTitleIndex], pThisObject->DetailLevel <= MAX_LEVEL ? DetailLevelStr[pThisObject->DetailLevel/100-1] : "<N\\A>", pThisObject->NumInstances == PERF_NO_INSTANCES ? 0 : 1, pThisObject->CodePage, pThisObject->ObjectHelpTitleIndex, lpDisplayText[pThisObject->ObjectHelpTitleIndex]); } else if (bFormatMOF) { if (dwLoop < 2) PrintMofObject (pThisObject, (dwLoop == 0 ? FALSE : TRUE), (dwIndex == 0 ? FALSE : TRUE), ((DWORD)pDataBlock->DefaultObject == pThisObject->ObjectNameTitleIndex ? TRUE : FALSE)); } else { printf ("\nObject: \"%ws\" [%3.3d]", lpDisplayText[pThisObject->ObjectNameTitleIndex], pThisObject->ObjectNameTitleIndex); if (!bCheckCtrType) { printf ("\n Detail Level: %s\n", pThisObject->DetailLevel <= MAX_LEVEL ? DetailLevelStr[pThisObject->DetailLevel/100-1] : "<N\\A>"); PrintHelpText (9, pThisObject->ObjectHelpTitleIndex, lpDisplayText[pThisObject->ObjectHelpTitleIndex]); } }
dwErrorCount = 0;
for (dwThisCounter = 0, pThisCounter = FirstCounter(pThisObject); dwThisCounter < pThisObject->NumCounters; dwThisCounter++, pThisCounter = NextCounter(pThisCounter)) {
__try { if (pThisCounter->DetailLevel <= dwDisplayLevel) { if (bFormatCSV) { printf (fmtCounterRecord, pThisObject->ObjectNameTitleIndex, lpDisplayText[pThisObject->ObjectNameTitleIndex], pThisCounter->CounterNameTitleIndex, lpDisplayText[pThisCounter->CounterNameTitleIndex], ((pThisCounter->DetailLevel <= MAX_LEVEL) && (pThisCounter->DetailLevel > 0 )) ? DetailLevelStr[pThisCounter->DetailLevel/100-1] : "<N\\A>", pThisCounter->CounterType, GetCounterType(pThisCounter->CounterType), pThisCounter->CounterSize, IsDisplayableType(pThisCounter->CounterType) ? 1 : 0, pThisCounter->CounterHelpTitleIndex, lpDisplayText[pThisCounter->CounterHelpTitleIndex]); } else if (bFormatMOF) { if (dwLoop < 2) { PrintMofCounter (pThisCounter, (dwLoop == 0 ? FALSE : TRUE), (dwThisCounter == (DWORD)pThisObject->DefaultCounter ? TRUE : FALSE)); } } else if (bCheckCtrType) { if (!ValidCtrSizeDef(pThisCounter)) { printf ("\n [%3.3d] \"%ws\" data size should be %d bytes, but reports a size of %d bytes", pThisCounter->CounterNameTitleIndex, lpDisplayText[pThisCounter->CounterNameTitleIndex], CtrTypeSize (pThisCounter), pThisCounter->CounterSize); dwErrorCount++; } } else { printf ("\n <%ws> [%3.3d]", lpDisplayText[pThisCounter->CounterNameTitleIndex], pThisCounter->CounterNameTitleIndex); printf ("\n Default Scale: %d", pThisCounter->DefaultScale); printf ("\n Detail Level: %s", ((pThisCounter->DetailLevel <= MAX_LEVEL) && (pThisCounter->DetailLevel > 0 ))? DetailLevelStr[pThisCounter->DetailLevel/100-1] : "<N\\A>"); printf ("\n Counter Type: 0x%x, %s", pThisCounter->CounterType, GetCounterType(pThisCounter->CounterType)); printf ("\n Counter Size: %d bytes", pThisCounter->CounterSize);
printf ("\n"); PrintHelpText (16, pThisCounter->CounterHelpTitleIndex, lpDisplayText[pThisCounter->CounterHelpTitleIndex]); } } // end if the right detail level
} __except (EXCEPTION_EXECUTE_HANDLER) { if (!bFormatCSV) { printf ("\n Error (%d) reading this counter", GetExceptionCode()); } } } // end for each counter
if ((dwLoop == 2) && bFormatMOF) { // dump data for raw classes only
PrintMofInstances (pDataBlock, pThisObject, TRUE); }
// close up object text
if ((bFormatMOF) && (dwLoop != 2)) { //{ brace inserted to not throw off the brace counter
printf("\n};\n"); }
if (bCheckCtrType) { printf ("\n %d bad counters in this object.\n", dwErrorCount); } else { printf ("\n"); }
} while (dwLoop++ < dwLoopEnd); // end while
} RegCloseKey (hKeyPerformance); if (szComputerName[0] != 0) { RegCloseKey (hKeyMachine); } }
if (lpDisplayText != NULL) MemoryFree (lpDisplayText); if (lpCounterText != NULL) MemoryFree (lpCounterText);
return 0; } #pragma warning ( default : 4706)
|