home *** CD-ROM | disk | FTP | other *** search
/ Windows Graphics Programming / Feng_Yuan_Win32_GDI_DirectX.iso / Samples / Chapt_03 / Fosterer / Fosterer.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-30  |  13.4 KB  |  571 lines

  1. //-----------------------------------------------------------------------------------//
  2. //              Windows Graphics Programming: Win32 GDI and DirectDraw               //
  3. //                             ISBN  0-13-086985-6                                   //
  4. //                                                                                   //
  5. //  Written            by  Yuan, Feng                             www.fengyuan.com   //
  6. //  Copyright (c) 2000 by  Hewlett-Packard Company                www.hp.com         //
  7. //  Published          by  Prentice Hall PTR, Prentice-Hall, Inc. www.phptr.com      //
  8. //                                                                                   //
  9. //  FileName   : fosterer.cpp                                                         //
  10. //  Description: Hosting program for WinDBG debugger extension, Chapter 3            //
  11. //  Version    : 1.00.000, May 31, 2000                                              //
  12. //-----------------------------------------------------------------------------------//
  13.  
  14. #define STRICT
  15. #define WIN32_LEAN_AND_MEAN
  16.  
  17. #include <windows.h>
  18. #include <assert.h>
  19. #include <tchar.h>
  20. #include <imagehlp.h> 
  21. #include <richedit.h>
  22. #include <stdio.h>
  23. #include <commctrl.h>
  24. #include <wdbgexts.h>
  25.  
  26. #include "Extension.h"
  27. #include "Host.h"
  28. #include "ImageModule.h"
  29. #include "win.h"
  30. #include "resource.h"
  31. #include "memdump.h"
  32.  
  33. class KLogWindow : public KWindow
  34. {
  35.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  36.  
  37.     HINSTANCE m_hInst;
  38.     HWND      m_Output;
  39.  
  40.     void GetWndClassEx(WNDCLASSEX & wc)
  41.     {
  42.         KWindow::GetWndClassEx(wc);
  43.         wc.hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_SPY));
  44.     }
  45.  
  46. public:
  47.     KLogWindow(HINSTANCE hInst)
  48.     {
  49.         m_hInst   = hInst;
  50.     }
  51.  
  52.     void Dump(const char * cmd);
  53. };
  54.  
  55.  
  56. void KLogWindow::Dump(const char * cmd)
  57. {
  58.     if ( cmd==NULL )
  59.         return;
  60.  
  61.     //    ReadKRam(%08x, %d)
  62.     //  ReadURam(%x, %08x, %d)
  63.  
  64.     unsigned addr;
  65.     unsigned process;
  66.     int         length, len;
  67.     char   * buffer;
  68.     const char * p;
  69.  
  70.     if ( strncmp(cmd, "ReadKRam", 8)==0 )
  71.     {
  72.         p = strchr(cmd, '(') + 1; sscanf(p, "%x", & addr);
  73.         p = strchr(cmd, ',') + 1; sscanf(p, "%d", & length);
  74.  
  75.         assert( addr>=0x80000000 );
  76.         assert( length>0 );
  77.  
  78.         len = (length+15)/16*16;
  79.         buffer = new char[len];
  80.         assert( buffer );
  81.         memset(buffer, 0, len);
  82.         
  83.         theHost.pScope->Read(buffer, (const void *) addr, length);
  84.     }
  85.     else if ( strncmp(cmd, "ReadURam", 8)==0 )
  86.     {
  87.         p = strchr(cmd, '(') + 1; sscanf(p, "%x", & process);
  88.         p = strchr(p,   ',') + 1; sscanf(p, "%x", & addr);
  89.         p = strchr(p,   ',') + 1; sscanf(p, "%d", & length);
  90.  
  91.         len = (length+15)/16*16;
  92.  
  93.         buffer = new char[len];
  94.         assert(buffer);
  95.         memset(buffer, 0, len);
  96.         DWORD dwRead;
  97.         ReadProcessMemory((HANDLE) process, (const void *) addr, buffer, length, & dwRead);
  98.     }
  99.  
  100.     if ( buffer )
  101.     {
  102.         KMemDump dump;
  103.  
  104.         dump.OpenDump();
  105.         dump.Dump((unsigned char *)buffer, addr - (unsigned) buffer, length, 4);
  106.         dump.CloseDump();
  107.  
  108. //        if ( length==1548 )
  109. //        {
  110. //            TestDCObj(buffer);
  111. //        }
  112.         
  113.         delete [] buffer;
  114.     }
  115. }
  116.  
  117.  
  118. LRESULT KLogWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  119. {
  120.     switch( uMsg )
  121.     {
  122.         case WM_CREATE:
  123.         {
  124.             RECT rect;
  125.  
  126.             m_hWnd  = hWnd;
  127.             
  128.             GetClientRect(m_hWnd, & rect);
  129.  
  130.             m_Output = CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, NULL, 
  131.                 WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL |
  132.                 ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN,
  133.                 0, 0, rect.right, rect.bottom,
  134.                 m_hWnd, (HMENU) 101, m_hInst, NULL);
  135.  
  136.             SendMessage(m_Output, EM_LIMITTEXT, 1024 * 1024, 0);
  137.             SendMessage(m_Output, WM_SETFONT, (WPARAM) GetStockObject(ANSI_FIXED_FONT), FALSE);;
  138.  
  139.             theHost.hwndLog = m_Output;
  140.         }
  141.         return 0;
  142.  
  143.         case WM_PARENTNOTIFY:
  144.             if ( LOWORD(wParam)==WM_RBUTTONDOWN )
  145.             {
  146.                 char buffer[MAX_PATH];
  147.  
  148.                 buffer[0] =0 ;
  149.                 SendMessage(m_Output, EM_GETSELTEXT, 0, (LPARAM) & buffer);
  150.                 Dump(buffer);
  151.             }
  152.             return 0;
  153.         
  154.         case WM_SIZE:
  155.         {
  156.             int width       = LOWORD(lParam);
  157.             int height       = HIWORD(lParam);
  158.     
  159.             MoveWindow(m_Output, 0, 0, width, height, TRUE);
  160.         }
  161.         return 0;
  162.     }
  163.  
  164.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
  165. };
  166.  
  167.  
  168. class KMainWindow : public KWindow
  169. {
  170.     virtual LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  171.  
  172.     HWND      m_Output;
  173.     HWND      m_Command;
  174.     HWND      m_Action;
  175.     HWND      m_Pid;
  176.  
  177.     DWORD      m_curPid;
  178.     HANDLE      m_curProcess;
  179.  
  180.     HINSTANCE m_hInst;
  181.  
  182.     void GetWndClassEx(WNDCLASSEX & wc)
  183.     {
  184.         KWindow::GetWndClassEx(wc);
  185.         wc.hbrBackground = GetSysColorBrush(COLOR_MENU);
  186.         wc.hIcon         = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_SPY));
  187.     }
  188.  
  189. public:
  190.  
  191.     KGDIExtension gdi;
  192.     
  193.     KMainWindow(HINSTANCE hInst)
  194.     {
  195.         m_hInst   = hInst;
  196.         
  197.         m_Output  = NULL;
  198.         m_Command = NULL;
  199.         m_Action  = NULL;
  200.         m_Pid     = NULL;
  201.     }
  202.  
  203.     HANDLE GetProcess(void);
  204. };
  205.  
  206.  
  207. HANDLE KMainWindow::GetProcess(void)
  208. {
  209.     char sPid[64];
  210.     DWORD nPid;
  211.  
  212.     GetWindowText(m_Pid, sPid, sizeof(sPid));
  213.     sscanf(sPid, "%x", & nPid);
  214.  
  215.     if ( nPid != m_curPid )
  216.     {
  217.         HANDLE hProcess = OpenProcess(PROCESS_VM_READ, FALSE, nPid);
  218.  
  219.         if ( hProcess == NULL )
  220.         {
  221.             wsprintf(sPid, "Unable to open process %x", nPid);
  222.             MyMessageBox(NULL, sPid, "Fosterer", MB_OK, IDI_SPY);
  223.         }
  224.         else
  225.         {
  226.             CloseHandle(m_curProcess);
  227.  
  228.             m_curPid = nPid;
  229.             m_curProcess = hProcess;
  230.         }
  231.     }
  232.  
  233.     return m_curProcess;
  234. }
  235.  
  236.  
  237. LRESULT KMainWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  238. {
  239.     switch( uMsg )
  240.     {
  241.         case WM_CREATE:
  242.             {
  243.                 RECT rect;
  244.  
  245.                 m_hWnd  = hWnd;
  246.             
  247.                 GetClientRect(m_hWnd, & rect);
  248.  
  249.                 int textheight = GetSystemMetrics(SM_CYSIZE) * 13 / 10;
  250.  
  251.                 m_curPid     = GetCurrentProcessId();
  252.                 m_curProcess = GetCurrentProcess();
  253.  
  254.                 char id[32];
  255.                 wsprintf(id, "%x", m_curPid);
  256.                 
  257.                 m_Pid  = CreateWindowEx(0, "EDIT", id,
  258.                     WS_CHILD | WS_VISIBLE | WS_BORDER,
  259.                     8, 0, 80, textheight,
  260.                     m_hWnd, NULL, m_hInst, NULL);
  261.  
  262.                 m_Action  = CreateWindowEx(0, "BUTTON", "Do",
  263.                     WS_CHILD | WS_VISIBLE | WS_BORDER,
  264.                     100, 0, 80, textheight,
  265.                     m_hWnd, (HMENU) IDOK, m_hInst, NULL);
  266.  
  267.                 m_Command = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, 
  268.                     WS_CHILD | WS_VISIBLE | WS_BORDER, 
  269.                     200, 0, rect.right - 200, textheight, 
  270.                     m_hWnd, NULL, m_hInst, NULL);
  271.                 assert(m_Command);
  272.  
  273.                 m_Output = CreateWindowEx(WS_EX_CLIENTEDGE, RICHEDIT_CLASS, NULL, 
  274.                     WS_CHILD | WS_VISIBLE | WS_BORDER | WS_HSCROLL | WS_VSCROLL |
  275.                     ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN,
  276.                     0, textheight + 1, rect.right, rect.bottom - textheight - 1,
  277.                     m_hWnd, NULL, m_hInst, NULL);
  278.  
  279.                 assert(m_Output);
  280.                 SendMessage(m_Output, WM_SETFONT, (WPARAM) GetStockObject(ANSI_FIXED_FONT), FALSE);;
  281.  
  282.                 theHost.hwndOutput = m_Output; 
  283.             }
  284.             return 0;
  285.  
  286.         case WM_SIZE:
  287.             {
  288.                 int width       = LOWORD(lParam);
  289.                 int height       = HIWORD(lParam);
  290.                 int textheight = GetSystemMetrics(SM_CYSIZE) * 13 / 10;
  291.  
  292.                 MoveWindow(m_Pid,      10, 0,            80,          textheight, FALSE);
  293.                 MoveWindow(m_Action,  100, 0,            80,          textheight, FALSE);
  294.                 MoveWindow(m_Command, 200, 0,            width - 200, textheight, TRUE);
  295.                 MoveWindow(m_Output,  0,   textheight+1, width,       height - textheight-1, TRUE);
  296.             }
  297.             return 0;
  298.  
  299.         case WM_PAINT:
  300.             {
  301.                 PAINTSTRUCT ps; 
  302.                 
  303.                 BeginPaint(m_hWnd, &ps);
  304.                 EndPaint(m_hWnd, &ps);
  305.             }
  306.             return 0;
  307.  
  308.         case WM_COMMAND:
  309.                 
  310.  
  311.             switch ( LOWORD(wParam) )
  312.             {
  313.                 case IDOK:
  314.                     {
  315.                         char text[MAX_PATH];
  316.  
  317.                         GetWindowText(m_Command, text, sizeof(text));
  318.  
  319.                         gdi.SetProcess(GetProcess());
  320.                         gdi.Do(text);
  321.                     }
  322.                     return 0;
  323.  
  324.                 case ID_EXIT:
  325.                     DestroyWindow(hWnd);
  326.                     return 0;
  327.  
  328.                 case ID_HELP_GDIKDX:
  329.                     gdi.Do("help");
  330.                     return 0;
  331.  
  332.                 case ID_HELP_DUMPHMGR:
  333.                     gdi.Do("dumphmgr -?");
  334.                     return 0;
  335.  
  336.                 case ID_HELP_DUMPOBJ:
  337.                     gdi.Do("dumpobj -?");
  338.                     return 0;
  339.  
  340.                 case ID_CMD_DUMPHMGR:
  341.                     gdi.Do("dumphmgr");
  342.                     return 0;
  343.  
  344.                 case ID_CMD_DUMPOBJ:
  345.                     gdi.Do("dumpobj");
  346.                     return 0;
  347.  
  348.                 case ID_CMD_DPDEV:
  349.                     gdi.Do("dpdev");
  350.                     return 0;
  351.  
  352.                 case ID_CMD_DLDEV:
  353.                     gdi.Do("dldev");
  354.                     return 0;
  355.  
  356.                 case ID_CMD_DGDEV:
  357.                     gdi.Do("dgdev");
  358.                     return 0;
  359.             }
  360.             break;
  361.  
  362.         case WM_DESTROY:
  363.             PostQuitMessage(0);
  364.             return 0;
  365.     }
  366.  
  367.     return DefWindowProc(hWnd, uMsg, wParam, lParam);
  368. }
  369.  
  370.  
  371. // 8x8 24-bit DIB
  372. typedef struct
  373. {
  374.     BITMAPINFOHEADER bmiHeader; 
  375.     unsigned char    bmiBits[8*3*8];
  376. }  CSmallDib;
  377.  
  378.  
  379. // 8x8 24 bit DIB
  380. const CSmallDib dib = 
  381.     { sizeof(BITMAPINFOHEADER), 8, 8, 1, 24,  BI_RGB, 8*3*8, 0, 0, 0, 0 }, 
  382.  
  383.     {   0,0,0, 1,1,1, 2,2,2, 3,3,3, 4,4,4, 5,5,5, 6,6,6, 7,7,7,
  384.         1,1,1, 2,2,2, 3,3,3, 4,4,4, 5,5,5, 6,6,6, 7,7,7, 0,0,0, 
  385.         2,2,2, 3,3,3, 4,4,4, 5,5,5, 6,6,6, 7,7,7, 0,0,0, 1,1,1, 
  386.         3,3,3, 4,4,4, 5,5,5, 6,6,6, 7,7,7, 0,0,0, 1,1,1, 2,2,2, 
  387.         4,4,4, 5,5,5, 6,6,6, 7,7,7, 0,0,0, 1,1,1, 2,2,2, 3,3,3, 
  388.         5,5,5, 6,6,6, 7,7,7, 0,0,0, 1,1,1, 2,2,2, 3,3,3, 4,4,4, 
  389.         6,6,6, 7,7,7, 0,0,0, 1,1,1, 2,2,2, 3,3,3, 4,4,4, 5,5,5, 
  390.         7,7,7, 0,0,0, 1,1,1, 2,2,2, 3,3,3, 4,4,4, 5,5,5, 6,6,6 
  391.     }
  392. };
  393.  
  394.  
  395. long FIXARRAY[] =
  396. {
  397.           0x00000630, 0xfffffff8, 
  398.           0x00000630, 0xfffffc89, 
  399.           0x00000368, 0xfffff9c0, 
  400.           0xfffffff8, 0xfffff9c0, 
  401.           0xfffffc88, 0xfffff9c0, 
  402.           0xfffff9c0, 0xfffffc89, 
  403.           0xfffff9c0, 0xfffffff8, 
  404.           0xfffff9c0, 0x00000367, 
  405.           0xfffffc88, 0x00000630, 
  406.           0xfffffff8, 0x00000630, 
  407.           0x00000368, 0x00000630, 
  408.           0x00000630, 0x00000367, 
  409.           0x00000630, 0xfffffff8 
  410. };
  411.  
  412.  
  413. const POINT Points[3] = { {200, 50}, {250, 150}, {300, 50} };
  414.  
  415.  
  416. void GDITest(void)
  417. {
  418.     ENUMLOGFONTEXW enumlog;
  419.     EXTLOGFONTW extlog;
  420.     
  421.     memset(& enumlog, 0, sizeof(enumlog));
  422.     memset(& extlog, 0, sizeof(extlog));
  423.  
  424.     int j = sizeof(enumlog);
  425.     int k = sizeof(extlog);
  426.     
  427.     for (int i=0; i<sizeof(FIXARRAY)/sizeof(long); i++)
  428.     {
  429.         char t[20];
  430.  
  431.         long v = FIXARRAY[i];
  432.  
  433.         if ( v >= 0)
  434.             t[0] = '+';
  435.         else
  436.         {
  437.             t[0] = '-';
  438.             v = - v;
  439.         }
  440.  
  441.         sprintf(t+1, "%d + %d/16\n", v/16, v%16);
  442.         OutputDebugString(t);
  443.     }
  444.  
  445.     HDC hDC = GetDC(NULL);
  446.     
  447.     HBITMAP bmp1 = CreateBitmap(100, 100, 1, 1, NULL);
  448.     HBITMAP bmp2 = CreateBitmap(100, 100, 1, 4, NULL);
  449.     HBITMAP bmp3 = CreateBitmap(100, 100, 1, 8, NULL);
  450.     HBITMAP bmp4 = CreateBitmap(100, 100, 3, 8, NULL);
  451.     HBITMAP bmp5 = CreateBitmap(100, 100, 1, 24, NULL);
  452.  
  453.     void * dibbits;
  454.  
  455.     HBITMAP bmp6 = CreateDIBSection(hDC, (BITMAPINFO *) & dib, 
  456.                         DIB_RGB_COLORS, & dibbits, NULL, 0);
  457.  
  458.     BeginPath(hDC);
  459.     MoveToEx(hDC, 100, 100, NULL);
  460.     LineTo(hDC, 150, 150);
  461.     PolyBezierTo(hDC, & Points[0], 3);
  462.     CloseFigure(hDC);
  463.     Ellipse(hDC, -100, -100, 100, 100);
  464.     EndPath(hDC);
  465.     POINT points[20];
  466.     BYTE  types[20];
  467.  
  468.     int n = GetPath(hDC, NULL, NULL, 0);
  469.     n = GetPath(hDC, points, types, min(n, 20));
  470.  
  471.     SetBitmapDimensionEx(bmp1, 10000, 10000, NULL);
  472. }
  473.  
  474. void GetFullName(HINSTANCE hInstance, const TCHAR * module, TCHAR fullname[])
  475. {
  476.     GetModuleFileName(hInstance, fullname, MAX_PATH);
  477.  
  478.     TCHAR * pName = fullname;
  479.  
  480.     while ( _tcschr(pName, ':') || _tcschr(pName, '\\') )
  481.         if ( _tcschr(pName, ':') )
  482.             pName = _tcschr(pName, ':') + 1;
  483.         else
  484.             pName = _tcschr(pName, '\\') + 1;
  485.  
  486.     if ( pName )
  487.         _tcscpy(pName, module);
  488. }
  489.  
  490.  
  491. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmd, int nShow)
  492. {
  493.     if ( LoadLibrary("RICHED20.DLL")==NULL )
  494.     {
  495.         MyMessageBox(NULL, "Unable to load RICHED20.DLL", "Fosterer", MB_OK, IDI_SPY);
  496.         return -1;
  497.     }
  498.     
  499.     KMainWindow win(hInst);
  500.     KLogWindow  log(hInst);
  501.     
  502.     log.CreateEx(0, "LogWindow", "LogWindow",
  503.                  WS_OVERLAPPEDWINDOW,
  504.                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  505.                  NULL, NULL, hInst);
  506.     log.ShowWindow(nShow);
  507.     log.UpdateWindow();
  508.  
  509.     win.CreateEx(0, "Fosterer", "Fosterer",
  510.                  WS_OVERLAPPEDWINDOW,
  511.                  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 
  512.                  NULL, LoadMenu(hInst, MAKEINTRESOURCE(IDR_MAIN)), hInst);
  513.         
  514.     win.ShowWindow(nShow);
  515.     win.UpdateWindow();
  516.  
  517.     KPeriscopeClient scope("PeriScope");
  518.     KImageModule     win32k;
  519.  
  520.     TCHAR fullname[MAX_PATH];
  521.     GetFullName(hInst, "periscope.sys", fullname);
  522.  
  523.     if ( scope.Load(fullname)==ERROR_SUCCESS )
  524.     {
  525.         theHost.ExtOutput("Periscope loaded\n");
  526.  
  527.         try
  528.         {
  529.             char SysDir[MAX_PATH];
  530.  
  531.             GetSystemDirectory(SysDir, sizeof(SysDir)); // c:\winnt\system32
  532.  
  533.             char * p = strchr(SysDir, '\\');   // first '\\'
  534.             while ( p && strchr(p+1, '\\') )   // last '\\'    
  535.                 p = strchr(p+1, '\\');
  536.  
  537.             if ( p )                           // c:\winnt
  538.                 * p = NULL;
  539.  
  540.             strcat(SysDir, "\\symbols\\sys");
  541.  
  542.             if ( win32k.Load("win32k.sys", SysDir) )
  543.             {
  544.                 theHost.pWin32k = & win32k;
  545.                 theHost.pScope  = & scope;
  546.     
  547.                 if ( ! win.gdi.Load(& ExtensionAPI, "gdikdx.dll") )
  548.                     MyMessageBox(NULL, "Unable to load GDI kernel extension GDIKDX.DLL.\n", "Fosterer", MB_OK, IDI_SPY);
  549.             }
  550.             else
  551.                 MyMessageBox(NULL, "Unable to load win32k.sys debug information", "Fosterer", MB_OK, IDI_SPY);
  552.         }
  553.         catch (...)
  554.         {
  555.             OutputDebugString("Exception in WinMain");
  556.         }
  557.     }
  558.     else
  559.         MyMessageBox(NULL, fullname, "Unable to load kernel mode driver", MB_OK, IDI_SPY);
  560.  
  561.     win.MessageLoop();
  562.  
  563.     DestroyWindow(log.m_hWnd);
  564.  
  565.     scope.Close();
  566.  
  567.     return 0;
  568. }
  569.  
  570.