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

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