PVIEWER.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:43k
源码类别:

Windows编程

开发平台:

Visual C++

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