#include #include #include #include #include #include #include "showperf.h" #include "perfdata.h" #include "resource.h" #include "maindlg.h" static PPERF_DATA_BLOCK pMainPerfData = NULL; // pointer to perfdata block static LPWSTR *szNameTable = NULL; // pointer to perf name table static DWORD dwLastName = 0; static TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH+3]; static TCHAR szThisComputerName[MAX_COMPUTERNAME_LENGTH+3]; static HKEY hKeyMachine = NULL; static HKEY hKeyPerformance = NULL; #define NUM_TAB_STOPS 3 static INT nDataListTabs[NUM_TAB_STOPS] = { 26 , 160 , 235 }; static BOOL LoadObjectList ( IN HWND hDlg, IN LPCTSTR szMatchItem ) { PPERF_OBJECT_TYPE pObject; HWND hWndObjectCB; UINT nInitial = 0; UINT nIndex; LONG lObjectId; TCHAR szNameBuffer[MAX_PATH]; DWORD dwThisObject; DWORD dwCounterType; hWndObjectCB = GetDlgItem (hDlg, IDC_OBJECT); if (IsDlgButtonChecked (hDlg, IDC_INCLUDE_COSTLY) == CHECKED) { dwCounterType = 1; } else { dwCounterType = 0; } // get current data block if (GetSystemPerfData (hKeyPerformance, &pMainPerfData, dwCounterType) == ERROR_SUCCESS) { // data acquired so clear combo and display SendMessage (hWndObjectCB, CB_RESETCONTENT, 0, 0); pObject = FirstObject (pMainPerfData); __try { for (dwThisObject = 0; dwThisObject < pMainPerfData->NumObjectTypes; dwThisObject++) { // get counter object name here... _stprintf (szNameBuffer, TEXT("(%d) %s"), pObject->ObjectNameTitleIndex, szNameTable[pObject->ObjectNameTitleIndex]); nIndex = SendMessage (hWndObjectCB, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)szNameBuffer); if (nIndex != CB_ERR) { // save object pointer SendMessage (hWndObjectCB, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)pObject); if (pObject->ObjectNameTitleIndex == (DWORD)pMainPerfData->DefaultObject) { // remember this index to set the default object nInitial = nIndex; } } pObject = NextObject(pObject); } } __except (EXCEPTION_EXECUTE_HANDLER) { _stprintf (szNameBuffer, TEXT("An exception (0x%8.8x) occured in object block # %d returned by the system."), GetExceptionCode (), dwThisObject+1); MessageBox (hDlg, szNameBuffer, TEXT("Data Error"), MB_OK); // update the data buffer so that only the valid objects // are accessed in the future. pMainPerfData->NumObjectTypes = dwThisObject-1; } if (szMatchItem == NULL) { SendMessage (hWndObjectCB, CB_SETCURSEL, (WPARAM)nInitial, 0); } else { // match to arg string as best as possible if (SendMessage (hWndObjectCB, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)szMatchItem) == CB_ERR) { // no match found so use default SendMessage (hWndObjectCB, CB_SETCURSEL, (WPARAM)nInitial, 0); } } } else { DisplayMessageBox (hDlg, IDS_UNABLE_GET_DATA, IDS_APP_ERROR, MB_OK); } return TRUE; } static LoadInstanceList ( IN HWND hDlg, IN LPCTSTR szMatchItem ) { PPERF_OBJECT_TYPE pObject; PPERF_OBJECT_TYPE pParentObject; PPERF_COUNTER_BLOCK pCounterBlock; PPERF_INSTANCE_DEFINITION pInstance; PPERF_INSTANCE_DEFINITION pParentInstance; UINT nCbSel; LONG lThisInstance; TCHAR szNameBuffer[MAX_PATH]; TCHAR szParentName[MAX_PATH]; UINT nIndex; nCbSel = SendDlgItemMessage (hDlg, IDC_OBJECT, CB_GETCURSEL, 0, 0); if (nCbSel != CB_ERR) { pObject = (PPERF_OBJECT_TYPE)SendDlgItemMessage (hDlg, IDC_OBJECT, CB_GETITEMDATA, (WPARAM)nCbSel, 0); if (pObject->NumInstances == PERF_NO_INSTANCES) { // no instances so... // clear old contents SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_RESETCONTENT, 0, 0); // add display text SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("")); // select this (and only) string SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETCURSEL, 0, 0); // get pointer to counter data pCounterBlock = (PPERF_COUNTER_BLOCK)((LPBYTE)pObject + pObject->DefinitionLength); // and save it as item data SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETITEMDATA, 0, (LPARAM)pCounterBlock); // finally grey the window to prevent selections EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE), FALSE); } else { //enable window EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE), TRUE); SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_RESETCONTENT, 0, 0); pInstance = FirstInstance (pObject); for (lThisInstance = 0; lThisInstance < pObject->NumInstances; lThisInstance++) { pParentObject = GetObjectDefByTitleIndex ( pMainPerfData, pInstance->ParentObjectTitleIndex); if (pParentObject != NULL) { pParentInstance = GetInstance (pParentObject, pInstance->ParentObjectInstance); } else { pParentInstance = NULL; } if (pParentInstance != NULL) { if (pParentInstance->UniqueID < 0) { // use the instance name wcsncpy (szParentName, (LPWSTR)((LPBYTE)pParentInstance+pParentInstance->NameOffset), pParentInstance->NameLength); lstrcat (szParentName, TEXT("==>")); } else { // use the instance number _stprintf (szParentName, TEXT("[%d]==>"), pParentInstance->UniqueID); } } else { // unknown parent *szParentName = 0; } if (pInstance->UniqueID < 0) { // use the instance name wcsncpy (szNameBuffer, (LPWSTR)((LPBYTE)pInstance+pInstance->NameOffset), pInstance->NameLength); } else { // use the instance number _stprintf (szNameBuffer, TEXT("(%d)"), pInstance->UniqueID); } lstrcat (szParentName, szNameBuffer); nIndex = SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)szParentName); if (nIndex != CB_ERR) { // save pointer to counter block pCounterBlock = (PERF_COUNTER_BLOCK *) ((PCHAR) pInstance + pInstance->ByteLength); SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETITEMDATA, (WPARAM)nIndex, (LPARAM)pCounterBlock); } pInstance = NextInstance (pInstance); } if (szMatchItem == NULL) { SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETCURSEL, 0, 0); } else { if (SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SELECTSTRING, (WPARAM)-1, (LPARAM)szMatchItem) == CB_ERR) { SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETCURSEL, 0, 0); } } } } else { // no object selected // clear old contents SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_RESETCONTENT, 0, 0); // add display text SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("")); // select this (and only) string SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETCURSEL, 0, 0); // and save null pointer as item data SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_SETITEMDATA, 0, (LPARAM)0); // finally grey the window to prevent selections EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE), FALSE); } return TRUE; } static LPCTSTR GetCounterTypeName ( IN DWORD dwCounterType ) { UINT nTypeString = 0; switch (dwCounterType) { case PERF_COUNTER_COUNTER: nTypeString = IDS_TYPE_COUNTER_COUNTER ; break; case PERF_COUNTER_TIMER: nTypeString = IDS_TYPE_COUNTER_TIMER ; break; case PERF_COUNTER_QUEUELEN_TYPE: nTypeString = IDS_TYPE_COUNTER_QUEUELEN ; break; case PERF_COUNTER_BULK_COUNT: nTypeString = IDS_TYPE_COUNTER_BULK_COUNT ; break; case PERF_COUNTER_TEXT: nTypeString = IDS_TYPE_COUNTER_TEXT ; break; case PERF_COUNTER_RAWCOUNT: nTypeString = IDS_TYPE_COUNTER_RAWCOUNT ; break; case PERF_COUNTER_LARGE_RAWCOUNT: nTypeString = IDS_TYPE_COUNTER_LARGE_RAW ; break; case PERF_SAMPLE_FRACTION: nTypeString = IDS_TYPE_SAMPLE_FRACTION ; break; case PERF_SAMPLE_COUNTER: nTypeString = IDS_TYPE_SAMPLE_COUNTER ; break; case PERF_COUNTER_NODATA: nTypeString = IDS_TYPE_COUNTER_NODATA ; break; case PERF_COUNTER_TIMER_INV: nTypeString = IDS_TYPE_COUNTER_TIMER_INV ; break; case PERF_SAMPLE_BASE: nTypeString = IDS_TYPE_SAMPLE_BASE ; break; case PERF_AVERAGE_TIMER: nTypeString = IDS_TYPE_AVERAGE_TIMER ; break; case PERF_AVERAGE_BASE: nTypeString = IDS_TYPE_AVERAGE_BASE ; break; case PERF_AVERAGE_BULK: nTypeString = IDS_TYPE_AVERAGE_BULK ; break; case PERF_100NSEC_TIMER: nTypeString = IDS_TYPE_100NS_TIMER ; break; case PERF_100NSEC_TIMER_INV: nTypeString = IDS_TYPE_100NS_TIMER_INV ; break; case PERF_COUNTER_MULTI_TIMER: nTypeString = IDS_TYPE_MULTI_TIMER ; break; case PERF_COUNTER_MULTI_TIMER_INV: nTypeString = IDS_TYPE_MULTI_TIMER_INV ; break; case PERF_COUNTER_MULTI_BASE: nTypeString = IDS_TYPE_MULTI_BASE ; break; case PERF_100NSEC_MULTI_TIMER: nTypeString = IDS_TYPE_100NS_MULTI_TIMER ; break; case PERF_100NSEC_MULTI_TIMER_INV: nTypeString = IDS_TYPE_100NS_MULTI_TIMER_INV ; break; case PERF_RAW_FRACTION: nTypeString = IDS_TYPE_RAW_FRACTION; break; case PERF_RAW_BASE: nTypeString = IDS_TYPE_RAW_BASE ; break; case PERF_ELAPSED_TIME: nTypeString = IDS_TYPE_ELAPSED_TIME ; break; case PERF_COUNTER_HISTOGRAM_TYPE: nTypeString = IDS_TYPE_HISTOGRAM ; break; case PERF_COUNTER_LARGE_QUEUELEN_TYPE: nTypeString = IDS_TYPE_COUNTER_LARGE_QUEUELEN ; break; case PERF_COUNTER_DELTA: nTypeString = IDS_TYPE_COUNTER_DELTA ; break; case PERF_COUNTER_LARGE_DELTA: nTypeString = IDS_TYPE_COUNTER_LARGE_DELTA ; break; } if (nTypeString != 0) { return GetStringResource (NULL, nTypeString); } else { return TEXT(""); } } static BOOL ShowCounterData ( IN HWND hDlg, IN LONG lDisplayIndex ) { PPERF_OBJECT_TYPE pObject; PPERF_COUNTER_DEFINITION pCounterDef; PPERF_COUNTER_BLOCK pCounterBlock; UINT nSelObject, nSelInstance; TCHAR szTypeNameBuffer[MAX_PATH]; TCHAR szDisplayBuffer [SMALL_BUFFER_SIZE]; DWORD *pdwLoDword, *pdwHiDword; DWORD dwThisCounter; SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_RESETCONTENT, 0, 0); nSelObject = SendDlgItemMessage (hDlg, IDC_OBJECT, CB_GETCURSEL, 0, 0); nSelInstance = SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_GETCURSEL, 0, 0); if ((nSelObject != CB_ERR) && (nSelInstance != CB_ERR)) { pObject = (PPERF_OBJECT_TYPE)SendDlgItemMessage (hDlg, IDC_OBJECT, CB_GETITEMDATA, (WPARAM)nSelObject, 0); pCounterBlock = (PPERF_COUNTER_BLOCK)SendDlgItemMessage (hDlg, IDC_INSTANCE, CB_GETITEMDATA, (WPARAM)nSelInstance, 0); pCounterDef = FirstCounter (pObject); for (dwThisCounter = 0; dwThisCounter < pObject->NumCounters; dwThisCounter++) { // get pointer to this counter's data (in this instance if applicable pdwLoDword = (PDWORD)((LPBYTE)pCounterBlock + pCounterDef->CounterOffset); pdwHiDword = pdwLoDword + 1; lstrcpy (szTypeNameBuffer, GetCounterTypeName (pCounterDef->CounterType)); if (*szTypeNameBuffer == 0) { // no string returned so format data as HEX DWORD _stprintf (szTypeNameBuffer, TEXT("Undefined Type: 0x%8.8x"), pCounterDef->CounterType); } if (pCounterDef->CounterSize <= sizeof(DWORD)) { _stprintf (szDisplayBuffer, TEXT("%d\t%s\t%s\t0x%8.8x (%d)"), pCounterDef->CounterNameTitleIndex, szNameTable[pCounterDef->CounterNameTitleIndex], szTypeNameBuffer, *pdwLoDword, *pdwLoDword); } else { _stprintf (szDisplayBuffer, TEXT("%d\t%s\t%s\t0x%8.8x%8.8x"), pCounterDef->CounterNameTitleIndex, szNameTable[pCounterDef->CounterNameTitleIndex], szTypeNameBuffer, *pdwHiDword, *pdwLoDword); } SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)szDisplayBuffer); pCounterDef = NextCounter(pCounterDef); } if (lDisplayIndex < 0) { if (pObject->DefaultCounter >= 0) { SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_SETCURSEL, (WPARAM)pObject->DefaultCounter, 0); } else { SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_SETCURSEL, (WPARAM)0, 0); } } else { SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_SETCURSEL, (WPARAM)lDisplayIndex, (LPARAM)0); } } else { // no object and/or instsance selected so nothing else to do } return TRUE; } static BOOL OnComputerChange ( IN HWND hDlg ) { TCHAR szLocalComputerName [MAX_COMPUTERNAME_LENGTH+3]; HKEY hLocalMachineKey = NULL; HKEY hLocalPerfKey = NULL; LPWSTR *szLocalNameTable = NULL; BOOL bResult = FALSE; HWND hWndComputerName; SET_WAIT_CURSOR; // get name from edit control hWndComputerName = GetDlgItem (hDlg, IDC_COMPUTERNAME); GetWindowText (hWndComputerName, szLocalComputerName, MAX_COMPUTERNAME_LENGTH); if (lstrcmpi(szComputerName, szLocalComputerName) != 0) { // a new name has been entered so try to connect to it if (lstrcmpi(szLocalComputerName, szThisComputerName) == 0) { // then this is the local machine which is a special case hLocalMachineKey = HKEY_LOCAL_MACHINE; hLocalPerfKey = HKEY_PERFORMANCE_DATA; szLocalComputerName[0] = 0; } else { // try to connect to remote computer if (RegConnectRegistry (szLocalComputerName, HKEY_LOCAL_MACHINE, &hLocalMachineKey) == ERROR_SUCCESS) { // connected to the new machine, so Try to connect to // the performance data, too if (RegConnectRegistry (szLocalComputerName, HKEY_PERFORMANCE_DATA, &hLocalPerfKey) == ERROR_SUCCESS) { } else { DisplayMessageBox (hDlg, IDS_UNABLE_CONNECT_PERF, IDS_APP_ERROR, MB_OK); } } else { DisplayMessageBox (hDlg, IDS_UNABLE_CONNECT_MACH, IDS_APP_ERROR, MB_OK); } } if ((hLocalMachineKey != NULL) && (hLocalPerfKey != NULL)) { // try to get a new name table szLocalNameTable = BuildNameTable ( (szLocalComputerName == 0 ? NULL : szLocalComputerName), NULL, &dwLastName); if (szLocalNameTable) { bResult = TRUE; } else { DisplayMessageBox (hDlg, IDS_UNABLE_GET_NAMES, IDS_APP_ERROR, MB_OK); } } if (bResult) { // made it so close the old connections if (hKeyMachine != NULL) { RegCloseKey (hKeyMachine); } hKeyMachine = hLocalMachineKey; if (hKeyPerformance != NULL) { RegCloseKey (hKeyPerformance); } hKeyPerformance = hLocalPerfKey; if (szNameTable != NULL) { MemoryFree (szNameTable); } szNameTable = szLocalNameTable; if (szLocalComputerName[0] == 0) { lstrcpy (szComputerName, szThisComputerName); } // then update the fields LoadObjectList (hDlg, NULL); LoadInstanceList (hDlg, NULL); ShowCounterData (hDlg, -1); } else { // unable to get info from machine so clean up if (hLocalPerfKey != NULL) RegCloseKey (hLocalPerfKey); if (hLocalMachineKey != NULL) RegCloseKey (hLocalMachineKey); if (szLocalNameTable != NULL) MemoryFree (szLocalNameTable); // reset computer name to the one that works. SetWindowText (hWndComputerName, szComputerName); } } else { // the name hasn't changed } return TRUE; } static BOOL MainDlg_WM_INITDIALOG ( IN HWND hDlg, IN WPARAM wParam, IN LPARAM lParam ) { DWORD dwComputerNameLength = MAX_COMPUTERNAME_LENGTH+1; SET_WAIT_CURSOR; lstrcpy (szThisComputerName, TEXT("\\\\")); GetComputerName (szThisComputerName+2, &dwComputerNameLength); szComputerName[0] = 0; // reset the computer name // load the local machine name into the edit box SetWindowText (GetDlgItem (hDlg, IDC_COMPUTERNAME), szThisComputerName); SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_SETTABSTOPS, (WPARAM)NUM_TAB_STOPS, (LPARAM)&nDataListTabs); CheckDlgButton (hDlg, IDC_INCLUDE_COSTLY, UNCHECKED); OnComputerChange (hDlg); SetFocus (GetDlgItem (hDlg, IDC_OBJECT)); SET_ARROW_CURSOR; return FALSE; } static BOOL MainDlg_IDC_COMPUTERNAME ( IN HWND hDlg, IN WORD wNotifyMsg, IN HWND hWndControl ) { switch (wNotifyMsg) { case EN_KILLFOCUS: OnComputerChange(hDlg); return TRUE; default: return FALSE; } } static BOOL MainDlg_IDC_OBJECT ( IN HWND hDlg, IN WORD wNotifyMsg, IN HWND hWndControl ) { switch (wNotifyMsg) { case CBN_SELCHANGE: SET_WAIT_CURSOR; LoadInstanceList (hDlg, NULL); ShowCounterData (hDlg, -1); SET_ARROW_CURSOR; return TRUE; default: return FALSE; } } static BOOL MainDlg_IDC_INSTANCE ( IN HWND hDlg, IN WORD wNotifyMsg, IN HWND hWndControl ) { switch (wNotifyMsg) { case CBN_SELCHANGE: SET_WAIT_CURSOR; ShowCounterData (hDlg, -1); SET_ARROW_CURSOR; return TRUE; default: return FALSE; } } static BOOL MainDlg_IDC_DATA_LIST ( IN HWND hDlg, IN WORD wNotifyMsg, IN HWND hWndControl ) { switch (wNotifyMsg) { default: return FALSE; } } static BOOL MainDlg_IDC_REFRESH ( IN HWND hDlg, IN WORD wNotifyMsg, IN HWND hWndControl ) { TCHAR szSelObject[MAX_PATH]; TCHAR szSelInstance[MAX_PATH]; LONG lCounterIdx; switch (wNotifyMsg) { case BN_CLICKED: SET_WAIT_CURSOR; GetDlgItemText (hDlg, IDC_OBJECT, szSelObject, MAX_PATH-1); GetDlgItemText (hDlg, IDC_INSTANCE, szSelInstance, MAX_PATH-1); lCounterIdx = SendDlgItemMessage (hDlg, IDC_DATA_LIST, LB_GETCURSEL, 0, 0); LoadObjectList (hDlg, szSelObject); LoadInstanceList (hDlg, szSelInstance); ShowCounterData (hDlg, lCounterIdx); SET_ARROW_CURSOR; return TRUE; default: return FALSE; } } static BOOL MainDlg_WM_COMMAND ( IN HWND hDlg, IN WPARAM wParam, IN LPARAM lParam ) { WORD wCtrlId, wNotifyMsg; HWND hWndControl; wCtrlId = GET_CONTROL_ID (wParam); wNotifyMsg = GET_NOTIFY_MSG (wParam, lParam); hWndControl = GET_COMMAND_WND (lParam); switch (wCtrlId) { case IDC_COMPUTERNAME: return MainDlg_IDC_COMPUTERNAME (hDlg, wNotifyMsg, hWndControl); case IDC_OBJECT: return MainDlg_IDC_OBJECT (hDlg, wNotifyMsg, hWndControl); case IDC_INSTANCE: return MainDlg_IDC_INSTANCE (hDlg, wNotifyMsg, hWndControl); case IDC_DATA_LIST: return MainDlg_IDC_DATA_LIST (hDlg, wNotifyMsg, hWndControl); case IDC_REFRESH: return MainDlg_IDC_REFRESH (hDlg, wNotifyMsg, hWndControl); case IDOK: EndDialog (hDlg, IDOK); return TRUE; default: return FALSE; } } static BOOL MainDlg_WM_SYSCOMMAND ( IN HWND hDlg, IN WPARAM wParam, IN LPARAM lParam ) { switch (wParam) { case SC_CLOSE: EndDialog (hDlg, IDOK); return TRUE; default: return FALSE; } } static BOOL MainDlg_WM_CLOSE ( IN HWND hDlg, IN WPARAM wParam, IN LPARAM lParam ) { MemoryFree (pMainPerfData); pMainPerfData = NULL; MemoryFree (szNameTable); szNameTable = NULL; return TRUE; } BOOL MainDlgProc ( IN HWND hDlg, IN UINT message, IN WPARAM wParam, IN LPARAM lParam ) { switch (message) { case WM_INITDIALOG: return MainDlg_WM_INITDIALOG (hDlg, wParam, lParam); case WM_COMMAND: return MainDlg_WM_COMMAND (hDlg, wParam, lParam); case WM_SYSCOMMAND: return MainDlg_WM_SYSCOMMAND (hDlg, wParam, lParam); case WM_CLOSE: return MainDlg_WM_CLOSE (hDlg, wParam, lParam); default: return FALSE; } }