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