Source code of Windows XP (NT5)
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.

3833 lines
125 KiB

  1. /*++
  2. Copyright (C) 1995-1999 Microsoft Corporation
  3. Module Name:
  4. browsdlg.c
  5. Abstract:
  6. counter name browsing dialog box functions
  7. Revision History
  8. Bob Watson (a-robw) Oct-95 Created
  9. --*/
  10. #include <windows.h>
  11. #include <winperf.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include <tchar.h>
  16. #include "mbctype.h"
  17. #include "pdhidef.h"
  18. #include "pdhdlgs.h"
  19. #include "pdh.h"
  20. #include "browsdlg.h"
  21. #include "resource.h"
  22. #include "expldlg.h"
  23. #include "pdhui.h"
  24. #pragma warning ( disable : 4213)
  25. //
  26. // Constants used in this module
  27. //
  28. #define MACHINE_LIST_SIZE 1024
  29. #define OBJECT_LIST_SIZE 4096
  30. #define COUNTER_LIST_SIZE 8192
  31. #define INSTANCE_LIST_SIZE 8192
  32. // global data strings to load into combo box to select counter filtering level
  33. ULONG
  34. PdhiBrowseraulControlIdToHelpIdMap[] =
  35. {
  36. IDC_USE_LOCAL_MACHINE, IDH_USE_LOCAL_MACHINE,
  37. IDC_SELECT_MACHINE, IDH_SELECT_MACHINE,
  38. IDC_MACHINE_COMBO, IDH_MACHINE_COMBO,
  39. IDC_COUNTER_DETAIL_COMBO, IDH_COUNTER_DETAIL_COMBO,
  40. IDC_OBJECT_COMBO, IDH_OBJECT_COMBO,
  41. IDC_ALL_COUNTERS, IDH_ALL_COUNTERS,
  42. IDC_USE_COUNTER_LIST, IDH_USE_COUNTER_LIST,
  43. IDC_COUNTER_LIST, IDH_COUNTER_LIST,
  44. IDC_ALL_INSTANCES, IDH_ALL_INSTANCES,
  45. IDC_USE_INSTANCE_LIST, IDH_USE_INSTANCE_LIST,
  46. IDC_INSTANCE_LIST, IDH_INSTANCE_LIST,
  47. IDC_EXPLAIN_BTN, IDH_EXPLAIN_BTN,
  48. IDC_OBJECT_LIST, IDH_OBJECT_LIST,
  49. 0,0
  50. };
  51. PDHI_DETAIL_INFO PdhiDetailInfo[] = {
  52. {PERF_DETAIL_NOVICE, IDS_DETAIL_NOVICE},
  53. {PERF_DETAIL_ADVANCED, IDS_DETAIL_ADVANCED},
  54. {PERF_DETAIL_EXPERT, IDS_DETAIL_EXPERT},
  55. {PERF_DETAIL_WIZARD, IDS_DETAIL_WIZARD},
  56. {0,0}
  57. };
  58. static HWND hExplainDlg = NULL;
  59. static DWORD dwCounterListSize;
  60. static DWORD dwInstanceListSize;
  61. //
  62. // Function references
  63. //
  64. STATIC_BOOL
  65. PdhiLoadMachineObjects (
  66. IN HWND hDlg,
  67. IN BOOL bRefresh
  68. );
  69. STATIC_BOOL
  70. PdhiLoadCountersAndInstances (
  71. IN HWND hDlg
  72. );
  73. STATIC_BOOL
  74. PdhiBrowseCtrDlg_MACHINE_BUTTON (
  75. IN HWND hDlg,
  76. IN WORD wNotifyMsg,
  77. IN HWND hWndControl
  78. );
  79. STATIC_BOOL
  80. PdhiLoadNewMachine (
  81. IN HWND hDlg,
  82. IN LPCWSTR szNewMachineName
  83. );
  84. STATIC_DWORD
  85. PdhiLoadDetailLevelCombo (
  86. IN HWND hDlg,
  87. IN DWORD dwInitialLevel
  88. );
  89. STATIC_BOOL
  90. PdhiSelectItemsInPath (
  91. IN HWND hDlg
  92. );
  93. STATIC_BOOL
  94. PdhiLoadKnownMachines (
  95. IN HWND hDlg
  96. );
  97. STATIC_PDH_FUNCTION
  98. PdhiCompileSelectedCountersT (
  99. IN HWND hDlg,
  100. IN LPVOID pUsersPathBuffer,
  101. IN DWORD cchUsersPathLength,
  102. IN BOOL bUnicode
  103. );
  104. STATIC_PDH_FUNCTION
  105. PdhiCompileSelectedCountersW (
  106. IN HWND hDlg,
  107. IN LPWSTR szUsersPathBuffer,
  108. IN DWORD cchUsersPathLength
  109. );
  110. STATIC_PDH_FUNCTION
  111. PdhiCompileSelectedCountersA (
  112. IN HWND hDlg,
  113. IN LPSTR szUsersPathBuffer,
  114. IN DWORD cchUsersPathLength
  115. );
  116. STATIC_PDH_FUNCTION
  117. PdhiCompileSelectedObjectsT (
  118. IN HWND hDlg,
  119. IN LPVOID pUsersPathBuffer,
  120. IN DWORD cchUsersPathLength,
  121. IN BOOL bUnicode
  122. );
  123. STATIC_PDH_FUNCTION
  124. PdhiCompileSelectedObjectsW (
  125. IN HWND hDlg,
  126. IN LPWSTR szUsersPathBuffer,
  127. IN DWORD cchUsersPathLength
  128. );
  129. STATIC_PDH_FUNCTION
  130. PdhiCompileSelectedObjectsA (
  131. IN HWND hDlg,
  132. IN LPSTR szUsersPathBuffer,
  133. IN DWORD cchUsersPathLength
  134. );
  135. STATIC_BOOL
  136. PdhiBrowseCtrDlg_MACHINE_COMBO (
  137. IN HWND hDlg,
  138. IN WORD wNotifyMsg,
  139. IN HWND hWndControl
  140. );
  141. STATIC_BOOL
  142. PdhiBrowseCtrDlg_OBJECT_COMBO (
  143. IN HWND hDlg,
  144. IN WORD wNotifyMsg,
  145. IN HWND hWndControl
  146. );
  147. STATIC_BOOL
  148. PdhiBrowseCtrDlg_COUNTER_LIST (
  149. IN HWND hDlg,
  150. IN WORD wNotifyMsg,
  151. IN HWND hWndControl
  152. );
  153. STATIC_BOOL
  154. PdhiBrowseCtrDlg_OBJECT_LIST (
  155. IN HWND hDlg,
  156. IN WORD wNotifyMsg,
  157. IN HWND hWndControl
  158. );
  159. STATIC_BOOL
  160. PdhiBrowseCtrDlg_DETAIL_COMBO (
  161. IN HWND hDlg,
  162. IN WORD wNotifyMsg,
  163. IN HWND hWndControl
  164. );
  165. STATIC_BOOL
  166. PdhiBrowseCtrDlg_INSTANCE_BUTTON (
  167. IN HWND hDlg,
  168. IN WORD wNotifyMsg,
  169. IN HWND hWndControl
  170. );
  171. STATIC_BOOL
  172. PdhiBrowseCtrDlg_COUNTER_BUTTON (
  173. IN HWND hDlg,
  174. IN WORD wNotifyMsg,
  175. IN HWND hWndControl
  176. );
  177. STATIC_BOOL
  178. PdhiBrowseCtrDlg_OK (
  179. IN HWND hDlg,
  180. IN WORD wNotifyMsg,
  181. IN HWND hWndControl
  182. );
  183. STATIC_BOOL
  184. PdhiBrowseCtrDlg_CANCEL (
  185. IN HWND hDlg,
  186. IN WORD wNotifyMsg,
  187. IN HWND hWndControl
  188. );
  189. STATIC_BOOL
  190. PdhiBrowseCtrDlg_EXPLAIN_BTN (
  191. IN HWND hDlg,
  192. IN WORD wNotifyMsg,
  193. IN HWND hWndControl
  194. );
  195. STATIC_BOOL
  196. PdhiBrowseCtrDlg_HELP_BTN (
  197. IN HWND hDlg,
  198. IN WORD wNotifyMsg,
  199. IN HWND hWndControl
  200. );
  201. STATIC_BOOL
  202. PdhiBrowseCtrDlg_WM_INITDIALOG (
  203. IN HWND hDlg,
  204. IN WPARAM wParam,
  205. IN LPARAM lParam
  206. );
  207. STATIC_BOOL
  208. PdhiBrowseCtrDlg_WM_COMPAREITEM (
  209. IN HWND hDlg,
  210. IN WPARAM wParam,
  211. IN LPARAM lParam
  212. );
  213. STATIC_BOOL
  214. PdhiBrowseCtrDlg_WM_COMMAND (
  215. IN HWND hDlg,
  216. IN WPARAM wParam,
  217. IN LPARAM lParam
  218. );
  219. STATIC_BOOL
  220. PdhiBrowseCtrDlg_WM_SYSCOMMAND (
  221. IN HWND hDlg,
  222. IN WPARAM wParam,
  223. IN LPARAM lParam
  224. );
  225. STATIC_BOOL
  226. PdhiBrowseCtrDlg_WM_CLOSE (
  227. IN HWND hDlg,
  228. IN WPARAM wParam,
  229. IN LPARAM lParam
  230. );
  231. STATIC_BOOL
  232. PdhiBrowseCtrDlg_WM_DESTROY (
  233. IN HWND hDlg,
  234. IN WPARAM wParam,
  235. IN LPARAM lParam
  236. );
  237. __inline
  238. PDH_STATUS
  239. PdhiCopyString(
  240. LPBYTE * pszNextString,
  241. LPWSTR szWorkBuffer,
  242. LPDWORD pdwRemaining,
  243. BOOL bUnicode
  244. )
  245. {
  246. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  247. DWORD dwSize = 0;
  248. DWORD dwRemaining = * pdwRemaining;
  249. LPBYTE szNextString = * pszNextString;
  250. if (bUnicode) {
  251. dwSize = lstrlenW(szWorkBuffer);
  252. if (dwSize < dwRemaining) {
  253. lstrcpyW ((LPWSTR) szNextString, szWorkBuffer);
  254. szNextString += dwSize * sizeof(WCHAR);
  255. * ((LPWSTR) szNextString) = L'\0';
  256. szNextString += sizeof(WCHAR);
  257. } else {
  258. pdhStatus = PDH_MORE_DATA;
  259. }
  260. dwSize ++;
  261. }
  262. else {
  263. dwSize = dwRemaining;
  264. pdhStatus = PdhiConvertUnicodeToAnsi(_getmbcp(),
  265. szWorkBuffer,
  266. (LPSTR) szNextString,
  267. & dwSize);
  268. if (pdhStatus == ERROR_SUCCESS) {
  269. szNextString = szNextString
  270. + sizeof(CHAR) * (lstrlenA((LPSTR) szNextString) + 1);
  271. }
  272. }
  273. if (dwRemaining >= dwSize) {
  274. dwRemaining -= dwSize;
  275. } else {
  276. dwRemaining = 0;
  277. pdhStatus = PDH_MORE_DATA;
  278. }
  279. * pdwRemaining = dwRemaining;
  280. * pszNextString = szNextString;
  281. return pdhStatus;
  282. }
  283. STATIC_BOOL
  284. PdhiLoadNewMachine (
  285. IN HWND hDlg,
  286. IN LPCWSTR szNewMachineName
  287. )
  288. /*++
  289. Routine Description:
  290. Connects to a new machine and loads the necessary performance data
  291. from that machine.
  292. Arguments:
  293. IN HWND hDlg
  294. Handle to dialog box containing the combo & list boxes to fill
  295. IN LPCWSTR szNewMachineName
  296. Machine name to open and obtain data from
  297. Return Value:
  298. TRUE new machine connected and data loaded
  299. FALSE unable to connect to machine or obtain performance data from it.
  300. --*/
  301. {
  302. HWND hWndMachineCombo;
  303. PPDHI_BROWSE_DIALOG_DATA pData;
  304. LONG lMatchIndex;
  305. PDH_STATUS status;
  306. int mbStatus;
  307. BOOL bReturn = FALSE;
  308. DWORD dwDataSourceType;
  309. LPWSTR szMsg;
  310. // acquire the data block associated with this dialog instance
  311. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  312. if (pData == NULL) {
  313. // invalid data block, unable to continue
  314. #if PDHI_REPORT_CODE_ERRORS
  315. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  316. #endif
  317. return FALSE;
  318. }
  319. // get window handle of the dialog box
  320. hWndMachineCombo = GetDlgItem (hDlg, IDC_MACHINE_COMBO);
  321. // not in list so try to add it as long as the data source
  322. // is "Current Activity" (ie. == NULL) For Log Files, only
  323. // the machines listed may be selected.
  324. dwDataSourceType = DataSourceTypeH(pData->pDlgData->hDataSource);
  325. if (dwDataSourceType != DATA_SOURCE_LOGFILE) {
  326. status = PdhConnectMachineW (szNewMachineName);
  327. if (status == ERROR_SUCCESS) {
  328. // if successful, add string to combo box
  329. lMatchIndex = (LONG)SendMessageW (hWndMachineCombo, CB_ADDSTRING,
  330. 0, (LPARAM)szNewMachineName);
  331. SendMessageW (hWndMachineCombo, CB_SETCURSEL,
  332. (WPARAM)lMatchIndex, 0);
  333. // update other controls in this dialog
  334. PdhiLoadMachineObjects (hDlg, FALSE); // no need to update since it was just connected
  335. PdhiLoadCountersAndInstances (hDlg);
  336. SendMessageW (hDlg, WM_COMMAND,
  337. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  338. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  339. bReturn = TRUE;
  340. } else {
  341. szMsg = GetStringResource (IDS_ERR_UNABLE_TO_CONNECT);
  342. if (szMsg != NULL) {
  343. mbStatus = MessageBoxW (hDlg, szMsg, NULL,
  344. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_OK);
  345. if (mbStatus == IDCANCEL) {
  346. SetFocus(GetDlgItem(hDlg, IDC_MACHINE_COMBO));
  347. } else {
  348. SendMessageW (hWndMachineCombo, CB_SETCURSEL,
  349. pData->wpLastMachineSel, 0);
  350. }
  351. G_FREE (szMsg);
  352. } else {
  353. MessageBeep (MB_ICONEXCLAMATION);
  354. }
  355. bReturn = FALSE;
  356. }
  357. } else {
  358. szMsg = GetStringResource (IDS_ERR_MACHINE_NOT_IN_LOGFILE);
  359. if (szMsg != NULL) {
  360. mbStatus = MessageBoxW (hDlg,
  361. szMsg, NULL,
  362. MB_ICONEXCLAMATION | MB_TASKMODAL | MB_OK);
  363. G_FREE (szMsg);
  364. } else {
  365. MessageBeep (MB_ICONEXCLAMATION);
  366. }
  367. // re-select the last machine
  368. lMatchIndex = (long)SendMessageW (hWndMachineCombo,
  369. CB_FINDSTRINGEXACT,(WPARAM)-1,
  370. (LPARAM)pData->szLastMachineName);
  371. SendMessageW (hWndMachineCombo, CB_SETCURSEL,
  372. (WPARAM)lMatchIndex, 0);
  373. bReturn = FALSE;
  374. }
  375. return bReturn;
  376. }
  377. STATIC_BOOL
  378. PdhiSelectItemsInPath (
  379. IN HWND hDlg
  380. )
  381. /*++
  382. Routine Description:
  383. Selects the items in the list box based on the counter path
  384. string in the shared buffer.
  385. Arguments:
  386. IN HWND hDlg
  387. Handle to the dialog window containing the controls
  388. Return Value:
  389. TRUE if successful,
  390. FALSE if not
  391. --*/
  392. {
  393. // regular stack variables
  394. PDH_COUNTER_PATH_ELEMENTS_W *pCounterPathElementsW;
  395. PDH_COUNTER_PATH_ELEMENTS_A *pCounterPathElementsA;
  396. PDH_STATUS status;
  397. PPDHI_BROWSE_DIALOG_DATA pData;
  398. BOOL bReturn = FALSE;
  399. DWORD dwBufferSize;
  400. HWND hWndMachineCombo;
  401. HWND hWndObjectCombo;
  402. HWND hWndCounterList;
  403. HWND hWndInstanceList;
  404. LONG lIndex;
  405. WCHAR wszMachineName[MAX_PATH];
  406. // reset the last error value
  407. SetLastError (ERROR_SUCCESS);
  408. // get this dialog's user data
  409. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  410. if (pData == NULL) {
  411. #if PDHI_REPORT_CODE_ERRORS
  412. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  413. #endif
  414. return bReturn;
  415. }
  416. hWndMachineCombo = GetDlgItem (hDlg, IDC_MACHINE_COMBO);
  417. hWndObjectCombo = GetDlgItem (hDlg, IDC_OBJECT_COMBO);
  418. hWndCounterList = GetDlgItem (hDlg, IDC_COUNTER_LIST);
  419. hWndInstanceList = GetDlgItem (hDlg, IDC_INSTANCE_LIST);
  420. // Call the right conversion function based on user's buffer
  421. if (pData->pDlgData->pWideStruct != NULL) {
  422. // UNICODE/ wide characters
  423. dwBufferSize = MAX_PATH * 2 * sizeof (WCHAR);
  424. pCounterPathElementsW = (PDH_COUNTER_PATH_ELEMENTS_W *)
  425. G_ALLOC(dwBufferSize);
  426. if (pCounterPathElementsW == NULL) {
  427. SetLastError (PDH_MEMORY_ALLOCATION_FAILURE);
  428. return bReturn;
  429. }
  430. status = PdhParseCounterPathW (
  431. pData->pDlgData->pWideStruct->szReturnPathBuffer,
  432. pCounterPathElementsW,
  433. &dwBufferSize,
  434. 0);
  435. if (status == ERROR_SUCCESS) {
  436. // select entry in each list box
  437. // select machine entry. Load machine if necessary
  438. lIndex = (LONG)SendMessageW (hWndMachineCombo, CB_FINDSTRINGEXACT,
  439. (WPARAM)-1, (LPARAM)pCounterPathElementsW->szMachineName);
  440. if (lIndex == CB_ERR) {
  441. // try adding the machine
  442. if (!PdhiLoadNewMachine (hDlg, pCounterPathElementsW->szMachineName)) {
  443. // give up
  444. bReturn = FALSE;
  445. } else {
  446. // the correct machine has been selected
  447. }
  448. } else {
  449. // the machine has been found so select it
  450. SendMessageW (hWndMachineCombo, CB_SETCURSEL,
  451. (WPARAM)lIndex, 0);
  452. // update other fields
  453. PdhiLoadMachineObjects (hDlg, FALSE); // no need to update since it was just connected
  454. }
  455. // select the current object
  456. lIndex = (LONG)SendMessageW (hWndObjectCombo, CB_FINDSTRING,
  457. (WPARAM)-1, (LPARAM)pCounterPathElementsW->szObjectName);
  458. if (lIndex != CB_ERR) {
  459. SendMessageW (hWndObjectCombo, CB_SETCURSEL,
  460. (WPARAM)lIndex, 0);
  461. // update the counters for this object
  462. PdhiLoadCountersAndInstances (hDlg);
  463. // now select the counter
  464. lIndex = (LONG)SendMessageW (hWndCounterList, LB_FINDSTRING,
  465. (WPARAM)-1, (LPARAM)pCounterPathElementsW->szCounterName);
  466. if (lIndex != LB_ERR) {
  467. if (pData->bSelectMultipleCounters) {
  468. SendMessageW (hWndCounterList, LB_SETSEL, FALSE, (LPARAM)-1);
  469. SendMessageW (hWndCounterList, LB_SETSEL, TRUE, lIndex);
  470. SendMessageW (hWndCounterList, LB_SETCARETINDEX,
  471. (WPARAM)lIndex, MAKELPARAM(FALSE, 0));
  472. } else {
  473. SendMessageW (hWndCounterList, LB_SETCURSEL, lIndex, 0);
  474. }
  475. // display explain text if necessary
  476. SendMessageW (hDlg, WM_COMMAND,
  477. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  478. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  479. bReturn = TRUE;
  480. } else {
  481. // unable to locate counter
  482. bReturn = FALSE;
  483. }
  484. } else {
  485. // unable to locate the selected object
  486. bReturn = FALSE;
  487. }
  488. } // else unable to read path so exit
  489. G_FREE (pCounterPathElementsW);
  490. } else {
  491. // ANSI characters
  492. dwBufferSize = MAX_PATH * 2 * sizeof (CHAR);
  493. pCounterPathElementsA = (PDH_COUNTER_PATH_ELEMENTS_A *)G_ALLOC(
  494. dwBufferSize);
  495. if (pCounterPathElementsA == NULL) {
  496. SetLastError (PDH_MEMORY_ALLOCATION_FAILURE);
  497. return bReturn;
  498. }
  499. status = PdhParseCounterPathA (
  500. pData->pDlgData->pAnsiStruct->szReturnPathBuffer,
  501. pCounterPathElementsA,
  502. &dwBufferSize,
  503. 0);
  504. if (status == ERROR_SUCCESS) {
  505. // select entry in each list box
  506. // select machine entry. Load machine if necessary
  507. lIndex = (LONG)SendMessageA (hWndMachineCombo, CB_FINDSTRINGEXACT,
  508. (WPARAM)-1, (LPARAM)pCounterPathElementsA->szMachineName);
  509. if (lIndex == CB_ERR) {
  510. // try adding the machine
  511. // convert ansi buffer to wide char first
  512. MultiByteToWideChar(_getmbcp(),
  513. 0,
  514. pCounterPathElementsA->szMachineName,
  515. lstrlenA(pCounterPathElementsA->szMachineName),
  516. wszMachineName,
  517. MAX_PATH);
  518. if (!PdhiLoadNewMachine (hDlg, wszMachineName)) {
  519. // give up
  520. bReturn = FALSE;
  521. } else {
  522. // the correct machine has been selected
  523. }
  524. } else {
  525. // the machine has been found so select it
  526. SendMessageA (hWndMachineCombo, CB_SETCURSEL,
  527. (WPARAM)lIndex, 0);
  528. // update other fields
  529. PdhiLoadMachineObjects (hDlg, FALSE); // no need to update since it was just connected
  530. }
  531. // select the current object
  532. lIndex = (LONG)SendMessageA (hWndObjectCombo, CB_FINDSTRING,
  533. (WPARAM)-1, (LPARAM)pCounterPathElementsA->szObjectName);
  534. if (lIndex != CB_ERR) {
  535. SendMessageA (hWndObjectCombo, CB_SETCURSEL,
  536. (WPARAM)lIndex, 0);
  537. // update the counters for this object
  538. PdhiLoadCountersAndInstances (hDlg);
  539. // now select the counter
  540. lIndex = (LONG)SendMessageA (hWndCounterList, LB_FINDSTRING,
  541. (WPARAM)-1, (LPARAM)pCounterPathElementsA->szCounterName);
  542. if (lIndex != LB_ERR) {
  543. if (pData->bSelectMultipleCounters) {
  544. SendMessageA (hWndCounterList, LB_SETSEL, FALSE, (LPARAM)-1);
  545. SendMessageA (hWndCounterList, LB_SETSEL, TRUE, lIndex);
  546. SendMessageA (hWndCounterList, LB_SETCARETINDEX,
  547. (WPARAM)lIndex, MAKELPARAM(FALSE, 0));
  548. } else {
  549. SendMessageA (hWndCounterList, LB_SETCURSEL, lIndex, 0);
  550. }
  551. // display explain text if necessary
  552. SendMessage (hDlg, WM_COMMAND,
  553. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  554. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  555. bReturn = TRUE;
  556. } else {
  557. // unable to locate counter
  558. bReturn = FALSE;
  559. }
  560. } else {
  561. // unable to locate the selected object
  562. bReturn = FALSE;
  563. }
  564. } // else unable to read path so exit
  565. G_FREE (pCounterPathElementsA);
  566. }
  567. return bReturn;
  568. }
  569. STATIC_DWORD
  570. PdhiLoadDetailLevelCombo (
  571. IN HWND hDlg,
  572. IN DWORD dwInitialLevel
  573. )
  574. /*++
  575. Routine Description:
  576. Loads the Detail Level Combo box with the strings and ID's
  577. defined by the PdhiDetailInfo string array above.
  578. Arguments:
  579. IN HWND hDlg
  580. Handle to the dialog box containing the combo box
  581. IN DWORD dwInitialLevel
  582. the intitial detail level to select in the combo box.
  583. Return Value:
  584. Returns the selected level or 0 if an error ocurred.
  585. --*/
  586. {
  587. HWND hWndCombo;
  588. DWORD dwIndex;
  589. DWORD dwStringLength;
  590. DWORD dwDefaultIndex = 0;
  591. DWORD dwSelectedLevel = 0;
  592. DWORD dwThisCbIndex;
  593. WCHAR szTempBuffer[MAX_PATH]; // for loading string resource
  594. hWndCombo = GetDlgItem (hDlg, IDC_COUNTER_DETAIL_COMBO);
  595. // load all combo box strings from static data array defined above
  596. for (dwIndex = 0; PdhiDetailInfo[dwIndex].dwLevelValue > 0; dwIndex++) {
  597. // load the string resource for this string
  598. dwStringLength = LoadStringW (ThisDLLHandle,
  599. PdhiDetailInfo[dwIndex].dwStringResourceId,
  600. szTempBuffer, MAX_PATH);
  601. if (dwStringLength == 0) {
  602. // unable to read the string in, so
  603. // substitute the value for the string
  604. _ltow (PdhiDetailInfo[dwIndex].dwLevelValue,
  605. szTempBuffer, 10);
  606. }
  607. // load the strings into the combo box in the same order they
  608. // were described in the array above
  609. dwThisCbIndex = (DWORD)SendMessageW (hWndCombo, CB_INSERTSTRING,
  610. (WPARAM)-1, (LPARAM)szTempBuffer);
  611. // set the initial CB entry to the highest item <= to the
  612. // desired default level
  613. if (dwThisCbIndex != CB_ERR) {
  614. // set item data to be the corresponding detail level
  615. SendMessageW (hWndCombo, CB_SETITEMDATA, (WPARAM)dwThisCbIndex,
  616. (LPARAM)PdhiDetailInfo[dwIndex].dwLevelValue);
  617. // save default selection if it matches.
  618. if (PdhiDetailInfo[dwIndex].dwLevelValue <= dwInitialLevel) {
  619. dwDefaultIndex = dwThisCbIndex;
  620. dwSelectedLevel = PdhiDetailInfo[dwIndex].dwLevelValue;
  621. }
  622. }
  623. }
  624. // select desired default entry
  625. SendMessageW (hWndCombo, CB_SETCURSEL, (WPARAM)dwDefaultIndex, 0);
  626. return dwSelectedLevel;
  627. }
  628. STATIC_BOOL
  629. PdhiLoadKnownMachines (
  630. IN HWND hDlg
  631. )
  632. /*++
  633. Routine Description:
  634. Get the list of machines that are currently connected and disply
  635. them in the machine list box.
  636. Arguments:
  637. IN HWND hDlg
  638. Handle to the dialog window containing the controls
  639. Return Value:
  640. TRUE if successful,
  641. FALSE if not
  642. --*/
  643. {
  644. // big stack variables
  645. WCHAR mszMachineList[MACHINE_LIST_SIZE];
  646. // regular stack variables
  647. LPWSTR szThisMachine;
  648. DWORD dwLength;
  649. PDH_STATUS status;
  650. HWND hMachineListWnd;
  651. HCURSOR hOldCursor;
  652. PPDHI_BROWSE_DIALOG_DATA pData;
  653. BOOL bReturn = FALSE;
  654. // get this dialog's user data
  655. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  656. if (pData == NULL) {
  657. #if PDHI_REPORT_CODE_ERRORS
  658. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  659. #endif
  660. return bReturn;
  661. }
  662. // clear the machine list buffer
  663. memset (&mszMachineList[0], 0, (MACHINE_LIST_SIZE * sizeof (WCHAR)));
  664. // display wait cursor since this is potentially time consuming
  665. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  666. // get window handle to Machine list combo box
  667. hMachineListWnd = GetDlgItem (hDlg, IDC_MACHINE_COMBO);
  668. // clear machine combo box
  669. SendMessageW (hMachineListWnd, CB_RESETCONTENT, 0, 0);
  670. // get list of connected machines from PDH library
  671. dwLength = MACHINE_LIST_SIZE;
  672. status = PdhEnumMachinesHW (
  673. pData->pDlgData->hDataSource,
  674. &mszMachineList[0],
  675. &dwLength);
  676. if (status == ERROR_SUCCESS) {
  677. // update the combo box
  678. // go through MSZ and load each string into combo box
  679. for (szThisMachine = &mszMachineList[0];
  680. *szThisMachine != 0;
  681. szThisMachine += lstrlenW(szThisMachine)+1) {
  682. // add to the list box and let the list box sort them
  683. SendMessageW (hMachineListWnd, CB_ADDSTRING, 0,
  684. (LPARAM)szThisMachine);
  685. }
  686. // select the first item in the list (as the initial selection)
  687. SendMessageW (hMachineListWnd, CB_SETCURSEL, 0, 0);
  688. // the "current" machine has not been defined, then
  689. // do it now
  690. GetWindowTextW(hMachineListWnd, (LPWSTR)pData->szLastMachineName,
  691. MAX_PATH);
  692. bReturn = TRUE;
  693. } else {
  694. // no machines, so select local button and disable the edit window
  695. CheckRadioButton (hDlg, IDC_USE_LOCAL_MACHINE, IDC_SELECT_MACHINE,
  696. IDC_USE_LOCAL_MACHINE);
  697. PdhiBrowseCtrDlg_MACHINE_BUTTON (hDlg, BN_CLICKED,
  698. GetDlgItem (hDlg, IDC_USE_LOCAL_MACHINE));
  699. bReturn = TRUE;
  700. }
  701. // restore cursor
  702. SetCursor (hOldCursor);
  703. // return status of function
  704. return bReturn;
  705. }
  706. STATIC_BOOL
  707. PdhiLoadMachineObjects (
  708. IN HWND hDlg,
  709. IN BOOL bRefresh
  710. )
  711. /*++
  712. Routine Description:
  713. For the currently selected machine, load the object list box
  714. with the objects supported by that machine. If the bRefresh
  715. flag is TRUE, then query the system for the current perf data
  716. before loading the list box.
  717. Arguments:
  718. IN HWND hDlg
  719. Window handle of parent dialog box
  720. IN BOOL bRefresh
  721. TRUE = Query performance data of system before updating
  722. FALSE = Use the current system perf data to load the objects from
  723. Return Value:
  724. TRUE if successful,
  725. FALSE if not
  726. --*/
  727. {
  728. // big stack variables
  729. WCHAR szMachineName[MAX_PATH];
  730. WCHAR szDefaultObject[MAX_PATH];
  731. LPWSTR mszObjectList = NULL;
  732. // regular stack variables
  733. DWORD dwObjectListLength = OBJECT_LIST_SIZE;
  734. DWORD dwLength;
  735. LPWSTR szThisObject;
  736. HCURSOR hOldCursor;
  737. HWND hObjectListWnd;
  738. PPDHI_BROWSE_DIALOG_DATA pData;
  739. PDH_STATUS pdhStatus;
  740. DWORD dwReturn;
  741. DWORD dwDetailLevel;
  742. LPWSTR szMsg;
  743. LRESULT nEntry;
  744. DWORD dwFlags;
  745. // get the pointer to the dialog's user data
  746. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  747. if (pData == NULL) {
  748. #if PDHI_REPORT_CODE_ERRORS
  749. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  750. #endif
  751. return FALSE;
  752. }
  753. mszObjectList = G_ALLOC (dwObjectListLength * sizeof(WCHAR));
  754. if (mszObjectList == NULL) {
  755. return FALSE;
  756. }
  757. // save old cursor and display wait cursor
  758. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  759. if (!pData->bShowObjects) {
  760. // get window handle to combo box control
  761. hObjectListWnd = GetDlgItem (hDlg, IDC_OBJECT_COMBO);
  762. } else {
  763. hObjectListWnd = GetDlgItem (hDlg, IDC_OBJECT_LIST);
  764. }
  765. // get current machine name
  766. GetDlgItemTextW (hDlg, IDC_MACHINE_COMBO, szMachineName, MAX_PATH);
  767. if (lstrcmpW(szMachineName, pData->szLastMachineName) != 0) {
  768. #ifdef _DEBUG
  769. // to catch any snafus during debugging & development
  770. MessageBoxW(hDlg, cszNameDontMatch,
  771. cszNotice, MB_OK);
  772. #endif
  773. lstrcpyW (pData->szLastMachineName, szMachineName);
  774. }
  775. if (!pData->bShowObjects) {
  776. // first clear out any old contents
  777. SendMessageW (hObjectListWnd, CB_RESETCONTENT, 0, 0);
  778. } else {
  779. SendMessageW (hObjectListWnd, LB_RESETCONTENT, 0, 0);
  780. }
  781. // get object list from the PDH
  782. dwDetailLevel = pData->dwCurrentDetailLevel;
  783. dwDetailLevel |= pData->bIncludeCostlyObjects ? PERF_DETAIL_COSTLY : 0;
  784. dwLength = dwObjectListLength;
  785. pdhStatus = PdhEnumObjectsHW (
  786. pData->pDlgData->hDataSource,
  787. szMachineName, mszObjectList, &dwLength,
  788. dwDetailLevel, bRefresh);
  789. while ( pdhStatus == PDH_MORE_DATA
  790. || pdhStatus == PDH_INSUFFICIENT_BUFFER) {
  791. // then realloc and try again, but only once
  792. G_FREE (mszObjectList);
  793. dwObjectListLength = dwLength;
  794. mszObjectList = G_ALLOC (dwObjectListLength * sizeof(WCHAR));
  795. if (mszObjectList == NULL) {
  796. pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
  797. } else {
  798. pdhStatus = PdhEnumObjectsHW (
  799. pData->pDlgData->hDataSource,
  800. szMachineName, mszObjectList, &dwLength,
  801. dwDetailLevel, bRefresh);
  802. }
  803. }
  804. if (pdhStatus == ERROR_SUCCESS) {
  805. EnableWindow (hObjectListWnd, TRUE);
  806. // load object list to the list (combo) box
  807. for (szThisObject = &mszObjectList[0];
  808. *szThisObject != 0;
  809. szThisObject += lstrlenW(szThisObject) + 1) {
  810. if (pData->bShowObjects) {
  811. DWORD dwCounterListLength = 0;
  812. DWORD dwInstanceListLength = 0;
  813. pdhStatus = PdhEnumObjectItemsHW (
  814. pData->pDlgData->hDataSource,
  815. szMachineName,
  816. szThisObject,
  817. NULL,
  818. & dwCounterListLength,
  819. NULL,
  820. & dwInstanceListLength,
  821. PERF_DETAIL_WIZARD,
  822. 0);
  823. if ( pdhStatus != ERROR_SUCCESS
  824. && pdhStatus != PDH_MORE_DATA
  825. && pdhStatus != PDH_INSUFFICIENT_BUFFER) {
  826. dwInstanceListLength = 0;
  827. }
  828. if (dwInstanceListLength == 0 || dwInstanceListLength > 2) {
  829. // send to list box control
  830. nEntry = SendMessageW(hObjectListWnd, LB_ADDSTRING, 0,
  831. (LPARAM) szThisObject);
  832. dwFlags = 0;
  833. if (dwInstanceListLength > 2) {
  834. dwFlags |= PDH_OBJECT_HAS_INSTANCES;
  835. }
  836. SendMessageW(hObjectListWnd,
  837. LB_SETITEMDATA,
  838. (WPARAM) nEntry,
  839. (LPARAM) dwFlags);
  840. }
  841. pdhStatus = ERROR_SUCCESS;
  842. } else {
  843. // send to combo box
  844. // add each string...
  845. SendMessageW(hObjectListWnd, CB_ADDSTRING, 0,
  846. (LPARAM)szThisObject);
  847. }
  848. }
  849. if (!pData->bShowObjects) {
  850. // get default Object
  851. dwLength = MAX_PATH;
  852. pdhStatus = PdhGetDefaultPerfObjectHW (
  853. pData->pDlgData->hDataSource,
  854. szMachineName,
  855. szDefaultObject,
  856. &dwLength);
  857. if (pdhStatus == ERROR_SUCCESS) {
  858. // and select it if it's present (which it should be)
  859. dwReturn = (DWORD)SendMessageW (hObjectListWnd, CB_SELECTSTRING,
  860. (WPARAM)-1, (LPARAM)szDefaultObject);
  861. if (dwReturn == CB_ERR) pdhStatus = PDH_CSTATUS_NO_OBJECT;
  862. }
  863. if (pdhStatus != ERROR_SUCCESS) {
  864. // default object not found in list so select the first one
  865. SendMessageW (hObjectListWnd, CB_SETCURSEL, 0, 0);
  866. }
  867. }
  868. } else {
  869. // unable to obtain object list so display message and disable list
  870. szMsg = GetStringResource (IDS_BRWS_NO_OBJECTS);
  871. if (szMsg != NULL) {
  872. if (!pData->bShowObjects) {
  873. SendMessageW (hObjectListWnd, CB_ADDSTRING, 0, (LPARAM)szMsg);
  874. } else {
  875. SendMessageW (hObjectListWnd, LB_ADDSTRING, 0, (LPARAM)szMsg);
  876. }
  877. G_FREE (szMsg);
  878. EnableWindow (hObjectListWnd, FALSE);
  879. }
  880. }
  881. // restore cursor
  882. SetCursor (hOldCursor);
  883. if (mszObjectList != NULL) G_FREE (mszObjectList);
  884. // return status
  885. return (pdhStatus == ERROR_SUCCESS) ? (TRUE) : (FALSE);
  886. }
  887. STATIC_BOOL
  888. PdhiLoadCountersAndInstances (
  889. IN HWND hDlg
  890. )
  891. /*++
  892. Routine Description:
  893. Load the counters and instances of the selected object on the
  894. current machine
  895. Arguments:
  896. IN HWND hDlg
  897. Window handle of the dialog box containing these controls
  898. Return Value:
  899. TRUE if successful,
  900. FALSE if not
  901. --*/
  902. {
  903. // big Stack variables
  904. WCHAR szMachineName[MAX_PATH];
  905. WCHAR szObjectName[MAX_PATH];
  906. WCHAR szDefaultCounter[MAX_PATH];
  907. WCHAR szInstanceString[MAX_PATH];
  908. // regular Stack variables
  909. LPWSTR szIndexStringPos;
  910. DWORD dwCounterLen;
  911. DWORD dwDefaultIndex;
  912. DWORD dwCounterListLength;
  913. DWORD dwInstanceListLength;
  914. DWORD dwInstanceMatch;
  915. DWORD dwInstanceIndex;
  916. DWORD dwInstanceCount;
  917. LPWSTR szThisItem;
  918. HWND hWndCounterListBox;
  919. HWND hWndInstanceListBox;
  920. HCURSOR hOldCursor;
  921. PPDHI_BROWSE_DIALOG_DATA pData;
  922. PDH_STATUS pdhStatus;
  923. LPWSTR mszCounterList = NULL;
  924. LPWSTR mszInstanceList = NULL;
  925. LPWSTR mszTmpList;
  926. LPWSTR szMsg;
  927. HDC hDcListBox;
  928. SIZE Size;
  929. LONG dwHorizExtent;
  930. // get the pointer to the dialog's user data
  931. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  932. if (pData == NULL) {
  933. #if PDHI_REPORT_CODE_ERRORS
  934. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  935. #endif
  936. return FALSE;
  937. }
  938. hWndCounterListBox = GetDlgItem (hDlg, IDC_COUNTER_LIST);
  939. hWndInstanceListBox = GetDlgItem (hDlg, IDC_INSTANCE_LIST);
  940. if (hWndCounterListBox == NULL || hWndInstanceListBox == NULL) {
  941. SetLastError(PDH_INVALID_HANDLE);
  942. return FALSE;
  943. }
  944. // save current cursor and display wait cursor
  945. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  946. // get current machine & object name
  947. GetDlgItemTextW(hDlg, IDC_MACHINE_COMBO, szMachineName, MAX_PATH);
  948. GetDlgItemTextW(hDlg, IDC_OBJECT_COMBO, szObjectName, MAX_PATH);
  949. #ifdef _DEBUG
  950. if (lstrcmpW(szMachineName, pData->szLastMachineName) != 0) {
  951. MessageBoxW(hDlg, cszNameDontMatch,
  952. cszNotice, MB_OK);
  953. }
  954. #endif
  955. // get object list
  956. mszCounterList = G_ALLOC (dwCounterListSize * sizeof(WCHAR));
  957. if (mszCounterList != NULL) {
  958. dwCounterListLength = dwCounterListSize;
  959. } else {
  960. return FALSE;
  961. }
  962. mszInstanceList = G_ALLOC (dwInstanceListSize * sizeof(WCHAR));
  963. if (mszInstanceList != NULL) {
  964. dwInstanceListLength = dwInstanceListSize;
  965. } else {
  966. G_FREE (mszCounterList);
  967. return FALSE;
  968. }
  969. pdhStatus = PdhEnumObjectItemsHW(pData->pDlgData->hDataSource,
  970. szMachineName,
  971. szObjectName,
  972. mszCounterList,
  973. & dwCounterListLength,
  974. mszInstanceList,
  975. & dwInstanceListLength,
  976. pData->dwCurrentDetailLevel,
  977. 0);
  978. while ( pdhStatus == PDH_MORE_DATA
  979. || pdhStatus == PDH_INSUFFICIENT_BUFFER) {
  980. // enlarge the buffer if necessary
  981. if (dwCounterListLength > dwCounterListSize) {
  982. mszTmpList = mszCounterList;
  983. mszCounterList = G_REALLOC (mszCounterList, (dwCounterListLength * sizeof(WCHAR)));
  984. if (mszCounterList != NULL) {
  985. dwCounterListSize = dwCounterListLength;
  986. } else {
  987. G_FREE (mszTmpList);
  988. G_FREE (mszInstanceList);
  989. return FALSE;
  990. }
  991. } else {
  992. // reset the buffer size values
  993. dwCounterListLength = dwCounterListSize;
  994. }
  995. if (dwInstanceListLength > dwInstanceListSize) {
  996. mszTmpList = mszInstanceList;
  997. mszInstanceList = G_REALLOC (mszInstanceList, (dwInstanceListLength * sizeof(WCHAR)));
  998. if (mszInstanceList != NULL) {
  999. dwInstanceListSize = dwInstanceListLength;
  1000. } else {
  1001. G_FREE (mszTmpList);
  1002. G_FREE (mszCounterList);
  1003. return FALSE;
  1004. }
  1005. } else {
  1006. // reset the buffer size values
  1007. dwInstanceListLength = dwInstanceListSize;
  1008. }
  1009. // retry the call
  1010. pdhStatus = PdhEnumObjectItemsHW(pData->pDlgData->hDataSource,
  1011. szMachineName,
  1012. szObjectName,
  1013. mszCounterList,
  1014. & dwCounterListLength,
  1015. mszInstanceList,
  1016. & dwInstanceListLength,
  1017. pData->dwCurrentDetailLevel,
  1018. 0);
  1019. }
  1020. if (pdhStatus == ERROR_SUCCESS) {
  1021. //reset contents of both list boxes
  1022. SendMessageW (hWndCounterListBox, LB_RESETCONTENT, 0, 0);
  1023. SendMessageW (hWndInstanceListBox, LB_RESETCONTENT, 0, 0);
  1024. // enable both list boxes
  1025. EnableWindow (hWndInstanceListBox, TRUE);
  1026. EnableWindow (hWndCounterListBox, TRUE);
  1027. // now fill 'em up
  1028. // start with the counters
  1029. hDcListBox = GetDC(hWndCounterListBox);
  1030. if (hDcListBox == NULL)
  1031. return FALSE;
  1032. dwHorizExtent = 0;
  1033. for (szThisItem = mszCounterList;
  1034. *szThisItem != 0;
  1035. szThisItem += lstrlenW(szThisItem) + 1) {
  1036. if (GetTextExtentPoint32W(hDcListBox, szThisItem,
  1037. lstrlenW(szThisItem), &Size)) {
  1038. if (Size.cx > dwHorizExtent) {
  1039. dwHorizExtent = Size.cx;
  1040. SendMessageW (hWndCounterListBox,
  1041. LB_SETHORIZONTALEXTENT, (WPARAM)dwHorizExtent, 0);
  1042. }
  1043. }
  1044. SendMessageW (hWndCounterListBox, LB_ADDSTRING,
  1045. 0, (LPARAM)szThisItem);
  1046. }
  1047. ReleaseDC (hWndCounterListBox, hDcListBox);
  1048. // once the list box has been loaded see if we want to keep it
  1049. // enabled. It's filled regardless just so the user can see some
  1050. // of the entries, even if they have this disabled by the "all"
  1051. // counter button
  1052. if (pData->bSelectAllCounters) {
  1053. // disable instance list
  1054. EnableWindow(hWndCounterListBox, FALSE);
  1055. } else {
  1056. // set the default selection if there are entries in the
  1057. // list box and use the correct message depending on the
  1058. // selection options
  1059. // set the default counter
  1060. dwCounterLen = MAX_PATH;
  1061. pdhStatus = PdhGetDefaultPerfCounterHW (
  1062. pData->pDlgData->hDataSource,
  1063. szMachineName,
  1064. szObjectName,
  1065. szDefaultCounter,
  1066. &dwCounterLen);
  1067. if (pdhStatus != ERROR_SUCCESS) {
  1068. dwDefaultIndex = 0;
  1069. } else {
  1070. dwDefaultIndex = (DWORD)SendMessageW (hWndCounterListBox,
  1071. LB_FINDSTRINGEXACT,
  1072. (WPARAM)-1, (LPARAM)szDefaultCounter);
  1073. if (dwDefaultIndex == LB_ERR) dwDefaultIndex = 0;
  1074. }
  1075. if (pData->bSelectMultipleCounters) {
  1076. SendMessageW (hWndCounterListBox, LB_SETSEL, TRUE, dwDefaultIndex);
  1077. SendMessageW (hWndCounterListBox, LB_SETCARETINDEX,
  1078. (WPARAM)dwDefaultIndex, MAKELPARAM(FALSE, 0));
  1079. } else {
  1080. SendMessageW (hWndCounterListBox, LB_SETCURSEL, dwDefaultIndex, 0);
  1081. }
  1082. }
  1083. // now the instance list
  1084. if (dwInstanceListLength > 0) {
  1085. // there's at least one entry, so prepare the list box
  1086. // enable the list box and the instance radio buttons on the
  1087. // assumption that they will be used. this is tested later.
  1088. EnableWindow (hWndInstanceListBox, TRUE);
  1089. EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE_CAPTION), TRUE);
  1090. EnableWindow (GetDlgItem (hDlg, IDC_ALL_INSTANCES), TRUE);
  1091. EnableWindow (GetDlgItem (hDlg, IDC_USE_INSTANCE_LIST), TRUE);
  1092. dwInstanceCount = 0;
  1093. // load instance entries
  1094. hDcListBox = GetDC(hWndInstanceListBox);
  1095. if (hDcListBox == NULL)
  1096. return FALSE;
  1097. dwHorizExtent = 0;
  1098. for (szThisItem = mszInstanceList;
  1099. *szThisItem != 0;
  1100. szThisItem += lstrlenW(szThisItem) + 1) {
  1101. // see if the index number should be displayed
  1102. if (pData->bShowIndex) {
  1103. // if so, it must be derived,
  1104. // this is accomplished by making an index entry starting
  1105. // at 1, and looking for a match in the current entries.
  1106. // if a match is found, then the index is incremented and
  1107. // the process is repeated until the specified
  1108. // instance is not found. The first value not found is
  1109. // then the index entry for that item.
  1110. //
  1111. // first see if there's an undecorated one in the list box
  1112. // if not then add this one
  1113. lstrcpyW (szInstanceString, szThisItem);
  1114. dwInstanceMatch = (DWORD)-1;
  1115. dwInstanceMatch = (DWORD)SendMessageW (
  1116. hWndInstanceListBox, LB_FINDSTRINGEXACT,
  1117. (WPARAM)dwInstanceMatch, (LPARAM)szInstanceString);
  1118. if (dwInstanceMatch == LB_ERR) {
  1119. // then this is the first one so add it in the
  1120. // undecorated form
  1121. if (GetTextExtentPoint32W(hDcListBox, szInstanceString,
  1122. lstrlenW(szThisItem), &Size)) {
  1123. if (Size.cx > dwHorizExtent) {
  1124. dwHorizExtent = Size.cx;
  1125. SendMessageW (hWndInstanceListBox,
  1126. LB_SETHORIZONTALEXTENT, (WPARAM)dwHorizExtent, 0);
  1127. }
  1128. }
  1129. SendMessageW (hWndInstanceListBox, LB_ADDSTRING, 0,
  1130. (LPARAM)szInstanceString);
  1131. } else {
  1132. // there's already a plain one, so increment through
  1133. // the index values and find one that's not in the
  1134. // list already
  1135. dwInstanceIndex = 1;
  1136. dwInstanceMatch = (DWORD)-1;
  1137. // find the index of this instance
  1138. lstrcpyW (szInstanceString, szThisItem);
  1139. lstrcatW (szInstanceString, cszPoundSign);
  1140. szIndexStringPos = &szInstanceString[lstrlenW(szInstanceString)];
  1141. do {
  1142. _ltow ((long)dwInstanceIndex++, szIndexStringPos, 10);
  1143. dwInstanceMatch = (DWORD)SendMessageW (
  1144. hWndInstanceListBox, LB_FINDSTRINGEXACT,
  1145. (WPARAM)dwInstanceMatch, (LPARAM)szInstanceString);
  1146. } while (dwInstanceMatch != LB_ERR);
  1147. // add the last entry checked (the first one not found)
  1148. // to the list box now.
  1149. if (GetTextExtentPoint32W(hDcListBox, szInstanceString,
  1150. lstrlenW(szThisItem), &Size)) {
  1151. if (Size.cx > dwHorizExtent) {
  1152. dwHorizExtent = Size.cx;
  1153. SendMessageW (hWndInstanceListBox,
  1154. LB_SETHORIZONTALEXTENT, (WPARAM)dwHorizExtent, 0);
  1155. }
  1156. }
  1157. SendMessageW (hWndInstanceListBox, LB_ADDSTRING, 0,
  1158. (LPARAM)szInstanceString);
  1159. }
  1160. } else {
  1161. // index values are not required so just add the string
  1162. // to the list box
  1163. if (GetTextExtentPoint32W(hDcListBox, szInstanceString,
  1164. lstrlenW(szThisItem), &Size)) {
  1165. if (Size.cx > dwHorizExtent) {
  1166. dwHorizExtent = Size.cx;
  1167. SendMessageW (hWndInstanceListBox,
  1168. LB_SETHORIZONTALEXTENT, (WPARAM)dwHorizExtent, 0);
  1169. }
  1170. }
  1171. SendMessageW (hWndInstanceListBox, LB_ADDSTRING, 0,
  1172. (LPARAM)szThisItem);
  1173. }
  1174. dwInstanceCount++;
  1175. }
  1176. ReleaseDC (hWndInstanceListBox, hDcListBox);
  1177. if (dwInstanceCount == 0) {
  1178. // disable the OK/Add button, since this object has no
  1179. // current instances to monitor
  1180. EnableWindow (GetDlgItem(hDlg, IDOK), FALSE);
  1181. szMsg = GetStringResource (IDS_BRWS_NO_INSTANCES);
  1182. if (szMsg != NULL) {
  1183. SendMessageW (hWndInstanceListBox, LB_ADDSTRING, 0,
  1184. (LPARAM)szMsg);
  1185. G_FREE (szMsg);
  1186. }
  1187. EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE_CAPTION), FALSE);
  1188. EnableWindow (GetDlgItem (hDlg, IDC_ALL_INSTANCES), FALSE);
  1189. EnableWindow (GetDlgItem (hDlg, IDC_USE_INSTANCE_LIST), FALSE);
  1190. EnableWindow (hWndInstanceListBox, FALSE);
  1191. } else {
  1192. // enable the OK/Add button since there is some monitorable
  1193. // instance(s)
  1194. EnableWindow (GetDlgItem(hDlg, IDOK), TRUE);
  1195. EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE_CAPTION), TRUE);
  1196. EnableWindow (GetDlgItem (hDlg, IDC_ALL_INSTANCES), TRUE);
  1197. EnableWindow (GetDlgItem (hDlg, IDC_USE_INSTANCE_LIST), TRUE);
  1198. EnableWindow (hWndInstanceListBox, TRUE);
  1199. }
  1200. // once the list box has been loaded see if we want to keep it
  1201. // enabled. It's filled regardless just so the user can see some
  1202. // of the entries, even if they have this disabled by the "all"
  1203. // instance button
  1204. if (pData->bSelectAllInstances) {
  1205. // disable instance list
  1206. EnableWindow(hWndInstanceListBox, FALSE);
  1207. } else {
  1208. // set the default selection if there are entries in the
  1209. // list box and use the correct message depending on the
  1210. // selection options
  1211. if ((dwInstanceCount > 0) &&
  1212. (SendMessageW (hWndInstanceListBox, LB_GETCOUNT, 0, 0) !=
  1213. LB_ERR)) {
  1214. if (pData->bSelectMultipleCounters) {
  1215. SendMessageW (hWndInstanceListBox, LB_SETSEL, TRUE, 0);
  1216. } else {
  1217. SendMessageW (hWndInstanceListBox, LB_SETCURSEL, 0, 0);
  1218. }
  1219. }
  1220. }
  1221. } else {
  1222. // there are no instances of this counter so display the
  1223. // string and disable the buttons and the list box
  1224. EnableWindow (hWndInstanceListBox, FALSE);
  1225. EnableWindow (GetDlgItem (hDlg, IDC_INSTANCE_CAPTION), FALSE);
  1226. EnableWindow (GetDlgItem (hDlg, IDC_ALL_INSTANCES), FALSE);
  1227. EnableWindow (GetDlgItem (hDlg, IDC_USE_INSTANCE_LIST), FALSE);
  1228. EnableWindow (GetDlgItem(hDlg, IDOK), TRUE);
  1229. }
  1230. } else {
  1231. // unable to retrieve the counters and instances so
  1232. // clear and then...
  1233. SendMessageW (hWndCounterListBox, LB_RESETCONTENT, 0, 0);
  1234. SendMessageW (hWndInstanceListBox, LB_RESETCONTENT, 0, 0);
  1235. // disable the windows
  1236. szMsg = GetStringResource (IDS_BRWS_NO_INSTANCES);
  1237. if (szMsg != NULL) {
  1238. SendMessageW (hWndInstanceListBox, LB_ADDSTRING, 0,
  1239. (LPARAM)szMsg);
  1240. G_FREE (szMsg);
  1241. }
  1242. szMsg = GetStringResource (IDS_BRWS_NO_COUNTERS);
  1243. if (szMsg != NULL) {
  1244. SendMessageW (hWndCounterListBox, LB_ADDSTRING, 0,
  1245. (LPARAM)szMsg);
  1246. G_FREE (szMsg);
  1247. }
  1248. EnableWindow (hWndInstanceListBox, FALSE);
  1249. EnableWindow (hWndCounterListBox, FALSE);
  1250. EnableWindow (GetDlgItem (hDlg, IDC_ALL_INSTANCES), FALSE);
  1251. EnableWindow (GetDlgItem (hDlg, IDC_USE_INSTANCE_LIST), FALSE);
  1252. EnableWindow (GetDlgItem(hDlg, IDOK), FALSE);
  1253. }
  1254. if (mszCounterList != NULL) G_FREE(mszCounterList);
  1255. if (mszInstanceList != NULL) G_FREE(mszInstanceList);
  1256. // restore the cursor to it's original shape
  1257. SetCursor (hOldCursor);
  1258. // return status
  1259. return TRUE;
  1260. }
  1261. STATIC_PDH_FUNCTION
  1262. PdhiCompileSelectedObjectsT (
  1263. IN HWND hDlg,
  1264. IN LPVOID pUsersPathBuffer,
  1265. IN DWORD cchUsersPathLength,
  1266. IN BOOL bUnicode
  1267. )
  1268. /*++
  1269. Routine Description:
  1270. Scans the selected objects, counter, instances and builds a multi-SZ
  1271. string containing the expanded path of all the selections, unless
  1272. the wild card syntax is specified.
  1273. Arguments:
  1274. IN HWND hDlg
  1275. Window Handle of Dialog containing the controls
  1276. IN LPVOID pUsersPathBuffer
  1277. pointer to the caller's buffer that will receive the MSZ string
  1278. IN DWORD cchUsersPathLength
  1279. size of caller's buffer in characters
  1280. IN BOOL bUnicode
  1281. size of characters to return: TRUE = WCHAR, FALSE = CHAR
  1282. Return Value:
  1283. WIN32 Status of function completion
  1284. ERROR_SUCCESS if successful
  1285. --*/
  1286. {
  1287. // big Stack Variables
  1288. static WCHAR lszMachineName[MAX_PATH];
  1289. static WCHAR lszObjectName[MAX_PATH];
  1290. static WCHAR lszInstanceName[SMALL_BUFFER_SIZE];
  1291. static WCHAR lszCounterName[SMALL_BUFFER_SIZE];
  1292. static WCHAR szWorkBuffer[SMALL_BUFFER_SIZE];
  1293. // regular Stack Variables
  1294. LRESULT iNumEntries;
  1295. int iThisEntry;
  1296. LRESULT iCurSelState;
  1297. LRESULT iTextLen;
  1298. LRESULT dwObjectFlags;
  1299. DWORD dwBufferRemaining;
  1300. DWORD dwSize1;
  1301. PDH_COUNTER_PATH_ELEMENTS_W lszPath;
  1302. LPVOID szCounterStart;
  1303. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1304. PPDHI_BROWSE_DIALOG_DATA pData;
  1305. // get pointer to dialog user data
  1306. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  1307. if (pData == NULL) {
  1308. #if PDHI_REPORT_CODE_ERRORS
  1309. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  1310. #endif
  1311. return PDH_NO_DIALOG_DATA;
  1312. }
  1313. // clear user's string
  1314. if (pUsersPathBuffer != NULL) {
  1315. // clear first four bytes of string
  1316. *((LPDWORD)pUsersPathBuffer) = 0;
  1317. dwBufferRemaining = cchUsersPathLength;
  1318. szCounterStart = pUsersPathBuffer;
  1319. } else {
  1320. #if PDHI_REPORT_CODE_ERRORS
  1321. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_INVALID_BUFFER);
  1322. #endif
  1323. return PDH_INVALID_BUFFER; // no point in continuing if the caller doesn't have a buffer
  1324. }
  1325. // each counter path string is built by setting the elements of
  1326. // the counter data structure and then calling the MakeCounterPath
  1327. // function to build the string
  1328. // build base string using selected machine & objects from list
  1329. if (pData->bIncludeMachineInPath) {
  1330. lszPath.szMachineName = &lszMachineName[0];
  1331. memset (lszMachineName, 0, sizeof(lszMachineName));
  1332. GetDlgItemTextW (hDlg, IDC_MACHINE_COMBO, lszMachineName, MAX_PATH);
  1333. } else {
  1334. lszPath.szMachineName = NULL;
  1335. }
  1336. // Get number of objects currently listed in the list box
  1337. iNumEntries = SendMessageW(GetDlgItem(hDlg, IDC_OBJECT_LIST), LB_GETCOUNT, 0, 0);
  1338. if (iNumEntries != LB_ERR) {
  1339. // check each one and add selected ones to the list
  1340. lszInstanceName[0] = SPLAT_L;
  1341. lszInstanceName[1] = 0;
  1342. lszCounterName[0] = SPLAT_L;
  1343. lszCounterName[1] = 0;
  1344. lszPath.szCounterName = lszCounterName; // wildcard counter entry
  1345. lszPath.szParentInstance = NULL; // no parent instances
  1346. lszPath.dwInstanceIndex = ((DWORD)-1); // no index numbers
  1347. for (iThisEntry = 0; iThisEntry < iNumEntries; iThisEntry++) {
  1348. iCurSelState = SendMessageW(GetDlgItem(hDlg, IDC_OBJECT_LIST),
  1349. LB_GETSEL, (WPARAM)iThisEntry, 0);
  1350. if (iCurSelState > 0) {
  1351. // then get the string and add it to the list
  1352. iTextLen = SendMessageW(GetDlgItem(hDlg, IDC_OBJECT_LIST),
  1353. LB_GETTEXTLEN, iThisEntry, 0);
  1354. if ((iTextLen < MAX_PATH) && (iTextLen != LB_ERR)) {
  1355. // the string and it's null will fit so fetch it
  1356. iTextLen = SendMessageW(GetDlgItem(hDlg, IDC_OBJECT_LIST),
  1357. LB_GETTEXT, iThisEntry, (LPARAM)lszObjectName);
  1358. dwObjectFlags = SendMessage (GetDlgItem(hDlg, IDC_OBJECT_LIST),
  1359. LB_GETITEMDATA, (WPARAM)iThisEntry, 0);
  1360. if (iTextLen != LB_ERR) {
  1361. // build path elements
  1362. lszPath.szObjectName = lszObjectName;
  1363. if (dwObjectFlags & PDH_OBJECT_HAS_INSTANCES) {
  1364. lszPath.szInstanceName = lszInstanceName;
  1365. } else {
  1366. lszPath.szInstanceName = NULL;
  1367. }
  1368. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1369. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1370. szWorkBuffer,
  1371. & dwSize1,
  1372. 0);
  1373. }
  1374. else {
  1375. pdhStatus = PDH_INVALID_ARGUMENT;
  1376. }
  1377. if (pdhStatus == ERROR_SUCCESS) {
  1378. // add the string if there's room
  1379. pdhStatus = PdhiCopyString(& ((LPBYTE) szCounterStart),
  1380. szWorkBuffer,
  1381. & dwBufferRemaining,
  1382. bUnicode);
  1383. }
  1384. } else {
  1385. // unable to read the string (to big or List Box error)
  1386. }
  1387. } // else, item isn't selected so skip
  1388. } // end for each item in the list box
  1389. if (bUnicode) {
  1390. *((LPWSTR)szCounterStart)++ = 0; // terminate MSZ
  1391. } else {
  1392. *((LPSTR)szCounterStart)++ = 0; // terminate MSZ
  1393. }
  1394. } else {
  1395. // no items in the list
  1396. }
  1397. return pdhStatus;
  1398. }
  1399. STATIC_PDH_FUNCTION
  1400. PdhiCompileSelectedObjectsW (
  1401. IN HWND hDlg,
  1402. IN LPWSTR szUsersPathBuffer,
  1403. IN DWORD cchUsersPathLength
  1404. )
  1405. {
  1406. return PdhiCompileSelectedObjectsT (
  1407. hDlg,
  1408. (LPVOID)szUsersPathBuffer,
  1409. cchUsersPathLength,
  1410. TRUE);
  1411. }
  1412. STATIC_PDH_FUNCTION
  1413. PdhiCompileSelectedObjectsA (
  1414. IN HWND hDlg,
  1415. IN LPSTR szUsersPathBuffer,
  1416. IN DWORD cchUsersPathLength
  1417. )
  1418. {
  1419. return PdhiCompileSelectedObjectsT (
  1420. hDlg,
  1421. (LPVOID)szUsersPathBuffer,
  1422. cchUsersPathLength,
  1423. FALSE);
  1424. }
  1425. STATIC_PDH_FUNCTION
  1426. PdhiCompileSelectedCountersT (
  1427. IN HWND hDlg,
  1428. IN LPVOID pUsersPathBuffer,
  1429. IN DWORD cchUsersPathLength,
  1430. IN BOOL bUnicode
  1431. )
  1432. /*++
  1433. Routine Description:
  1434. Scans the selected objects, counter, instances and builds a multi-SZ
  1435. string containing the expanded path of all the selections, unless
  1436. the wild card syntax is specified.
  1437. Arguments:
  1438. IN HWND hDlg
  1439. Window Handle of Dialog containing the controls
  1440. IN LPVOID pUsersPathBuffer
  1441. pointer to the caller's buffer that will receive the MSZ string
  1442. IN DWORD cchUsersPathLength
  1443. size of caller's buffer in characters
  1444. IN BOOL bUnicode
  1445. size of characters to return: TRUE = WCHAR, FALSE = CHAR
  1446. Return Value:
  1447. WIN32 Status of function completion
  1448. ERROR_SUCCESS if successful
  1449. --*/
  1450. {
  1451. // big Stack Variables
  1452. static WCHAR lszMachineName[MAX_PATH];
  1453. static WCHAR lszObjectName[MAX_PATH];
  1454. static WCHAR lszInstanceName[SMALL_BUFFER_SIZE];
  1455. static WCHAR lszParentInstance[SMALL_BUFFER_SIZE];
  1456. static WCHAR lszCounterName[SMALL_BUFFER_SIZE];
  1457. static WCHAR szWorkBuffer[SMALL_BUFFER_SIZE];
  1458. // regular Stack Variables
  1459. DWORD dwBufferRemaining;
  1460. DWORD dwCountCounters;
  1461. DWORD dwThisCounter;
  1462. DWORD dwCountInstances;
  1463. DWORD dwThisInstance;
  1464. DWORD dwSize1, dwSize2;
  1465. PDH_COUNTER_PATH_ELEMENTS_W lszPath;
  1466. LPVOID szCounterStart;
  1467. HWND hWndCounterList;
  1468. HWND hWndInstanceList;
  1469. BOOL bSel;
  1470. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  1471. PPDHI_BROWSE_DIALOG_DATA pData;
  1472. // get pointer to dialog user data
  1473. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  1474. if (pData == NULL) {
  1475. #if PDHI_REPORT_CODE_ERRORS
  1476. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  1477. #endif
  1478. return PDH_NO_DIALOG_DATA;
  1479. }
  1480. // clear user's string
  1481. if (pUsersPathBuffer != NULL) {
  1482. // clear first four bytes of string
  1483. *((LPDWORD)pUsersPathBuffer) = 0;
  1484. dwBufferRemaining = cchUsersPathLength;
  1485. szCounterStart = pUsersPathBuffer;
  1486. } else {
  1487. #if PDHI_REPORT_CODE_ERRORS
  1488. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_INVALID_BUFFER);
  1489. #endif
  1490. return PDH_INVALID_BUFFER; // no point in continuing if the caller doesn't have a buffer
  1491. }
  1492. // each counter path string is built by setting the elements of
  1493. // the counter data structure and then calling the MakeCounterPath
  1494. // function to build the string
  1495. // build base string using selected machine and object
  1496. if (pData->bIncludeMachineInPath) {
  1497. lszPath.szMachineName = &lszMachineName[0];
  1498. memset (lszMachineName, 0, sizeof(lszMachineName));
  1499. GetDlgItemTextW (hDlg, IDC_MACHINE_COMBO, lszMachineName, MAX_PATH);
  1500. } else {
  1501. lszPath.szMachineName = NULL;
  1502. }
  1503. lszPath.szObjectName = &lszObjectName[0];
  1504. memset (lszObjectName, 0, sizeof(lszObjectName));
  1505. GetDlgItemTextW (hDlg, IDC_OBJECT_COMBO, lszObjectName, MAX_PATH);
  1506. hWndCounterList = GetDlgItem (hDlg, IDC_COUNTER_LIST);
  1507. hWndInstanceList = GetDlgItem (hDlg, IDC_INSTANCE_LIST);
  1508. if (pData->bSelectMultipleCounters) {
  1509. if (pData->bWildCardInstances && pData->bSelectAllInstances) {
  1510. if (IsWindowEnabled(GetDlgItem (hDlg, IDC_ALL_INSTANCES))) {
  1511. // then this object has instances and we want ALL of them
  1512. lszPath.szInstanceName = &lszInstanceName[0];
  1513. memset (lszInstanceName, 0, sizeof(lszInstanceName));
  1514. lstrcpyW (lszInstanceName, cszSplat);
  1515. lszPath.szParentInstance = NULL;
  1516. lszPath.dwInstanceIndex = (DWORD)-1;
  1517. } else {
  1518. // this object has no instances
  1519. lszPath.szInstanceName = NULL;
  1520. lszPath.szParentInstance = NULL;
  1521. lszPath.dwInstanceIndex = (DWORD)-1;
  1522. }
  1523. // make a counter path for each selected counter
  1524. dwCountCounters = (DWORD)SendMessageW (hWndCounterList, LB_GETCOUNT, 0, 0);
  1525. if (pData->bSelectAllCounters) {
  1526. lszPath.szCounterName = &lszCounterName[0];
  1527. lstrcpyW (lszPath.szCounterName, cszSplat);
  1528. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1529. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1530. szWorkBuffer,
  1531. &dwSize1,
  1532. 0);
  1533. if (pdhStatus == ERROR_SUCCESS) {
  1534. // add the string if there's room
  1535. pdhStatus = PdhiCopyString(& ((LPBYTE) szCounterStart),
  1536. szWorkBuffer,
  1537. & dwBufferRemaining,
  1538. bUnicode);
  1539. }
  1540. } else {
  1541. for (dwThisCounter = 0; dwThisCounter < dwCountCounters; dwThisCounter++) {
  1542. if (SendMessageW (hWndCounterList, LB_GETSEL, (WPARAM)dwThisCounter, 0)) {
  1543. lszPath.szCounterName = &lszCounterName[0];
  1544. memset (lszCounterName, 0, sizeof(lszCounterName));
  1545. SendMessageW (hWndCounterList, LB_GETTEXT,
  1546. (WPARAM)dwThisCounter, (LPARAM)lszCounterName);
  1547. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1548. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1549. szWorkBuffer,
  1550. &dwSize1,
  1551. 0);
  1552. if (pdhStatus == ERROR_SUCCESS) {
  1553. // add the string if there's room
  1554. pdhStatus = PdhiCopyString(
  1555. & ((LPBYTE) szCounterStart),
  1556. szWorkBuffer,
  1557. & dwBufferRemaining,
  1558. bUnicode);
  1559. } else {
  1560. // skip this counter since it could not be formed correctly
  1561. continue;
  1562. }
  1563. } // end if this counter was selected
  1564. } // end for each counter in object list box
  1565. }
  1566. } else {
  1567. // get selected instances from list
  1568. dwCountCounters = (DWORD)SendMessageW (hWndCounterList, LB_GETCOUNT, 0, 0);
  1569. for (dwThisCounter = 0; dwThisCounter < dwCountCounters; dwThisCounter++) {
  1570. bSel = (BOOL) SendMessageW (hWndCounterList, LB_GETSEL, (WPARAM)dwThisCounter, 0);
  1571. if (bSel || pData->bSelectAllCounters ) {
  1572. lszPath.szCounterName = &lszCounterName[0];
  1573. memset (lszCounterName, 0, sizeof(lszCounterName));
  1574. SendMessageW (hWndCounterList, LB_GETTEXT,
  1575. (WPARAM)dwThisCounter, (LPARAM)lszCounterName);
  1576. if (IsWindowEnabled(hWndInstanceList) || pData->bSelectAllInstances) {
  1577. dwCountInstances = (DWORD)SendMessageW (hWndInstanceList,
  1578. LB_GETCOUNT, 0, 0);
  1579. for (dwThisInstance = 0; dwThisInstance < dwCountInstances; dwThisInstance++) {
  1580. if (SendMessageW (hWndInstanceList, LB_GETSEL,
  1581. (WPARAM)dwThisInstance, 0) || pData->bSelectAllInstances) {
  1582. lszPath.szInstanceName = &lszInstanceName[0];
  1583. memset (lszInstanceName, 0, sizeof(lszInstanceName));
  1584. SendMessageW (hWndInstanceList, LB_GETTEXT,
  1585. (WPARAM)dwThisInstance, (LPARAM)lszInstanceName);
  1586. lszPath.szParentInstance = &lszParentInstance[0];
  1587. memset (lszParentInstance, 0, sizeof(lszParentInstance));
  1588. dwSize1 = dwSize2 = MAX_PATH;
  1589. pdhStatus = PdhParseInstanceNameW (lszInstanceName,
  1590. lszInstanceName,
  1591. &dwSize1,
  1592. lszParentInstance,
  1593. &dwSize2,
  1594. &lszPath.dwInstanceIndex);
  1595. if (pdhStatus == ERROR_SUCCESS) {
  1596. // parse instance name adds in the default index if one is
  1597. // not present. so if it's not wanted, this will remove it
  1598. if (!pData->bShowIndex) {
  1599. lszPath.dwInstanceIndex = (DWORD)-1;
  1600. } else {
  1601. // only add in the instance # if it's not 0
  1602. if (lszPath.dwInstanceIndex == 0) {
  1603. lszPath.dwInstanceIndex = (DWORD)-1;
  1604. }
  1605. }
  1606. if (dwSize1 > 1) {
  1607. lszPath.szInstanceName = &lszInstanceName[0];
  1608. } else {
  1609. lszPath.szInstanceName = NULL;
  1610. }
  1611. if (dwSize2 > 1) {
  1612. lszPath.szParentInstance = &lszParentInstance[0];
  1613. } else {
  1614. lszPath.szParentInstance = NULL;
  1615. }
  1616. } else {
  1617. // ignore the instances
  1618. lszPath.szInstanceName = NULL;
  1619. lszPath.szParentInstance = NULL;
  1620. }
  1621. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1622. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1623. szWorkBuffer,
  1624. &dwSize1,
  1625. 0);
  1626. if (pdhStatus == ERROR_SUCCESS) {
  1627. pdhStatus = PdhiCopyString(
  1628. & ((LPBYTE) szCounterStart),
  1629. szWorkBuffer,
  1630. & dwBufferRemaining,
  1631. bUnicode);
  1632. } else {
  1633. // unable to make counter path so skip
  1634. }
  1635. } // end if instance is selected
  1636. } // end for each instance in list
  1637. } else {
  1638. // this counter has no instances so process now
  1639. lszPath.szInstanceName = NULL;
  1640. lszPath.szParentInstance = NULL;
  1641. lszPath.dwInstanceIndex = (DWORD)-1;
  1642. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1643. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1644. szWorkBuffer,
  1645. &dwSize1,
  1646. 0);
  1647. if (pdhStatus == ERROR_SUCCESS) {
  1648. pdhStatus = PdhiCopyString(
  1649. & ((LPBYTE) szCounterStart),
  1650. szWorkBuffer,
  1651. & dwBufferRemaining,
  1652. bUnicode);
  1653. } else {
  1654. // unable to create a path so skip and continue
  1655. }
  1656. } // end if counter has instances
  1657. } // else counter is not selected
  1658. } // end for each counter in list
  1659. } // end if not wild card instances
  1660. if (bUnicode) {
  1661. *((LPWSTR)szCounterStart)++ = 0; // terminate MSZ
  1662. } else {
  1663. *((LPSTR)szCounterStart)++ = 0; // terminate MSZ
  1664. }
  1665. } else {
  1666. // only single selections are allowed
  1667. if (pData->bWildCardInstances && pData->bSelectAllInstances) {
  1668. lszPath.szInstanceName = &lszInstanceName[0];
  1669. memset (lszInstanceName, 0, sizeof(lszInstanceName));
  1670. lstrcpyW (lszInstanceName, cszSplat);
  1671. lszPath.szParentInstance = NULL;
  1672. lszPath.dwInstanceIndex = (DWORD)-1;
  1673. dwThisCounter = (DWORD)SendMessageW (hWndCounterList, LB_GETCURSEL, 0, 0);
  1674. if (dwThisCounter != LB_ERR) {
  1675. lszPath.szCounterName = &lszCounterName[0];
  1676. memset (lszCounterName, 0, sizeof(lszCounterName));
  1677. SendMessageW (hWndCounterList, LB_GETTEXT,
  1678. (WPARAM)dwThisCounter, (LPARAM)lszCounterName);
  1679. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1680. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1681. szWorkBuffer,
  1682. &dwSize1,
  1683. 0);
  1684. if (pdhStatus == ERROR_SUCCESS) {
  1685. pdhStatus = PdhiCopyString(& ((LPBYTE) szCounterStart),
  1686. szWorkBuffer,
  1687. & dwBufferRemaining,
  1688. bUnicode);
  1689. } else {
  1690. // unable to make counter path so skip
  1691. }
  1692. } //end if counter was found in list box
  1693. } else {
  1694. // get selected instance from list
  1695. dwThisCounter = (DWORD)SendMessageW (hWndCounterList, LB_GETCURSEL, 0, 0);
  1696. if (dwThisCounter != LB_ERR) {
  1697. lszPath.szCounterName = &lszCounterName[0];
  1698. memset (lszCounterName, 0, sizeof(lszCounterName));
  1699. SendMessageW (hWndCounterList, LB_GETTEXT,
  1700. (WPARAM)dwThisCounter, (LPARAM)lszCounterName);
  1701. if (IsWindowEnabled(hWndInstanceList)) {
  1702. dwThisInstance = (DWORD)SendMessageW (hWndInstanceList,
  1703. LB_GETCURSEL, 0, 0);
  1704. if (dwThisInstance == LB_ERR) {
  1705. // instance not found so select 0
  1706. dwThisInstance = 0;
  1707. }
  1708. lszPath.szInstanceName = &lszInstanceName[0];
  1709. memset (lszInstanceName, 0, sizeof(lszInstanceName));
  1710. SendMessageW (hWndInstanceList, LB_GETTEXT,
  1711. (WPARAM)dwThisInstance, (LPARAM)lszInstanceName);
  1712. lszPath.szParentInstance = &lszParentInstance[0];
  1713. memset (lszParentInstance, 0, sizeof(lszParentInstance));
  1714. dwSize1 = dwSize2 = MAX_PATH;
  1715. pdhStatus = PdhParseInstanceNameW (lszInstanceName,
  1716. lszInstanceName,
  1717. &dwSize1,
  1718. lszParentInstance,
  1719. &dwSize2,
  1720. &lszPath.dwInstanceIndex);
  1721. if (pdhStatus == ERROR_SUCCESS ) {
  1722. // parse instance name adds in the default index of one is
  1723. // not present. so if it's not wanted, this will remove it
  1724. if (!pData->bShowIndex) {
  1725. lszPath.dwInstanceIndex = (DWORD)-1;
  1726. }
  1727. // size values include trailing NULL char so
  1728. // strings must be > 1 char in length to have some
  1729. // text since a length of 1 would imply only a
  1730. // NULL character.
  1731. if (dwSize1 > 1) {
  1732. lszPath.szInstanceName = &lszInstanceName[0];
  1733. } else {
  1734. lszPath.szInstanceName = NULL;
  1735. }
  1736. if (dwSize2 > 1) {
  1737. lszPath.szParentInstance = &lszParentInstance[0];
  1738. } else {
  1739. lszPath.szParentInstance = NULL;
  1740. }
  1741. } else {
  1742. // skip this instance
  1743. lszPath.szParentInstance = NULL;
  1744. lszPath.szInstanceName = NULL;
  1745. lszPath.dwInstanceIndex = (DWORD)-1;
  1746. }
  1747. } else {
  1748. // this counter has no instances so process now
  1749. lszPath.szInstanceName = NULL;
  1750. lszPath.szParentInstance = NULL;
  1751. lszPath.dwInstanceIndex = (DWORD)-1;
  1752. } // end if counter has instances
  1753. dwSize1 = sizeof (szWorkBuffer) / sizeof (WCHAR);
  1754. pdhStatus = PdhMakeCounterPathW (&lszPath,
  1755. szWorkBuffer,
  1756. &dwSize1,
  1757. 0);
  1758. if (pdhStatus == ERROR_SUCCESS) {
  1759. pdhStatus = PdhiCopyString(& ((LPBYTE) szCounterStart),
  1760. szWorkBuffer,
  1761. & dwBufferRemaining,
  1762. bUnicode);
  1763. } else {
  1764. // unable to build a counter path so skip
  1765. }
  1766. } // end if counter found
  1767. } // end if not wild card instances
  1768. }
  1769. if (bUnicode) {
  1770. *((LPWSTR)szCounterStart)++ = 0; // terminate MSZ
  1771. } else {
  1772. *((LPSTR)szCounterStart)++ = 0; // terminate MSZ
  1773. }
  1774. return pdhStatus;
  1775. }
  1776. STATIC_PDH_FUNCTION
  1777. PdhiCompileSelectedCountersW (
  1778. IN HWND hDlg,
  1779. IN LPWSTR szUsersPathBuffer,
  1780. IN DWORD cchUsersPathLength
  1781. )
  1782. /*++
  1783. Routine Description:
  1784. UNICODE function wrapper for base function which scans the selected
  1785. objects, counter, instances and builds a multi-SZ string containing
  1786. the expanded path of all the selections, unless the wild card
  1787. syntax is specified.
  1788. Arguments:
  1789. IN HWND hDlg
  1790. Window Handle of Dialog containing the controls
  1791. IN LPWSTR szUsersPathBuffer
  1792. pointer to the caller's buffer that will receive the MSZ
  1793. wide characters string
  1794. IN DWORD cchUsersPathLength
  1795. size of caller's buffer in characters
  1796. Return Value:
  1797. WIN32 Status of function completion
  1798. ERROR_SUCCESS if successful
  1799. --*/
  1800. {
  1801. return PdhiCompileSelectedCountersT (
  1802. hDlg,
  1803. (LPVOID)szUsersPathBuffer,
  1804. cchUsersPathLength,
  1805. TRUE);
  1806. }
  1807. STATIC_PDH_FUNCTION
  1808. PdhiCompileSelectedCountersA (
  1809. IN HWND hDlg,
  1810. IN LPSTR szUsersPathBuffer,
  1811. IN DWORD cchUsersPathLength
  1812. )
  1813. /*++
  1814. Routine Description:
  1815. ANSI function wrapper for base function which scans the selected
  1816. objects, counter, instances and builds a multi-SZ string containing
  1817. the expanded path of all the selections, unless the wild card
  1818. syntax is specified.
  1819. Arguments:
  1820. IN HWND hDlg
  1821. Window Handle of Dialog containing the controls
  1822. IN LPsSTR szUsersPathBuffer
  1823. pointer to the caller's buffer that will receive the MSZ
  1824. single-byte characters string
  1825. IN DWORD cchUsersPathLength
  1826. size of caller's buffer in characters
  1827. Return Value:
  1828. WIN32 Status of function completion
  1829. ERROR_SUCCESS if successful
  1830. --*/
  1831. {
  1832. return PdhiCompileSelectedCountersT (
  1833. hDlg,
  1834. (LPVOID)szUsersPathBuffer,
  1835. cchUsersPathLength,
  1836. FALSE);
  1837. }
  1838. STATIC_BOOL
  1839. PdhiBrowseCtrDlg_MACHINE_COMBO (
  1840. IN HWND hDlg,
  1841. IN WORD wNotifyMsg,
  1842. IN HWND hWndControl
  1843. )
  1844. /*++
  1845. Routine Description:
  1846. Processes the windows messags sent by the Machine selection combo box
  1847. Arguments:
  1848. IN HWND hDlg
  1849. Window Handle to the dialog box containing the control
  1850. IN WORD wNotifyMsg
  1851. Notification message sent by the control
  1852. IN HWND hWndControl
  1853. Window handle of the control sending the message
  1854. Return Value:
  1855. TRUE if this function handles the message
  1856. FALSE if this function did not process the message and the Default
  1857. message handler for this function should handle the message
  1858. --*/
  1859. {
  1860. WCHAR szNewMachineName[MAX_PATH];
  1861. HWND hWndMachineCombo = hWndControl;
  1862. long lMatchIndex;
  1863. HCURSOR hOldCursor;
  1864. PPDHI_BROWSE_DIALOG_DATA pData;
  1865. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  1866. if (pData == NULL) {
  1867. #if PDHI_REPORT_CODE_ERRORS
  1868. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  1869. #endif
  1870. return FALSE;
  1871. }
  1872. switch (wNotifyMsg) {
  1873. case CBN_KILLFOCUS:
  1874. // the user has left the control so see if there's a new
  1875. // machine name that will need to be connected to and loaded
  1876. // display the wait cursor as this could take a while
  1877. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  1878. // Get current combo box text
  1879. GetWindowTextW (hWndMachineCombo, szNewMachineName, MAX_PATH);
  1880. // see if it's in the combo box already
  1881. lMatchIndex = (long)SendMessageW (hWndMachineCombo,
  1882. CB_FINDSTRINGEXACT,(WPARAM)-1, (LPARAM)szNewMachineName);
  1883. // if name is in list, then select it and initialize the dialog
  1884. // update the current counter list & data block for this machine
  1885. // in the process.
  1886. if (lMatchIndex != CB_ERR) {
  1887. // this name is already in the list so see if it's the same as the last selected machine
  1888. if (lstrcmpiW (szNewMachineName, pData->szLastMachineName) != 0) {
  1889. // this is a different machine so update the display
  1890. SendMessageW (hWndMachineCombo, CB_SETCURSEL,
  1891. (WPARAM)lMatchIndex, 0);
  1892. PdhiLoadMachineObjects (hDlg, TRUE);
  1893. PdhiLoadCountersAndInstances (hDlg);
  1894. // display explain text if necessary
  1895. SendMessageW (hDlg, WM_COMMAND,
  1896. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  1897. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  1898. lstrcpyW (pData->szLastMachineName, szNewMachineName);
  1899. } else {
  1900. // they just reselected this machine so nothing to do
  1901. }
  1902. } else {
  1903. if (PdhiLoadNewMachine (hDlg, szNewMachineName)) {
  1904. // new machine loaded and selected so save the name.
  1905. lstrcpyW (pData->szLastMachineName, szNewMachineName);
  1906. }
  1907. }
  1908. SetCursor (hOldCursor);
  1909. return TRUE;
  1910. default:
  1911. return FALSE;
  1912. }
  1913. }
  1914. STATIC_BOOL
  1915. PdhiBrowseCtrDlg_MACHINE_BUTTON (
  1916. IN HWND hDlg,
  1917. IN WORD wNotifyMsg,
  1918. IN HWND hWndControl
  1919. )
  1920. /*++
  1921. Routine Description:
  1922. Processes the windows message that occurs when one of the
  1923. machine context selection buttons in pressed in the dialog
  1924. Arguments:
  1925. IN HWND hDlg
  1926. Window Handle to the dialog box containing the button controls
  1927. IN WORD wNotifyMsg
  1928. Notification message sent by the button
  1929. IN HWND hWndControl
  1930. Window handle of the control sending the message
  1931. Return Value:
  1932. TRUE if this function handles the message
  1933. FALSE if this function did not process the message and the Default
  1934. message handler for this function should handle the message
  1935. --*/
  1936. {
  1937. BOOL bMode;
  1938. PPDHI_BROWSE_DIALOG_DATA pData;
  1939. HWND hWndMachineCombo;
  1940. UNREFERENCED_PARAMETER (hWndControl);
  1941. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  1942. if (pData == NULL) {
  1943. #if PDHI_REPORT_CODE_ERRORS
  1944. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  1945. #endif
  1946. return FALSE;
  1947. }
  1948. switch (wNotifyMsg) {
  1949. case BN_CLICKED:
  1950. // select the current display and processing mode based
  1951. // on the button that his currently checked.
  1952. bMode = !(BOOL)IsDlgButtonChecked(hDlg, IDC_USE_LOCAL_MACHINE);
  1953. EnableWindow(GetDlgItem(hDlg, IDC_MACHINE_COMBO), bMode);
  1954. if (!bMode) {
  1955. hWndMachineCombo = GetDlgItem(hDlg, IDC_MACHINE_COMBO);
  1956. // then this is a Local machine query so
  1957. // make sure the machine name is set to the local machine
  1958. SetWindowTextW (hWndMachineCombo, szStaticLocalMachineName);
  1959. PdhiBrowseCtrDlg_MACHINE_COMBO (hDlg, CBN_KILLFOCUS, hWndMachineCombo);
  1960. }
  1961. pData->bIncludeMachineInPath = bMode;
  1962. return TRUE;
  1963. default:
  1964. return FALSE;
  1965. }
  1966. }
  1967. STATIC_BOOL
  1968. PdhiBrowseCtrDlg_OBJECT_COMBO (
  1969. IN HWND hDlg,
  1970. IN WORD wNotifyMsg,
  1971. IN HWND hWndControl
  1972. )
  1973. /*++
  1974. Routine Description:
  1975. Processes the windows messags sent by the Object selection combo box.
  1976. Arguments:
  1977. IN HWND hDlg
  1978. Window Handle to the dialog box containing the control
  1979. IN WORD wNotifyMsg
  1980. Notification message sent by the control
  1981. IN HWND hWndControl
  1982. Window handle of the control sending the message
  1983. Return Value:
  1984. TRUE if this function handles the message
  1985. FALSE if this function did not process the message and the Default
  1986. message handler for this function should handle the message
  1987. --*/
  1988. {
  1989. UNREFERENCED_PARAMETER (hWndControl);
  1990. switch (wNotifyMsg) {
  1991. case CBN_SELCHANGE:
  1992. PdhiLoadCountersAndInstances (hDlg);
  1993. SendMessageW (hDlg, WM_COMMAND,
  1994. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  1995. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  1996. return TRUE;
  1997. default:
  1998. return FALSE;
  1999. }
  2000. }
  2001. STATIC_BOOL
  2002. PdhiBrowseCtrDlg_COUNTER_LIST (
  2003. IN HWND hDlg,
  2004. IN WORD wNotifyMsg,
  2005. IN HWND hWndControl
  2006. )
  2007. /*++
  2008. Routine Description:
  2009. Processes the windows messags sent by the Object selection combo box.
  2010. Arguments:
  2011. IN HWND hDlg
  2012. Window Handle to the dialog box containing the control
  2013. IN WORD wNotifyMsg
  2014. Notification message sent by the control
  2015. IN HWND hWndControl
  2016. Window handle of the control sending the message
  2017. Return Value:
  2018. TRUE if this function handles the message
  2019. FALSE if this function did not process the message and the Default
  2020. message handler for this function should handle the message
  2021. --*/
  2022. {
  2023. WCHAR szMachineName[MAX_PATH];
  2024. WCHAR szObjectName[MAX_PATH];
  2025. WCHAR szCounterName[MAX_PATH];
  2026. WCHAR szDisplayString[MAX_PATH*2];
  2027. LPWSTR szExplainText = NULL;
  2028. BOOL bFreeExplain = FALSE;
  2029. LONG lIndex;
  2030. UNREFERENCED_PARAMETER (hWndControl);
  2031. switch (wNotifyMsg) {
  2032. case LBN_SELCHANGE:
  2033. if (hExplainDlg != NULL) {
  2034. // get machine name
  2035. GetDlgItemTextW (hDlg, IDC_MACHINE_COMBO,
  2036. szMachineName, MAX_PATH);
  2037. // get object name
  2038. GetDlgItemTextW (hDlg, IDC_OBJECT_COMBO,
  2039. szObjectName, MAX_PATH);
  2040. // get counter name
  2041. // depending on list box type
  2042. lIndex = (LONG)SendDlgItemMessageW (hDlg, IDC_COUNTER_LIST,
  2043. LB_GETCARETINDEX, 0, 0);
  2044. if (lIndex != LB_ERR) {
  2045. lIndex = (LONG)SendDlgItemMessageW (hDlg, IDC_COUNTER_LIST,
  2046. LB_GETTEXT, (WPARAM)lIndex, (LPARAM)&szCounterName[0]);
  2047. // get help string
  2048. if (dwPdhiLocalDefaultDataSource == DATA_SOURCE_WBEM) {
  2049. PDH_STATUS Status = PDH_MORE_DATA;
  2050. DWORD dwExplain = 0;
  2051. szExplainText = NULL;
  2052. while (Status == PDH_MORE_DATA) {
  2053. dwExplain += MAX_PATH;
  2054. if (szExplainText != NULL) {
  2055. G_FREE(szExplainText);
  2056. }
  2057. szExplainText = G_ALLOC(dwExplain * sizeof(WCHAR));
  2058. if (szExplainText == NULL) {
  2059. bFreeExplain = FALSE;
  2060. Status = PDH_MEMORY_ALLOCATION_FAILURE;
  2061. }
  2062. else {
  2063. bFreeExplain = TRUE;
  2064. Status = PdhiGetWbemExplainText(
  2065. szMachineName,
  2066. szObjectName,
  2067. szCounterName,
  2068. szExplainText,
  2069. & dwExplain);
  2070. }
  2071. }
  2072. if (Status != ERROR_SUCCESS) {
  2073. if (bFreeExplain) {
  2074. bFreeExplain = FALSE;
  2075. G_FREE(szExplainText);
  2076. }
  2077. szExplainText = NULL;
  2078. }
  2079. }
  2080. else {
  2081. szExplainText = PdhiGetExplainText(
  2082. szMachineName, szObjectName, szCounterName);
  2083. }
  2084. lstrcpyW(szDisplayString, szMachineName);
  2085. lstrcatW(szDisplayString, cszBackSlash);
  2086. lstrcatW(szDisplayString, szObjectName);
  2087. lstrcatW(szDisplayString, cszBackSlash);
  2088. lstrcatW(szDisplayString, szCounterName);
  2089. } else {
  2090. szExplainText = NULL;
  2091. szDisplayString[0] = 0;
  2092. }
  2093. // send to explain dialog
  2094. SendMessageW (hExplainDlg, EDM_UPDATE_EXPLAIN_TEXT,
  2095. 0, (LPARAM)szExplainText);
  2096. SendMessageW (hExplainDlg, EDM_UPDATE_TITLE_TEXT,
  2097. 0, (LPARAM)szDisplayString);
  2098. }
  2099. if (bFreeExplain && szExplainText != NULL) {
  2100. G_FREE(szExplainText);
  2101. }
  2102. return TRUE;
  2103. default:
  2104. return FALSE;
  2105. }
  2106. }
  2107. STATIC_BOOL
  2108. PdhiBrowseCtrDlg_OBJECT_LIST (
  2109. IN HWND hDlg,
  2110. IN WORD wNotifyMsg,
  2111. IN HWND hWndControl
  2112. )
  2113. /*++
  2114. Routine Description:
  2115. Processes the windows messags sent by the Object selection combo box.
  2116. Arguments:
  2117. IN HWND hDlg
  2118. Window Handle to the dialog box containing the control
  2119. IN WORD wNotifyMsg
  2120. Notification message sent by the control
  2121. IN HWND hWndControl
  2122. Window handle of the control sending the message
  2123. Return Value:
  2124. TRUE if this function handles the message
  2125. FALSE if this function did not process the message and the Default
  2126. message handler for this function should handle the message
  2127. --*/
  2128. {
  2129. WCHAR szMachineName[MAX_PATH];
  2130. WCHAR szObjectName[MAX_PATH];
  2131. WCHAR szDisplayString[MAX_PATH*2];
  2132. LPWSTR szExplainText = NULL;
  2133. BOOL bFreeExplain = FALSE;
  2134. LONG lIndex;
  2135. UNREFERENCED_PARAMETER (hWndControl);
  2136. switch (wNotifyMsg) {
  2137. case LBN_SELCHANGE:
  2138. if (hExplainDlg != NULL) {
  2139. // get machine name
  2140. GetDlgItemTextW (hDlg, IDC_MACHINE_COMBO,
  2141. szMachineName, MAX_PATH);
  2142. // get object name depending on list box type
  2143. lIndex = (LONG)SendDlgItemMessageW (hDlg, IDC_OBJECT_LIST,
  2144. LB_GETCARETINDEX, 0, 0);
  2145. if (lIndex != LB_ERR) {
  2146. lIndex = (LONG)SendDlgItemMessageW (hDlg, IDC_OBJECT_LIST,
  2147. LB_GETTEXT, (WPARAM)lIndex, (LPARAM)&szObjectName[0]);
  2148. // get help string
  2149. if (dwPdhiLocalDefaultDataSource == DATA_SOURCE_WBEM) {
  2150. PDH_STATUS Status = PDH_MORE_DATA;
  2151. DWORD dwExplain = 0;
  2152. szExplainText = NULL;
  2153. while (Status == PDH_MORE_DATA) {
  2154. dwExplain += MAX_PATH;
  2155. if (szExplainText != NULL) {
  2156. G_FREE(szExplainText);
  2157. }
  2158. szExplainText = G_ALLOC(dwExplain * sizeof(WCHAR));
  2159. if (szExplainText == NULL) {
  2160. bFreeExplain = FALSE;
  2161. Status = PDH_MEMORY_ALLOCATION_FAILURE;
  2162. }
  2163. else {
  2164. bFreeExplain = TRUE;
  2165. Status = PdhiGetWbemExplainText(
  2166. szMachineName,
  2167. szObjectName,
  2168. NULL,
  2169. szExplainText,
  2170. & dwExplain);
  2171. }
  2172. }
  2173. if (Status != ERROR_SUCCESS) {
  2174. if (bFreeExplain) {
  2175. bFreeExplain = FALSE;
  2176. G_FREE(szExplainText);
  2177. }
  2178. szExplainText = NULL;
  2179. }
  2180. }
  2181. else {
  2182. szExplainText = PdhiGetExplainText(
  2183. szMachineName, szObjectName, NULL);
  2184. }
  2185. lstrcpyW(szDisplayString, szMachineName);
  2186. lstrcatW(szDisplayString, cszBackSlash);
  2187. lstrcatW(szDisplayString, szObjectName);
  2188. } else {
  2189. szExplainText = NULL;
  2190. szDisplayString[0] = 0;
  2191. }
  2192. // send to explain dialog
  2193. SendMessageW (hExplainDlg, EDM_UPDATE_EXPLAIN_TEXT,
  2194. 0, (LPARAM)szExplainText);
  2195. SendMessageW (hExplainDlg, EDM_UPDATE_TITLE_TEXT,
  2196. 0, (LPARAM)szDisplayString);
  2197. }
  2198. if (bFreeExplain && szExplainText != NULL) {
  2199. G_FREE(szExplainText);
  2200. }
  2201. return TRUE;
  2202. default:
  2203. return FALSE;
  2204. }
  2205. }
  2206. STATIC_BOOL
  2207. PdhiBrowseCtrDlg_DETAIL_COMBO (
  2208. IN HWND hDlg,
  2209. IN WORD wNotifyMsg,
  2210. IN HWND hWndControl
  2211. )
  2212. /*++
  2213. Routine Description:
  2214. Processes the windows messags sent by the Detail Level Combo box.
  2215. Arguments:
  2216. IN HWND hDlg
  2217. Window Handle to the dialog box containing the control
  2218. IN WORD wNotifyMsg
  2219. Notification message sent by the control
  2220. IN HWND hWndControl
  2221. Window handle of the control sending the message
  2222. Return Value:
  2223. TRUE if this function handles the message
  2224. FALSE if this function did not process the message and the Default
  2225. message handler for this function should handle the message
  2226. --*/
  2227. {
  2228. DWORD dwCurSel;
  2229. PPDHI_BROWSE_DIALOG_DATA pData;
  2230. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  2231. if (pData == NULL) {
  2232. #if PDHI_REPORT_CODE_ERRORS
  2233. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  2234. #endif
  2235. return FALSE;
  2236. }
  2237. switch (wNotifyMsg) {
  2238. case CBN_SELCHANGE:
  2239. dwCurSel = (DWORD)SendMessageW (hWndControl, CB_GETCURSEL, 0, 0);
  2240. if (dwCurSel != CB_ERR) {
  2241. pData->dwCurrentDetailLevel = (DWORD)SendMessageW (hWndControl,
  2242. CB_GETITEMDATA, (WPARAM)dwCurSel, 0);
  2243. // update all the windows to show the new level
  2244. PdhiLoadMachineObjects (hDlg, FALSE);
  2245. PdhiLoadCountersAndInstances (hDlg);
  2246. // display explain text if necessary
  2247. SendMessageW (hDlg, WM_COMMAND,
  2248. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  2249. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  2250. }
  2251. return TRUE;
  2252. default:
  2253. return FALSE;
  2254. }
  2255. }
  2256. STATIC_BOOL
  2257. PdhiBrowseCtrDlg_INSTANCE_BUTTON (
  2258. IN HWND hDlg,
  2259. IN WORD wNotifyMsg,
  2260. IN HWND hWndControl
  2261. )
  2262. /*++
  2263. Routine Description:
  2264. Processes the windows messags sent by the Instance configuration
  2265. selection buttons
  2266. Arguments:
  2267. IN HWND hDlg
  2268. Window Handle to the dialog box containing the control
  2269. IN WORD wNotifyMsg
  2270. Notification message sent by the control
  2271. IN HWND hWndControl
  2272. Window handle of the control sending the message
  2273. Return Value:
  2274. TRUE if this function handles the message
  2275. FALSE if this function did not process the message and the Default
  2276. message handler for this function should handle the message
  2277. --*/
  2278. {
  2279. BOOL bMode;
  2280. HWND hWndInstanceList;
  2281. PPDHI_BROWSE_DIALOG_DATA pData;
  2282. UNREFERENCED_PARAMETER (hWndControl);
  2283. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  2284. if (pData == NULL) {
  2285. #if PDHI_REPORT_CODE_ERRORS
  2286. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  2287. #endif
  2288. return FALSE;
  2289. }
  2290. switch (wNotifyMsg) {
  2291. case BN_CLICKED:
  2292. bMode = (BOOL)IsDlgButtonChecked(hDlg, IDC_ALL_INSTANCES);
  2293. hWndInstanceList = GetDlgItem(hDlg, IDC_INSTANCE_LIST);
  2294. // if "Select ALL" then clear list box selections and disable
  2295. // the list box
  2296. if (bMode) {
  2297. SendMessageW (hWndInstanceList, LB_SETSEL, FALSE, (LPARAM)-1);
  2298. } else {
  2299. LRESULT dwCountInstance =
  2300. SendMessage(hWndInstanceList, LB_GETCOUNT, 0, 0);
  2301. LRESULT dwThisInstance = 0;
  2302. BOOL bSelection = FALSE;
  2303. for (dwThisInstance = 0;
  2304. ! bSelection && dwThisInstance < dwCountInstance;
  2305. dwThisInstance ++) {
  2306. bSelection = (BOOL) SendMessage(hWndInstanceList,
  2307. LB_GETSEL,
  2308. (WPARAM) dwThisInstance,
  2309. 0);
  2310. }
  2311. if (! bSelection) {
  2312. SendMessageW (hWndInstanceList, LB_SETSEL, TRUE, (LPARAM)0);
  2313. }
  2314. }
  2315. EnableWindow(hWndInstanceList, !bMode);
  2316. pData->bSelectAllInstances = bMode;
  2317. return TRUE;
  2318. default:
  2319. return FALSE;
  2320. }
  2321. }
  2322. STATIC_BOOL
  2323. PdhiBrowseCtrDlg_COUNTER_BUTTON (
  2324. IN HWND hDlg,
  2325. IN WORD wNotifyMsg,
  2326. IN HWND hWndControl
  2327. )
  2328. /*++
  2329. Routine Description:
  2330. Processes the windows messags sent by the Instance configuration
  2331. selection buttons
  2332. Arguments:
  2333. IN HWND hDlg
  2334. Window Handle to the dialog box containing the control
  2335. IN WORD wNotifyMsg
  2336. Notification message sent by the control
  2337. IN HWND hWndControl
  2338. Window handle of the control sending the message
  2339. Return Value:
  2340. TRUE if this function handles the message
  2341. FALSE if this function did not process the message and the Default
  2342. message handler for this function should handle the message
  2343. --*/
  2344. {
  2345. BOOL bMode;
  2346. HWND hWndCounterList;
  2347. PPDHI_BROWSE_DIALOG_DATA pData;
  2348. UNREFERENCED_PARAMETER (hWndControl);
  2349. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  2350. if (pData == NULL) {
  2351. #if PDHI_REPORT_CODE_ERRORS
  2352. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  2353. #endif
  2354. return FALSE;
  2355. }
  2356. switch (wNotifyMsg) {
  2357. case BN_CLICKED:
  2358. bMode = (BOOL)IsDlgButtonChecked(hDlg, IDC_ALL_COUNTERS);
  2359. hWndCounterList = GetDlgItem(hDlg, IDC_COUNTER_LIST);
  2360. // if "Select ALL" then clear list box selections and disable
  2361. // the list box
  2362. if (bMode) {
  2363. SendMessageW (hWndCounterList, LB_SETSEL, FALSE, (LPARAM)-1);
  2364. } else {
  2365. LRESULT dwCountCounter =
  2366. SendMessage(hWndCounterList, LB_GETCOUNT, 0, 0);
  2367. LRESULT dwThisCounter = 0;
  2368. BOOL bSelection = FALSE;
  2369. for (dwThisCounter = 0;
  2370. ! bSelection && dwThisCounter < dwCountCounter;
  2371. dwThisCounter ++) {
  2372. bSelection = (BOOL) SendMessage(hWndCounterList,
  2373. LB_GETSEL,
  2374. (WPARAM) dwThisCounter,
  2375. 0);
  2376. }
  2377. if (! bSelection) {
  2378. PDH_STATUS pdhStatus = ERROR_SUCCESS;
  2379. DWORD dwCounterName = MAX_PATH;
  2380. DWORD dwCounterIndex = 0;
  2381. WCHAR szMachineName[MAX_PATH + 1];
  2382. WCHAR szObjectName[MAX_PATH + 1];
  2383. WCHAR szCounterName[MAX_PATH + 1];
  2384. GetDlgItemTextW(hDlg,
  2385. IDC_MACHINE_COMBO,
  2386. szMachineName
  2387. , MAX_PATH);
  2388. GetDlgItemTextW(hDlg,
  2389. IDC_OBJECT_COMBO,
  2390. szObjectName,
  2391. MAX_PATH);
  2392. pdhStatus = PdhGetDefaultPerfCounterHW (
  2393. pData->pDlgData->hDataSource,
  2394. szMachineName,
  2395. szObjectName,
  2396. szCounterName,
  2397. & dwCounterName);
  2398. if (pdhStatus == ERROR_SUCCESS) {
  2399. dwCounterIndex = (DWORD) SendMessageW(
  2400. hWndCounterList,
  2401. LB_FINDSTRINGEXACT,
  2402. (WPARAM) -1,
  2403. (LPARAM) szCounterName);
  2404. if (dwCounterIndex == LB_ERR) {
  2405. dwCounterIndex = 0;
  2406. }
  2407. }
  2408. SendMessageW(hWndCounterList,
  2409. LB_SETSEL,
  2410. TRUE,
  2411. (LPARAM) dwCounterIndex);
  2412. }
  2413. }
  2414. EnableWindow(hWndCounterList, !bMode);
  2415. pData->bSelectAllCounters = bMode;
  2416. return TRUE;
  2417. default:
  2418. return FALSE;
  2419. }
  2420. }
  2421. #pragma warning ( disable : 4127 )
  2422. STATIC_BOOL
  2423. PdhiBrowseCtrDlg_OK (
  2424. IN HWND hDlg,
  2425. IN WORD wNotifyMsg,
  2426. IN HWND hWndControl
  2427. )
  2428. /*++
  2429. Routine Description:
  2430. Processes the currently selected counter and instance strings to
  2431. build a list of selected paths strings in the user's supplied
  2432. buffer. This buffer will either be processed by a call back
  2433. string or the dialog box will be terminated allowing the
  2434. calling function to continue processing the returned strings.
  2435. Arguments:
  2436. IN HWND hDlg
  2437. Window Handle to the dialog box containing the button controls
  2438. IN WORD wNotifyMsg
  2439. Notification message sent by the button
  2440. IN HWND hWndControl
  2441. Window handle of the control sending the message
  2442. Return Value:
  2443. TRUE if this function handles the message
  2444. FALSE if this function did not process the message and the Default
  2445. message handler for this function should handle the message
  2446. --*/
  2447. {
  2448. HCURSOR hOldCursor;
  2449. CounterPathCallBack pCallBack;
  2450. DWORD_PTR dwArg;
  2451. PDH_STATUS pdhStatus;
  2452. PPDHI_BROWSE_DIALOG_DATA pData;
  2453. PPDHI_BROWSE_DLG_INFO pDlgData;
  2454. HWND hWndFocus;
  2455. HWND hWndMachine;
  2456. UNREFERENCED_PARAMETER (hWndControl);
  2457. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  2458. if (pData == NULL) {
  2459. #if PDHI_REPORT_CODE_ERRORS
  2460. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  2461. #endif
  2462. return FALSE;
  2463. }
  2464. pDlgData = pData->pDlgData;
  2465. hWndFocus = GetFocus();
  2466. hWndMachine = GetDlgItem (hDlg, IDC_MACHINE_COMBO);
  2467. if (hWndFocus == hWndMachine) {
  2468. //special case to make sure the dialog has the current machine data
  2469. PdhiBrowseCtrDlg_MACHINE_COMBO (hDlg, CBN_KILLFOCUS, hWndMachine);
  2470. SetFocus (hWndControl);
  2471. }
  2472. switch (wNotifyMsg) {
  2473. case BN_CLICKED:
  2474. // display wait cursor while this is being processed
  2475. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  2476. while (TRUE) {
  2477. if (pData->bShowObjects) {
  2478. // then return object spec(s) using selected perf objects
  2479. if (pDlgData->pWideStruct != NULL) {
  2480. // use wide character function
  2481. pdhStatus = PdhiCompileSelectedObjectsW (hDlg,
  2482. pDlgData->pWideStruct->szReturnPathBuffer,
  2483. pDlgData->pWideStruct->cchReturnPathLength);
  2484. pCallBack = pDlgData->pWideStruct->pCallBack;
  2485. dwArg = pDlgData->pWideStruct->dwCallBackArg;
  2486. pDlgData->pWideStruct->CallBackStatus = pdhStatus;
  2487. } else if (pDlgData->pAnsiStruct != NULL) {
  2488. // use ansi char functions
  2489. pdhStatus = PdhiCompileSelectedObjectsA (hDlg,
  2490. pDlgData->pAnsiStruct->szReturnPathBuffer,
  2491. pDlgData->pAnsiStruct->cchReturnPathLength);
  2492. pCallBack = pDlgData->pAnsiStruct->pCallBack;
  2493. dwArg = pDlgData->pAnsiStruct->dwCallBackArg;
  2494. pDlgData->pAnsiStruct->CallBackStatus = pdhStatus;
  2495. } else {
  2496. // do nothing
  2497. pCallBack = NULL;
  2498. dwArg = 0;
  2499. }
  2500. } else {
  2501. // return selected counters & instances
  2502. // process these string until it works. (note, this
  2503. // could cause an infinite loop if the callback
  2504. // function is not working correctly (i.e. always
  2505. // returning PDH_RETRY, for example)
  2506. if (pDlgData->pWideStruct != NULL) {
  2507. // use wide character function
  2508. pdhStatus = PdhiCompileSelectedCountersW (hDlg,
  2509. pDlgData->pWideStruct->szReturnPathBuffer,
  2510. pDlgData->pWideStruct->cchReturnPathLength);
  2511. pCallBack = pDlgData->pWideStruct->pCallBack;
  2512. dwArg = pDlgData->pWideStruct->dwCallBackArg;
  2513. pDlgData->pWideStruct->CallBackStatus = pdhStatus;
  2514. } else if (pDlgData->pAnsiStruct != NULL) {
  2515. // use ansi char functions
  2516. pdhStatus = PdhiCompileSelectedCountersA (hDlg,
  2517. pDlgData->pAnsiStruct->szReturnPathBuffer,
  2518. pDlgData->pAnsiStruct->cchReturnPathLength);
  2519. pCallBack = pDlgData->pAnsiStruct->pCallBack;
  2520. dwArg = pDlgData->pAnsiStruct->dwCallBackArg;
  2521. pDlgData->pAnsiStruct->CallBackStatus = pdhStatus;
  2522. } else {
  2523. // do nothing
  2524. pCallBack = NULL;
  2525. dwArg = 0;
  2526. }
  2527. }
  2528. if (pCallBack != NULL) {
  2529. pdhStatus = (*pCallBack)(dwArg);
  2530. } else {
  2531. pdhStatus = ERROR_SUCCESS;
  2532. }
  2533. // see if the callback wants to try again
  2534. if (pdhStatus != PDH_RETRY) {
  2535. break;
  2536. }
  2537. } // end while (retry loop)
  2538. // if the caller only wants to give the user ONE chance to
  2539. // add counters, then end the dialog now.
  2540. if (!pData->bAddMultipleCounters) {
  2541. EndDialog (hDlg, IDOK);
  2542. }
  2543. SetCursor (hOldCursor);
  2544. return TRUE;
  2545. default:
  2546. return FALSE;
  2547. }
  2548. }
  2549. #pragma warning ( default : 4127 )
  2550. STATIC_BOOL
  2551. PdhiBrowseCtrDlg_CANCEL (
  2552. IN HWND hDlg,
  2553. IN WORD wNotifyMsg,
  2554. IN HWND hWndControl
  2555. )
  2556. /*++
  2557. Routine Description:
  2558. Processes the windows messages that occur when the cancel button
  2559. is pressed.
  2560. Arguments:
  2561. IN HWND hDlg
  2562. Window Handle to the dialog box containing the button controls
  2563. IN WORD wNotifyMsg
  2564. Notification message sent by the button
  2565. IN HWND hWndControl
  2566. Window handle of the control sending the message
  2567. Return Value:
  2568. TRUE if this function handles the message
  2569. FALSE if this function did not process the message and the Default
  2570. message handler for this function should handle the message
  2571. --*/
  2572. {
  2573. UNREFERENCED_PARAMETER (hWndControl);
  2574. switch (wNotifyMsg) {
  2575. case BN_CLICKED:
  2576. EndDialog (hDlg, IDCANCEL);
  2577. return TRUE;
  2578. default:
  2579. return FALSE;
  2580. }
  2581. }
  2582. STATIC_BOOL
  2583. PdhiBrowseCtrDlg_EXPLAIN_BTN (
  2584. IN HWND hDlg,
  2585. IN WORD wNotifyMsg,
  2586. IN HWND hWndControl
  2587. )
  2588. /*++
  2589. Routine Description:
  2590. Processes the windows message that occurs when the help button
  2591. is pressed. (This feature is not currently implemented)
  2592. Arguments:
  2593. IN HWND hDlg
  2594. Window Handle to the dialog box containing the button controls
  2595. IN WORD wNotifyMsg
  2596. Notification message sent by the button
  2597. IN HWND hWndControl
  2598. Window handle of the control sending the message
  2599. Return Value:
  2600. TRUE if this function handles the message
  2601. FALSE if this function did not process the message and the Default
  2602. message handler for this function should handle the message
  2603. --*/
  2604. {
  2605. HWND hFocusWnd;
  2606. PPDHI_BROWSE_DIALOG_DATA pData =
  2607. (PPDHI_BROWSE_DIALOG_DATA) GetWindowLongPtrW(hDlg, DWLP_USER);
  2608. UNREFERENCED_PARAMETER (wNotifyMsg);
  2609. if (hExplainDlg == NULL) {
  2610. hFocusWnd = GetFocus();
  2611. // create a modeless dialog to display the explain text
  2612. hExplainDlg = CreateDialogW (
  2613. ThisDLLHandle,
  2614. MAKEINTRESOURCEW(IDD_EXPLAIN_DLG),
  2615. hDlg,
  2616. (DLGPROC)ExplainTextDlgProc);
  2617. SetFocus(hFocusWnd);
  2618. EnableWindow (hWndControl, FALSE);
  2619. }
  2620. if (pData->bShowObjects) {
  2621. SendMessageW(hDlg,
  2622. WM_COMMAND,
  2623. MAKEWPARAM(IDC_OBJECT_LIST, LBN_SELCHANGE),
  2624. (LPARAM) GetDlgItem(hDlg, IDC_OBJECT_LIST));
  2625. }
  2626. else {
  2627. SendMessageW(hDlg,
  2628. WM_COMMAND,
  2629. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  2630. (LPARAM) GetDlgItem(hDlg, IDC_COUNTER_LIST));
  2631. }
  2632. return TRUE;
  2633. }
  2634. STATIC_BOOL
  2635. PdhiBrowseCtrDlg_HELP_BTN (
  2636. IN HWND hDlg,
  2637. IN WORD wNotifyMsg,
  2638. IN HWND hWndControl
  2639. )
  2640. /*++
  2641. Routine Description:
  2642. Processes the windows message that occurs when the network button
  2643. is pressed. (This feature is not currently implemented)
  2644. Arguments:
  2645. IN HWND hDlg
  2646. Window Handle to the dialog box containing the button controls
  2647. IN WORD wNotifyMsg
  2648. Notification message sent by the button
  2649. IN HWND hWndControl
  2650. Window handle of the control sending the message
  2651. Return Value:
  2652. TRUE if this function handles the message
  2653. FALSE if this function did not process the message and the Default
  2654. message handler for this function should handle the message
  2655. --*/
  2656. {
  2657. LPWSTR szMsg;
  2658. UNREFERENCED_PARAMETER (wNotifyMsg);
  2659. UNREFERENCED_PARAMETER (hWndControl);
  2660. szMsg = GetStringResource (IDS_ERR_NO_HELP);
  2661. if (szMsg != NULL) {
  2662. MessageBoxW (hDlg, szMsg, szMsg, MB_OK);
  2663. G_FREE (szMsg);
  2664. } else {
  2665. MessageBeep (MB_ICONEXCLAMATION);
  2666. }
  2667. return TRUE;
  2668. }
  2669. STATIC_BOOL
  2670. PdhiBrowseCtrDlg_WM_INITDIALOG (
  2671. IN HWND hDlg,
  2672. IN WPARAM wParam,
  2673. IN LPARAM lParam
  2674. )
  2675. /*++
  2676. Routine Description:
  2677. Processes the windows message that occurs just before the dialog
  2678. box is displayed for the first time.
  2679. Arguments:
  2680. IN HWND hDlg
  2681. Window Handle to the dialog box containing the button controls
  2682. IN WORD wParam
  2683. IN HWND lParam
  2684. Pointer to dialog box data block
  2685. Return Value:
  2686. TRUE if this function handles the message
  2687. FALSE if this function did not process the message and the Default
  2688. message handler for this function should handle the message
  2689. --*/
  2690. {
  2691. PPDHI_BROWSE_DIALOG_DATA pData;
  2692. PPDHI_BROWSE_DLG_INFO pDlgData;
  2693. HCURSOR hOldCursor;
  2694. LPWSTR szMsg;
  2695. UNREFERENCED_PARAMETER (wParam);
  2696. // reset the last error value
  2697. SetLastError (ERROR_SUCCESS);
  2698. hOldCursor = SetCursor (LoadCursor (NULL, IDC_WAIT));
  2699. pData = (PPDHI_BROWSE_DIALOG_DATA)G_ALLOC(
  2700. sizeof(PDHI_BROWSE_DIALOG_DATA));
  2701. if (pData == NULL) {
  2702. SetLastError (PDH_MEMORY_ALLOCATION_FAILURE);
  2703. EndDialog (hDlg, IDCANCEL);
  2704. return TRUE;
  2705. }
  2706. // initialize local static variables
  2707. dwCounterListSize = COUNTER_LIST_SIZE;
  2708. dwInstanceListSize = INSTANCE_LIST_SIZE;
  2709. // save user data
  2710. pDlgData = (PPDHI_BROWSE_DLG_INFO) lParam;
  2711. pData->pDlgData = (PPDHI_BROWSE_DLG_INFO) lParam;
  2712. SetWindowLongPtrW (hDlg, DWLP_USER, (LONG_PTR)pData);
  2713. // load configuration flags from user data
  2714. if (pData->pDlgData->pWideStruct != NULL) {
  2715. // use wide structure
  2716. pData->bShowIndex =
  2717. (BOOL)pDlgData->pWideStruct->bIncludeInstanceIndex;
  2718. pData->bSelectMultipleCounters =
  2719. !(BOOL)pDlgData->pWideStruct->bSingleCounterPerAdd;
  2720. pData->bAddMultipleCounters =
  2721. !(BOOL)pDlgData->pWideStruct->bSingleCounterPerDialog;
  2722. pData->bLocalCountersOnly =
  2723. (BOOL)pDlgData->pWideStruct->bLocalCountersOnly;
  2724. pData->bIncludeMachineInPath = !pData->bLocalCountersOnly;
  2725. pData->bWildCardInstances =
  2726. (BOOL)pDlgData->pWideStruct->bWildCardInstances;
  2727. pData->bHideDetailLevel =
  2728. (BOOL)pDlgData->pWideStruct->bHideDetailBox;
  2729. if (pDlgData->pWideStruct->szDialogBoxCaption != NULL) {
  2730. SetWindowTextW (hDlg, pDlgData->pWideStruct->szDialogBoxCaption);
  2731. }
  2732. pData->dwCurrentDetailLevel =
  2733. pDlgData->pWideStruct->dwDefaultDetailLevel;
  2734. pData->bDisableMachineSelection =
  2735. (BOOL)pDlgData->pWideStruct->bDisableMachineSelection;
  2736. pData->bInitializePath =
  2737. (BOOL)pDlgData->pWideStruct->bInitializePath;
  2738. pData->bIncludeCostlyObjects =
  2739. (BOOL)pDlgData->pWideStruct->bIncludeCostlyObjects;
  2740. pData->bShowObjects =
  2741. (BOOL)pDlgData->pWideStruct->bShowObjectBrowser;
  2742. } else if (pData->pDlgData->pAnsiStruct != NULL) {
  2743. // use Ansi struct
  2744. pData->bShowIndex =
  2745. (BOOL)pDlgData->pAnsiStruct->bIncludeInstanceIndex;
  2746. pData->bSelectMultipleCounters =
  2747. !(BOOL)pDlgData->pAnsiStruct->bSingleCounterPerAdd;
  2748. pData->bAddMultipleCounters =
  2749. !(BOOL)pDlgData->pAnsiStruct->bSingleCounterPerDialog;
  2750. pData->bLocalCountersOnly =
  2751. (BOOL)pDlgData->pAnsiStruct->bLocalCountersOnly;
  2752. pData->bIncludeMachineInPath = !pData->bLocalCountersOnly;
  2753. pData->bWildCardInstances =
  2754. (BOOL)pDlgData->pAnsiStruct->bWildCardInstances;
  2755. pData->bHideDetailLevel =
  2756. (BOOL)pDlgData->pAnsiStruct->bHideDetailBox;
  2757. if (pDlgData->pAnsiStruct->szDialogBoxCaption != NULL) {
  2758. SetWindowTextA (hDlg, pDlgData->pAnsiStruct->szDialogBoxCaption);
  2759. }
  2760. pData->dwCurrentDetailLevel =
  2761. pDlgData->pAnsiStruct->dwDefaultDetailLevel;
  2762. pData->bDisableMachineSelection =
  2763. (BOOL)pDlgData->pAnsiStruct->bDisableMachineSelection;
  2764. pData->bInitializePath =
  2765. (BOOL)pDlgData->pAnsiStruct->bInitializePath;
  2766. pData->bIncludeCostlyObjects =
  2767. (BOOL)pDlgData->pAnsiStruct->bIncludeCostlyObjects;
  2768. pData->bShowObjects =
  2769. (BOOL)pDlgData->pAnsiStruct->bShowObjectBrowser;
  2770. } else {
  2771. // bad data so bail out
  2772. EndDialog (hDlg, IDCANCEL);
  2773. G_FREE(pData);
  2774. return TRUE;
  2775. }
  2776. // selecting objects implies multiple selections
  2777. if (pData->bShowObjects) {
  2778. pData->bSelectMultipleCounters = TRUE;
  2779. }
  2780. // limit text to machine name
  2781. SendDlgItemMessageW (hDlg, IDC_MACHINE_COMBO, EM_LIMITTEXT, MAX_PATH, 0);
  2782. // set check boxes to the caller defined setting
  2783. if (pData->bLocalCountersOnly) {
  2784. // then only the local counters button is selected and enabled
  2785. EnableWindow (GetDlgItem(hDlg, IDC_SELECT_MACHINE), FALSE);
  2786. }
  2787. CheckRadioButton (hDlg, IDC_USE_LOCAL_MACHINE, IDC_SELECT_MACHINE,
  2788. (pData->bIncludeMachineInPath ? IDC_SELECT_MACHINE : IDC_USE_LOCAL_MACHINE));
  2789. EnableWindow (GetDlgItem(hDlg, IDC_MACHINE_COMBO),
  2790. (pData->bIncludeMachineInPath ? TRUE : FALSE));
  2791. if (!pData->bShowObjects) {
  2792. // these controls aren't found in the Object browser
  2793. CheckRadioButton (hDlg, IDC_ALL_INSTANCES, IDC_USE_INSTANCE_LIST,
  2794. IDC_USE_INSTANCE_LIST);
  2795. pData->bSelectAllInstances = FALSE;
  2796. CheckRadioButton (hDlg, IDC_ALL_COUNTERS, IDC_USE_COUNTER_LIST,
  2797. IDC_USE_COUNTER_LIST);
  2798. pData->bSelectAllCounters = FALSE;
  2799. }
  2800. // set button text strings to reflect mode of dialog
  2801. if (pData->bAddMultipleCounters) {
  2802. szMsg = GetStringResource (IDS_BRWS_ADD);
  2803. if (szMsg != NULL) {
  2804. SetWindowTextW(GetDlgItem(hDlg, IDOK), (LPCWSTR)szMsg);
  2805. G_FREE (szMsg);
  2806. }
  2807. szMsg = GetStringResource (IDS_BRWS_CLOSE);
  2808. if (szMsg != NULL) {
  2809. SetWindowTextW(GetDlgItem(hDlg, IDCANCEL), (LPCWSTR)szMsg);
  2810. G_FREE (szMsg);
  2811. }
  2812. } else {
  2813. szMsg = GetStringResource (IDS_BRWS_OK);
  2814. if (szMsg != NULL) {
  2815. SetWindowTextW(GetDlgItem(hDlg, IDOK), (LPCWSTR)szMsg);
  2816. G_FREE (szMsg);
  2817. }
  2818. szMsg = GetStringResource (IDS_BRWS_CANCEL);
  2819. if (szMsg != NULL) {
  2820. SetWindowTextW(GetDlgItem(hDlg, IDCANCEL), (LPCWSTR)szMsg);
  2821. G_FREE (szMsg);
  2822. }
  2823. }
  2824. // see if the data source supports detail levels
  2825. if (!PdhiDataSourceHasDetailLevelsH (pData->pDlgData->hDataSource)) {
  2826. //then set detail to wizard and hide the combo box
  2827. pData->bHideDetailLevel = TRUE;
  2828. pData->dwCurrentDetailLevel = PERF_DETAIL_WIZARD;
  2829. }
  2830. // hide detail combo box if desired
  2831. if (pData->bHideDetailLevel) {
  2832. ShowWindow (GetDlgItem(hDlg, IDC_COUNTER_DETAIL_CAPTION), SW_HIDE);
  2833. ShowWindow (GetDlgItem(hDlg, IDC_COUNTER_DETAIL_COMBO), SW_HIDE);
  2834. // make sure this is a "legal" value
  2835. switch (pData->dwCurrentDetailLevel) {
  2836. case PERF_DETAIL_NOVICE:
  2837. case PERF_DETAIL_EXPERT:
  2838. case PERF_DETAIL_ADVANCED:
  2839. case PERF_DETAIL_WIZARD:
  2840. // these are OK
  2841. break;
  2842. default:
  2843. // default is to show all
  2844. pData->dwCurrentDetailLevel = PERF_DETAIL_WIZARD;
  2845. break;
  2846. }
  2847. } else {
  2848. // load the combo box entries
  2849. pData->dwCurrentDetailLevel = PdhiLoadDetailLevelCombo (
  2850. hDlg, pData->dwCurrentDetailLevel);
  2851. }
  2852. // connect to this machine
  2853. if (pData->pDlgData->hDataSource == H_REALTIME_DATASOURCE) {
  2854. PdhConnectMachineW(NULL); // Null is local machine
  2855. }
  2856. PdhiLoadKnownMachines(hDlg); // load machine list
  2857. PdhiLoadMachineObjects(hDlg, TRUE); // load object list
  2858. if (!pData->bShowObjects) {
  2859. // these controls don't exist in the object browser
  2860. PdhiLoadCountersAndInstances(hDlg);
  2861. }
  2862. if (pData->bShowObjects) {
  2863. // display explain text if necessary
  2864. SendMessageW (hDlg, WM_COMMAND,
  2865. MAKEWPARAM(IDC_OBJECT_LIST, LBN_SELCHANGE),
  2866. (LPARAM)GetDlgItem(hDlg, IDC_OBJECT_LIST));
  2867. } else {
  2868. // display explain text if necessary
  2869. SendMessageW (hDlg, WM_COMMAND,
  2870. MAKEWPARAM(IDC_COUNTER_LIST, LBN_SELCHANGE),
  2871. (LPARAM)GetDlgItem(hDlg, IDC_COUNTER_LIST));
  2872. }
  2873. if (pData->bInitializePath) {
  2874. PdhiSelectItemsInPath(hDlg);
  2875. }
  2876. // hide the machine selection buttons and disable the
  2877. // machine combo box if selected (after the connection has been
  2878. // made, of course)
  2879. if (pData->bDisableMachineSelection) {
  2880. ShowWindow (GetDlgItem(hDlg, IDC_USE_LOCAL_MACHINE), SW_HIDE);
  2881. ShowWindow (GetDlgItem(hDlg, IDC_SELECT_MACHINE), SW_HIDE);
  2882. EnableWindow (GetDlgItem(hDlg, IDC_MACHINE_COMBO), FALSE);
  2883. ShowWindow (GetDlgItem(hDlg, IDC_MACHINE_CAPTION), SW_SHOW);
  2884. } else {
  2885. EnableWindow (GetDlgItem(hDlg, IDC_MACHINE_COMBO), TRUE);
  2886. ShowWindow (GetDlgItem(hDlg, IDC_MACHINE_CAPTION), SW_HIDE);
  2887. }
  2888. pData->wpLastMachineSel = 0;
  2889. hExplainDlg = NULL;
  2890. SetCursor (hOldCursor);
  2891. return TRUE; // return TRUE unless you set the focus to a control
  2892. }
  2893. STATIC_BOOL
  2894. PdhiBrowseCtrDlg_WM_COMPAREITEM (
  2895. IN HWND hDlg,
  2896. IN WPARAM wParam,
  2897. IN LPARAM lParam
  2898. )
  2899. /*++
  2900. Routine Description:
  2901. Processes the windows message that are generated when a combo
  2902. box is searched
  2903. Arguments:
  2904. IN HWND hDlg
  2905. Window handle to the dialog box window
  2906. IN WPARAM wParam
  2907. HIWORD is the notification message ID
  2908. LOWORD is the control ID of the control issuing the command
  2909. IN LPARAM lParam
  2910. the pointer to a compare item structure
  2911. Return Value:
  2912. TRUE if this function handles the message
  2913. FALSE if this function did not process the message and the Default
  2914. message handler for this function should handle the message
  2915. --*/
  2916. {
  2917. LPCOMPAREITEMSTRUCT pCIS = (LPCOMPAREITEMSTRUCT) lParam;
  2918. LPWSTR szString1;
  2919. LPWSTR szString2;
  2920. int nResult;
  2921. UNREFERENCED_PARAMETER (hDlg);
  2922. if (wParam == IDC_MACHINE_COMBO) {
  2923. // then process this
  2924. szString1 = (LPWSTR)pCIS->itemData1;
  2925. szString2 = (LPWSTR)pCIS->itemData2;
  2926. if ((szString1 != NULL) && (szString2 != NULL)) {
  2927. nResult = lstrcmpiW (szString1, szString2);
  2928. } else {
  2929. nResult = 0;
  2930. }
  2931. if (nResult < 0) {
  2932. // string 1 < string 2
  2933. return (BOOL)-1;
  2934. } else if (nResult > 0) {
  2935. // string 1 > string 2
  2936. return (BOOL)1;
  2937. } else {
  2938. // nResult must == 0
  2939. // string 1 == string 2
  2940. return (BOOL)0;
  2941. }
  2942. } else {
  2943. // who knows?
  2944. return (BOOL) 0;
  2945. }
  2946. }
  2947. STATIC_BOOL
  2948. PdhiBrowseCtrDlg_WM_COMMAND (
  2949. IN HWND hDlg,
  2950. IN WPARAM wParam,
  2951. IN LPARAM lParam
  2952. )
  2953. /*++
  2954. Routine Description:
  2955. Processes the windows message that occurs when the user interacts
  2956. with the dialog box
  2957. Arguments:
  2958. IN HWND hDlg
  2959. Window handle to the dialog box window
  2960. IN WPARAM wParam
  2961. HIWORD is the notification message ID
  2962. LOWORD is the control ID of the control issuing the command
  2963. IN LPARAM lParam
  2964. The window handle of the controle issuing the message
  2965. Return Value:
  2966. TRUE if this function handles the message
  2967. FALSE if this function did not process the message and the Default
  2968. message handler for this function should handle the message
  2969. --*/
  2970. {
  2971. WORD wNotifyMsg;
  2972. wNotifyMsg = HIWORD(wParam);
  2973. switch (LOWORD(wParam)) { // select on the control ID
  2974. case IDC_USE_LOCAL_MACHINE:
  2975. case IDC_SELECT_MACHINE:
  2976. return PdhiBrowseCtrDlg_MACHINE_BUTTON (hDlg, wNotifyMsg, (HWND)lParam);
  2977. case IDC_MACHINE_COMBO:
  2978. return PdhiBrowseCtrDlg_MACHINE_COMBO (hDlg, wNotifyMsg, (HWND)lParam);
  2979. case IDC_OBJECT_COMBO:
  2980. return PdhiBrowseCtrDlg_OBJECT_COMBO (hDlg, wNotifyMsg, (HWND)lParam);
  2981. case IDC_ALL_INSTANCES:
  2982. case IDC_USE_INSTANCE_LIST:
  2983. return PdhiBrowseCtrDlg_INSTANCE_BUTTON (hDlg, wNotifyMsg, (HWND)lParam);
  2984. case IDC_ALL_COUNTERS:
  2985. case IDC_USE_COUNTER_LIST:
  2986. return PdhiBrowseCtrDlg_COUNTER_BUTTON (hDlg, wNotifyMsg, (HWND)lParam);
  2987. case IDC_COUNTER_LIST:
  2988. return PdhiBrowseCtrDlg_COUNTER_LIST (hDlg, wNotifyMsg, (HWND)lParam);
  2989. case IDC_OBJECT_LIST:
  2990. return PdhiBrowseCtrDlg_OBJECT_LIST (hDlg, wNotifyMsg, (HWND)lParam);
  2991. case IDC_COUNTER_DETAIL_COMBO:
  2992. return PdhiBrowseCtrDlg_DETAIL_COMBO (hDlg, wNotifyMsg, (HWND)lParam);
  2993. case IDOK:
  2994. return PdhiBrowseCtrDlg_OK (hDlg, wNotifyMsg, (HWND)lParam);
  2995. case IDCANCEL:
  2996. return PdhiBrowseCtrDlg_CANCEL (hDlg, wNotifyMsg, (HWND)lParam);
  2997. case IDC_EXPLAIN_BTN:
  2998. return PdhiBrowseCtrDlg_EXPLAIN_BTN (hDlg, wNotifyMsg, (HWND)lParam);
  2999. case IDC_HELP_BTN:
  3000. return PdhiBrowseCtrDlg_HELP_BTN (hDlg, wNotifyMsg, (HWND)lParam);
  3001. default:
  3002. return FALSE;
  3003. }
  3004. }
  3005. STATIC_BOOL
  3006. PdhiBrowseCtrDlg_WM_SYSCOMMAND (
  3007. IN HWND hDlg,
  3008. IN WPARAM wParam,
  3009. IN LPARAM lParam
  3010. )
  3011. /*++
  3012. Routine Description:
  3013. Processes the windows message that occurs when the user selects an
  3014. item from the system menu
  3015. Arguments:
  3016. IN HWND hDlg
  3017. Window Handle to the dialog box containing the button controls
  3018. IN WPARAM wParam
  3019. menu ID of item selected
  3020. IN LPARAM lParam
  3021. Not Used
  3022. Return Value:
  3023. TRUE if this function handles the message
  3024. FALSE if this function did not process the message and the Default
  3025. message handler for this function should handle the message
  3026. --*/
  3027. {
  3028. UNREFERENCED_PARAMETER(lParam);
  3029. switch (wParam) {
  3030. case SC_CLOSE:
  3031. EndDialog (hDlg, IDOK);
  3032. return TRUE;
  3033. default:
  3034. return FALSE;
  3035. }
  3036. }
  3037. STATIC_BOOL
  3038. PdhiBrowseCtrDlg_WM_CLOSE (
  3039. IN HWND hDlg,
  3040. IN WPARAM wParam,
  3041. IN LPARAM lParam
  3042. )
  3043. /*++
  3044. Routine Description:
  3045. Processes the windows message that occurs when the dialog box
  3046. is closed. No processing is needed so this function merely returns.
  3047. Arguments:
  3048. IN HWND hDlg
  3049. Window Handle to the dialog box containing the button controls
  3050. IN WPARAM wParam
  3051. Not Used
  3052. IN LPARAM lParam
  3053. Not Used
  3054. Return Value:
  3055. TRUE if this function handles the message
  3056. FALSE if this function did not process the message and the Default
  3057. message handler for this function should handle the message
  3058. --*/
  3059. {
  3060. UNREFERENCED_PARAMETER (lParam);
  3061. UNREFERENCED_PARAMETER (wParam);
  3062. UNREFERENCED_PARAMETER (hDlg);
  3063. return TRUE;
  3064. }
  3065. STATIC_BOOL
  3066. PdhiBrowseCtrDlg_WM_DESTROY (
  3067. IN HWND hDlg,
  3068. IN WPARAM wParam,
  3069. IN LPARAM lParam
  3070. )
  3071. /*++
  3072. Routine Description:
  3073. Processes the windows message that occurs just before the window
  3074. is destroyed. Any memory allocations made are now freed.
  3075. Arguments:
  3076. IN HWND hDlg
  3077. Window Handle to the dialog box containing the button controls
  3078. IN WPARAM wParam
  3079. Not Used
  3080. IN LPARAM lParam
  3081. Not Used
  3082. Return Value:
  3083. TRUE if this function handles the message
  3084. FALSE if this function did not process the message and the Default
  3085. message handler for this function should handle the message
  3086. --*/
  3087. {
  3088. PPDHI_BROWSE_DIALOG_DATA pData;
  3089. UNREFERENCED_PARAMETER (lParam);
  3090. UNREFERENCED_PARAMETER (wParam);
  3091. pData = (PPDHI_BROWSE_DIALOG_DATA)GetWindowLongPtrW(hDlg, DWLP_USER);
  3092. if (pData == NULL) {
  3093. #if PDHI_REPORT_CODE_ERRORS
  3094. REPORT_EVENT (EVENTLOG_ERROR_TYPE, PDH_EVENT_CATEGORY_DEBUG, PDH_NO_DIALOG_DATA);
  3095. #endif
  3096. return FALSE;
  3097. }
  3098. G_FREE (pData); // free memory block
  3099. return TRUE;
  3100. }
  3101. INT_PTR
  3102. CALLBACK
  3103. BrowseCounterDlgProc (
  3104. IN HWND hDlg,
  3105. IN UINT message,
  3106. IN WPARAM wParam,
  3107. IN LPARAM lParam
  3108. )
  3109. /*++
  3110. Routine Description:
  3111. Processes all windows messages that are sent to the dialog box window.
  3112. This function is the main dispatching function for the processing
  3113. of these messages.
  3114. Arguments:
  3115. IN HWND hDlg
  3116. Window Handle to the dialog box containing the button controls
  3117. IN WPARAM wParam
  3118. Not Used
  3119. IN LPARAM lParam
  3120. Not Used
  3121. Return Value:
  3122. TRUE if this function handles the message
  3123. FALSE if this function did not process the message and the Default
  3124. message handler for this function should handle the message
  3125. --*/
  3126. {
  3127. INT iCtrlID;
  3128. BOOL bReturn = FALSE;
  3129. iCtrlID = GetDlgCtrlID ( (HWND) wParam );
  3130. switch (message) {
  3131. case WM_INITDIALOG:
  3132. return PdhiBrowseCtrDlg_WM_INITDIALOG (hDlg, wParam, lParam);
  3133. case WM_COMMAND:
  3134. return PdhiBrowseCtrDlg_WM_COMMAND (hDlg, wParam, lParam);
  3135. case WM_SYSCOMMAND:
  3136. return PdhiBrowseCtrDlg_WM_SYSCOMMAND (hDlg, wParam, lParam);
  3137. case WM_CLOSE:
  3138. return PdhiBrowseCtrDlg_WM_CLOSE (hDlg, wParam, lParam);
  3139. case WM_DESTROY:
  3140. return PdhiBrowseCtrDlg_WM_DESTROY (hDlg, wParam, lParam);
  3141. case WM_COMPAREITEM:
  3142. return PdhiBrowseCtrDlg_WM_COMPAREITEM (hDlg, wParam, lParam);
  3143. case EDM_EXPLAIN_DLG_CLOSING:
  3144. hExplainDlg = NULL;
  3145. EnableWindow (GetDlgItem(hDlg, IDC_EXPLAIN_BTN), TRUE);
  3146. return TRUE;
  3147. case WM_CONTEXTMENU:
  3148. if ( 0 != iCtrlID ) {
  3149. TCHAR pszHelpFilePath[MAX_PATH * 2];
  3150. UINT nLen;
  3151. nLen = GetWindowsDirectory(pszHelpFilePath, 2*MAX_PATH);
  3152. lstrcpy(& pszHelpFilePath[nLen], _T("\\help\\sysmon.hlp"));
  3153. bReturn = WinHelp(
  3154. (HWND) wParam,
  3155. pszHelpFilePath,
  3156. HELP_CONTEXTMENU,
  3157. (DWORD_PTR) PdhiBrowseraulControlIdToHelpIdMap);
  3158. }
  3159. return bReturn;
  3160. case WM_HELP:
  3161. {
  3162. // Only display help for known context IDs.
  3163. TCHAR pszHelpFilePath[MAX_PATH * 2];
  3164. UINT nLen;
  3165. LPHELPINFO pInfo = NULL;
  3166. pInfo = (LPHELPINFO)lParam;
  3167. for (nLen = 0;
  3168. PdhiBrowseraulControlIdToHelpIdMap[nLen] != 0;
  3169. nLen +=2) {
  3170. if ( (INT) PdhiBrowseraulControlIdToHelpIdMap[nLen]
  3171. == pInfo->iCtrlId) {
  3172. break;
  3173. }
  3174. }
  3175. if (PdhiBrowseraulControlIdToHelpIdMap[nLen] != 0) {
  3176. nLen = GetWindowsDirectory(pszHelpFilePath, 2*MAX_PATH);
  3177. if ( nLen == 0 ) {
  3178. // Report error.
  3179. }
  3180. lstrcpy(&pszHelpFilePath[nLen], _T("\\help\\sysmon.hlp") );
  3181. if (pInfo->iContextType == HELPINFO_WINDOW){
  3182. bReturn = WinHelp (
  3183. pInfo->hItemHandle,
  3184. pszHelpFilePath,
  3185. HELP_WM_HELP,
  3186. (DWORD_PTR) PdhiBrowseraulControlIdToHelpIdMap);
  3187. }
  3188. }
  3189. else {
  3190. bReturn = FALSE;
  3191. }
  3192. return bReturn;
  3193. }
  3194. default:
  3195. return FALSE;
  3196. }
  3197. }