Windows-Server-2003/sdktools/exctrlst/exctrdlg.cpp

1364 lines
40 KiB
C++

// exctrdlg.cpp : implementation file
//
#ifndef UNICODE
#define UNICODE 1
#endif
#ifndef _UNICODE
#define _UNICODE 1
#endif
#include "stdafx.h"
#include "exctrlst.h"
#include "exctrdlg.h"
#include "tchar.h"
// string constants
// displayed strings
const TCHAR cszNotFound[] = {TEXT("Not Found")};
const TCHAR cszNA[] = {TEXT("N/A")};
// strings that are not displayed
const WCHAR cszServiceKeyName[] = L"SYSTEM\\CurrentControlSet\\Services";
const WCHAR cszNamesKey[] = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
// Performance subkey registry value names
const WCHAR cszDisablePerformanceCounters[] = {L"Disable Performance Counters"};
const TCHAR cszDoubleBackslash[] = {TEXT("\\\\")};
const TCHAR cszSpace[] = {TEXT(" ")};
const TCHAR cszSplat[] = {TEXT("*")};
const TCHAR cszServIdFmt[] = {TEXT("%d %s")};
const TCHAR cszOpen[] = {TEXT("Open")};
const TCHAR cszCollect[] = {TEXT("Collect")};
const TCHAR cszClose[] = {TEXT("Close")};
const TCHAR cszIdFmt[] = {TEXT("0x%8.8x (%d) %s")};
const TCHAR cszSortIdFmt[] = {TEXT("0x%8.8x\t%s")};
const TCHAR cszTab[] = {TEXT("\t")};
const TCHAR cszFirstCounter[] = {TEXT("First Counter")};
const TCHAR cszLastCounter[] = {TEXT("Last Counter")};
const TCHAR cszFirstHelp[] = {TEXT("First Help")};
const TCHAR cszLastHelp[] = {TEXT("Last Help")};
const TCHAR cszLibrary[] = {TEXT("Library")};
const TCHAR cszPerformance[] = {TEXT("\\Performance")};
const TCHAR cszSlash[] = {TEXT("\\")};
const WCHAR cszVersionName[] = {L"Version"};
const WCHAR cszCounterName[] = {L"Counter "};
const WCHAR cszHelpName[] = {L"Explain "};
const WCHAR cszCounters[] = {L"Counters"};
const TCHAR cszHelp[] = {TEXT("Help")};
// Perflib registry values
const WCHAR cszDefaultLangId[] = L"009";
const WCHAR cszConfigurationFlags[] = L"Configuration Flags";
const WCHAR cszEventLogLevel[] = L"EventLogLevel";
const WCHAR cszExtCounterTestLevel[] = L"ExtCounterTestLevel";
const WCHAR cszFailureLimit[] = L"Error Count Limit";
#ifdef _DEBUG
#undef THIS_FILE
char BASED_CODE THIS_FILE[] = __FILE__;
#endif
BOOL CExctrlstDlg::IndexHasString (
DWORD dwIndex
)
{
if ((dwIndex <= dwLastElement) && (pNameTable != NULL)) {
if (pNameTable[dwIndex] != NULL) {
return TRUE;
} else {
return FALSE;
}
} else {
return FALSE;
}
}
LPWSTR
*BuildNameTable(
LPCWSTR szMachineName,
LPCWSTR lpszLangIdArg, // unicode value of Language subkey
PDWORD pdwLastItem, // size of array in elements
PDWORD pdwIdArray // array for index ID's
)
/*++
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 MemoryFree it when finished!)
the table is an array of pointers to zero terminated strings. NULL is
returned if an error occured.
--*/
{
HKEY hKeyRegistry; // handle to registry db with counter names
LPWSTR *lpReturnValue;
LPCWSTR lpszLangId;
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;
DWORD dwLastCounterIdUsed;
DWORD dwLastHelpIdUsed;
HKEY hKeyValue;
HKEY hKeyNames;
LPWSTR lpValueNameString;
WCHAR CounterNameBuffer [50];
WCHAR HelpNameBuffer [50];
hKeyRegistry = NULL;
if (szMachineName != NULL) {
lWin32Status = RegConnectRegistryW (szMachineName,
HKEY_LOCAL_MACHINE,
&hKeyRegistry);
} else {
lWin32Status = ERROR_SUCCESS;
hKeyRegistry = HKEY_LOCAL_MACHINE;
}
lpValueNameString = NULL; //initialize to NULL
lpReturnValue = NULL;
hKeyValue = NULL;
hKeyNames = NULL;
// check for null arguments and insert defaults if necessary
if (!lpszLangIdArg) {
lpszLangId = cszDefaultLangId;
} else {
lpszLangId = lpszLangIdArg;
}
// open registry to get number of items for computing array size
if (lWin32Status == ERROR_SUCCESS) {
lWin32Status = RegOpenKeyEx (
hKeyRegistry,
cszNamesKey,
RESERVED,
KEY_READ,
&hKeyValue);
}
if (lWin32Status != ERROR_SUCCESS) {
goto BNT_BAILOUT;
}
// get number of items
dwBufferSize = sizeof (dwLastHelpId);
lWin32Status = RegQueryValueEx (
hKeyValue,
cszLastHelp,
RESERVED,
&dwValueType,
(LPBYTE)&dwLastHelpId,
&dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
goto BNT_BAILOUT;
}
pdwIdArray[2] = dwLastHelpId;
// get number of items
dwBufferSize = sizeof (dwLastId);
lWin32Status = RegQueryValueEx (
hKeyValue,
cszLastCounter,
RESERVED,
&dwValueType,
(LPBYTE)&dwLastId,
&dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
goto BNT_BAILOUT;
}
pdwIdArray[0] = dwLastId;
if (dwLastId < dwLastHelpId)
dwLastId = dwLastHelpId;
dwArraySize = dwLastId * sizeof(LPWSTR);
// get Perflib system version
dwBufferSize = sizeof (dwSystemVersion);
lWin32Status = RegQueryValueEx (
hKeyValue,
cszVersionName,
RESERVED,
&dwValueType,
(LPBYTE)&dwSystemVersion,
&dwBufferSize);
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
dwSystemVersion = OLD_VERSION;
// reset the error status
lWin32Status = ERROR_SUCCESS;
}
if (dwSystemVersion == OLD_VERSION) {
// get names from registry
lpValueNameString = (LPWSTR)HeapAlloc (GetProcessHeap(), 0,
lstrlen(cszNamesKey) * sizeof (WCHAR) +
lstrlen(cszSlash) * sizeof (WCHAR) +
lstrlen(lpszLangId) * sizeof (WCHAR) +
sizeof (UNICODE_NULL));
if (!lpValueNameString) goto BNT_BAILOUT;
lstrcpy (lpValueNameString, cszNamesKey);
lstrcat (lpValueNameString, cszSlash);
lstrcat (lpValueNameString, lpszLangId);
lWin32Status = RegOpenKeyEx (
hKeyRegistry,
lpValueNameString,
RESERVED,
KEY_READ,
&hKeyNames);
} else {
if (szMachineName[0] == 0) {
hKeyNames = HKEY_PERFORMANCE_DATA;
} else {
lWin32Status = RegConnectRegistry (szMachineName,
HKEY_PERFORMANCE_DATA,
&hKeyNames);
}
lstrcpy (CounterNameBuffer, cszCounterName);
lstrcat (CounterNameBuffer, lpszLangId);
lstrcpy (HelpNameBuffer, cszHelpName);
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 == (DWORD)OLD_VERSION ? cszCounters : 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 == (DWORD)OLD_VERSION ? cszHelp : HelpNameBuffer,
RESERVED,
&dwValueType,
NULL,
&dwBufferSize);
if (lWin32Status != ERROR_SUCCESS) {
goto BNT_BAILOUT;
}
dwHelpSize = dwBufferSize;
lpReturnValue = (LPWSTR *)HeapAlloc (GetProcessHeap(), 0,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 = RegQueryValueExW (
hKeyNames,
dwSystemVersion == OLD_VERSION ? cszCounters : CounterNameBuffer,
RESERVED,
&dwValueType,
(LPBYTE)lpCounterNames,
&dwBufferSize);
if (!lpReturnValue) {
goto BNT_BAILOUT;
}
dwBufferSize = dwHelpSize;
lWin32Status = RegQueryValueExW (
hKeyNames,
dwSystemVersion == OLD_VERSION ? cszHelp : HelpNameBuffer,
RESERVED,
&dwValueType,
(LPBYTE)lpHelpText,
&dwBufferSize);
if (!lpReturnValue) {
goto BNT_BAILOUT;
}
dwLastCounterIdUsed = 0;
dwLastHelpIdUsed = 0;
// 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;
if (dwThisCounter > dwLastCounterIdUsed) dwLastCounterIdUsed = dwThisCounter;
}
pdwIdArray[1] = dwLastCounterIdUsed;
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 (dwThisCounter > dwLastHelpIdUsed) dwLastHelpIdUsed= dwThisCounter;
}
pdwIdArray[3] = dwLastHelpIdUsed;
dwLastId = dwLastHelpIdUsed;
if (dwLastId < dwLastCounterIdUsed) dwLastId = dwLastCounterIdUsed;
if (pdwLastItem) *pdwLastItem = dwLastId;
HeapFree (GetProcessHeap(), 0, (LPVOID)lpValueNameString);
RegCloseKey (hKeyValue);
// if (dwSystemVersion == OLD_VERSION)
RegCloseKey (hKeyNames);
if ((hKeyRegistry != HKEY_LOCAL_MACHINE) &&
(hKeyRegistry != NULL)) {
RegCloseKey(hKeyRegistry);
}
return lpReturnValue;
BNT_BAILOUT:
if (lWin32Status != ERROR_SUCCESS) {
dwLastError = GetLastError();
}
if (lpValueNameString) {
HeapFree (GetProcessHeap(), 0, (LPVOID)lpValueNameString);
}
if (lpReturnValue) {
HeapFree (GetProcessHeap(), 0, (LPVOID)lpReturnValue);
}
if ((hKeyValue != NULL) && (hKeyValue != INVALID_HANDLE_VALUE)) {
RegCloseKey (hKeyValue);
}
// if (dwSystemVersion == OLD_VERSION &&
// hKeyNames)
if ((hKeyNames != NULL) && (hKeyNames != INVALID_HANDLE_VALUE)) {
RegCloseKey (hKeyNames);
}
if ((hKeyRegistry != HKEY_LOCAL_MACHINE) &&
(hKeyRegistry != NULL)) {
RegCloseKey(hKeyRegistry);
}
return NULL;
}
BOOL
IsMsObject(CString *pLibraryName)
{
CString LocalLibraryName;
LocalLibraryName = *pLibraryName;
LocalLibraryName.MakeLower();
// for now this just compares known DLL names. valid as of
// NT v4.0
if (LocalLibraryName.Find((LPCWSTR)L"perfctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"ftpctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"rasctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"winsctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"sfmctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"atkctrs.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"bhmon.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"tapictrs.dll") >= 0) return TRUE;
// NT v5.0
if (LocalLibraryName.Find((LPCWSTR)L"perfdisk.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"perfos.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"perfproc.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"perfnet.dll") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"winspool.drv") >= 0) return TRUE;
if (LocalLibraryName.Find((LPCWSTR)L"tapiperf.dll") >= 0) return TRUE;
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CExctrlstDlg dialog
CExctrlstDlg::CExctrlstDlg(CWnd* pParent /*=NULL*/)
: CDialog(CExctrlstDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CExctrlstDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
hKeyMachine = HKEY_LOCAL_MACHINE;
hKeyServices = NULL;
dwSortOrder = SORT_ORDER_SERVICE;
bReadWriteAccess = TRUE;
dwRegAccessMask = KEY_READ | KEY_WRITE;
pNameTable = NULL;
dwLastElement = 0;
dwListBoxHorizExtent = 0;
dwTabStopCount = 1;
dwTabStopArray[0] = 85;
memset (&dwIdArray[0], 0, sizeof(dwIdArray));
}
CExctrlstDlg::~CExctrlstDlg()
{
if (hKeyServices != NULL && hKeyServices != INVALID_HANDLE_VALUE) {
RegCloseKey(hKeyServices);
}
if (hKeyMachine != NULL && hKeyMachine != INVALID_HANDLE_VALUE
&& hKeyMachine != HKEY_LOCAL_MACHINE) {
RegCloseKey(hKeyMachine);
}
if (pNameTable != NULL) {
HeapFree (GetProcessHeap(), 0, pNameTable);
pNameTable = NULL;
dwLastElement = 0;
}
}
void CExctrlstDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CExctrlstDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CExctrlstDlg, CDialog)
//{{AFX_MSG_MAP(CExctrlstDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_LBN_SELCHANGE(IDC_EXT_LIST, OnSelchangeExtList)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_REFRESH, OnRefresh)
ON_BN_CLICKED(IDC_ABOUT, OnAbout)
ON_EN_KILLFOCUS(IDC_MACHINE_NAME, OnKillfocusMachineName)
ON_BN_CLICKED(IDC_SORT_LIBRARY, OnSortButton)
ON_BN_CLICKED(IDC_SORT_SERVICE, OnSortButton)
ON_BN_CLICKED(IDC_SORT_ID, OnSortButton)
ON_BN_CLICKED(IDC_ENABLED_BTN, OnEnablePerf)
ON_WM_SYSCOMMAND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
DWORD CExctrlstDlg::EnablePerfCounters (HKEY hKeyItem, DWORD dwNewValue)
{
DWORD dwStatus;
DWORD dwType;
DWORD dwValue;
DWORD dwSize;
DWORD dwReturn;
switch (dwNewValue) {
case ENABLE_PERF_CTR_QUERY:
dwType = 0;
dwSize = sizeof (dwValue);
dwValue = 0;
dwStatus = RegQueryValueExW (
hKeyItem,
cszDisablePerformanceCounters,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwSize);
if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
switch (dwValue) {
case 0: dwReturn = ENABLE_PERF_CTR_ENABLE; break;
case 1: dwReturn = ENABLE_PERF_CTR_DISABLE; break;
default: dwReturn = 0; break;
}
} else {
// if the value is not present, or not = 1, then the perfctrs
// are enabled
dwReturn = ENABLE_PERF_CTR_ENABLE;
}
break;
case ENABLE_PERF_CTR_ENABLE:
dwType = REG_DWORD;
dwSize = sizeof (dwValue);
dwValue = 0;
dwStatus = RegSetValueExW (
hKeyItem,
cszDisablePerformanceCounters,
0L,
dwType,
(LPBYTE)&dwValue,
dwSize);
if (dwStatus == ERROR_SUCCESS) {
dwReturn = ENABLE_PERF_CTR_ENABLE;
} else {
dwReturn = 0;
}
break;
case ENABLE_PERF_CTR_DISABLE:
dwType = REG_DWORD;
dwSize = sizeof (dwValue);
dwValue = 1;
dwStatus = RegSetValueExW (
hKeyItem,
cszDisablePerformanceCounters,
0L,
dwType,
(LPBYTE)&dwValue,
dwSize);
if (dwStatus == ERROR_SUCCESS) {
dwReturn = ENABLE_PERF_CTR_DISABLE;
} else {
dwReturn = 0;
}
break;
default:
dwReturn = 0;
}
return dwReturn;
}
void CExctrlstDlg::ScanForExtensibleCounters ()
{
LONG lStatus = ERROR_SUCCESS;
LONG lEnumStatus = ERROR_SUCCESS;
DWORD dwServiceIndex;
TCHAR szServiceSubKeyName[MAX_PATH];
TCHAR szPerfSubKeyName[MAX_PATH+20];
TCHAR szItemText[MAX_PATH];
TCHAR szListText[MAX_PATH*2];
DWORD dwNameSize;
HKEY hKeyPerformance;
UINT_PTR nListBoxEntry;
DWORD dwItemSize, dwType, dwValue;
HCURSOR hOldCursor;
DWORD dwThisExtent;
HDC hDcListBox;
CWnd *pCWndListBox;
hOldCursor = ::SetCursor (LoadCursor(NULL, IDC_WAIT));
ResetListBox();
if (hKeyServices == NULL) {
// try read/write access
lStatus = RegOpenKeyEx (hKeyMachine,
cszServiceKeyName,
0L,
dwRegAccessMask,
&hKeyServices);
if (lStatus != ERROR_SUCCESS) {
// try read-only then
dwRegAccessMask = KEY_READ;
bReadWriteAccess = FALSE;
lStatus = RegOpenKeyEx (hKeyMachine,
cszServiceKeyName,
0L,
dwRegAccessMask,
&hKeyServices);
if (lStatus != ERROR_SUCCESS) {
// display Read Only message
AfxMessageBox (IDS_READ_ONLY);
} else {
// fall through with error code
// display no access message
AfxMessageBox (IDS_NO_ACCESS);
}
}
} else {
lStatus = ERROR_SUCCESS;
}
if (lStatus == ERROR_SUCCESS) {
pCWndListBox = GetDlgItem (IDC_EXT_LIST);
hDcListBox = ::GetDC (pCWndListBox->m_hWnd);
if (hDcListBox == NULL) {
return;
}
dwServiceIndex = 0;
dwNameSize = MAX_PATH;
while ((lEnumStatus = RegEnumKeyEx (
hKeyServices,
dwServiceIndex,
szServiceSubKeyName,
&dwNameSize,
NULL,
NULL,
NULL,
NULL)) == ERROR_SUCCESS) {
//try to open the perfkey under this key.
lstrcpy (szPerfSubKeyName, szServiceSubKeyName);
lstrcat (szPerfSubKeyName, cszPerformance);
lStatus = RegOpenKeyEx (
hKeyServices,
szPerfSubKeyName,
0L,
dwRegAccessMask,
&hKeyPerformance);
if (lStatus == ERROR_SUCCESS) {
// look up the library name
dwItemSize = MAX_PATH * sizeof(TCHAR);
dwType = 0;
lStatus = RegQueryValueEx (
hKeyPerformance,
cszLibrary,
NULL,
&dwType,
(LPBYTE)&szItemText[0],
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) ||
((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
lstrcpy (szItemText, cszNotFound);
}
dwItemSize = sizeof(DWORD);
dwType = 0;
dwValue = 0;
lStatus = RegQueryValueEx (
hKeyPerformance,
cszFirstCounter,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
dwValue = 0;
}
// make the string for the list box here depending
// on the selected sort order.
if (dwSortOrder == SORT_ORDER_LIBRARY) {
lstrcpy(szListText, szItemText);
lstrcat(szListText, cszTab);
lstrcat(szListText, szServiceSubKeyName);
} else if (dwSortOrder == SORT_ORDER_ID) {
_stprintf (szListText, cszSortIdFmt,
dwValue, szServiceSubKeyName);
} else { // default is sort by service
lstrcpy(szListText, szServiceSubKeyName);
lstrcat(szListText, cszTab);
lstrcat(szListText, szItemText);
}
// add this name to the list box
nListBoxEntry = SendDlgItemMessage(IDC_EXT_LIST,
LB_ADDSTRING, 0, (LPARAM)&szListText[0]);
if (nListBoxEntry != LB_ERR) {
dwThisExtent = GetTabbedTextExtent (
hDcListBox,
szListText,
lstrlen(szListText),
(int)dwTabStopCount,
(int *)&dwTabStopArray[0]);
if (dwThisExtent > dwListBoxHorizExtent) {
dwListBoxHorizExtent = dwThisExtent;
SendDlgItemMessage(IDC_EXT_LIST,
LB_SETHORIZONTALEXTENT,
(WPARAM)LOWORD(dwListBoxHorizExtent), (LPARAM)0);
}
// save key to this entry in the registry
SendDlgItemMessage(IDC_EXT_LIST,
LB_SETITEMDATA, (WPARAM)nListBoxEntry,
(LPARAM)hKeyPerformance);
// Ignore PREFIX complains of handle leak for hKeyPerformance.
//
// local variable hKeyPerformance (registry key for "<service>\Performace") is
// put in persistent data storage so that later EXCTRLST can retrieve its value in
// CExctrlstDlg::UpdateDllInfo() and CExctrlstDlg::OnEnablePerf() and uses it as
// a parameter in RegQueryValueEx() calls.
// These registry keys will be released in CExctrlstDlg::ResetListBox().
}
else {
// close the key since there's no point in
// keeping it open
RegCloseKey(hKeyPerformance);
SendDlgItemMessage(IDC_EXT_LIST,
LB_SETITEMDATA, (WPARAM) nListBoxEntry,
(LPARAM) NULL);
}
}
// reset for next loop
dwServiceIndex++;
dwNameSize = MAX_PATH;
}
::ReleaseDC (pCWndListBox->m_hWnd, hDcListBox);
}
nListBoxEntry = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCOUNT);
if (nListBoxEntry > 0) {
SendDlgItemMessage (IDC_EXT_LIST, LB_SETCURSEL, 0, 0);
}
::SetCursor (hOldCursor);
}
void CExctrlstDlg::UpdateSystemInfo () {
TCHAR szItemText[MAX_PATH];
_stprintf (szItemText, cszIdFmt,
dwIdArray[0], dwIdArray[0], cszSpace);
SetDlgItemText (IDC_LAST_COUNTER_VALUE, szItemText);
_stprintf (szItemText, cszIdFmt,
dwIdArray[1], dwIdArray[1],
dwIdArray[1] != dwIdArray[0] ? cszSplat : cszSpace);
SetDlgItemText (IDC_LAST_TEXT_COUNTER_VALUE, szItemText);
_stprintf (szItemText, cszIdFmt,
dwIdArray[2], dwIdArray[2], cszSpace);
SetDlgItemText (IDC_LAST_HELP_VALUE, szItemText);
_stprintf (szItemText, cszIdFmt,
dwIdArray[3], dwIdArray[3],
dwIdArray[3] != dwIdArray[2] ? cszSplat : cszSpace);
SetDlgItemText (IDC_LAST_TEXT_HELP_VALUE, szItemText);
}
void CExctrlstDlg::UpdateDllInfo () {
HKEY hKeyItem;
TCHAR szItemText[MAX_PATH];
UINT_PTR nSelectedItem;
LONG lStatus;
DWORD dwType;
DWORD dwValue;
DWORD dwItemSize;
BOOL bNoIndexValues = FALSE;
DWORD dwEnabled;
CString OpenProcName;
CString LibraryName;
HCURSOR hOldCursor;
hOldCursor = ::SetCursor (LoadCursor(NULL, IDC_WAIT));
OpenProcName.Empty();
LibraryName.Empty();
// update the performance counter information
nSelectedItem = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCURSEL);
if (nSelectedItem != LB_ERR) {
// get registry key for the selected item
hKeyItem = (HKEY)SendDlgItemMessage(IDC_EXT_LIST, LB_GETITEMDATA,
(WPARAM)nSelectedItem, 0);
if (hKeyItem == NULL) {
lStatus = ERROR_INVALID_HANDLE;
}
else {
dwItemSize = MAX_PATH * sizeof(TCHAR);
dwType = 0;
lStatus = RegQueryValueEx(
hKeyItem,
cszLibrary,
NULL,
& dwType,
(LPBYTE) & szItemText[0],
& dwItemSize);
}
if ((lStatus != ERROR_SUCCESS) ||
((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
lstrcpy (szItemText, cszNotFound);
} else {
LibraryName = szItemText;
}
SetDlgItemText (IDC_DLL_NAME, szItemText);
dwItemSize = MAX_PATH * sizeof(TCHAR);
dwType = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszOpen,
NULL,
&dwType,
(LPBYTE)&szItemText[0],
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) ||
((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
lstrcpy (szItemText, cszNotFound);
} else {
OpenProcName = szItemText;
}
SetDlgItemText (IDC_OPEN_PROC, szItemText);
dwItemSize = MAX_PATH * sizeof(TCHAR);
dwType = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszCollect,
NULL,
&dwType,
(LPBYTE)&szItemText[0],
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) ||
((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
lstrcpy (szItemText, cszNotFound);
}
SetDlgItemText (IDC_COLLECT_PROC, szItemText);
dwItemSize = MAX_PATH * sizeof(TCHAR);
dwType = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszClose,
NULL,
&dwType,
(LPBYTE)&szItemText[0],
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) ||
((dwType != REG_SZ) && dwType != REG_EXPAND_SZ)) {
lstrcpy (szItemText, cszNotFound);
}
SetDlgItemText (IDC_CLOSE_PROC, szItemText);
dwItemSize = sizeof(DWORD);
dwType = 0;
dwValue = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszFirstCounter,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
lstrcpy (szItemText, cszNotFound);
bNoIndexValues = TRUE;
} else {
_stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
}
SetDlgItemText (IDC_FIRST_CTR_ID, szItemText);
dwItemSize = sizeof(DWORD);
dwType = 0;
dwValue = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszLastCounter,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
lstrcpy (szItemText, cszNotFound);
} else {
_stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
}
SetDlgItemText (IDC_LAST_CTR_ID, szItemText);
dwItemSize = sizeof(DWORD);
dwType = 0;
dwValue = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszFirstHelp,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
lstrcpy (szItemText, cszNotFound);
bNoIndexValues = TRUE;
} else {
_stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
}
SetDlgItemText (IDC_FIRST_HELP_ID, szItemText);
dwItemSize = sizeof(DWORD);
dwType = 0;
dwValue = 0;
lStatus = RegQueryValueEx (
hKeyItem,
cszLastHelp,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwItemSize);
if ((lStatus != ERROR_SUCCESS) || (dwType != REG_DWORD)) {
lstrcpy (szItemText, cszNotFound);
} else {
_stprintf (szItemText, cszServIdFmt, dwValue, IndexHasString (dwValue) ? cszSpace : cszSplat);
}
SetDlgItemText (IDC_LAST_HELP_ID, szItemText);
if (bNoIndexValues) {
// test to see if this is a "standard" i.e. Microsoft provided
// extensible counter or simply one that hasn't been completely
// installed
if (IsMsObject(&LibraryName)) {
SetDlgItemText (IDC_FIRST_HELP_ID, cszNA);
SetDlgItemText (IDC_LAST_HELP_ID, cszNA);
SetDlgItemText (IDC_FIRST_CTR_ID, cszNA);
SetDlgItemText (IDC_LAST_CTR_ID, cszNA);
}
}
GetDlgItem(IDC_ENABLED_BTN)->ShowWindow (bReadWriteAccess ? SW_SHOW : SW_HIDE);
GetDlgItem(IDC_ENABLED_BTN)->EnableWindow (bReadWriteAccess);
dwEnabled = EnablePerfCounters (hKeyItem, ENABLE_PERF_CTR_QUERY);
if (bReadWriteAccess) {
// then set the check box
CheckDlgButton (IDC_ENABLED_BTN, dwEnabled == ENABLE_PERF_CTR_ENABLE ? 1 : 0);
GetDlgItem(IDC_DISABLED_TEXT)->ShowWindow (SW_HIDE);
} else {
// update the text message
GetDlgItem(IDC_DISABLED_TEXT)->ShowWindow (
(!(dwEnabled == ENABLE_PERF_CTR_ENABLE)) ?
SW_SHOW : SW_HIDE);
GetDlgItem(IDC_DISABLED_TEXT)->EnableWindow (TRUE);
}
}
::SetCursor (hOldCursor);
}
void CExctrlstDlg::ResetListBox ()
{
INT_PTR nItemCount;
INT nThisItem;
HKEY hKeyItem;
nItemCount = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCOUNT);
nThisItem = 0;
while (nThisItem > nItemCount) {
hKeyItem = (HKEY) SendDlgItemMessage(IDC_EXT_LIST,
LB_GETITEMDATA, (WPARAM)nThisItem);
if (hKeyItem != NULL) RegCloseKey(hKeyItem);
nThisItem++;
}
SendDlgItemMessage (IDC_EXT_LIST, LB_RESETCONTENT);
dwListBoxHorizExtent = 0;
SendDlgItemMessage(IDC_EXT_LIST,
LB_SETHORIZONTALEXTENT,
(WPARAM)LOWORD(dwListBoxHorizExtent), (LPARAM)0);
}
void CExctrlstDlg::SetSortButtons()
{
DWORD dwBtn;
switch (dwSortOrder) {
case SORT_ORDER_LIBRARY: dwBtn = IDC_SORT_LIBRARY; break;
case SORT_ORDER_SERVICE: dwBtn = IDC_SORT_SERVICE; break;
case SORT_ORDER_ID: dwBtn = IDC_SORT_ID; break;
default: dwBtn = IDC_SORT_SERVICE; break;
}
CheckRadioButton (
IDC_SORT_LIBRARY,
IDC_SORT_ID,
dwBtn);
}
/////////////////////////////////////////////////////////////////////////////
// CExctrlstDlg message handlers
BOOL CExctrlstDlg::OnInitDialog()
{
HCURSOR hOldCursor;
DWORD dwLength;
hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
CDialog::OnInitDialog();
CenterWindow();
lstrcpy (szThisComputerName, cszDoubleBackslash);
dwLength = MAX_COMPUTERNAME_LENGTH+1;
GetComputerName (&szThisComputerName[2], &dwLength);
lstrcpy (szComputerName, szThisComputerName);
SetDlgItemText (IDC_MACHINE_NAME, szComputerName);
hKeyMachine = HKEY_LOCAL_MACHINE;
pNameTable = BuildNameTable (
szComputerName,
cszDefaultLangId,
&dwLastElement, // size of array in elements
&dwIdArray[0]);
SendDlgItemMessage (IDC_MACHINE_NAME, EM_LIMITTEXT,
(WPARAM)MAX_COMPUTERNAME_LENGTH+2, 0); // include 2 leading backslash
SendDlgItemMessage (IDC_EXT_LIST, LB_SETTABSTOPS,
(WPARAM)dwTabStopCount, (LPARAM)&dwTabStopArray[0]);
SetSortButtons();
ScanForExtensibleCounters(); //.checks for access to the registry
UpdateSystemInfo();
// set the check box to the appropriate state
UpdateDllInfo ();
::SetCursor(hOldCursor);
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CExctrlstDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CExctrlstDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CExctrlstDlg::OnSelchangeExtList()
{
UpdateDllInfo ();
}
void CExctrlstDlg::OnDestroy()
{
ResetListBox();
CDialog::OnDestroy();
}
void CExctrlstDlg::OnAbout()
{
CAbout dlg;
dlg.DoModal();
}
void CExctrlstDlg::OnRefresh()
{
HCURSOR hOldCursor;
hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
ScanForExtensibleCounters();
if (pNameTable != NULL) {
HeapFree (GetProcessHeap(), 0, pNameTable);
pNameTable = NULL;
dwLastElement = 0;
}
pNameTable = BuildNameTable (
szComputerName,
cszDefaultLangId,
&dwLastElement, // size of array in elements
&dwIdArray[0]);
UpdateSystemInfo();
UpdateDllInfo ();
::SetCursor(hOldCursor);
}
void CExctrlstDlg::OnKillfocusMachineName()
{
TCHAR szNewMachineName[MAX_PATH];
HKEY hKeyNewMachine;
LONG lStatus;
HCURSOR hOldCursor;
hOldCursor = ::SetCursor (::LoadCursor (NULL, IDC_WAIT));
GetDlgItemText (IDC_MACHINE_NAME, szNewMachineName, MAX_PATH);
if (lstrcmpi(szComputerName, szNewMachineName) != 0) {
// a new computer has been entered so try to connect to it
lStatus = RegConnectRegistry (szNewMachineName,
HKEY_LOCAL_MACHINE, &hKeyNewMachine);
if (lStatus == ERROR_SUCCESS) {
RegCloseKey (hKeyServices); // close the old key
hKeyServices = NULL; // clear it
bReadWriteAccess = TRUE; // reset the access variables
dwRegAccessMask = KEY_READ | KEY_WRITE;
if (hKeyMachine != NULL && hKeyMachine != INVALID_HANDLE_VALUE
&& hKeyMachine != HKEY_LOCAL_MACHINE) {
RegCloseKey(hKeyMachine); // close the old machine
}
hKeyMachine = hKeyNewMachine; // update to the new machine
lstrcpy (szComputerName, szNewMachineName); // update the name
OnRefresh(); // get new counters
} else {
SetDlgItemText (IDC_MACHINE_NAME, szComputerName);
}
} else {
// the machine name has not changed
}
::SetCursor (hOldCursor);
}
void CExctrlstDlg::OnSortButton()
{
if (IsDlgButtonChecked(IDC_SORT_LIBRARY)) {
dwSortOrder = SORT_ORDER_LIBRARY;
} else if (IsDlgButtonChecked(IDC_SORT_SERVICE)) {
dwSortOrder = SORT_ORDER_SERVICE;
} else if (IsDlgButtonChecked(IDC_SORT_ID)) {
dwSortOrder = SORT_ORDER_ID;
}
ScanForExtensibleCounters();
UpdateDllInfo ();
}
void CExctrlstDlg::OnEnablePerf()
{
HKEY hKeyItem;
UINT_PTR nSelectedItem;
DWORD dwNewValue;
nSelectedItem = SendDlgItemMessage (IDC_EXT_LIST, LB_GETCURSEL);
if (nSelectedItem != LB_ERR) {
// get registry key for the selected item
hKeyItem = (HKEY)SendDlgItemMessage (IDC_EXT_LIST, LB_GETITEMDATA,
(WPARAM)nSelectedItem, 0);
if (hKeyItem != NULL) {
// get selected perf item and the corre
dwNewValue = IsDlgButtonChecked(IDC_ENABLED_BTN) ?
ENABLE_PERF_CTR_ENABLE :
ENABLE_PERF_CTR_DISABLE;
if (EnablePerfCounters (hKeyItem, dwNewValue) == 0) {
MessageBeep(0xFFFFFFFF);
// then it failed so reset to the curent value
dwNewValue = EnablePerfCounters (hKeyItem, ENABLE_PERF_CTR_QUERY);
CheckDlgButton (IDC_ENABLED_BTN, dwNewValue == ENABLE_PERF_CTR_ENABLE ? 1 : 0);
}
}
}
}
void CExctrlstDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
switch (nID) {
case SC_CLOSE:
EndDialog(IDOK);
break;
default:
CDialog::OnSysCommand (nID, lParam);
break;
}
}
/////////////////////////////////////////////////////////////////////////////
// CAbout dialog
CAbout::CAbout(CWnd* pParent /*=NULL*/)
: CDialog(CAbout::IDD, pParent)
{
//{{AFX_DATA_INIT(CAbout)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
}
void CAbout::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAbout)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BOOL CAbout::OnInitDialog()
{
CDialog::OnInitDialog();
TCHAR buffer[512];
TCHAR strProgram[1024];
DWORD dw;
BYTE* pVersionInfo;
LPTSTR pVersion = NULL;
LPTSTR pProduct = NULL;
LPTSTR pCopyRight = NULL;
dw = GetModuleFileName(NULL, strProgram, 1024);
if( dw>0 ){
dw = GetFileVersionInfoSize( strProgram, &dw );
if( dw > 0 ){
pVersionInfo = (BYTE*)malloc(dw);
if( NULL != pVersionInfo ){
if(GetFileVersionInfo( strProgram, 0, dw, pVersionInfo )){
LPDWORD lptr = NULL;
VerQueryValue( pVersionInfo, _T("\\VarFileInfo\\Translation"), (void**)&lptr, (UINT*)&dw );
if( lptr != NULL ){
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("ProductVersion") );
VerQueryValue( pVersionInfo, buffer, (void**)&pVersion, (UINT*)&dw );
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("OriginalFilename") );
VerQueryValue( pVersionInfo, buffer, (void**)&pProduct, (UINT*)&dw );
_stprintf( buffer, _T("\\StringFileInfo\\%04x%04x\\%s"), LOWORD(*lptr), HIWORD(*lptr), _T("LegalCopyright") );
VerQueryValue( pVersionInfo, buffer, (void**)&pCopyRight, (UINT*)&dw );
}
if( pProduct != NULL && pVersion != NULL && pCopyRight != NULL ){
GetDlgItem(IDC_COPYRIGHT)->SetWindowText( pCopyRight );
GetDlgItem(IDC_VERSION)->SetWindowText( pVersion );
}
}
free( pVersionInfo );
}
}
}
return TRUE;
}
BEGIN_MESSAGE_MAP(CAbout, CDialog)
//{{AFX_MSG_MAP(CAbout)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAbout message handlers