1317 lines
38 KiB
C
1317 lines
38 KiB
C
/*++
|
||
|
||
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)
|