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

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. *  Note:  pwalk will only work correctly with Win32 applications.
  12. *
  13. *
  14. ******************************************************************************/
  15. #include "pwalk.h"
  16. #define strtok      My_mbstok
  17. #define MAX_DRIVES    26    /* maximum number of logical drives */
  18. /* system constants used externally */
  19. int      xChar,
  20.      yChar,
  21.      xScreen,
  22.      yScreen,
  23.      yFrame,
  24.      xFrame,
  25.      yCaption,
  26.      xVScrollBar;
  27. char      szCaptionText[] ="AddressStateProtSizeBaseAddrObjectSectionName";
  28. char      szFormat[] = "%08lX~%s ~%s ~%lu~%08lX~%s ~%s ~%s ~";
  29. SIZE                 sChar0;
  30. char      szFormatPages[] = "%05lX~%s ~%s ~%lu~%05lX~%s ~%s ~%s ~";
  31. int                  taColumns[] = {TA_RIGHT,  TA_LEFT, TA_LEFT, TA_RIGHT,
  32.                                     TA_RIGHT, TA_RIGHT, TA_LEFT,  TA_LEFT,
  33.                                    };
  34. int                  xColumns[]  = {      8,       9,      17,       31,
  35.                                          40,      46,      47,       55,
  36.                                    };
  37. BOOL      bNumbersAsBytes = TRUE;
  38. HFONT      hFontVar;
  39. char      szFilePath[MAX_PATH] = "";
  40. char      szFilename[MAX_PATH] = "";
  41. HFONT      hFont;
  42. LPVOID      lpWalkerList = NULL;
  43. int      *Objects;
  44. int      nSortType = IDM_SORTADDRESS;
  45. HWND      hWndSysStat, hWndProStat, hInitDlg, hMemWnd;
  46. HANDLE      hChildEvents[nDEBUGEVENTS];
  47. DBGPROCESS      *lpChildProcess = NULL;
  48. HMENU      hPopup[MENUPOPUPS];
  49. char      szCurPath[MAX_PATH];
  50. /* local functions */
  51. BOOL   WINAPI InitEnvironment (HANDLE, int, char *);
  52. void   WINAPI InitMenu (HWND);
  53. void   WINAPI DrawListItem (DRAWITEMSTRUCT *);
  54. int    WINAPI MakeVMQString (int, char *);
  55. DWORD  WINAPI VMExceptionFilter (EXCEPTION_POINTERS *);
  56. void   WINAPI SortList (HWND, int);
  57. BOOL   WINAPI ViewableMemorySelection (HWND);
  58. static void TextOutFields (HDC, int, LPRECT, LPSTR);
  59. /****************************************************************************
  60.     My_mbschr:  strchr() DBCS version
  61. ****************************************************************************/
  62. unsigned char * _CRTAPI1 My_mbschr(
  63.     unsigned char *psz, unsigned short uiSep)
  64. {
  65.     while (*psz != '' && *psz != uiSep) {
  66.         psz = CharNext(psz);
  67.     }
  68.     if (*psz == '' && uiSep != '') {
  69.         return NULL;
  70.     } else {
  71.         return psz;
  72.     }
  73. }
  74. /****************************************************************************
  75.     My_mbstok:  strtok() DBCS version
  76. ****************************************************************************/
  77. unsigned char * _CRTAPI1 My_mbstok(
  78.     unsigned char *pszSrc, unsigned char *pszSep)
  79. {
  80.     static char *pszSave = NULL;
  81.     char *pszHead;
  82.     char *psz;
  83.     if (pszSrc == NULL) {
  84.         if (pszSave == NULL) {
  85.             return NULL;
  86.         } else {
  87.             psz = pszSave;
  88.         }
  89.     } else {
  90.         psz = pszSrc;
  91.     }
  92.     /*********************************************/
  93.     /* Skip delimiters to find a head of a token */
  94.     /*********************************************/
  95.     while (*psz) {
  96.         if (IsDBCSLeadByte(*psz)) {
  97.             break;
  98.         } else if (NULL == My_mbschr(pszSep, *psz)) {
  99.             break;
  100.         }
  101.         psz++;
  102.     }
  103.     if (*psz == '') {
  104.         //No more token
  105.         return (pszSave = NULL);
  106.     }
  107.     pszHead = psz;
  108.     /******************************/
  109.     /* Search a Tail of the token */
  110.     /******************************/
  111.     while (*psz) {
  112.         if (IsDBCSLeadByte(*psz)) {
  113.             psz += 2;
  114.             continue;
  115.         } else if (NULL != My_mbschr(pszSep, *psz)) {
  116.             break;
  117.         }
  118.         psz++;
  119.     }
  120.     if (*psz == '') {
  121.         pszSave = NULL;
  122.     } else {
  123.         //Found next delimiter
  124.         pszSave = psz + 1;
  125.         *psz = '';
  126.     }
  127.     return pszHead;
  128. }
  129. /* entry point of this executable */
  130. int WINAPI WinMain (hInstance, hPrevInstance, lpCmdLine, nCmdShow)
  131.     HINSTANCE hInstance;
  132.     HINSTANCE hPrevInstance;
  133.     LPSTR     lpCmdLine;
  134.     int       nCmdShow;
  135. {
  136.     MSG      msg;
  137.     char     *lpszCmdLine = NULL;
  138.     char     *lpCL;
  139.     BOOL     bSwitch;
  140.     /* set current path for use later */
  141.     GetCurrentDirectory (MAX_PATH, szCurPath);
  142.     // parse and copy command line parameters to local memory
  143.     lpCL = GetCommandLine ();
  144.     if (lpszCmdLine = (char *)LocalAlloc (LPTR, strlen (lpCL) + 1))
  145. GetCmdLine (lpCL, lpszCmdLine, &bSwitch);
  146.     /* start window environment */
  147.     if (!InitEnvironment (hInstance, nCmdShow, IsValidFile (lpszCmdLine) ? lpszCmdLine : NULL))
  148. return FALSE;
  149.     /* free memory allocated for lpCmdLine */
  150.     if (lpszCmdLine)
  151. LocalFree ((HLOCAL)lpszCmdLine);
  152.     /* main window message loop */
  153.     while (GetMessage (&msg, NULL, 0, 0))
  154. {
  155. TranslateMessage (&msg);
  156. DispatchMessage (&msg);
  157. }
  158.     /* return success of application */
  159.     return TRUE;
  160. }
  161. /*  start app */
  162. BOOL WINAPI InitEnvironment (
  163.     HANDLE    hInstance,
  164.     int       nCmdShow,
  165.     char      *lpszCmdLine)
  166.     {
  167.     WNDCLASS   wc;
  168.     char       szClass[MAX_PATH];
  169.     char       szTitle[MAX_PATH];
  170.     char       szFilename[MAX_PATH];
  171.     HWND       hWnd;
  172.     /* register system statistics window class */
  173.     LoadString (hInstance, IDS_SYSSTATCLASS, szClass, sizeof (szClass));
  174.     wc.style      = 0;
  175.     wc.lpfnWndProc   = (WNDPROC)SysStatWndProc;
  176.     wc.cbClsExtra    = 0;
  177.     wc.cbWndExtra    = 0;
  178.     wc.hInstance     = hInstance;
  179.     wc.hIcon      = LoadIcon (hInstance, MAKEINTRESOURCE (IDR_SYSSTATICON));
  180.     wc.hCursor      = LoadCursor (0, IDC_ARROW);
  181.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  182.     wc.lpszMenuName  = NULL;
  183.     wc.lpszClassName = szClass;
  184.     if (!RegisterClass (&wc) )
  185. return FALSE;
  186.     /* register process statistics window class */
  187.     LoadString (hInstance, IDS_PROSTATCLASS, szClass, sizeof (szClass));
  188.     wc.style      = 0;
  189.     wc.lpfnWndProc   = (WNDPROC)ProStatWndProc;
  190.     wc.cbClsExtra    = 0;
  191.     wc.cbWndExtra    = 0;
  192.     wc.hInstance     = hInstance;
  193.     wc.hIcon      = LoadIcon (hInstance, MAKEINTRESOURCE (IDR_PROSTATICON));
  194.     wc.hCursor      = LoadCursor (0, IDC_ARROW);
  195.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  196.     wc.lpszMenuName  = NULL;
  197.     wc.lpszClassName = szClass;
  198.     if (!RegisterClass (&wc) )
  199. return FALSE;
  200.     /* register the status bar window class */
  201.     LoadString (hInstance, IDS_STATUSCLASS, szClass, sizeof (szClass));
  202.     wc.style      = 0;
  203.     wc.lpfnWndProc   = (WNDPROC)StatusWndProc;
  204.     wc.cbClsExtra    = 0;
  205.     wc.cbWndExtra    = STATUSWXB;
  206.     wc.hInstance     = hInstance;
  207.     wc.hIcon      = (HICON)NULL;
  208.     wc.hCursor      = LoadCursor (0, IDC_ARROW);
  209.     wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
  210.     wc.lpszMenuName  = NULL;
  211.     wc.lpszClassName = szClass;
  212.     if (!RegisterClass (&wc) )
  213. return FALSE;
  214.     /* register the main frame window class */
  215.     LoadString (hInstance, IDS_MEMVIEWCLASS, szClass, sizeof (szClass));
  216.     wc.style      = 0;
  217.     wc.lpfnWndProc   = (WNDPROC)MemWndProc;
  218.     wc.cbClsExtra    = 0;
  219.     wc.cbWndExtra    = VIEWWXB;
  220.     wc.hInstance     = hInstance;
  221.     wc.hIcon      = LoadIcon (hInstance, MAKEINTRESOURCE (IDR_MAINICON));
  222.     wc.hCursor      = LoadCursor (0, IDC_ARROW);
  223.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  224.     wc.lpszMenuName  = NULL;
  225.     wc.lpszClassName = szClass;
  226.     if (!RegisterClass (&wc) )
  227. return FALSE;
  228.     /* register the main frame window class */
  229.     LoadString (hInstance, IDS_WALKERCLASS, szClass, sizeof (szClass));
  230.     wc.style      = 0;
  231.     wc.lpfnWndProc   = (WNDPROC)WalkerWndProc;
  232.     wc.cbClsExtra    = 0;
  233.     wc.cbWndExtra    = 0;
  234.     wc.hInstance     = hInstance;
  235.     wc.hIcon      = LoadIcon (hInstance, MAKEINTRESOURCE (IDR_MAINICON));
  236.     wc.hCursor      = LoadCursor (0, IDC_ARROW);
  237.     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  238.     wc.lpszMenuName  = MAKEINTRESOURCE (IDR_WALKERMENU);
  239.     wc.lpszClassName = szClass;
  240.     if (!RegisterClass (&wc) )
  241. return FALSE;
  242.     /* create window caption */
  243.     LoadString (hInstance, IDS_CAPTION, szTitle, sizeof (szTitle));
  244.     if (lpszCmdLine != NULL &&
  245. ((lpChildProcess = StartChildProcess (NULL, lpszCmdLine, hChildEvents)) != NULL))
  246. GetFileFromPath (lpszCmdLine, szFilename);
  247.     else
  248. LoadString (hInstance, IDS_SELF, szFilename, MAX_PATH);
  249.     strcat (szTitle, szFilename);
  250.     /* create main frame window */
  251.     hWnd = CreateWindow (szClass,
  252.  szTitle,
  253.  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  254.  CW_USEDEFAULT,
  255.  0,
  256.  CW_USEDEFAULT,
  257.  0,
  258.  NULL,
  259.  NULL,
  260.  hInstance,
  261.  NULL);
  262.     /* update parent window handle in child process information structure */
  263.     if (lpChildProcess != NULL)
  264. lpChildProcess->hWnd = hWnd;
  265.     if (!hWnd)
  266. return 0;
  267.     ShowWindow (hWnd, nCmdShow);
  268.     UpdateWindow (hWnd);
  269.     return TRUE;
  270. }
  271. /* main window procedure */
  272. LONG WINAPI WalkerWndProc (
  273.     HWND    hWnd,
  274.     UINT    uMsg,
  275.     WPARAM  wParam,
  276.     LPARAM  lParam)
  277. {
  278.        LONG    lRet = 1;
  279. static LOGFONT lf_Font = {
  280.  -10, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
  281.  OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  282.  DEFAULT_QUALITY, FIXED_PITCH | FF_DONTCARE,
  283.                          "Courier",
  284.  };
  285. static LOGFONT lf_FontVar = {
  286.     -10, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
  287.  OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  288.  DEFAULT_QUALITY, 0, // FIXED_PITCH | FF_DONTCARE,
  289.                          "MS Sans Serif",
  290.  };
  291.     /* On a Japanese system, change the fonts...  should generalize to all FE */
  292.     if (PRIMARYLANGID(GetUserDefaultLangID ()) == LANG_JAPANESE) {
  293.         lf_Font.lfCharSet = SHIFTJIS_CHARSET;
  294.         lstrcpy (lf_Font.lfFaceName , "Terminal");
  295.         lf_FontVar.lfHeight= -12;
  296.         lf_FontVar.lfCharSet = SHIFTJIS_CHARSET;
  297.         lstrcpy (lf_Font.lfFaceName , "俵俽 僑僔僢僋");
  298.     }
  299.     switch (uMsg)
  300. {
  301. /* initialize menu before drawing */
  302. case WM_INITMENU:
  303.     InitMenu (hWnd);
  304.     break;
  305. /* display status messages for menu commands */
  306. case WM_MENUSELECT:
  307.     {
  308.     char     *lpszMenuString;
  309.     lpszMenuString = LocalAlloc (LPTR, MAX_PATH);
  310.     if (HIWORD (wParam) ==  0xFFFF)
  311. {
  312. LocalFree (lpszMenuString);
  313. lpszMenuString = NULL;
  314. }
  315.     else if (HIWORD (wParam) & MF_POPUP)
  316. {
  317. int  i;
  318. HMENU  hPopupMenu = GetSubMenu ((HMENU)lParam, LOWORD (wParam));
  319. lpszMenuString = LocalAlloc (LPTR, MAX_PATH);
  320. for (i=0; i<MENUPOPUPS; i++)
  321.     {
  322.     if (hPopup[i] == hPopupMenu)
  323. {
  324. LoadString (GetModuleHandle (NULL),
  325.     i+IDM_POPUPMENUS,
  326.     lpszMenuString,
  327.     MAX_PATH);
  328. break;
  329. }
  330.     }
  331. }
  332.     else
  333. LoadString (GetModuleHandle (NULL),
  334.     LOWORD (wParam),
  335.     lpszMenuString,
  336.     MAX_PATH);
  337.     /* send the status string, gray if necessary */
  338.     SendMessage (GetDlgItem (hWnd, IDC_STATUSWND),
  339.  WM_SETTEXT,
  340.  (HIWORD (wParam) & MF_GRAYED) ?
  341.      (LPARAM)GetSysColor (COLOR_GRAYTEXT):
  342.      0,
  343.  (WPARAM)lpszMenuString);
  344.     LocalFree (lpszMenuString);
  345.     }
  346.     break;
  347. case WM_CREATE:
  348.     {
  349.     HCURSOR   hOldCursor;
  350.     HDC    hDC;
  351.     TEXTMETRIC   tm;
  352.     char   szWndClass[MAX_PATH];
  353.     HWND   hList, hStatus;
  354.     int    i=0, j, k;
  355.     HMENU   hMenu;
  356.     /* build array of popup menu handles */
  357.     hMenu = GetMenu (hWnd);
  358.     for (k=0; k<MENUPOPUPS-(i-1); k++)
  359. {
  360. hPopup[i] = GetSubMenu (hMenu, k);
  361. j=0;
  362. while ((hPopup[i+j+1] = GetSubMenu (hPopup[i], j)) != NULL)
  363.     j++;
  364. if (j)
  365.     i+=j;
  366. i++;
  367. }
  368.     /* put hourglass cursor up */
  369.     hOldCursor = (HCURSOR)SetClassLong (hWnd, GCL_HCURSOR, 0);
  370.     SetCursor (LoadCursor (0, IDC_WAIT));
  371.     hDC = GetDC(hWnd);
  372.     /* want a font with point size of 10 (smallest size it comes in) */
  373.     lf_Font.lfHeight = -(10 * GetDeviceCaps(hDC, LOGPIXELSY)/72);
  374.     hFont = CreateFontIndirect(&lf_Font);
  375.     hFontVar = CreateFontIndirect(&lf_FontVar);
  376.             // find the width of a '0' in the variable font
  377.             //
  378.             SelectObject(hDC, hFontVar);
  379.             GetTextExtentPoint (hDC, "0", 1, &sChar0);
  380.             SelectObject(hDC, hFont);
  381.     /* initialize system constants */
  382.     GetTextMetrics(hDC, &tm);
  383.     yChar = tm.tmHeight;
  384.     xChar = tm.tmAveCharWidth;
  385.     xScreen = GetSystemMetrics(SM_CXSCREEN);
  386.     yScreen = GetSystemMetrics(SM_CYSCREEN);
  387.     yFrame = GetSystemMetrics(SM_CYFRAME);
  388.     xFrame = GetSystemMetrics(SM_CXFRAME);
  389.     yCaption = GetSystemMetrics(SM_CYCAPTION);
  390.     xVScrollBar = GetSystemMetrics(SM_CXVSCROLL);
  391.     //Actually, it's not good that a width of each column
  392.     // depends on a width of "0"!!
  393.     if (xChar > sChar0.cx) {
  394. // sChar0.cx = xChar;
  395. sChar0.cx = sChar0.cx * 12 / 10; //sChar0.cx *= 1.2
  396.     }
  397.             SelectObject(hDC, GetStockObject(SYSTEM_FONT));
  398.             ReleaseDC(hWnd, hDC);
  399.     /* create listbox for client area */
  400.     LoadString (GetModuleHandle (NULL),
  401. IDS_LISTBOX,
  402. szWndClass,
  403. sizeof (szWndClass));
  404.     hList = CreateWindow (szWndClass,
  405.   NULL,
  406.   WS_CHILD | WS_VISIBLE | WS_VSCROLL |
  407.   LBS_EXTENDEDSEL | LBS_NOTIFY | LBS_OWNERDRAWFIXED |
  408.   LBS_WANTKEYBOARDINPUT | LBS_NOINTEGRALHEIGHT,
  409.   0, 0, 0, 0,
  410.   hWnd,
  411.   (HMENU)IDC_LISTBOX,
  412.   GetModuleHandle (NULL),
  413.   NULL);
  414.     /* if listbox failed, abort app */
  415.     if (!IsWindow (hList))
  416. DestroyWindow(hWnd);
  417.     SendMessage (hList, WM_SETFONT, (WPARAM)hFontVar, 0L);
  418.     /* create status window for client area */
  419.     LoadString (GetModuleHandle (NULL),
  420. IDS_STATUSCLASS,
  421. szWndClass,
  422. sizeof (szWndClass));
  423.     if (!(hStatus = CreateWindow (szWndClass,
  424.   NULL,
  425.   WS_CHILD | WS_VISIBLE | WS_BORDER,
  426.   0, 0, 0, 0,
  427.   hWnd,
  428.   (HMENU)IDC_STATUSWND,
  429.   GetModuleHandle (NULL),
  430.   NULL)))
  431. ReportError (IDS_ERRCREATEWINDOW);
  432.     /* initialize status window */
  433.     SendMessage (GetDlgItem (hWnd, IDC_STATUSWND),
  434.  UM_UPDATE,
  435.  (WPARAM)lpChildProcess,
  436.  0);
  437.     /* if child process post message to display initialization dialog */
  438.     if (lpChildProcess != NULL)
  439. PostMessage (hWnd, UM_STARTINITDIALOG, 0, 0);
  440.     /* remove hourglass cursor */
  441.     SetClassLong (hWnd, GCL_HCURSOR, (LONG)hOldCursor);
  442.     SetCursor (hOldCursor);
  443.     }
  444.     break;
  445. case UM_STARTINITDIALOG:
  446.     /* start modal initializing information window */
  447.     DialogBoxParam (GetModuleHandle (NULL),
  448.     (char *)IDD_INITIALIZING,
  449.     hWnd,
  450.     InitDlgProc,
  451.     (LPARAM)&hInitDlg);
  452.     hInitDlg = NULL;
  453.     break;
  454. case WM_SETFOCUS:
  455.     /* keep focus in listbox when possible */
  456.     SetFocus (GetDlgItem (hWnd, IDC_LISTBOX));
  457.     break;
  458. case WM_MEASUREITEM:
  459.             ((MEASUREITEMSTRUCT FAR *)lParam)->itemHeight = sChar0.cy;
  460.             break;
  461. case WM_DRAWITEM:
  462.     DrawListItem ((DRAWITEMSTRUCT FAR *)lParam);
  463.             break;
  464. case WM_PAINT:
  465.     {
  466.     PAINTSTRUCT ps;
  467.     RECT rc;
  468.     /* draw the caption line above the list box */
  469.     BeginPaint(hWnd, &ps);
  470.     SetRect(&rc, 0, 0, GetSystemMetrics (SM_CXSCREEN), sChar0.cy);
  471.     SelectObject(ps.hdc, hFontVar);
  472.     SetTextColor(ps.hdc, GetSysColor(COLOR_CAPTIONTEXT));
  473.     SetBkColor(ps.hdc, GetSysColor(COLOR_ACTIVECAPTION));
  474.             TextOutFields (ps.hdc, 6, &rc, szCaptionText);
  475.     SelectObject(ps.hdc, GetStockObject(SYSTEM_FONT));
  476.     EndPaint(hWnd, &ps);
  477.     }
  478.     break;
  479. case WM_SIZE:
  480.     /* size listbox and status bar */
  481.     if ((wParam == SIZE_RESTORED) || (wParam == SIZE_MAXIMIZED))
  482. {
  483. int    yBorder = GetSystemMetrics (SM_CYBORDER);
  484. int    xBorder = GetSystemMetrics (SM_CXBORDER);
  485. int    yStatus = yChar + 10*yBorder;
  486. /* size listbox */
  487. MoveWindow(GetDlgItem (hWnd, IDC_LISTBOX),
  488.    0,
  489.    sChar0.cy,
  490.    LOWORD(lParam),
  491.    HIWORD(lParam)-(sChar0.cy + yStatus - yBorder),
  492.    TRUE);
  493. /* size status bar */
  494. MoveWindow(GetDlgItem (hWnd, IDC_STATUSWND),
  495.    0-xBorder,
  496.    HIWORD(lParam)-yStatus+yBorder,
  497.    LOWORD(lParam) + 2*xBorder,
  498.    yStatus,
  499.    TRUE);
  500. }
  501.     break;
  502. case WM_COMMAND:
  503.     {
  504.     switch (LOWORD (wParam))
  505. {
  506. case IDM_EXIT:
  507.     SendMessage (hWnd, WM_CLOSE, 0, 0);
  508.     break;
  509. case IDM_PROCESSUNLOAD:
  510.     {
  511.     char    szFilename[MAX_PATH];
  512.     char    szTitle[MAX_PATH];
  513.     HWND    hViewWnd = NULL;
  514.     /* close child process */
  515.     CloseChildProcess (lpChildProcess, hChildEvents);
  516.     lpChildProcess = NULL;
  517.     SendMessage (GetDlgItem (hWnd, IDC_LISTBOX), LB_RESETCONTENT, 0, 0);
  518.     SendMessage (GetDlgItem (hWnd, IDC_STATUSWND),
  519.  UM_UPDATE,
  520.  0,
  521.  0);
  522.     /* reset caption */
  523.     LoadString (GetModuleHandle (NULL),
  524. IDS_CAPTION,
  525. szTitle,
  526. MAX_PATH);
  527.     LoadString (GetModuleHandle (NULL),
  528. IDS_SELF,
  529. szFilename,
  530. MAX_PATH);
  531.     strcat (szTitle, szFilename);
  532.     SetWindowText (hWnd, szTitle);
  533.     if (IsWindow (hWndSysStat))
  534. {
  535. InvalidateRect (hWndSysStat, NULL, TRUE);
  536. UpdateWindow (hWndSysStat);
  537. }
  538.     if (IsWindow (hWndProStat))
  539. DestroyWindow (hWndProStat);
  540.     while ((hViewWnd = EnumViewWindows (hWnd, hViewWnd)) != NULL)
  541. DestroyWindow (hViewWnd);
  542.     }
  543.     break;
  544. case IDM_PROCESSLOAD:
  545.     {
  546.     char      szTitle[MAX_PATH];
  547.     char      szFilePath[MAX_PATH];
  548.     HWND      hViewWnd = NULL;
  549.     /* detaching from old process, okay?? */
  550.     if (lpChildProcess != NULL)
  551. {
  552. strcpy (szTitle, "Detach from process ");
  553. strcat (szTitle, lpChildProcess->szModule);
  554. strcat (szTitle, "?");
  555. LoadString (GetModuleHandle (NULL),
  556.     IDS_WALKERCLASS,
  557.     szFilePath,
  558.     MAX_PATH);
  559. if (IDYES != MessageBox (hWnd,
  560.  szTitle,
  561.  szFilePath,
  562.  MB_YESNO | MB_ICONQUESTION))
  563.     break;
  564. }
  565.     /* call open file dialog to get filename of exe, and validate */
  566.     *szFilePath = 0;
  567.     if (GetFileName (hWnd, szFilePath, NULL))
  568. {
  569. if (IsValidFile (szFilePath))
  570.     {
  571.     if (lpChildProcess != NULL)
  572. {
  573. /* close any open view windows for this process */
  574. while ((hViewWnd = EnumViewWindows (hWnd, hViewWnd)) != NULL)
  575.     DestroyWindow (hViewWnd);
  576. CloseChildProcess (lpChildProcess, hChildEvents);
  577. SendMessage (GetDlgItem (hWnd, IDC_LISTBOX),
  578.      LB_RESETCONTENT,
  579.      0,
  580.      0);
  581. SendMessage (GetDlgItem (hWnd, IDC_STATUSWND),
  582.      UM_UPDATE,
  583.      0,
  584.      0);
  585. }
  586.     if ((lpChildProcess =
  587.  StartChildProcess (hWnd, szFilePath, hChildEvents)) != NULL)
  588. {
  589. /* force rewalk of process */
  590. PostMessage (hWnd, UM_STARTINITDIALOG, 0, 0);
  591. SendMessage (GetDlgItem (hWnd, IDC_STATUSWND),
  592.      UM_UPDATE,
  593.      (WPARAM)lpChildProcess,
  594.      0);
  595. /* load new window caption */
  596. LoadString (GetModuleHandle (NULL),
  597.     IDS_CAPTION,
  598.     szTitle,
  599.     MAX_PATH);
  600. GetFileFromPath (szFilePath, szFilename);
  601. strcat (szTitle, szFilename);
  602. SetWindowText (hWnd, szTitle);
  603. }
  604.     }
  605. }
  606.     }
  607.     break;
  608. case IDM_PROCESSREWALK:
  609.     {
  610.     HWND      hList = GetDlgItem (hWnd, IDC_LISTBOX);
  611.     int       nCnt, nNewCnt, i;
  612.     LPVOID    lpNewList=NULL, lpTempList=NULL;
  613.     HWND      hViewWnd = NULL;
  614.     /* clear listbox of current contents, but first find out how many exist */
  615.     nCnt = SendMessage (hList, LB_GETCOUNT, 0, 0);
  616.     SendMessage (hList, WM_SETREDRAW, 0, 0);
  617.     SendMessage (hList, LB_RESETCONTENT, 0, 0);
  618.     /* walk process address space */
  619.     if (lpChildProcess != NULL)
  620. {
  621. nNewCnt = WalkProcess (lpChildProcess->hProcess, &lpNewList, &Objects);
  622. AnalyzeProcess (lpChildProcess, (LPVMOBJECT)lpNewList, nNewCnt);
  623. /* indentify which objects are new */
  624. if (nCnt)
  625.     IdentifyNewObjects (lpWalkerList, nCnt, lpNewList, nNewCnt);
  626. /* free old list and update cnt */
  627. lpTempList = lpWalkerList;
  628. lpWalkerList = lpNewList;
  629. VirtualFree (lpTempList, TOTALVMRESERVE, MEM_DECOMMIT);
  630. VirtualFree (lpTempList, 0, MEM_RELEASE);
  631. nCnt = nNewCnt;
  632. }
  633.     for (i=0; i<nCnt; i++)
  634. SendMessage (hList, LB_ADDSTRING, 0, i);
  635.     /* sort if other than by address is selected */
  636.     if (nSortType != IDM_SORTADDRESS)
  637. SortList (hList, nSortType);
  638.     /* reenable redraw of listbox */
  639.     SendMessage (hList, WM_SETREDRAW, 1, 0);
  640.     InvalidateRect (hList, NULL, TRUE);
  641.     UpdateWindow (hList);
  642.     /* if any memory view windows, send update message */
  643.     while ((hViewWnd = EnumViewWindows (hWnd, hViewWnd)) != NULL)
  644. {
  645. LPMEMVIEW     pmv, pmvOld;
  646. int     nAddress, nSize;
  647. MEMORY_BASIC_INFORMATION    mbi;
  648. char     *szCaption;
  649. /* retrieve view memory range */
  650. szCaption = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, MAX_PATH);
  651. GetWindowText (hViewWnd, szCaption, MAX_PATH);
  652. /* validate range */
  653. sscanf (strtok (szCaption, "-"), "%8x", &nAddress);
  654. sscanf (strtok (NULL, " "), "%8x", &nSize);
  655. nSize -= nAddress;
  656. VirtualQueryEx (lpChildProcess->hProcess,
  657. (LPVOID)nAddress,
  658. &mbi,
  659. sizeof (MEMORY_BASIC_INFORMATION));
  660. if (mbi.State != MEM_COMMIT)
  661.     {
  662.     NotifyUser (hWnd, IDS_ERROR, IDS_NOTCOMMITTEDMEMORY, NULL, 0);
  663.     DestroyWindow (hViewWnd);
  664.     goto NOT;
  665.     }
  666. /* if size of committed region changed, update caption */
  667. if (mbi.RegionSize != (DWORD)nSize)
  668.     {
  669.     wsprintf (szCaption,
  670.       "%4lx-%-4lx",
  671.       (DWORD)mbi.BaseAddress,
  672.       (DWORD)mbi.BaseAddress+mbi.RegionSize);
  673.     SetWindowText (hViewWnd, szCaption);
  674.     }
  675. /* free default heap memory */
  676. HeapFree (GetProcessHeap (), 0, szCaption);
  677. /* if an old view structure existed, release virtual memory */
  678. if ((pmvOld = (LPMEMVIEW)GetWindowLong (hViewWnd, WXB_LPOLDMEMVIEW)) != NULL)
  679.     VirtualFree (pmvOld->lpMem, 0, MEM_RELEASE);
  680. pmvOld = (LPMEMVIEW)GetWindowLong (hViewWnd, WXB_LPMEMVIEW);
  681. /* save past pmv for update comparison */
  682. SetWindowLong (hViewWnd,
  683.        WXB_LPOLDMEMVIEW,
  684.        (LONG)pmvOld);
  685. /* allocate memory structure for view memory object */
  686. pmv = (LPMEMVIEW)LocalAlloc (LPTR, sizeof (MEMVIEW));
  687. /* copy old mem view to new mem view */
  688. for (i=0; i<sizeof (MEMVIEW); i++)
  689.     ((LPBYTE)pmv)[i] = ((LPBYTE)pmvOld)[i];
  690. /* update structure for new mem structure */
  691. pmv->nBase = (int)mbi.BaseAddress;
  692. pmv->nSize = (int)mbi.RegionSize;
  693. if ((pmv->lpMem = VirtualAlloc (NULL, pmv->nSize, MEM_COMMIT, PAGE_READWRITE)) == NULL)
  694.     {
  695.     ReportError (IDS_ERRVIRTUALALLOC);
  696.     DestroyWindow (hViewWnd);
  697.     }
  698. else if (AccessProcessMemory (hChildEvents[READMEMORY],
  699.       hChildEvents[ACKNOWLEDGE],
  700.       (LPVOID)nAddress,
  701.       pmv->lpMem,
  702.       &(pmv->nSize))  && pmv->nSize)
  703.     {
  704.     pmv->nLines = (pmv->nSize+15)/16;
  705.     pmv->nExtraBytes = (pmv->nSize & 0x0000000F);
  706.     SetWindowLong (hViewWnd, WXB_LPMEMVIEW, (LONG)pmv);
  707.     /* post message to view window to update */
  708.     PostMessage (hViewWnd, UM_UPDATE, 0, 0);
  709.     }
  710. else
  711.     {
  712.     NotifyUser (hWnd, IDS_ERROR, IDS_COULDNOTREADPROCESS, NULL, 0);
  713.     DestroyWindow (hViewWnd);
  714.     }
  715. }
  716. NOT:
  717.     /* if initialization dialog, send notification to remove */
  718.     if (IsWindow (hInitDlg))
  719. PostMessage (hInitDlg, UM_ENDDIALOG, 0, 0);
  720.     }
  721.     break;
  722. case IDM_PROCESSSUSPEND:
  723.     SetEvent (hChildEvents[SUSPENDDEBUGGER]);
  724.     break;
  725. case IDM_PROCESSRESUME:
  726.     SetEvent (hChildEvents[RESUMEDEBUGGER]);
  727.     break;
  728. case IDM_VIEWSYSSTAT:
  729.     /* if window exists, destroy it */
  730.     if (IsWindow (hWndSysStat))
  731. {
  732. DestroyWindow (hWndSysStat);
  733. CheckMenuItem (GetMenu (hWnd), wParam, MF_UNCHECKED);
  734. }
  735.     else
  736. {
  737. char szClass[100];
  738. char szTitle[100];
  739. RECT rc;
  740. GetWindowRect (hWnd, &rc);
  741. LoadString (GetModuleHandle (NULL), IDS_SYSSTATCLASS, szClass, 100);
  742. LoadString (GetModuleHandle (NULL), IDS_SYSSTATTITLE, szTitle, 100);
  743. hWndSysStat = CreateWindow (szClass,
  744.     szTitle,
  745.     WS_POPUP | WS_CAPTION | WS_MINIMIZEBOX |
  746.     WS_SYSMENU | WS_DLGFRAME | WS_VISIBLE,
  747.     rc.left+50, rc.top+50, 500, 270,
  748.     hWnd,
  749.     NULL,
  750.     GetModuleHandle (NULL),
  751.     NULL);
  752. UpdateWindow (hWndSysStat);
  753. ShowWindow (hWndSysStat, SW_SHOWNORMAL);
  754. CheckMenuItem (GetMenu (hWnd), wParam, MF_CHECKED);
  755. }
  756.     break;
  757. case IDM_VIEWPROSTAT:
  758.     /* if window exists, destroy it */
  759.     if (IsWindow (hWndProStat))
  760. {
  761. DestroyWindow (hWndProStat);
  762. CheckMenuItem (GetMenu (hWnd), wParam, MF_UNCHECKED);
  763. }
  764.     else
  765. {
  766. char szClass[100];
  767. char szTitle[100];
  768. RECT rc;
  769. GetWindowRect (hWnd, &rc);
  770. LoadString (GetModuleHandle (NULL), IDS_PROSTATCLASS, szClass, 100);
  771. LoadString (GetModuleHandle (NULL), IDS_PROSTATTITLE, szTitle, 100);
  772. hWndProStat = CreateWindow (szClass,
  773.     szTitle,
  774.     WS_POPUP | WS_CAPTION | WS_MINIMIZEBOX |
  775.     WS_SYSMENU | WS_DLGFRAME | WS_VISIBLE,
  776.     rc.left+75, rc.top+75, 355, 120,
  777.     hWnd,
  778.     NULL,
  779.     GetModuleHandle (NULL),
  780.     NULL);
  781. UpdateWindow (hWndProStat);
  782. ShowWindow (hWndProStat, SW_SHOWNORMAL);
  783. CheckMenuItem (GetMenu (hWnd), wParam, MF_CHECKED);
  784. }
  785.     break;
  786. /* accept bouble click messages from listbox only */
  787. case IDC_LISTBOX:
  788.     if (HIWORD (wParam) != LBN_DBLCLK)
  789. break;
  790. case IDM_VIEWMEMORY:
  791.     if (ViewableMemorySelection (hWnd))
  792. {
  793. char   szBuff[50];
  794. HWND   hList = GetDlgItem (hWnd, IDC_LISTBOX);
  795. int   iCaret = SendMessage (hList, LB_GETCARETINDEX, 0, 0);
  796. DWORD   nAddress =
  797.   (DWORD)((LPVMOBJECT)lpWalkerList)[Objects[iCaret]].mbi.BaseAddress;
  798. int   nSize = ((LPVMOBJECT)lpWalkerList)[Objects[iCaret]].mbi.RegionSize;
  799. LPVOID   lpMem;
  800. HCURSOR   hOldCursor;
  801. if ((lpMem = VirtualAlloc (NULL, nSize, MEM_COMMIT, PAGE_READWRITE)) == NULL)
  802.     {
  803.     ReportError (IDS_ERRVIRTUALALLOC);
  804.     break;
  805.     }
  806. /* put wait cursor up */
  807. hOldCursor = (HCURSOR)SetClassLong (hWnd, GCL_HCURSOR, 0);
  808. SetCursor (LoadCursor (0, IDC_WAIT));
  809. /* signal debugger thread to read process memory */
  810. if (AccessProcessMemory (hChildEvents[READMEMORY],
  811.  hChildEvents[ACKNOWLEDGE],
  812.  (LPVOID)nAddress,
  813.  lpMem,
  814.  &nSize)  && nSize)
  815.     {
  816.     wsprintf (szBuff, "%4lx-%-4lx", nAddress, nAddress+nSize);
  817.     ViewMemory (hWnd, szBuff, lpMem, nSize, nAddress);
  818.     /* if first view window, add separator */
  819.     if (GetMenuItemCount (GetSubMenu (GetMenu (hWnd), 2)) == 5)
  820. AppendMenu (GetSubMenu (GetMenu (hWnd), 2),
  821.     MF_SEPARATOR,
  822.     0,
  823.     NULL);
  824.     AppendMenu (GetSubMenu (GetMenu (hWnd), 2),
  825. MF_STRING | MF_CHECKED,
  826. AddAtom (szBuff),
  827. szBuff);
  828.     }
  829. else
  830.     NotifyUser (hWnd, IDS_ERROR, IDS_COULDNOTREADPROCESS, NULL, 0);
  831. /* replace wait cursor with old cursor */
  832. SetClassLong (hWnd, GCL_HCURSOR, (LONG)hOldCursor);
  833. SetCursor (hOldCursor);
  834. }
  835.     else
  836. {
  837. NotifyUser (hWnd, IDS_ERROR, IDS_NOTCOMMITTEDMEMORY, NULL, 0);
  838. break;
  839. }
  840.     break;
  841. case IDM_VIEWADDRESS:
  842.     {
  843.     int  nAddress;
  844.     MEMORY_BASIC_INFORMATION mbi;
  845.     LPVOID lpMem;
  846.     char szBuff[MAX_PATH];
  847.     int  nLine;
  848.     HWND hViewWnd;
  849.     if (nAddress = DialogBox (GetModuleHandle (NULL), (char *)IDD_ADDR, hWnd, AddrDlgProc))
  850. {
  851. VirtualQueryEx (lpChildProcess->hProcess,
  852. (LPVOID)nAddress,
  853. &mbi,
  854. sizeof (MEMORY_BASIC_INFORMATION));
  855. if (mbi.State != MEM_COMMIT)
  856.     {
  857.     NotifyUser (hWnd, IDS_ERROR, IDS_NOTCOMMITTEDMEMORY, NULL, 0);
  858.     break;
  859.     }
  860. if ((lpMem = VirtualAlloc (NULL, mbi.RegionSize, MEM_COMMIT, PAGE_READWRITE)) == NULL)
  861.     {
  862.     ReportError (IDS_ERRVIRTUALALLOC);
  863.     break;
  864.     }
  865. /* signal debugger thread to read process memory */
  866. if (AccessProcessMemory (hChildEvents[READMEMORY],
  867.  hChildEvents[ACKNOWLEDGE],
  868.  (LPVOID)mbi.BaseAddress,
  869.  lpMem,
  870.  &(mbi.RegionSize))  && mbi.RegionSize)
  871.     {
  872.     wsprintf (szBuff,
  873.       "%4lx-%-4lx",
  874.       (int)mbi.BaseAddress,
  875.       (int)mbi.BaseAddress+mbi.RegionSize);
  876.     hViewWnd = ViewMemory (hWnd, szBuff, lpMem, mbi.RegionSize, (int)mbi.BaseAddress);
  877.     /* if first view window, add separator */
  878.     if (GetMenuItemCount (GetSubMenu (GetMenu (hWnd), 2)) == 4)
  879. AppendMenu (GetSubMenu (GetMenu (hWnd), 2),
  880.     MF_SEPARATOR,
  881.     0,
  882.     NULL);
  883.     AppendMenu (GetSubMenu (GetMenu (hWnd), 2),
  884. MF_STRING | MF_CHECKED,
  885. AddAtom (szBuff),
  886. szBuff);
  887.     /* send WM_VSCROLL message to scroll address into view */
  888.     nLine = (nAddress - (int)mbi.BaseAddress)/16 - 5;
  889.     PostMessage (hViewWnd, WM_VSCROLL, MAKELONG (SB_THUMBPOSITION, nLine), 0);
  890.     }
  891. else
  892.     NotifyUser (hWnd, IDS_ERROR, IDS_COULDNOTREADPROCESS, NULL, 0);
  893. }
  894.     }
  895.     break;
  896. case IDM_REMOVEVIEWWND:
  897.     {
  898.     ATOM    aCaption = FindAtom ((char *)lParam);
  899.     HMENU   hMenu = GetMenu (hWnd);
  900.     HMENU   hViewMenu = GetSubMenu (hMenu, 2);
  901.     RemoveMenu (hMenu, (UINT)aCaption, MF_BYCOMMAND);
  902.     DeleteAtom (aCaption);
  903.     /* there are 4 menuitems in the view menu without view windows open */
  904.     if (GetMenuItemCount (hViewMenu) == 6)
  905. RemoveMenu (hViewMenu, 5, MF_BYPOSITION);
  906.     }
  907.     break;
  908. case IDM_SORTADDRESS:
  909. case IDM_SORTSTATE:
  910. case IDM_SORTPROTECTION:
  911. case IDM_SORTSIZE:
  912. case IDM_SORTBASEADDRESS:
  913.     {
  914.     HWND    hList = GetDlgItem (hWnd, IDC_LISTBOX);
  915.     HCURSOR hOldCursor;
  916.     if (nSortType != (int)LOWORD (wParam))
  917. {
  918. /* put wait cursor up */
  919. hOldCursor = (HCURSOR)SetClassLong (hWnd, GCL_HCURSOR, 0);
  920. SetCursor (LoadCursor (0, IDC_WAIT));
  921. /* reset menuitems to indicate which sort method is being used */
  922. CheckMenuItem (GetMenu (hWnd), nSortType, MF_UNCHECKED);
  923. CheckMenuItem (GetMenu (hWnd), wParam, MF_CHECKED);
  924. /* save new sort type and resort */
  925. SortList (hList, nSortType = wParam);
  926. /* repaint after sorting */
  927. InvalidateRect (hList, NULL, TRUE);
  928. UpdateWindow (hList);
  929. /* replace wait cursor with old cursor */
  930. SetClassLong (hWnd, GCL_HCURSOR, (LONG)hOldCursor);
  931. SetCursor (hOldCursor);
  932.  }
  933.     }
  934.     break;
  935.                 case IDM_OPTBYTES:
  936.                 case IDM_OPTPAGES:
  937.                     {
  938.                     HWND hList = GetDlgItem (hWnd, IDC_LISTBOX);
  939.                     bNumbersAsBytes = (LOWORD(wParam) == IDM_OPTBYTES);
  940.                     InvalidateRect (hList, NULL, TRUE);
  941.                     }
  942.                     break;
  943. default:
  944.     /* if popup window, bring to front */
  945.     ActivateViewWindow (LOWORD (wParam));
  946.     lRet = TRUE;
  947.     break;
  948. }
  949.     }
  950.     break;
  951. case WM_CLOSE:
  952. case WM_QUERYENDSESSION:
  953.     /* if child process is active, close it first then exit */
  954.     if (lpChildProcess != NULL)
  955. CloseChildProcess (lpChildProcess, hChildEvents);
  956.     /* destroy this window */
  957.     DestroyWindow (hWnd);
  958.     break;
  959. case WM_DESTROY:
  960.     PostQuitMessage (0);
  961.     break;
  962. default:
  963.     /* pass all unhandled messages to DefWindowProc */
  964.     lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
  965.     break;
  966. }
  967.     /* return 1 if handled message, 0 if not */
  968.     return lRet;
  969. }
  970. /* initialize all menuitems */
  971. void WINAPI InitMenu (
  972.     HWND    hWnd)
  973. {
  974.     HMENU hMenu = GetMenu (hWnd);
  975.     /* if child process exists enable options */
  976.     EnableMenuItem (hMenu,
  977.     IDM_PROCESSREWALK,
  978.     MF_BYCOMMAND | ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  979.     EnableMenuItem (hMenu,
  980.     IDM_PROCESSUNLOAD,
  981.     MF_BYCOMMAND | ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  982.     /* check appropriate sort menuitem */
  983.     CheckMenuItem (hMenu, nSortType, MF_CHECKED);
  984.     /* check view as bytes/pages menuitems */
  985.     CheckMenuItem (hMenu, IDM_OPTBYTES, bNumbersAsBytes ? MF_CHECKED : MF_UNCHECKED);
  986.     CheckMenuItem (hMenu, IDM_OPTPAGES, bNumbersAsBytes ? MF_UNCHECKED : MF_CHECKED);
  987.     /* enable process and selection stat windows only when child process exists */
  988.     EnableMenuItem (hMenu,
  989.     IDM_VIEWPROSTAT,
  990.     MF_BYCOMMAND | ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  991.     EnableMenuItem (hMenu,
  992.     IDM_VIEWSYSSTAT,
  993.     MF_BYCOMMAND | ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  994.     /* check all appropriate view menuitem */
  995.     CheckMenuItem (hMenu,
  996.    IDM_VIEWSYSSTAT,
  997.    IsWindow (hWndSysStat) ? MF_CHECKED : MF_UNCHECKED);
  998.     CheckMenuItem (hMenu,
  999.    IDM_VIEWPROSTAT,
  1000.    IsWindow (hWndProStat) ? MF_CHECKED : MF_UNCHECKED);
  1001.     /* if child process exists */
  1002.     if (lpChildProcess != NULL)
  1003. {
  1004. /* child process is active */
  1005. if (lpChildProcess->bActive)
  1006.     {
  1007.     EnableMenuItem (hMenu, IDM_PROCESSRESUME, MF_GRAYED);
  1008.     EnableMenuItem (hMenu, IDM_PROCESSSUSPEND, MF_ENABLED);
  1009.     }
  1010. else
  1011.     {
  1012.     EnableMenuItem (hMenu, IDM_PROCESSSUSPEND, MF_GRAYED);
  1013.     EnableMenuItem (hMenu, IDM_PROCESSRESUME, MF_ENABLED);
  1014.     }
  1015. }
  1016.     /* diasble both menuitems */
  1017.     else
  1018. {
  1019. EnableMenuItem (hMenu, IDM_PROCESSSUSPEND, MF_GRAYED);
  1020. EnableMenuItem (hMenu, IDM_PROCESSRESUME, MF_GRAYED);
  1021. }
  1022.     /* sort only when process exists */
  1023.     EnableMenuItem (hMenu,
  1024.     IDM_SORTADDRESS,
  1025.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1026.     EnableMenuItem (hMenu,
  1027.     IDM_SORTSTATE,
  1028.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1029.     EnableMenuItem (hMenu,
  1030.     IDM_SORTPROTECTION,
  1031.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1032.     EnableMenuItem (hMenu,
  1033.     IDM_SORTSIZE,
  1034.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1035.     EnableMenuItem (hMenu,
  1036.     IDM_SORTBASEADDRESS,
  1037.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1038.     /* if child process & selection, and selection is committed memory */
  1039.     if (lpChildProcess != NULL &&
  1040. ViewableMemorySelection (hWnd))
  1041. EnableMenuItem (hMenu, IDM_VIEWMEMORY, MF_ENABLED);
  1042.     else
  1043. EnableMenuItem (hMenu, IDM_VIEWMEMORY, MF_GRAYED);
  1044. /* View address if child process */
  1045. EnableMenuItem (hMenu,
  1046. IDM_VIEWADDRESS,
  1047.     ((lpChildProcess != NULL) ? MF_ENABLED : MF_GRAYED));
  1048. }
  1049. int WINAPI MakeVMQString (
  1050.     int    nItem,
  1051.     char   *lpszMem)
  1052. {
  1053.     char   szState[10], szProtection[3];
  1054.     LPVMOBJECT   lpVMObject;
  1055.     int           nLen;
  1056.     int           nBaseAddr;
  1057.     int           nRegionSize;
  1058.     int           nAllocBase;
  1059.     LPSTR         lpszFormat;
  1060.     /* lookup object offset in array index */
  1061.     lpVMObject = ((VMOBJECT *)lpWalkerList)+Objects[nItem];
  1062.     /* determine state of memory object */
  1063.     if (lpVMObject->mbi.State & MEM_COMMIT)
  1064. strcpy (szState, "Commit ");
  1065.     else if (lpVMObject->mbi.State & MEM_RESERVE)
  1066. strcpy (szState, "Reserve");
  1067.     else
  1068. strcpy (szState, "Free   ");
  1069.     /* determine protection of memory */
  1070.     if (lpVMObject->mbi.Protect & PAGE_READWRITE)
  1071. strcpy (szProtection, "RW");
  1072.     else if (lpVMObject->mbi.Protect & PAGE_READONLY)
  1073. strcpy (szProtection, "RO");
  1074.     else
  1075. strcpy (szProtection, "NA");
  1076.     lpszFormat = szFormat;
  1077.     nBaseAddr = (int)(lpVMObject->mbi.BaseAddress);
  1078.     nRegionSize = lpVMObject->mbi.RegionSize;
  1079.     nAllocBase = (int)(lpVMObject->mbi.AllocationBase);
  1080.     if (!bNumbersAsBytes)
  1081.        {
  1082.        nBaseAddr /= PAGESIZE;
  1083.        nRegionSize /= PAGESIZE;
  1084.        nAllocBase /= PAGESIZE;
  1085.        lpszFormat = szFormatPages;
  1086.        }
  1087.     /* create list object */
  1088.     wsprintf(lpszMem,
  1089.      lpszFormat,
  1090.      nBaseAddr,
  1091.      szState,
  1092.      szProtection,
  1093.      nRegionSize,
  1094.      nAllocBase,
  1095.      lpVMObject->szObjType,
  1096.      lpVMObject->szSection,
  1097.              lpVMObject->szModule);
  1098.     /* return length of resulting string */
  1099.     nLen = strlen (lpszMem);
  1100.     // convert the ~ separators to  for the benefit of
  1101.     // TextOutFields
  1102.     //
  1103.     while (*lpszMem)
  1104.        {
  1105.        if (*lpszMem == '~') {
  1106.            *lpszMem = 0;
  1107.            // CharNext() returns the same pointer, if 'lpszMem' points ''.
  1108.            // So, we must not call CharNext() in this case.
  1109.            ++lpszMem;
  1110.        } else {
  1111.            lpszMem = CharNext(lpszMem);
  1112.        }
  1113.        }
  1114.     return nLen;
  1115. }
  1116. static void TextOutFields (
  1117.    HDC    hDC,
  1118.    int    x,
  1119.    LPRECT lprc,
  1120.    LPSTR  lpszItems)
  1121.    {
  1122.    int eto = ETO_CLIPPED | ETO_OPAQUE;
  1123.    int ii = 0;
  1124.    PSTR psz = lpszItems;
  1125.    int nLen;
  1126.    // copy fields until we get one of zero size.
  1127.    //
  1128.    do {
  1129.       SetTextAlign (hDC, taColumns[ii]);
  1130.       ExtTextOut(hDC,
  1131.                  lprc->left + (xColumns[ii] * sChar0.cx) + x,
  1132.                  lprc->top,
  1133.                  eto,
  1134.                  lprc,
  1135.                  psz,
  1136.                  nLen = strlen(psz),
  1137.                  0L);
  1138.       psz += (nLen + 1);
  1139.       eto = ETO_CLIPPED;
  1140.       ++ii;
  1141.       } while (nLen);
  1142.    }
  1143. void WINAPI DrawListItem(
  1144.     DRAWITEMSTRUCT *lpItem)
  1145. {
  1146.     DWORD dwBkColor=0xffffffff, dwTextColor=0xffffffff;
  1147.     char  szListItem[200];
  1148.     int   nLen;
  1149.     /* Make sure it is the list box with a valid item ID */
  1150.     if (lpItem->CtlType != ODT_LISTBOX ||
  1151. lpItem->CtlID != IDC_LISTBOX)
  1152.         return;
  1153.     if (lpItem->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
  1154. {
  1155.         /* Alter the bk and text color for selected items */
  1156. if (lpItem->itemState & ODS_SELECTED)
  1157.     {
  1158.     dwBkColor = SetBkColor (lpItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
  1159.     dwTextColor = SetTextColor (lpItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  1160.     }
  1161. /* change TextColor for new entries too */
  1162. else if ((((LPVMOBJECT)lpWalkerList)+Objects[lpItem->itemData])->bNew)
  1163.     {
  1164.     dwBkColor = SetBkColor (lpItem->hDC, GetSysColor(COLOR_HIGHLIGHT));
  1165.     dwTextColor = SetTextColor (lpItem->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  1166.     }
  1167. /* make listbox string from virtual memory object */
  1168. nLen = MakeVMQString (lpItem->itemData, szListItem);
  1169.         TextOutFields (lpItem->hDC, 6, &lpItem->rcItem, szListItem);
  1170. /* Restore previous bk and text color if necessary */
  1171. if (dwBkColor != 0xffffffff)
  1172.             SetBkColor(lpItem->hDC, dwBkColor);
  1173. if (dwTextColor != 0xffffffff)
  1174.     SetTextColor(lpItem->hDC, dwTextColor);
  1175.         if (lpItem->itemState & ODS_FOCUS)
  1176.     lpItem->itemAction |= ODA_FOCUS;
  1177. }
  1178.     if (lpItem->itemAction & ODA_FOCUS)
  1179.         DrawFocusRect(lpItem->hDC, &lpItem->rcItem);
  1180. }
  1181. /* perform bubble sort on indexes to virtual memory objects as stored in
  1182.    ownerdraw listbox do not actually sort the objects, just the indexes  */
  1183. void  WINAPI SortList (
  1184.     HWND    hList,
  1185.     int     nSort)
  1186. {
  1187.     int    nItems = SendMessage (hList, LB_GETCOUNT, 0, 0);
  1188.     int    i, j, t;
  1189.     LPVMOBJECT   lpVMO = (LPVMOBJECT)lpWalkerList;
  1190.     /* loop through all items in list box */
  1191.     for (i=0; i<nItems-1; i++)
  1192. for (j=i+1; j<nItems; j++)
  1193.     {
  1194.     /* compare on sort order */
  1195.     switch (nSort)
  1196. {
  1197. case IDM_SORTADDRESS:
  1198.     if (lpVMO[Objects[i]].mbi.BaseAddress > lpVMO[Objects[j]].mbi.BaseAddress)
  1199. {
  1200. /* swap */
  1201. t = Objects[j];
  1202. Objects[j] = Objects[i];
  1203. Objects[i] = t;
  1204. }
  1205.     break;
  1206. case IDM_SORTSTATE:
  1207.     if ((lpVMO[Objects[i]].mbi.State > lpVMO[Objects[j]].mbi.State) ||
  1208. (lpVMO[Objects[i]].mbi.State == lpVMO[Objects[j]].mbi.State &&
  1209.  lpVMO[Objects[i]].mbi.BaseAddress > lpVMO[Objects[j]].mbi.BaseAddress))
  1210. {
  1211. /* swap */
  1212. t = Objects[j];
  1213. Objects[j] = Objects[i];
  1214. Objects[i] = t;
  1215. }
  1216.     break;
  1217. case IDM_SORTPROTECTION:
  1218.     if ((lpVMO[Objects[i]].mbi.Protect > lpVMO[Objects[j]].mbi.Protect) ||
  1219. (lpVMO[Objects[i]].mbi.Protect == lpVMO[Objects[j]].mbi.Protect &&
  1220.  lpVMO[Objects[i]].mbi.BaseAddress > lpVMO[Objects[j]].mbi.BaseAddress))
  1221. {
  1222. /* swap */
  1223. t = Objects[j];
  1224. Objects[j] = Objects[i];
  1225. Objects[i] = t;
  1226. }
  1227.     break;
  1228. case IDM_SORTSIZE:
  1229.     if ((lpVMO[Objects[i]].mbi.RegionSize > lpVMO[Objects[j]].mbi.RegionSize) ||
  1230. (lpVMO[Objects[i]].mbi.RegionSize == lpVMO[Objects[j]].mbi.RegionSize &&
  1231.  lpVMO[Objects[i]].mbi.BaseAddress > lpVMO[Objects[j]].mbi.BaseAddress))
  1232. {
  1233. /* swap */
  1234. t = Objects[j];
  1235. Objects[j] = Objects[i];
  1236. Objects[i] = t;
  1237. }
  1238.     break;
  1239. case IDM_SORTBASEADDRESS:
  1240.     if ((lpVMO[Objects[i]].mbi.AllocationBase > lpVMO[Objects[j]].mbi.AllocationBase) ||
  1241. (lpVMO[Objects[i]].mbi.AllocationBase == lpVMO[Objects[j]].mbi.AllocationBase &&
  1242.  lpVMO[Objects[i]].mbi.BaseAddress > lpVMO[Objects[j]].mbi.BaseAddress))
  1243. {
  1244. /* swap */
  1245. t = Objects[j];
  1246. Objects[j] = Objects[i];
  1247. Objects[i] = t;
  1248. }
  1249.     break;
  1250. }
  1251.     }
  1252. }
  1253. /* get free disk space on all fixed drives */
  1254. BOOL   WINAPI GetFreeDiskSpace (
  1255.     LPDWORD    lpdwTotalSpace,
  1256.     LPDWORD    lpdwFreeSpace)
  1257. {
  1258.     DWORD    dwBytesPerSector, dwSectorsPerCluster, dwFreeClusters, dwTotalClusters;
  1259.     DWORD    dwDriveMask = GetLogicalDrives();
  1260.     int      i;
  1261.     char     szDir[4];
  1262.     *lpdwTotalSpace = 0;
  1263.     *lpdwFreeSpace = 0;
  1264.     szDir[1] = TEXT(':');
  1265.     szDir[2] = TEXT('\');
  1266.     szDir[3] = 0;
  1267.     /* enumerate all logical, fixed drives */
  1268.     for (i = 0; i < MAX_DRIVES; dwDriveMask >>= 1, i++)
  1269. {
  1270. /* if logical drive exists */
  1271. if (dwDriveMask & 0x01)
  1272.     {
  1273.     szDir[0] = TEXT('A') + i;
  1274.     /* if it is a fixed drive */
  1275.     if (GetDriveType(szDir) == DRIVE_FIXED)
  1276. {
  1277. /* determine free space and total capacity */
  1278. GetDiskFreeSpace (szDir,
  1279.   &dwSectorsPerCluster,
  1280.   &dwBytesPerSector,
  1281.   &dwFreeClusters,
  1282.   &dwTotalClusters);
  1283. *lpdwTotalSpace += dwTotalClusters * dwSectorsPerCluster * dwBytesPerSector;
  1284. *lpdwFreeSpace += dwFreeClusters * dwSectorsPerCluster * dwBytesPerSector;
  1285. }
  1286.     }
  1287. }
  1288.     return (*lpdwTotalSpace || *lpdwFreeSpace);
  1289. }
  1290. /* generic message notification */
  1291. int WINAPI NotifyUser (
  1292.     HWND    hWndParent,
  1293.     int     nTitle,
  1294.     int     nError,
  1295.     char    *lpszAppend,
  1296.     UINT    uFlags)
  1297. {
  1298.     char    szError[MAX_PATH];
  1299.     char    szTitle[MAX_PATH];
  1300.     LoadString (GetModuleHandle (NULL), nTitle, szTitle, MAX_PATH);
  1301.     LoadString (GetModuleHandle (NULL), nError, szError, MAX_PATH);
  1302.     if (lpszAppend != NULL && *lpszAppend != 0)
  1303. strcat (szError, lpszAppend);
  1304.     if (!uFlags)
  1305. uFlags = MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND;
  1306.     /* return message box response */
  1307.     return (MessageBox (hWndParent, szError, szTitle, uFlags));
  1308. }
  1309. void   WINAPI ReportError (
  1310.     int     nIDS_CAPTION)
  1311. {
  1312.     char    *lpszError;
  1313.     char    szText[MAX_PATH];
  1314.     /* get formatted error message from system */
  1315.     if (!FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  1316. NULL,
  1317. GetLastError (),
  1318. MAKELONG (MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), 0),
  1319. (LPTSTR)&lpszError,
  1320. 0,
  1321. NULL))
  1322. return;
  1323.     /* if resource string provided, load caption string */
  1324.     if (nIDS_CAPTION)
  1325. LoadString (GetModuleHandle (NULL), nIDS_CAPTION, szText, MAX_PATH);
  1326.     else
  1327. strcpy (szText, "Error");
  1328.     MessageBox (NULL,
  1329. lpszError,
  1330. szText,
  1331. MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
  1332. }
  1333. BOOL WINAPI ViewableMemorySelection (
  1334.     HWND    hWnd)
  1335. {
  1336.     HWND   hList = GetDlgItem (hWnd, IDC_LISTBOX);
  1337.     int    iCaret = SendMessage (hList, LB_GETCARETINDEX, 0, 0);
  1338.     int    iAnchor = SendMessage (hList, LB_GETANCHORINDEX, 0, 0);
  1339.     if (iCaret > -1 &&
  1340. iAnchor > -1 &&
  1341. SendMessage (hList, LB_GETSEL, iCaret, 0) &&
  1342. CommittedMemoryRange (iCaret,
  1343.       iAnchor,
  1344.       (LPVMOBJECT)lpWalkerList,
  1345.       Objects))
  1346. return TRUE;
  1347.     else
  1348. return FALSE;
  1349. }
  1350. BOOL WINAPI InitDlgProc (
  1351.     HWND      hDlg,
  1352.     UINT      uMsg,
  1353.     WPARAM    wParam,
  1354.     LPARAM    lParam)
  1355. {
  1356.     switch (uMsg)
  1357. {
  1358. case WM_INITDIALOG:
  1359.     *(HANDLE *)lParam = hDlg;
  1360.     break;
  1361. case WM_CLOSE:
  1362. case UM_ENDDIALOG:
  1363.     EndDialog (hDlg, TRUE);
  1364.     break;
  1365. case WM_COMMAND:
  1366.     if (LOWORD (wParam) == IDCANCEL ||
  1367. LOWORD (wParam) == IDOK)
  1368. EndDialog (hDlg, TRUE);
  1369.     break;
  1370. default:
  1371.     return FALSE;
  1372. }
  1373.     return TRUE;
  1374. }