home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / winnt / pviewer / pviewer.c < prev    next >
C/C++ Source or Header  |  1997-10-05  |  44KB  |  1,462 lines

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