Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

423 lines
15 KiB

#include <windows.h>
#include <winperf.h>
#include <stdlib.h>
#include <strsafe.h>
#include "showperf.h"
#include "perfdata.h"
LPCWSTR NamesKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
LPCWSTR DefaultLangId = L"009";
LPCWSTR Counters = L"Counters";
LPCWSTR Help = L"Help";
LPCWSTR LastHelp = L"Last Help";
LPCWSTR LastCounter = L"Last Counter";
LPCWSTR Slash = L"\\";
// the following strings are for getting texts from perflib
#define OLD_VERSION 0x010000
LPCWSTR VersionName = L"Version";
LPCWSTR CounterName = L"Counter ";
LPCWSTR HelpName = L"Explain ";
LPWSTR
* BuildNameTable(
LPWSTR szComputerName, // computer to query names from
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 = NULL;
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 hKeyRegistry = NULL;
HKEY hKeyValue = NULL;
HKEY hKeyNames = NULL;
LPWSTR lpValueNameString = NULL; //initialize to NULL
WCHAR CounterNameBuffer[50];
WCHAR HelpNameBuffer[50];
HRESULT hError;
if (szComputerName == NULL) {
// use local machine
hKeyRegistry = HKEY_LOCAL_MACHINE;
}
else {
lWin32Status = RegConnectRegistryW(szComputerName, HKEY_LOCAL_MACHINE, & hKeyRegistry);
if (lWin32Status != ERROR_SUCCESS) {
// unable to connect to registry
goto BNT_BAILOUT;
}
}
// check for null arguments and insert defaults if necessary
if (lpszLangId == NULL) {
lpszLangId = (LPWSTR) DefaultLangId;
}
// open registry to get number of items for computing array size
lWin32Status = RegOpenKeyExW(hKeyRegistry, NamesKey, RESERVED, KEY_READ, & hKeyValue);
if (lWin32Status != ERROR_SUCCESS) {
goto BNT_BAILOUT;
}
// get number of items
dwBufferSize = sizeof(dwLastHelpId);
lWin32Status = RegQueryValueExW(
hKeyValue, LastHelp, RESERVED, & dwValueType, (LPBYTE) & dwLastHelpId, & dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
if (lWin32Status == ERROR_SUCCESS) lWin32Status = ERROR_INVALID_DATA;
goto BNT_BAILOUT;
}
// get number of items
dwBufferSize = sizeof(dwLastId);
lWin32Status = RegQueryValueExW(
hKeyValue, LastCounter, RESERVED, & dwValueType, (LPBYTE) & dwLastId, & dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
if (lWin32Status == ERROR_SUCCESS) lWin32Status = ERROR_INVALID_DATA;
goto BNT_BAILOUT;
}
if (dwLastId < dwLastHelpId) dwLastId = dwLastHelpId;
dwArraySize = dwLastId * sizeof(LPWSTR);
// get Perflib system version
dwBufferSize = sizeof(dwSystemVersion);
lWin32Status = RegQueryValueExW(
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(
(lstrlenW(NamesKey) + lstrlenW(Slash) + lstrlenW(lpszLangId) + 1) * sizeof (WCHAR));
if (lpValueNameString == NULL) {
lWin32Status = ERROR_OUTOFMEMORY;
goto BNT_BAILOUT;
}
hError = StringCbPrintfW(lpValueNameString, MemorySize(lpValueNameString), L"%ws%ws%ws",
NamesKey, Slash, lpszLangId);
if (SUCCEEDED(hError)) {
lWin32Status = RegOpenKeyExW(hKeyRegistry, lpValueNameString, RESERVED, KEY_READ, & hKeyNames);
}
else {
lWin32Status = HRESULT_CODE(hError);
}
MemoryFree(lpValueNameString);
}
else {
if (szComputerName == NULL) {
hKeyNames = HKEY_PERFORMANCE_DATA;
}
else {
lWin32Status = RegConnectRegistryW(szComputerName, HKEY_PERFORMANCE_DATA, & hKeyNames);
if (lWin32Status != ERROR_SUCCESS) {
goto BNT_BAILOUT;
}
}
hError = StringCchPrintfW(CounterNameBuffer, RTL_NUMBER_OF(CounterNameBuffer), L"%ws%ws",
CounterName, lpszLangId);
if (SUCCEEDED(hError)) {
hError = StringCchPrintfW(HelpNameBuffer, RTL_NUMBER_OF(HelpNameBuffer), L"%ws%ws", HelpName, lpszLangId);
if (FAILED(hError)) lWin32Status = HRESULT_CODE(hError);
}
else {
lWin32Status = HRESULT_CODE(hError);
}
}
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
// get size of counter names and add that to the arrays
dwBufferSize = 0;
lWin32Status = RegQueryValueExW(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 = RegQueryValueExW(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 == NULL) {
lWin32Status = ERROR_OUTOFMEMORY;
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 = RegQueryValueExW(hKeyNames,
dwSystemVersion == OLD_VERSION ? Counters : CounterNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) lpCounterNames,
& dwBufferSize);
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
dwBufferSize = dwHelpSize;
lWin32Status = RegQueryValueExW(hKeyNames,
dwSystemVersion == OLD_VERSION ? Help : HelpNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) lpHelpText,
& dwBufferSize);
if (lWin32Status != ERROR_SUCCESS) goto BNT_BAILOUT;
// load counter array items
for (lpThisName = lpCounterNames; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1)) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter > 0 && dwThisCounter < dwLastId) {
// point to corresponding counter name
lpThisName += (lstrlenW(lpThisName) + 1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
}
}
for (lpThisName = lpHelpText; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1)) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter > 0 && dwThisCounter < dwLastId) {
// point to corresponding counter name
lpThisName += (lstrlenW(lpThisName) + 1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
}
}
if (pdwLastItem) * pdwLastItem = dwLastId;
BNT_BAILOUT:
if (lWin32Status != ERROR_SUCCESS) {
MemoryFree(lpReturnValue);
dwLastError = GetLastError();
lpReturnValue = NULL;
}
if (hKeyValue != NULL) RegCloseKey(hKeyValue);
if (hKeyNames != NULL && hKeyNames != HKEY_PERFORMANCE_DATA) RegCloseKey(hKeyNames);
if (hKeyRegistry != NULL) RegCloseKey(hKeyRegistry);
return lpReturnValue;
}
PPERF_OBJECT_TYPE
FirstObject(
PPERF_DATA_BLOCK pPerfData
)
{
return ((PPERF_OBJECT_TYPE) ((PBYTE) pPerfData + pPerfData->HeaderLength));
}
PPERF_OBJECT_TYPE
NextObject(
PPERF_OBJECT_TYPE pObject
)
{ // NextObject
DWORD dwOffset = pObject->TotalByteLength;
return (dwOffset != 0) ? ((PPERF_OBJECT_TYPE) (((LPBYTE) pObject) + dwOffset)) : (NULL);
} // NextObject
PPERF_OBJECT_TYPE
GetObjectDefByTitleIndex(
PPERF_DATA_BLOCK pDataBlock,
DWORD ObjectTypeTitleIndex
)
{
DWORD NumTypeDef;
PPERF_OBJECT_TYPE pObjectDef;
PPERF_OBJECT_TYPE pRtnObject = NULL;
if (pDataBlock != NULL) {
pObjectDef = FirstObject(pDataBlock);
for (NumTypeDef = 0; pRtnObject == NULL && NumTypeDef < pDataBlock->NumObjectTypes; NumTypeDef ++) {
if (pObjectDef->ObjectNameTitleIndex == ObjectTypeTitleIndex ) {
pRtnObject = pObjectDef;
break;
}
else {
pObjectDef = NextObject(pObjectDef);
}
}
}
return pRtnObject;
}
PPERF_INSTANCE_DEFINITION
FirstInstance(
PPERF_OBJECT_TYPE pObjectDef
)
{
return (PPERF_INSTANCE_DEFINITION) ((LPBYTE) pObjectDef + pObjectDef->DefinitionLength);
}
PPERF_INSTANCE_DEFINITION
NextInstance(
PPERF_INSTANCE_DEFINITION pInstDef
)
{
PPERF_COUNTER_BLOCK pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pInstDef + pInstDef->ByteLength);
return (PPERF_INSTANCE_DEFINITION) ((LPBYTE) pCounterBlock + pCounterBlock->ByteLength);
}
PPERF_INSTANCE_DEFINITION
GetInstance(
PPERF_OBJECT_TYPE pObjectDef,
LONG InstanceNumber
)
{
PPERF_INSTANCE_DEFINITION pRtnInstance = NULL;
PPERF_INSTANCE_DEFINITION pInstanceDef;
LONG NumInstance;
if (pObjectDef != NULL) {
pInstanceDef = FirstInstance(pObjectDef);
for (NumInstance = 0; pRtnInstance == NULL && NumInstance < pObjectDef->NumInstances; NumInstance ++) {
if (InstanceNumber == NumInstance) {
pRtnInstance = pInstanceDef;
break;
}
else {
pInstanceDef = NextInstance(pInstanceDef);
}
}
}
return pRtnInstance;
}
PPERF_COUNTER_DEFINITION
FirstCounter(
PPERF_OBJECT_TYPE pObjectDef
)
{
return (PPERF_COUNTER_DEFINITION) ((LPBYTE) pObjectDef + pObjectDef->HeaderLength);
}
PPERF_COUNTER_DEFINITION
NextCounter(
PPERF_COUNTER_DEFINITION pCounterDef
)
{
DWORD dwOffset = pCounterDef->ByteLength;
return (dwOffset != 0) ? ((PPERF_COUNTER_DEFINITION) (((LPBYTE) pCounterDef) + dwOffset)) : (NULL);
}
LONG
GetSystemPerfData(
HKEY hKeySystem,
PPERF_DATA_BLOCK * pPerfData,
DWORD dwIndex // 0 = Global, 1 = Costly
)
{ // GetSystemPerfData
LONG lError = ERROR_SUCCESS;
BOOL bAlloc = FALSE;
DWORD Size;
DWORD Type;
if (dwIndex >= 2) {
lError = ! ERROR_SUCCESS;
}
else {
if (* pPerfData == NULL) {
* pPerfData = MemoryAllocate(INITIAL_SIZE);
bAlloc = TRUE;
if (* pPerfData == NULL) {
lError = ERROR_OUTOFMEMORY;
}
}
if (lError == ERROR_SUCCESS) {
lError = ERROR_MORE_DATA;
while (lError == ERROR_MORE_DATA) {
Size = MemorySize(* pPerfData);
lError = RegQueryValueExW(hKeySystem,
dwIndex == 0 ? L"Global" : L"Costly",
RESERVED,
& Type,
(LPBYTE) * pPerfData,
& Size);
if (lError == ERROR_MORE_DATA) {
PPERF_DATA_BLOCK pTmpBlock = * pPerfData;
* pPerfData = MemoryResize(* pPerfData, MemorySize(* pPerfData) + INITIAL_SIZE);
bAlloc = TRUE;
if (* pPerfData == NULL) {
MemoryFree(pTmpBlock);
lError = ERROR_OUTOFMEMORY;
}
}
else if ((lError == ERROR_SUCCESS) && (Size > 0)
&& ((* pPerfData)->Signature[0] == L'P')
&& ((* pPerfData)->Signature[1] == L'E')
&& ((* pPerfData)->Signature[2] == L'R')
&& ((* pPerfData)->Signature[3] == L'F')) {
// does nothing, will break out while loop and return;
}
else if (lError == ERROR_SUCCESS) {
// RegQueryValueEx() return bogus counter datablock, bail out.
lError = ERROR_INVALID_DATA;
}
}
}
}
if (lError != ERROR_SUCCESS) {
if (bAlloc = TRUE && * pPerfData != NULL) {
MemoryFree(* pPerfData);
* pPerfData = NULL;
}
}
return (lError);
} // GetSystemPerfData