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.

1412 lines
43 KiB

  1. /******************************************************************************
  2. P R O C E S S V I E W E R
  3. Name: pviewer.c
  4. Description:
  5. This program demonstrates the usage of special registry APIs
  6. for collecting performance data.
  7. C files used in this app:
  8. pviewer.c - this file
  9. pviewdat.c - updates the dialog
  10. perfdata.c - gets performance data structures
  11. objdata.c - access performance data objects
  12. instdata.c - access performance data instances
  13. cntrdata.c - access performance data counters
  14. ******************************************************************************/
  15. #include <windows.h>
  16. #include <winperf.h>
  17. #include "perfdata.h"
  18. #include "pviewdat.h"
  19. #include "pviewdlg.h"
  20. #include <string.h>
  21. #include <stdio.h>
  22. #define INDEX_STR_LEN 10
  23. #define MACHINE_NAME_LEN MAX_COMPUTERNAME_LENGTH+2
  24. #define MACHINE_NAME_SIZE MACHINE_NAME_LEN+1
  25. /****
  26. Globals
  27. ****/
  28. TCHAR INDEX_PROCTHRD_OBJ[2*INDEX_STR_LEN];
  29. TCHAR INDEX_COSTLY_OBJ[3*INDEX_STR_LEN];
  30. TCHAR gszMachineName[MACHINE_NAME_SIZE];
  31. TCHAR gszCurrentMachine[MACHINE_NAME_SIZE];
  32. DWORD gPerfDataSize = 50*1024; // start with 50K
  33. PPERF_DATA gpPerfData;
  34. DWORD gCostlyDataSize = 100*1024; // start wiih 100K
  35. PPERF_DATA gpCostlyData;
  36. PPERF_OBJECT gpProcessObject; // pointer to process objects
  37. PPERF_OBJECT gpThreadObject; // pointer to thread objects
  38. PPERF_OBJECT gpThreadDetailsObject; // pointer to thread detail objects
  39. PPERF_OBJECT gpAddressSpaceObject; // pointer to address space objects
  40. PPERF_OBJECT gpImageObject; // pointer to image objects
  41. HKEY ghPerfKey = HKEY_PERFORMANCE_DATA; // get perf data from this key
  42. HKEY ghMachineKey = HKEY_LOCAL_MACHINE; // get title index from this key
  43. HCURSOR ghCursor[2]; // 0 = arrow, 1 = hourglass
  44. HANDLE ghMemUpdateEvent; // to signal a refresh of mem stats
  45. HANDLE ghMemUpdateMutex; // to restrict overlapping refreshes
  46. HINSTANCE ghInstance; // handle for pviewer app
  47. /****
  48. Prototypes
  49. ****/
  50. INT_PTR CALLBACK PviewDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
  51. void PviewDlgRefresh (HWND hWnd);
  52. void PviewDlgRefreshCostlyData (HWND hPviewDlg);
  53. void PviewDlgRefreshProcess (HWND hWnd);
  54. void PviewDlgRefreshThread (HWND hWnd);
  55. void PviewDlgRefreshCurSelProcess (HWND hWnd);
  56. void PviewDlgRefreshCurSelThread (HWND hWnd);
  57. WORD PviewDlgGetCurSelPriority (HWND hWnd);
  58. BOOL PviewDlgChangePriority (HWND hWnd, WPARAM wParam, WORD wItem);
  59. BOOL PviewDlgTerminateProcess (HWND hPviewDlg);
  60. INT_PTR CALLBACK MemDlgProc (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
  61. void MemDlgUpdateThread (HWND hWnd);
  62. void MemDlgRefresh (HWND hWnd, HWND hPviewDlg);
  63. void MemDlgRefreshCurSelImage (HWND hMemDlg, HWND hPviewDlg);
  64. INT GetCurSelText (HWND hList, LPTSTR str);
  65. DWORD GetCurSelData (HWND hWnd, DWORD dwList);
  66. INT ReSelectText (HWND hList, INT StartIndex, LPTSTR str);
  67. void SetPerfIndexes (HWND hWnd);
  68. DWORD GetTitleIdx (HWND hWnd, LPTSTR TitleSz[], DWORD LastIndex, LPTSTR Name);
  69. void SetListBoxTabStops (HWND hWnd);
  70. void SetLocalMachine (void);
  71. BOOL ConnectComputer (HWND hWnd);
  72. void DisableControls (HWND hPviewDlg);
  73. void EnableControls (HWND hPviewDlg);
  74. //********************************************************
  75. //
  76. // WinMain --
  77. //
  78. // Build Up: create the program's dialog box,
  79. // load the desired icons, enter the message
  80. // loop.
  81. //
  82. // Tear Down: free up the memory allocated by the
  83. // dialog box proc, and exit.
  84. //
  85. int WINAPI WinMain (HINSTANCE hInstance,
  86. HINSTANCE hPrevInstance,
  87. LPSTR lpCmdLine,
  88. int nCmdShow)
  89. {
  90. HANDLE hWndDialog;
  91. MSG msg;
  92. ghInstance = hInstance;
  93. // load our default cursors
  94. //
  95. ghCursor[0] = LoadCursor (0, IDC_ARROW);
  96. ghCursor[1] = LoadCursor (0, IDC_WAIT);
  97. // open our dialog box
  98. //
  99. hWndDialog = CreateDialogParam (hInstance,
  100. MAKEINTRESOURCE (PVIEW_DLG),
  101. NULL,
  102. PviewDlgProc,
  103. 0);
  104. // the almighty Windows message loop:
  105. //
  106. while (GetMessage (&msg, NULL, 0, 0))
  107. if (!IsDialogMessage (hWndDialog, &msg)) {
  108. TranslateMessage (&msg);
  109. DispatchMessage (&msg);
  110. }
  111. // close up shop
  112. //
  113. DestroyWindow (hWndDialog);
  114. LocalFree (gpPerfData);
  115. return 0;
  116. }
  117. /*****************
  118. PviewDlg functions
  119. *****************/
  120. //********************************************************
  121. //
  122. // PviewDlgProc --
  123. //
  124. // Pview dialog procedure
  125. //
  126. INT_PTR CALLBACK PviewDlgProc (HWND hWnd,
  127. UINT wMsg,
  128. WPARAM wParam,
  129. LPARAM lParam)
  130. {
  131. WORD wItem;
  132. MSG Msg;
  133. switch (wMsg) {
  134. case WM_INITDIALOG:
  135. SetClassLongPtr (hWnd, GCLP_HICON, (LONG_PTR)LoadIcon(ghInstance, TEXT("VIEWPICON")) );
  136. SetListBoxTabStops (hWnd);
  137. SendDlgItemMessage (hWnd, PVIEW_COMPUTER, EM_LIMITTEXT, MACHINE_NAME_LEN, 0);
  138. PostMessage (hWnd, WM_COMMAND, PVIEW_REFRESH, 0);
  139. break;
  140. case WM_CLOSE:
  141. PostQuitMessage (0);
  142. break;
  143. case WM_COMMAND:
  144. //
  145. // handle our app-specific controls:
  146. //
  147. switch (LOWORD (wParam)) {
  148. // works just like "close"
  149. //
  150. case PVIEW_EXIT:
  151. PostQuitMessage (0);
  152. break;
  153. // if somebody moved the highlight in the thread list,
  154. // update the view
  155. //
  156. case PVIEW_THREAD_LIST:
  157. if (HIWORD(wParam) == LBN_DBLCLK || HIWORD(wParam) == LBN_SELCHANGE) {
  158. PviewDlgRefreshCurSelThread (hWnd);
  159. PostMessage (hWnd, WM_COMMAND, PVIEW_REFRESH_COSTLY_DATA, 0);
  160. }
  161. break;
  162. // if somebody clicked on a new process, update all of the
  163. // affected information.
  164. //
  165. case PVIEW_PROCESS_LIST:
  166. if (HIWORD(wParam) == CBN_DBLCLK || HIWORD(wParam) == CBN_SELCHANGE) {
  167. PviewDlgRefreshCurSelProcess (hWnd);
  168. PostMessage (hWnd, WM_COMMAND, PVIEW_REFRESH_COSTLY_DATA, 0);
  169. if (HIWORD(wParam) == CBN_DBLCLK)
  170. PostMessage (hWnd, WM_COMMAND, PVIEW_MEMORY_DETAIL, 0);
  171. }
  172. break;
  173. // the user wishes to view the memory stats in detail:
  174. //
  175. case PVIEW_MEMORY_DETAIL:
  176. //
  177. // check to see if we can get exclusive access
  178. // to the memory statistics
  179. //
  180. if (WaitForSingleObject (ghMemUpdateMutex, 0))
  181. // we can't, so just return.
  182. //
  183. return FALSE;
  184. else {
  185. // we have exclusive access, so start up the
  186. // memory statistics dialog.
  187. //
  188. // release the mutex first so the dialog can use it.
  189. //
  190. ReleaseMutex (ghMemUpdateMutex);
  191. DialogBoxParam (NULL,
  192. MAKEINTRESOURCE (MEMORY_DLG),
  193. hWnd,
  194. MemDlgProc,
  195. (LPARAM)hWnd);
  196. }
  197. break;
  198. // somebody clicked one of the priority radio
  199. // buttons. Find out which one was selected...
  200. //
  201. case PVIEW_PRIORITY_HIGH:
  202. case PVIEW_PRIORITY_NORMAL:
  203. case PVIEW_PRIORITY_IDL:
  204. if (SendDlgItemMessage (hWnd, PVIEW_PRIORITY_HIGH, BM_GETCHECK, 0, 0))
  205. wItem = PVIEW_PRIORITY_HIGH;
  206. else if (SendDlgItemMessage (hWnd, PVIEW_PRIORITY_NORMAL, BM_GETCHECK, 0, 0))
  207. wItem = PVIEW_PRIORITY_NORMAL;
  208. else
  209. wItem = PVIEW_PRIORITY_IDL;
  210. // if the user actually clicked on a NEW state,
  211. // do the change.
  212. //
  213. if (LOWORD(wParam) != wItem) {
  214. // of course, if it's a remote machine, disallow
  215. // the modification.
  216. //
  217. if (lstrcmp (gszCurrentMachine, gszMachineName)) {
  218. SendDlgItemMessage (hWnd, wItem, BM_SETCHECK, 1, 0);
  219. SetFocus (GetDlgItem (hWnd, wItem));
  220. MessageBox (hWnd,
  221. TEXT("Cannot change process priority on remote machine"),
  222. TEXT("Set priority"),
  223. MB_ICONEXCLAMATION|MB_OK);
  224. }
  225. // at this point, we know we are affecting the local
  226. // machine, and a change has to be made.
  227. // Just Do It(TM).
  228. //
  229. else if (PviewDlgChangePriority (hWnd, wParam, wItem))
  230. PviewDlgRefresh (hWnd);
  231. }
  232. break;
  233. case PVIEW_THREAD_HIGHEST:
  234. case PVIEW_THREAD_ABOVE:
  235. case PVIEW_THREAD_NORMAL:
  236. case PVIEW_THREAD_BELOW:
  237. case PVIEW_THREAD_LOWEST:
  238. //
  239. // this selection hasn't been fleshed out yet.
  240. //
  241. PviewDlgRefreshCurSelThread (hWnd);
  242. break;
  243. // terminate the selected process
  244. //
  245. case PVIEW_TERMINATE:
  246. if (PviewDlgTerminateProcess (hWnd))
  247. PviewDlgRefresh (hWnd);
  248. break;
  249. // if the text has changed, we want to connect and
  250. // view another system's processes...
  251. //
  252. case PVIEW_COMPUTER:
  253. if (HIWORD(wParam) == EN_CHANGE)
  254. EnableWindow (GetDlgItem (hWnd, PVIEW_CONNECT), TRUE);
  255. else
  256. return FALSE;
  257. break;
  258. // we were told to connect, go ahead and try...
  259. //
  260. case PVIEW_CONNECT:
  261. if (ConnectComputer (hWnd)) {
  262. SetPerfIndexes (hWnd);
  263. PviewDlgRefresh (hWnd);
  264. }
  265. break;
  266. // refresh the current information displayed
  267. //
  268. case PVIEW_REFRESH:
  269. if (ConnectComputer (hWnd))
  270. SetPerfIndexes (hWnd);
  271. PviewDlgRefresh (hWnd);
  272. break;
  273. // refresh the currently updated costly
  274. // statistics
  275. //
  276. case PVIEW_REFRESH_COSTLY_DATA:
  277. if (WaitForSingleObject (ghMemUpdateMutex, 0))
  278. return FALSE;
  279. PviewDlgRefreshCostlyData (hWnd);
  280. ReleaseMutex (ghMemUpdateMutex);
  281. break;
  282. default:
  283. return FALSE;
  284. }
  285. break;
  286. default:
  287. return FALSE;
  288. }
  289. return TRUE;
  290. }
  291. //********************************************************
  292. //
  293. // PviewDlgRefresh --
  294. //
  295. // Refresh the pview dialog.
  296. //
  297. void PviewDlgRefresh (HWND hWnd)
  298. {
  299. static HANDLE hMemUpdateThread = NULL;
  300. static DWORD MemUpdateThreadID;
  301. MSG Msg;
  302. SetCursor (ghCursor[1]);
  303. if (hMemUpdateThread) // get memory data
  304. SetEvent (ghMemUpdateEvent);
  305. else
  306. hMemUpdateThread = CreateThread (NULL,
  307. 0,
  308. (LPTHREAD_START_ROUTINE)MemDlgUpdateThread,
  309. (LPVOID)hWnd,
  310. 0,
  311. &MemUpdateThreadID);
  312. // get performance data
  313. //
  314. gpPerfData = RefreshPerfData (ghPerfKey, INDEX_PROCTHRD_OBJ, gpPerfData, &gPerfDataSize);
  315. gpProcessObject = FindObject (gpPerfData, PX_PROCESS);
  316. gpThreadObject = FindObject (gpPerfData, PX_THREAD);
  317. // refresh
  318. //
  319. PviewDlgRefreshProcess (hWnd);
  320. PviewDlgRefreshThread (hWnd);
  321. // Remove all mouse and key messages. They are not accepted
  322. // while the cursor is a hourglass.
  323. //
  324. while (PeekMessage (&Msg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE));
  325. while (PeekMessage (&Msg, hWnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
  326. SetCursor (ghCursor[0]);
  327. }
  328. //********************************************************
  329. //
  330. // PviewDlgRefreshCostlyData --
  331. //
  332. // Refresh the costly data.
  333. //
  334. void PviewDlgRefreshCostlyData (HWND hPviewDlg)
  335. {
  336. LPTSTR szProcessName;
  337. LPTSTR szThreadName;
  338. PPERF_INSTANCE pInstance;
  339. DWORD dwIndex;
  340. dwIndex = GetCurSelData (hPviewDlg, PVIEW_PROCESS_LIST);
  341. pInstance = FindInstanceN (gpProcessObject, dwIndex);
  342. szProcessName = InstanceName (pInstance);
  343. RefreshPviewDlgMemoryData (hPviewDlg,
  344. pInstance,
  345. gpProcessObject,
  346. gpAddressSpaceObject);
  347. dwIndex = GetCurSelData (hPviewDlg, PVIEW_THREAD_LIST);
  348. pInstance = FindInstanceN (gpThreadObject, dwIndex);
  349. szThreadName = InstanceName (pInstance);
  350. RefreshPviewDlgThreadPC (hPviewDlg,
  351. szProcessName,
  352. szThreadName ? szThreadName : TEXT("UNKNOWN"),
  353. gpThreadDetailsObject,
  354. gpCostlyData);
  355. }
  356. //********************************************************
  357. //
  358. // PviewDlgRefreshProcess --
  359. //
  360. // Refresh the process list and data in pview dialog.
  361. //
  362. void PviewDlgRefreshProcess (HWND hWnd)
  363. {
  364. TCHAR szProcessString[256];
  365. INT nProcess;
  366. INT nIndex;
  367. HWND hProcessList;
  368. DWORD dwProcessIndex;
  369. // refresh process list
  370. //
  371. hProcessList = GetDlgItem (hWnd, PVIEW_PROCESS_LIST);
  372. nProcess = GetCurSelText (hProcessList, szProcessString);
  373. SendMessage (hProcessList, WM_SETREDRAW, FALSE, 0);
  374. SendMessage (hProcessList, LB_RESETCONTENT, 0, 0);
  375. SendMessage (hProcessList, LB_SETITEMDATA, 0, 0);
  376. RefreshProcessList (hProcessList, gpProcessObject);
  377. // refresh process data
  378. //
  379. if (nProcess != LB_ERR)
  380. nIndex = ReSelectText (hProcessList, nProcess, szProcessString);
  381. else
  382. nIndex = 0;
  383. dwProcessIndex = (DWORD)SendMessage (hProcessList, LB_GETITEMDATA, nIndex, 0);
  384. RefreshProcessData (hWnd, gpProcessObject, dwProcessIndex);
  385. SendMessage (hProcessList, WM_SETREDRAW, TRUE, 0);
  386. }
  387. //********************************************************
  388. //
  389. // PviewDlgRefreshThread --
  390. //
  391. // Refresh the thread list and data in pview dialog.
  392. //
  393. void PviewDlgRefreshThread (HWND hWnd)
  394. {
  395. TCHAR szThreadString[256];
  396. INT nThread;
  397. INT nIndex;
  398. HWND hThreadList;
  399. DWORD dwThreadIndex;
  400. PPERF_INSTANCE pProcessInstance;
  401. DWORD dwProcessIndex;
  402. // get process info
  403. //
  404. dwProcessIndex = GetCurSelData (hWnd, PVIEW_PROCESS_LIST);
  405. pProcessInstance = FindInstanceN (gpProcessObject, dwProcessIndex);
  406. // refresh thread list
  407. //
  408. hThreadList = GetDlgItem (hWnd, PVIEW_THREAD_LIST);
  409. nThread = GetCurSelText (hThreadList, szThreadString);
  410. SendMessage (hThreadList, WM_SETREDRAW, FALSE, 0);
  411. SendMessage (hThreadList, LB_RESETCONTENT, 0, 0);
  412. SendMessage (hThreadList, LB_SETITEMDATA, 0, 0);
  413. RefreshThreadList (hThreadList, gpThreadObject, dwProcessIndex);
  414. // refresh thread data
  415. //
  416. if (nThread != LB_ERR)
  417. nIndex = ReSelectText (hThreadList, nThread, szThreadString);
  418. else
  419. nIndex = 0;
  420. dwThreadIndex = (DWORD)SendMessage (hThreadList, LB_GETITEMDATA, nIndex, 0);
  421. RefreshThreadData (hWnd,
  422. gpThreadObject,
  423. dwThreadIndex,
  424. gpProcessObject,
  425. pProcessInstance);
  426. SendMessage (hThreadList, WM_SETREDRAW, TRUE, 0);
  427. }
  428. //********************************************************
  429. //
  430. // PviewDlgGetCurSelPriority --
  431. //
  432. // Get the process priority of currently selected process.
  433. //
  434. WORD PviewDlgGetCurSelPriority (HWND hWnd)
  435. {
  436. DWORD dwIndex;
  437. PPERF_INSTANCE pInst;
  438. dwIndex = GetCurSelData (hWnd, PVIEW_PROCESS_LIST);
  439. pInst = FindInstanceN (gpProcessObject, dwIndex);
  440. return ProcessPriority (gpProcessObject, pInst);
  441. }
  442. //********************************************************
  443. //
  444. // PviewDlgRefreshCurSelProcess --
  445. //
  446. // Refresh the data of currently selected process.
  447. //
  448. void PviewDlgRefreshCurSelProcess (HWND hWnd)
  449. {
  450. DWORD dwIndex;
  451. dwIndex = GetCurSelData (hWnd, PVIEW_PROCESS_LIST);
  452. RefreshProcessData (hWnd, gpProcessObject, dwIndex);
  453. PviewDlgRefreshThread (hWnd);
  454. }
  455. //********************************************************
  456. //
  457. // PviewDlgRefreshCurSelThread --
  458. //
  459. // Refresh the data of currently selected thread.
  460. //
  461. void PviewDlgRefreshCurSelThread (HWND hWnd)
  462. {
  463. PPERF_INSTANCE pProcessInstance;
  464. DWORD dwIndex;
  465. dwIndex = GetCurSelData (hWnd, PVIEW_PROCESS_LIST);
  466. pProcessInstance = FindInstanceN (gpProcessObject, dwIndex);
  467. dwIndex = GetCurSelData (hWnd, PVIEW_THREAD_LIST);
  468. RefreshThreadData (hWnd,
  469. gpThreadObject,
  470. dwIndex,
  471. gpProcessObject,
  472. pProcessInstance);
  473. }
  474. //********************************************************
  475. //
  476. // PviewDlgChangePriority --
  477. //
  478. // Change process priority.
  479. //
  480. BOOL PviewDlgChangePriority (HWND hWnd, WPARAM wParam, WORD wItem)
  481. {
  482. DWORD dwIndex;
  483. PPERF_INSTANCE pInst;
  484. PPERF_COUNTER pCountID;
  485. DWORD *pProcessID;
  486. DWORD ProcessID = 0;
  487. HANDLE hProcess;
  488. BOOL bStat = TRUE;
  489. dwIndex = GetCurSelData (hWnd, PVIEW_PROCESS_LIST);
  490. pInst = FindInstanceN (gpProcessObject, dwIndex);
  491. if (pCountID = FindCounter (gpProcessObject, PX_PROCESS_ID)) {
  492. pProcessID = (DWORD *) CounterData (pInst, pCountID);
  493. if (pProcessID) {
  494. ProcessID = *pProcessID;
  495. }
  496. } else {
  497. SendDlgItemMessage (hWnd, wItem, BM_SETCHECK, 1, 0);
  498. SetFocus (GetDlgItem (hWnd, wItem));
  499. MessageBox (hWnd,
  500. TEXT("Cannot find ID for this process"),
  501. TEXT("Set priority"),
  502. MB_ICONEXCLAMATION|MB_OK);
  503. return FALSE;
  504. }
  505. hProcess = OpenProcess (PROCESS_SET_INFORMATION, FALSE, ProcessID);
  506. if (!hProcess) {
  507. SendDlgItemMessage (hWnd, wItem, BM_SETCHECK, 1, 0);
  508. SetFocus (GetDlgItem (hWnd, wItem));
  509. MessageBox (hWnd,
  510. TEXT("Unable to open the process; Priority not changed"),
  511. TEXT("Set priority"),
  512. MB_ICONEXCLAMATION|MB_OK);
  513. return FALSE;
  514. }
  515. switch (wParam) {
  516. case PVIEW_PRIORITY_HIGH:
  517. bStat = SetPriorityClass (hProcess, HIGH_PRIORITY_CLASS);
  518. break;
  519. case PVIEW_PRIORITY_NORMAL:
  520. bStat = SetPriorityClass (hProcess, NORMAL_PRIORITY_CLASS);
  521. break;
  522. case PVIEW_PRIORITY_IDL:
  523. bStat = SetPriorityClass (hProcess, IDLE_PRIORITY_CLASS);
  524. break;
  525. default:
  526. break;
  527. }
  528. CloseHandle (hProcess);
  529. if (!bStat) {
  530. SendDlgItemMessage (hWnd, wItem, BM_SETCHECK, 1, 0);
  531. SetFocus (GetDlgItem (hWnd, wItem));
  532. MessageBox (hWnd,
  533. TEXT("Unable to change priority"),
  534. TEXT("Set priority"),
  535. MB_ICONEXCLAMATION|MB_OK);
  536. return FALSE;
  537. }
  538. return TRUE;
  539. }
  540. //********************************************************
  541. //
  542. // PviewDlgTerminateProcess --
  543. //
  544. // Terminate the current selected process.
  545. //
  546. BOOL PviewDlgTerminateProcess (HWND hPviewDlg)
  547. {
  548. DWORD dwIndex;
  549. PPERF_INSTANCE pInst;
  550. PPERF_COUNTER pCountID;
  551. DWORD *pProcessID;
  552. DWORD ProcessID;
  553. HANDLE hProcess;
  554. TCHAR szTemp[50];
  555. dwIndex = GetCurSelData (hPviewDlg, PVIEW_PROCESS_LIST);
  556. pInst = FindInstanceN (gpProcessObject, dwIndex);
  557. if (pCountID = FindCounter (gpProcessObject, PX_PROCESS_ID)) {
  558. pProcessID = (DWORD *) CounterData (pInst, pCountID);
  559. if (pProcessID) {
  560. ProcessID = *pProcessID;
  561. }
  562. } else {
  563. MessageBox (hPviewDlg,
  564. TEXT("Cannot find ID for this process"),
  565. TEXT("Terminate Process"),
  566. MB_ICONEXCLAMATION|MB_OK);
  567. return FALSE;
  568. }
  569. wsprintf (szTemp, TEXT("Terminate process %s (ID %#x)?"),
  570. InstanceName (pInst), ProcessID);
  571. if (MessageBox (hPviewDlg, szTemp, TEXT("Terminate Process"), MB_ICONSTOP|MB_OKCANCEL) != IDOK)
  572. return FALSE;
  573. hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, ProcessID);
  574. if (!hProcess) {
  575. MessageBox (hPviewDlg,
  576. TEXT("Unable to open the process; Process not terminated"),
  577. TEXT("Terminate Process"),
  578. MB_ICONEXCLAMATION|MB_OK);
  579. return FALSE;
  580. }
  581. if (!TerminateProcess (hProcess, 99)) {
  582. MessageBox (hPviewDlg,
  583. TEXT("Unable to terminate the process."),
  584. TEXT("Terminate Process"),
  585. MB_ICONEXCLAMATION|MB_OK);
  586. CloseHandle (hProcess);
  587. return FALSE;
  588. }
  589. CloseHandle (hProcess);
  590. return TRUE;
  591. }
  592. /***************
  593. MemDlg functions
  594. ***************/
  595. //********************************************************
  596. //
  597. // MemDlgProc --
  598. //
  599. // MemoryDlg procedure
  600. //
  601. INT_PTR CALLBACK MemDlgProc (HWND hWnd,
  602. UINT wMsg,
  603. WPARAM wParam,
  604. LPARAM lParam)
  605. {
  606. static HWND hPviewDlg;
  607. switch (wMsg) {
  608. case WM_INITDIALOG:
  609. hPviewDlg = (HWND)lParam;
  610. PostMessage (hWnd, WM_COMMAND, MEMORY_REFRESH, 0);
  611. break;
  612. case WM_QUIT:
  613. case WM_CLOSE:
  614. EndDialog (hWnd, TRUE);
  615. break;
  616. case WM_COMMAND:
  617. switch (LOWORD (wParam)) {
  618. // get the memory statistics for the currently selected
  619. // process/thread
  620. //
  621. case MEMORY_IMAGE:
  622. if (HIWORD(wParam) == CBN_DBLCLK || HIWORD(wParam) == CBN_SELCHANGE) {
  623. if (WaitForSingleObject (ghMemUpdateMutex, 0))
  624. return FALSE;
  625. MemDlgRefreshCurSelImage (hWnd, hPviewDlg);
  626. ReleaseMutex (ghMemUpdateMutex);
  627. } else
  628. return FALSE;
  629. break;
  630. // refresh the current memory statistics,
  631. // retry if we can't get the mutex
  632. //
  633. case MEMORY_REFRESH:
  634. if (WaitForSingleObject (ghMemUpdateMutex, 1000)) {
  635. // can't get the mutex, retry...
  636. //
  637. PostMessage (hWnd, WM_COMMAND, MEMORY_REFRESH, 0);
  638. return FALSE;
  639. }
  640. MemDlgRefresh (hWnd, hPviewDlg);
  641. ReleaseMutex (ghMemUpdateMutex);
  642. break;
  643. case IDCANCEL:
  644. case IDOK:
  645. EndDialog (hWnd, TRUE);
  646. break;
  647. default:
  648. return FALSE;
  649. }
  650. default:
  651. return FALSE;
  652. }
  653. return TRUE;
  654. }
  655. //********************************************************
  656. //
  657. // MemDlgUpdateThread --
  658. //
  659. // This function runs in a separate thread to collect memory data.
  660. //
  661. void MemDlgUpdateThread (HWND hPviewDlg)
  662. {
  663. ghMemUpdateMutex = CreateMutex (NULL, TRUE, NULL);
  664. ghMemUpdateEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  665. while (TRUE) {
  666. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_MEMORY_DETAIL), FALSE);
  667. gpCostlyData = RefreshPerfData (ghPerfKey,
  668. INDEX_COSTLY_OBJ,
  669. gpCostlyData,
  670. &gCostlyDataSize);
  671. gpAddressSpaceObject = FindObject (gpCostlyData, PX_PROCESS_ADDRESS_SPACE);
  672. gpThreadDetailsObject = FindObject (gpCostlyData, PX_THREAD_DETAILS);
  673. gpImageObject = FindObject (gpCostlyData, PX_IMAGE);
  674. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_MEMORY_DETAIL), TRUE);
  675. ReleaseMutex (ghMemUpdateMutex);
  676. PostMessage (hPviewDlg, WM_COMMAND, PVIEW_REFRESH_COSTLY_DATA, 0);
  677. WaitForSingleObject (ghMemUpdateEvent, INFINITE);
  678. WaitForSingleObject (ghMemUpdateMutex, INFINITE);
  679. }
  680. }
  681. //********************************************************
  682. //
  683. // MemDlgRefresh --
  684. //
  685. // Refresh the memory dialog.
  686. //
  687. void MemDlgRefresh (HWND hMemDlg, HWND hPviewDlg)
  688. {
  689. HWND hImageList;
  690. DWORD dwIndex;
  691. BOOL bStat;
  692. PPERF_INSTANCE pInstance;
  693. hImageList = GetDlgItem (hMemDlg, MEMORY_IMAGE);
  694. SendMessage (hImageList, WM_SETREDRAW, FALSE, 0);
  695. SendMessage (hImageList, CB_RESETCONTENT, 0, 0);
  696. SendMessage (hImageList, CB_SETITEMDATA, 0, 0);
  697. dwIndex = GetCurSelData (hPviewDlg, PVIEW_PROCESS_LIST);
  698. pInstance = FindInstanceN (gpProcessObject, dwIndex);
  699. bStat = RefreshMemoryDlg (hMemDlg,
  700. pInstance,
  701. gpProcessObject,
  702. gpAddressSpaceObject,
  703. gpImageObject);
  704. SendMessage (hImageList, WM_SETREDRAW, TRUE, 0);
  705. SendMessage (hImageList, CB_SETCURSEL, 0, 0);
  706. if (!bStat) {
  707. MessageBox (hMemDlg,
  708. TEXT("Unable to retrieve memory detail"),
  709. TEXT("Memory detail"),
  710. MB_ICONSTOP|MB_OK);
  711. PostMessage (hMemDlg, WM_CLOSE, 0, 0);
  712. }
  713. }
  714. //********************************************************
  715. //
  716. // MemDlgRefreshCurSelImage --
  717. //
  718. // Refresh the current selected image for memory dialog.
  719. //
  720. void MemDlgRefreshCurSelImage (HWND hMemDlg, HWND hPviewDlg)
  721. {
  722. HWND hList;
  723. INT nIndex;
  724. DWORD dwIndex;
  725. hList = GetDlgItem (hMemDlg, MEMORY_IMAGE);
  726. nIndex = (INT)SendMessage (hList, CB_GETCURSEL, 0, 0);
  727. if (nIndex == CB_ERR)
  728. nIndex = 0;
  729. dwIndex = (DWORD)SendMessage (hList, CB_GETITEMDATA, nIndex, 0);
  730. if (dwIndex == 0xFFFFFFFF)
  731. MemDlgRefresh (hMemDlg, hPviewDlg);
  732. else
  733. RefreshMemoryDlgImage (hMemDlg, dwIndex, gpImageObject);
  734. }
  735. /****************
  736. utility functions
  737. ****************/
  738. //********************************************************
  739. //
  740. // GetCurSelText --
  741. //
  742. // Get the text of current selection. Used for later ReSelectText().
  743. //
  744. INT GetCurSelText (HWND hList, LPTSTR str)
  745. {
  746. INT Index;
  747. INT Length;
  748. Index = (INT)SendMessage (hList, LB_GETCURSEL, 0, 0);
  749. SendMessage (hList, LB_GETTEXT, Index, (LPARAM)str);
  750. return Index;
  751. }
  752. //********************************************************
  753. //
  754. // GetCurSelData --
  755. //
  756. // Get the data associated with the current selection.
  757. //
  758. DWORD GetCurSelData (HWND hWnd, DWORD dwList)
  759. {
  760. HWND hList;
  761. INT nIndex;
  762. DWORD dwIndex;
  763. hList = GetDlgItem (hWnd, dwList);
  764. nIndex = (INT)SendMessage (hList, LB_GETCURSEL, 0, 0);
  765. if (nIndex == LB_ERR)
  766. nIndex = 0;
  767. dwIndex = (DWORD)SendMessage (hList, LB_GETITEMDATA, nIndex, 0);
  768. return dwIndex;
  769. }
  770. //********************************************************
  771. //
  772. // ReSelectText --
  773. //
  774. // Reselect the line specified by str. Returns the new index. If cannot
  775. // find the line or any error, then 0 is returned.
  776. //
  777. INT ReSelectText (HWND hList, INT StartIndex, LPTSTR str)
  778. {
  779. INT_PTR Index;
  780. INT Length;
  781. TCHAR SaveChar = TEXT('\0');
  782. Index = SendMessage (hList, LB_FINDSTRING, StartIndex, (LPARAM)str);
  783. if (Index == LB_ERR) {
  784. Length = lstrlen (str);
  785. while (Index == LB_ERR && Length) {
  786. SaveChar = str[Length-1];
  787. str[Length-1] = TEXT('\0');
  788. Index = SendMessage (hList, LB_FINDSTRING, StartIndex, (LPARAM)str);
  789. str[Length-1] = SaveChar;
  790. Length--;
  791. }
  792. }
  793. if (Index == LB_ERR)
  794. return 0;
  795. else {
  796. SendMessage (hList, LB_SETCURSEL, Index, 0);
  797. return (INT)Index;
  798. }
  799. }
  800. //********************************************************
  801. //
  802. // SetPerfIndexes
  803. //
  804. // Setup the perf data indexes.
  805. //
  806. void SetPerfIndexes (HWND hWnd)
  807. {
  808. LPTSTR TitleBuffer;
  809. LPTSTR *Title;
  810. DWORD Last;
  811. TCHAR szTemp[50];
  812. DWORD dwR;
  813. dwR = GetPerfTitleSz (ghMachineKey, ghPerfKey, &TitleBuffer, &Title, &Last);
  814. if (dwR != ERROR_SUCCESS) {
  815. wsprintf (szTemp, TEXT("Unable to retrieve counter indexes, ERROR -> %#x"), dwR);
  816. MessageBox (hWnd, szTemp, TEXT("Pviewer"), MB_OK|MB_ICONEXCLAMATION);
  817. return;
  818. }
  819. PX_PROCESS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS);
  820. PX_PROCESS_CPU = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_CPU);
  821. PX_PROCESS_PRIV = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIV);
  822. PX_PROCESS_USER = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_USER);
  823. PX_PROCESS_WORKING_SET = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_WORKING_SET);
  824. PX_PROCESS_PEAK_WS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PEAK_WS);
  825. PX_PROCESS_PRIO = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIO);
  826. PX_PROCESS_ELAPSE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_ELAPSE);
  827. PX_PROCESS_ID = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_ID);
  828. PX_PROCESS_PRIVATE_PAGE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_PAGE);
  829. PX_PROCESS_VIRTUAL_SIZE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_VIRTUAL_SIZE);
  830. PX_PROCESS_PEAK_VS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PEAK_VS);
  831. PX_PROCESS_FAULT_COUNT = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_FAULT_COUNT);
  832. PX_THREAD = GetTitleIdx (hWnd, Title, Last, PN_THREAD);
  833. PX_THREAD_CPU = GetTitleIdx (hWnd, Title, Last, PN_THREAD_CPU);
  834. PX_THREAD_PRIV = GetTitleIdx (hWnd, Title, Last, PN_THREAD_PRIV);
  835. PX_THREAD_USER = GetTitleIdx (hWnd, Title, Last, PN_THREAD_USER);
  836. PX_THREAD_START = GetTitleIdx (hWnd, Title, Last, PN_THREAD_START);
  837. PX_THREAD_SWITCHES = GetTitleIdx (hWnd, Title, Last, PN_THREAD_SWITCHES);
  838. PX_THREAD_PRIO = GetTitleIdx (hWnd, Title, Last, PN_THREAD_PRIO);
  839. PX_THREAD_BASE_PRIO = GetTitleIdx (hWnd, Title, Last, PN_THREAD_BASE_PRIO);
  840. PX_THREAD_ELAPSE = GetTitleIdx (hWnd, Title, Last, PN_THREAD_ELAPSE);
  841. PX_THREAD_DETAILS = GetTitleIdx (hWnd, Title, Last, PN_THREAD_DETAILS);
  842. PX_THREAD_PC = GetTitleIdx (hWnd, Title, Last, PN_THREAD_PC);
  843. PX_IMAGE = GetTitleIdx (hWnd, Title, Last, PN_IMAGE);
  844. PX_IMAGE_NOACCESS = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_NOACCESS);
  845. PX_IMAGE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_READONLY);
  846. PX_IMAGE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_READWRITE);
  847. PX_IMAGE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_WRITECOPY);
  848. PX_IMAGE_EXECUTABLE = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_EXECUTABLE);
  849. PX_IMAGE_EXE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_EXE_READONLY);
  850. PX_IMAGE_EXE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_EXE_READWRITE);
  851. PX_IMAGE_EXE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_IMAGE_EXE_WRITECOPY);
  852. PX_PROCESS_ADDRESS_SPACE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_ADDRESS_SPACE);
  853. PX_PROCESS_PRIVATE_NOACCESS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_NOACCESS);
  854. PX_PROCESS_PRIVATE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_READONLY);
  855. PX_PROCESS_PRIVATE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_READWRITE);
  856. PX_PROCESS_PRIVATE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_WRITECOPY);
  857. PX_PROCESS_PRIVATE_EXECUTABLE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_EXECUTABLE);
  858. PX_PROCESS_PRIVATE_EXE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_EXE_READONLY);
  859. PX_PROCESS_PRIVATE_EXE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_EXE_READWRITE);
  860. PX_PROCESS_PRIVATE_EXE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_PRIVATE_EXE_WRITECOPY);
  861. PX_PROCESS_MAPPED_NOACCESS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_NOACCESS);
  862. PX_PROCESS_MAPPED_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_READONLY);
  863. PX_PROCESS_MAPPED_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_READWRITE);
  864. PX_PROCESS_MAPPED_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_WRITECOPY);
  865. PX_PROCESS_MAPPED_EXECUTABLE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_EXECUTABLE);
  866. PX_PROCESS_MAPPED_EXE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_EXE_READONLY);
  867. PX_PROCESS_MAPPED_EXE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_EXE_READWRITE);
  868. PX_PROCESS_MAPPED_EXE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_MAPPED_EXE_WRITECOPY);
  869. PX_PROCESS_IMAGE_NOACCESS = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_NOACCESS);
  870. PX_PROCESS_IMAGE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_READONLY);
  871. PX_PROCESS_IMAGE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_READWRITE);
  872. PX_PROCESS_IMAGE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_WRITECOPY);
  873. PX_PROCESS_IMAGE_EXECUTABLE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_EXECUTABLE);
  874. PX_PROCESS_IMAGE_EXE_READONLY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_EXE_READONLY);
  875. PX_PROCESS_IMAGE_EXE_READWRITE = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_EXE_READWRITE);
  876. PX_PROCESS_IMAGE_EXE_WRITECOPY = GetTitleIdx (hWnd, Title, Last, PN_PROCESS_IMAGE_EXE_WRITECOPY);
  877. wsprintf (INDEX_PROCTHRD_OBJ, TEXT("%ld %ld"), PX_PROCESS, PX_THREAD);
  878. wsprintf (INDEX_COSTLY_OBJ, TEXT("%ld %ld %ld"),
  879. PX_PROCESS_ADDRESS_SPACE, PX_IMAGE, PX_THREAD_DETAILS);
  880. LocalFree (TitleBuffer);
  881. LocalFree (Title);
  882. }
  883. //********************************************************
  884. //
  885. // GetTitleIdx
  886. //
  887. // Searches Titles[] for Name. Returns the index found.
  888. //
  889. DWORD GetTitleIdx (HWND hWnd, LPTSTR Title[], DWORD LastIndex, LPTSTR Name)
  890. {
  891. DWORD Index;
  892. for (Index = 0; Index <= LastIndex; Index++)
  893. if (Title[Index])
  894. if (!lstrcmpi (Title[Index], Name))
  895. return Index;
  896. MessageBox (hWnd, Name, TEXT("Pviewer cannot find index"), MB_OK);
  897. return 0;
  898. }
  899. //********************************************************
  900. //
  901. // SetListBoxTabStops --
  902. //
  903. // Set tab stops in the two list boxes.
  904. //
  905. void SetListBoxTabStops (HWND hWnd)
  906. {
  907. HWND hListBox;
  908. INT Tabs[4] = {22*4, 36*4, 44*4};
  909. hListBox = GetDlgItem (hWnd, PVIEW_PROCESS_LIST);
  910. SendMessage (hListBox, LB_SETTABSTOPS, 3, (DWORD_PTR)Tabs);
  911. hListBox = GetDlgItem (hWnd, PVIEW_THREAD_LIST);
  912. SendMessage (hListBox, LB_SETTABSTOPS, 3, (DWORD_PTR)Tabs);
  913. }
  914. //********************************************************
  915. //
  916. // SetLocalMachine --
  917. //
  918. // Set local machine as performance data focus.
  919. //
  920. // Sets ghPerfKey
  921. // ghMachineKey
  922. // gszMachineName
  923. // gszCurrentMachine
  924. //
  925. void SetLocalMachine (void)
  926. {
  927. TCHAR szName[MACHINE_NAME_SIZE];
  928. DWORD dwSize = MACHINE_NAME_SIZE;
  929. // close remote connections, if any
  930. //
  931. if (ghPerfKey != HKEY_PERFORMANCE_DATA)
  932. RegCloseKey (ghPerfKey);
  933. if (ghMachineKey != HKEY_LOCAL_MACHINE)
  934. RegCloseKey (ghMachineKey);
  935. // set to registry keys on local machine
  936. //
  937. ghPerfKey = HKEY_PERFORMANCE_DATA;
  938. ghMachineKey = HKEY_LOCAL_MACHINE;
  939. // get computer name
  940. GetComputerName (szName, &dwSize);
  941. if (szName[0] != '\\' || szName[1] != '\\') { // must have two '\\'
  942. wsprintf (gszMachineName, TEXT("\\\\%s"), szName);
  943. lstrcpy (gszCurrentMachine, gszMachineName);
  944. } else {
  945. lstrcpy (gszMachineName, szName);
  946. lstrcpy (gszCurrentMachine, gszMachineName);
  947. }
  948. }
  949. //********************************************************
  950. //
  951. // ConnectComputer --
  952. //
  953. // Connect to a computer with name entered in PVIEW_COMPUTER.
  954. // If a new connection is made, then return TRUE else return FALSE.
  955. //
  956. // Sets gszCurrentMachine
  957. // ghPerfKey
  958. // ghMachineKey
  959. //
  960. BOOL ConnectComputer (HWND hWnd)
  961. {
  962. DWORD dwR;
  963. HKEY hKey;
  964. TCHAR szTemp[MACHINE_NAME_SIZE];
  965. TCHAR szTemp2[MACHINE_NAME_SIZE+100];
  966. BOOL bResult = TRUE;
  967. MSG Msg;
  968. SetCursor (ghCursor[1]);
  969. if (!GetDlgItemText (hWnd, PVIEW_COMPUTER, szTemp, sizeof (szTemp)/sizeof(TCHAR))) {
  970. SetLocalMachine ();
  971. SetDlgItemText (hWnd, PVIEW_COMPUTER, gszCurrentMachine);
  972. }
  973. else if (!lstrcmpi (szTemp, gszCurrentMachine)) // didn't change name
  974. bResult = FALSE;
  975. else if (!lstrcmpi (szTemp, gszMachineName)) { // local machine
  976. SetLocalMachine ();
  977. EnableControls (hWnd);
  978. }
  979. else {
  980. // a remote machine, connect to it
  981. //
  982. dwR = RegConnectRegistry (szTemp, HKEY_PERFORMANCE_DATA, &hKey);
  983. if (dwR != ERROR_SUCCESS) {
  984. wsprintf (szTemp2, TEXT("Cannot connect to computer %s"), szTemp);
  985. MessageBox (hWnd, szTemp2, TEXT(""), MB_ICONEXCLAMATION|MB_OK);
  986. SetDlgItemText (hWnd, PVIEW_COMPUTER, gszCurrentMachine);
  987. bResult = FALSE;
  988. } else {
  989. // connected
  990. //
  991. lstrcpy (gszCurrentMachine, szTemp);
  992. if (ghPerfKey != HKEY_PERFORMANCE_DATA)
  993. RegCloseKey (ghPerfKey);
  994. ghPerfKey = hKey;
  995. DisableControls (hWnd);
  996. // we also need to get the remote machine's title indexes.
  997. //
  998. dwR = RegConnectRegistry (gszCurrentMachine, HKEY_LOCAL_MACHINE, &hKey);
  999. if (ghMachineKey != HKEY_LOCAL_MACHINE)
  1000. RegCloseKey (ghMachineKey);
  1001. if (dwR == ERROR_SUCCESS)
  1002. ghMachineKey = hKey;
  1003. else
  1004. // unable to connect, so we'll use our own indexes.
  1005. //
  1006. ghMachineKey = HKEY_LOCAL_MACHINE;
  1007. }
  1008. }
  1009. // Remove all mouse and key messages. They are not accepted
  1010. // while the cursor is a hourglass.
  1011. //
  1012. while (PeekMessage (&Msg, hWnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE));
  1013. while (PeekMessage (&Msg, hWnd, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
  1014. SetCursor (ghCursor[0]);
  1015. EnableWindow (GetDlgItem (hWnd, PVIEW_CONNECT), FALSE);
  1016. return bResult;
  1017. }
  1018. //********************************************************
  1019. //
  1020. // DisableControls --
  1021. //
  1022. // Disable controls that don't make sense on remote machine
  1023. //
  1024. void DisableControls (HWND hPviewDlg)
  1025. {
  1026. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_TERMINATE), FALSE);
  1027. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_HIGH), FALSE);
  1028. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_NORMAL), FALSE);
  1029. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_IDL), FALSE);
  1030. }
  1031. //********************************************************
  1032. //
  1033. // EnableControls --
  1034. //
  1035. // Enable controls disabled by DisableControl().
  1036. //
  1037. void EnableControls (HWND hPviewDlg)
  1038. {
  1039. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_TERMINATE), TRUE);
  1040. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_HIGH), TRUE);
  1041. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_NORMAL), TRUE);
  1042. EnableWindow (GetDlgItem (hPviewDlg, PVIEW_PRIORITY_IDL), TRUE);
  1043. }