Article ID: 174631
Article Last Modified on 11/21/2006
HKEY_LOCAL_MACHINE\System\CurrentControlSet\control\PerfStats\EnumEach registry key that is listed under this location is called an Object (for example, VFAT, KERNEL, etc.). The availability of objects is dynamic. Therefore, this location must be checked first before proceeding to collect performance data. The following sample code illustrates this concept:
#include <windows.h>
#include <stdio.h>
#define DIFFFLAGLEN 6
#define PERFENUMKEY
"System\\CurrentControlSet\\Control\\PerfStats\\Enum"
char szCounter[MAX_PATH];
char szObject[MAX_PATH];
char szName[MAX_PATH];
LPSTR lpszDescBuff = NULL;
char szDiffFlag[DIFFFLAGLEN]; // can contain either "TRUE" or "FALSE"
void main(void)
{
DWORD rc;
DWORD dwIndex1, dwIndex2;
DWORD dwType;
DWORD dwBufSize;
HKEY hKey;
HKEY hObject;
HKEY hCounter;
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
PERFENUMKEY, 0, KEY_READ, &hKey);
if (rc == ERROR_SUCCESS)
{
dwBufSize = MAX_PATH;
dwIndex1 = 0;
// enumerate objects
while ( RegEnumKeyEx(hKey, dwIndex1++, szObject,
&dwBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS )
{
if ( (rc=RegOpenKeyEx(hKey, szObject, 0, KEY_READ, &hObject))
== ERROR_SUCCESS)
{
// process information on the open key using hObject
}
RegCloseKey(hObject);
dwBufSize = MAX_PATH;
}
RegCloseKey(hKey);
}
else
printf("Error %d opening %s\n", rc, PERFENUMKEY);
} // end main
if ((rc=RegQueryValueEx(hObject, "Name", NULL, &dwType,
szObject, &dwBufSize)) == ERROR_SUCCESS)
{
}
// enumerate counters
dwIndex2 = 0;
dwBufSize = MAX_PATH;
while(RegEnumKeyEx(hObject, dwIndex2++, szCounter, &dwBufSize,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
if ( (rc=RegOpenKeyEx(hObject, szCounter, 0, KEY_READ, &hCounter))
== ERROR_SUCCESS)
{
// do processing on open counter key using hCounter
}
else
printf("Error %d opening counter %s\n", rc, szCounter);
RegCloseKey(hCounter);
dwBufSize = MAX_PATH;
}
Counter_Value2 - Counter_Value1
-----------------------------------------
Time_Taken2 - Time_Taken1
The following code illustrates this procedure:
// First, get the Name of the performance counter
dwBufSize = MAX_PATH;
rc = RegQueryValueEx(hObject, "Name", NULL, &dwType, szName,
&dwBufSize);
// Second, get the Description
dwBufSize = 0;
RegQueryValueEx(hCounter, "Description", NULL, &dwType, NULL,
&dwBufSize);
lpszDescBuff = LocalAlloc(LPTR, dwBufSize + 1);
rc = RegQueryValueEx(hCounter, "Description", NULL, &dwType,
lpszDescBuff, &dwBufSize);
if (ERROR_SUCCESS == rc)
{
printf("%s: %s\n", szCounter, lpszDescBuff);
LocalFree(lpszDescBuff);
}
// get the Differentiate value
dwBufSize = DIFFFLAGLEN;
rc = RegQueryValueEx(hCounter, "Differentiate", NULL, &dwType,
szDiffFlag, &dwBufSize);
if (ERROR_SUCCESS == rc)
{
printf("Differentiating Counter: %s\n\n", szDiffFlag);
}
BOOL EnableDataCollection(char *szObjName, char *szCounterName)
{
HKEY hOpen;
DWORD cbData;
DWORD dwType;
LPBYTE pByte;
DWORD rc;
char *szCounterData;
BOOL bSuccess = TRUE;
if ( (rc = RegOpenKeyEx(HKEY_DYN_DATA,"PerfStats\\StartStat", 0,
KEY_READ, &hOpen)) == ERROR_SUCCESS)
{
// concatenate the object and couter key names
szCounterData = LocalAlloc(LPTR,
lstrlen(szObjName) + lstrlen(szCounterName) + 2);
wsprintf(szCounterData, "%s\\%s", szObjName, szCounterName);
// query to get data size
if ( (rc = RegQueryValueEx(hOpen,szCounterData,NULL,&dwType,
NULL, &cbData )) == ERROR_SUCCESS )
{
pByte = LocalAlloc(LPTR, cbData);
// query the performance start key to initialize performance data
// query the start key to initialize performance data
rc = RegQueryValueEx(hOpen,szCounterData,NULL,&dwType, pByte,
&cbData );
// at this point we don't do anything with the data
// free up resources
LocalFree(pByte);
}
else
bSuccess = FALSE;
RegCloseKey(hOpen);
LocalFree(szCounterData);
}
else
bSuccess = FALSE;
return bSuccess;
}
BOOL CollectPerfData(char *szObjName, char *szCounterName,
DWORD *pdwData)
{
HKEY hOpen;
DWORD dwType;
DWORD cbData;
char *szCounterData;
DWORD rc;
BOOL bSuccess = TRUE;
// concatenate the object and counter keys
szCounterData = LocalAlloc(LPTR,
lstrlen(szObjName) + lstrlen(szCounterName) + 2);
wsprintf(szCounterData, "%s\\%s", szObjName, szCounterName);
// open performance data key
if ( (rc = RegOpenKeyEx(HKEY_DYN_DATA,"PerfStats\\StatData", 0,
KEY_READ, &hOpen)) == ERROR_SUCCESS)
{
cbData = sizeof(DWORD);
// retrieve performance data which is of size of DWORD
rc=RegQueryValueEx(hOpen,szCounterData,0,&dwType,
(LPBYTE)pdwData,&cbData );
// let the caller know if it worked or not
bSuccess = rc == ERROR_SUCCESS;
RegCloseKey(hOpen);
}
else
bSuccess = FALSE;
// free the resources
LocalFree(szCounterData);
return bSuccess;
}
BOOL DisableDataCollection(char *szObjName, char *szCounterName)
{
HKEY hOpen;
LPBYTE pByte;
DWORD cbData;
DWORD dwType;
DWORD rc;
char *szCounterData;
BOOL bSuccess = TRUE;
if ( (rc = RegOpenKeyEx(HKEY_DYN_DATA,"PerfStats\\StopStat", 0,
KEY_READ, &hOpen)) == ERROR_SUCCESS)
{
// concatenate the object and couter key names
szCounterData = LocalAlloc(LPTR,
lstrlen(szObjName) + lstrlen(szCounterName) + 2);
wsprintf(szCounterData, "%s\\%s", szObjName, szCounterName);
// query to get data size
if ( (rc = RegQueryValueEx(hOpen,szCounterData,NULL,&dwType,
NULL, &cbData )) == ERROR_SUCCESS )
{
pByte = LocalAlloc(LPTR, cbData);
// query the performance start key to initialize performance data
// query the start key to initialize performance data
rc = RegQueryValueEx(hOpen,szCounterData,NULL,&dwType, pByte,
&cbData );
// at this point we don't do anything with the data
// free up resources
LocalFree(pByte);
}
else
bSuccess = FALSE;
RegCloseKey(hopen);
LocalFree(szCounterData);
}
else
bSuccess = FALSE;
return bSuccess;
}
RegConnectRegistry(szComputerName, // name of remote computer
HKEY_LOCAL_MACHINE, // predefined registry handle
&hkRemoteMachine); // buffer for remote registry handle
RegConnectRegistry(szComputerName, // name of remote computer
HKEY_DYN_DATA, // predefined registry handle
&hkDynaData); // buffer for remote registry handle
Keywords: kbhowto kbkernbase kbperfmon kbregistry KB174631