All pastes #285391 Raw Edit

kumbayo

public text v1 · immutable
#285391 ·published 2006-12-19 20:30 UTC
rendered paste body
From 9e45225f04f17f4fb5ba448508b82c6b7c78047b Mon Sep 17 00:00:00 2001
From: Peter Oberndorfer <kumbayo84@arcor.de>
Date: Tue, 19 Dec 2006 21:23:34 +0100
Subject: [PATCH] winedbg: remote gdi object debugging

---
 programs/winedbg/dbg.y      |    4 +-
 programs/winedbg/debug.l    |    1 +
 programs/winedbg/debugger.h |    1 +
 programs/winedbg/info.c     |  248 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 253 insertions(+), 1 deletions(-)

diff --git a/programs/winedbg/dbg.y b/programs/winedbg/dbg.y
index 0c225e1..8578543 100644
--- a/programs/winedbg/dbg.y
+++ b/programs/winedbg/dbg.y
@@ -53,7 +53,7 @@ static int dbg_error(const char*);
 %token tCONT tPASS tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tALL tINFO tUP tDOWN
 %token tENABLE tDISABLE tBREAK tHBREAK tWATCH tDELETE tSET tPRINT tEXAM
 %token tABORT tECHO
-%token tCLASS tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tALLREGS tWND tQUEUE tLOCAL tEXCEPTION
+%token tCLASS tGDIOBJ tMAPS tSTACK tSEGMENTS tSYMBOL tREGS tALLREGS tWND tQUEUE tLOCAL tEXCEPTION
 %token tPROCESS tTHREAD tMODREF tEOL tEOF
 %token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY tDISASSEMBLE
 %token tSTEPI tNEXTI tFINISH tSHOW tDIR tWHATIS tSOURCE
@@ -271,6 +271,7 @@ info_command:
     | tINFO tDISPLAY            { display_info(); }
     | tINFO tCLASS              { info_win32_class(NULL, NULL); }
     | tINFO tCLASS tSTRING     	{ info_win32_class(NULL, $3); }
+    | tINFO tGDIOBJ             { info_gdiobj();}
     | tINFO tWND                { info_win32_window(NULL, FALSE); }
     | tINFO tWND expr_rvalue    { info_win32_window((HWND)$3, FALSE); }
     | tINFO '*' tWND            { info_win32_window(NULL, TRUE); }
@@ -281,6 +282,7 @@ info_command:
     | tINFO tEXCEPTION expr_rvalue { info_win32_exceptions($3); }
     | tINFO tMAPS               { info_win32_virtual(dbg_curr_pid); }
     | tINFO tMAPS expr_rvalue   { info_win32_virtual($3); }
+    | tINFO tIDENTIFIER         { dbg_printf("Undefined info command \"%s\", use \"help info\" to get a list\n", $2); }
     ;
 
 maintenance_command:
diff --git a/programs/winedbg/debug.l b/programs/winedbg/debug.l
index 451c96d..847f92b 100644
--- a/programs/winedbg/debug.l
+++ b/programs/winedbg/debug.l
@@ -184,6 +184,7 @@ STRING     \"[^\n"]+\"
 <INFO_CMD>share|shar|sha		{ return tSHARE; }
 <INFO_CMD>locals|local|loca|loc		{ return tLOCAL; }
 <INFO_CMD>class|clas|cla                { return tCLASS; }
+<INFO_CMD>gdiobj|gdi			{ return tGDIOBJ; }
 <INFO_CMD>process|proces|proce|proc   	{ return tPROCESS; }
 <INFO_CMD>threads|thread|threa|thre|thr|th { return tTHREAD; }
 <INFO_CMD>exception|except|exc|ex	{ return tEXCEPTION; }
diff --git a/programs/winedbg/debugger.h b/programs/winedbg/debugger.h
index 6e4c010..e3006d1 100644
--- a/programs/winedbg/debugger.h
+++ b/programs/winedbg/debugger.h
@@ -334,6 +334,7 @@ extern void             info_win32_excep
 extern void             info_win32_virtual(DWORD pid);
 extern void             info_win32_segments(DWORD start, int length);
 extern void             info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);
+extern void             info_gdiobj(void);
 
   /* memory.c */
 extern BOOL             memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result);
diff --git a/programs/winedbg/info.c b/programs/winedbg/info.c
index c5b7b1e..bfaf728 100644
--- a/programs/winedbg/info.c
+++ b/programs/winedbg/info.c
@@ -32,6 +32,139 @@
 #include "tlhelp32.h"
 #include "wine/debug.h"
 
+#define GDI_HEAP_SIZE 0xffe0
+#define GDI_FIRST_LARGE_HANDLE 16
+#define GDI_MAX_LARGE_HANDLES ((GDI_HEAP_SIZE >> 2) - GDI_FIRST_LARGE_HANDLE)
+
+  /* GDI objects magic numbers */
+#define FIRST_MAGIC           0x4f47
+#define PEN_MAGIC             0x4f47
+#define BRUSH_MAGIC           0x4f48
+#define FONT_MAGIC            0x4f49
+#define PALETTE_MAGIC         0x4f4a
+#define BITMAP_MAGIC          0x4f4b
+#define REGION_MAGIC          0x4f4c
+#define DC_MAGIC              0x4f4d
+#define DISABLED_DC_MAGIC     0x4f4e
+#define META_DC_MAGIC         0x4f4f
+#define METAFILE_MAGIC        0x4f50
+#define METAFILE_DC_MAGIC     0x4f51
+#define ENHMETAFILE_MAGIC     0x4f52
+#define ENHMETAFILE_DC_MAGIC  0x4f53
+#define MEMORY_DC_MAGIC       0x4f54
+#define EXT_PEN_MAGIC         0x4f55
+#define LAST_MAGIC            0x4f55
+
+#define MAGIC_DONTCARE	      0xffff
+
+/* GDI constants for making objects private/system (naming undoc. !) */
+#define OBJECT_PRIVATE        0x2000
+#define OBJECT_NOSYSTEM       0x8000
+
+#define GDIMAGIC(magic) ((magic) & ~(OBJECT_PRIVATE|OBJECT_NOSYSTEM))
+
+struct hdc_list
+{
+    HDC hdc;
+    struct hdc_list *next;
+};
+
+typedef struct tagGDIOBJHDR
+{
+    WORD        wMagic;
+    DWORD       dwCount;
+    const struct gdi_obj_funcs *funcs;
+    struct hdc_list *hdcs;
+} GDIOBJHDR;
+
+typedef struct { int opaque; } *PHYSDEV;  /* PHYSDEV is an opaque pointer */
+typedef LRESULT (CALLBACK *FARPROC16)();
+typedef unsigned short  BOOL16;
+typedef unsigned short HDC16;//no idea if this is right
+typedef BOOL16 (CALLBACK *DCHOOKPROC)(HDC16,WORD,DWORD,LPARAM);
+typedef struct tagDC
+{
+    GDIOBJHDR    header;
+    HDC          hSelf;            /* Handle to this DC */
+    const struct tagDC_FUNCS *funcs; /* DC function table */
+    PHYSDEV      physDev;         /* Physical device (driver-specific) */
+    INT          saveLevel;
+    HDC          saved_dc;
+    DWORD        dwHookData;
+    FARPROC16    hookProc;         /* the original SEGPTR ... */
+    DCHOOKPROC   hookThunk;        /* ... and the thunk to call it */
+
+    INT          wndOrgX;          /* Window origin */
+    INT          wndOrgY;
+    INT          wndExtX;          /* Window extent */
+    INT          wndExtY;
+    INT          vportOrgX;        /* Viewport origin */
+    INT          vportOrgY;
+    INT          vportExtX;        /* Viewport extent */
+    INT          vportExtY;
+    FLOAT        miterLimit;
+
+    int           flags;
+    DWORD         layout;
+    HRGN          hClipRgn;      /* Clip region (may be 0) */
+    HRGN          hMetaRgn;      /* Meta region (may be 0) */
+    HRGN          hMetaClipRgn;  /* Intersection of meta and clip regions (may be 0) */
+    HRGN          hVisRgn;       /* Visible region (must never be 0) */
+    HPEN          hPen;
+    HBRUSH        hBrush;
+    HFONT         hFont;
+    HBITMAP       hBitmap;
+    HANDLE        hDevice;
+    HPALETTE      hPalette;
+
+//     GdiFont      *gdiFont;
+//     GdiPath       path;
+// 
+//     WORD          ROPmode;
+//     WORD          polyFillMode;
+//     WORD          stretchBltMode;
+//     WORD          relAbsMode;
+//     WORD          backgroundMode;
+//     COLORREF      backgroundColor;
+//     COLORREF      textColor;
+//     COLORREF      dcBrushColor;
+//     COLORREF      dcPenColor;
+//     short         brushOrgX;
+//     short         brushOrgY;
+// 
+//     WORD          textAlign;         /* Text alignment from SetTextAlign() */
+//     INT           charExtra;         /* Spacing from SetTextCharacterExtra() */
+//     INT           breakExtra;        /* breakTotalExtra / breakCount */
+//     INT           breakRem;          /* breakTotalExtra % breakCount */
+//     INT           MapMode;
+//     INT           GraphicsMode;      /* Graphics mode */
+//     ABORTPROC     pAbortProc;        /* AbortProc for Printing */
+//     ABORTPROC16   pAbortProc16;
+//     INT           CursPosX;          /* Current position */
+//     INT           CursPosY;
+//     INT           ArcDirection;
+//     XFORM         xformWorld2Wnd;    /* World-to-window transformation */
+//     XFORM         xformWorld2Vport;  /* World-to-viewport transformation */
+//     XFORM         xformVport2World;  /* Inverse of the above transformation */
+//     BOOL          vport2WorldValid;  /* Is xformVport2World valid? */
+//     RECT          BoundsRect;        /* Current bounding rect */
+// 
+//     struct saved_visrgn *saved_visrgn;
+} DC;
+
+typedef struct tagBITMAPOBJ
+{
+    GDIOBJHDR           header;
+    BITMAP              bitmap;
+    SIZE                size;   /* For SetBitmapDimension() */
+    const struct DC_FUNCTIONS *funcs; /* DC function table */
+    /* For device-independent bitmaps: */
+    DIBSECTION         *dib;
+//     SEGPTR              segptr_bits;  /* segptr to DIB bits */
+//     RGBQUAD            *color_table;  /* DIB color table if <= 8bpp */
+//     UINT                nb_colors;    /* number of colors in table */
+} BITMAPOBJ;
+
 WINE_DEFAULT_DEBUG_CHANNEL(winedbg);
 
 /***********************************************************************
@@ -730,3 +863,118 @@ void info_wine_dbg_channel(BOOL turn_on,
     if (!done) dbg_printf("Unable to find debug channel %s\n", name);
     else WINE_TRACE("Changed %d channel instances\n", done);
 }
+
+static const char * magic_to_text(WORD magic)
+{
+    static char buffer[50];
+    switch(magic)
+    {
+    case PEN_MAGIC:             return "PEN            ";
+    case BRUSH_MAGIC:           return "BRUSH          ";
+    case FONT_MAGIC:            return "FONT           ";
+    case PALETTE_MAGIC:         return "PALETTE        ";
+    case BITMAP_MAGIC:          return "BITMAP         ";
+    case REGION_MAGIC:          return "REGION         ";
+    case DC_MAGIC:              return "DC             ";
+    case DISABLED_DC_MAGIC:     return "DISABLED_DC    ";
+    case META_DC_MAGIC:         return "META_DC        ";
+    case METAFILE_MAGIC:        return "PENMETAFILE    ";
+    case METAFILE_DC_MAGIC:     return "METAFILE_DC    ";
+    case ENHMETAFILE_MAGIC:     return "ENHMETAFILE    ";
+    case ENHMETAFILE_DC_MAGIC:  return "ENHMETAFILE_DC ";
+    case MEMORY_DC_MAGIC:       return "MEMORY_DC      ";
+    case EXT_PEN_MAGIC:         return "EXT_PEN        ";
+    default:
+        sprintf(buffer, "unknown 0x%02x  ", magic);
+        return buffer;
+    }
+}
+
+void info_dc(DC* dc)
+{
+    /* for now only print the bitmap brush font and palette */
+    dbg_printf("hBitmap %p", dc->hBitmap);
+    dbg_printf(" hPen %p hBrush %p hFont %p hPalette %p", dc->hPen, dc->hBrush, dc->hFont, dc->hPalette);
+}
+
+void info_bitmap(BITMAPOBJ* bmp)
+{
+    /* for now only print the bitmap size */
+    dbg_printf("Size: %d x %d, %d Bit", bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, bmp->bitmap.bmBitsPixel);
+}
+
+
+void info_gdiobj(void)
+{
+    void*                       addr;
+    GDIOBJHDR*                  local[GDI_MAX_LARGE_HANDLES];
+    int                         i;
+    SYMBOL_INFO                 sym;
+
+    sym.SizeOfStruct = sizeof(sym);
+    sym.MaxNameLen = 0;
+
+    if(!SymFromName(dbg_curr_process->handle, "gdi32!large_handles", &sym))
+    {
+        dbg_printf("Could not get table of GDI objects in target process\n");
+        return;
+    }
+    addr = (void *) sym.Address;
+    dbg_printf("\narray   handle  pointer  type            count\n");
+
+    dbg_read_memory(addr, &local, sizeof(local));
+    for(i = 0; i < GDI_MAX_LARGE_HANDLES; i++)
+    {
+        if(local[i] != 0)
+        {//i = ((UINT_PTR)handle >> 2) - FIRST_LARGE_HANDLE
+            GDIOBJHDR tmp;
+            dbg_printf("0x%04x, 0x%04x, %p ", i, (i + GDI_FIRST_LARGE_HANDLE)<<2, local[i]);
+            if(dbg_read_memory(local[i], &tmp, sizeof(tmp)))
+            {
+                dbg_printf("%s", magic_to_text(GDIMAGIC(tmp.wMagic)));
+//                 printf("magic: 0x%x ", GDIMAGIC(tmp.wMagic));
+                dbg_printf("%2d ", tmp.dwCount & ~0x80000000);
+                if(tmp.wMagic & OBJECT_PRIVATE)
+                    dbg_printf("private ");
+                if(tmp.wMagic & OBJECT_NOSYSTEM)
+                    dbg_printf("nosystem ");
+                if(tmp.dwCount & 0x80000000)
+                    dbg_printf("(marked for deletion)");
+//                 dbg_printf("funcs: 0x%x ", tmp.funcs);
+                if(tmp.hdcs)
+                {
+                    struct hdc_list tmp_list;
+                    dbg_printf("hdcs: ");
+                    dbg_read_memory(tmp.hdcs, &tmp_list, sizeof(tmp_list));
+                    while(tmp_list.next)
+                    {
+                        printf("0x%04x ", tmp_list.hdc);
+                        dbg_read_memory(tmp_list.next, &tmp_list, sizeof(tmp_list));
+                    }
+                }
+                if(GDIMAGIC(tmp.wMagic) == DC_MAGIC ||
+                   GDIMAGIC(tmp.wMagic) == MEMORY_DC_MAGIC)
+                {
+                    DC dc_tmp;
+                    if(dbg_read_memory(local[i], &dc_tmp, sizeof(dc_tmp)))
+                        info_dc(&dc_tmp);
+                    else
+                        dbg_printf("could not read DC memory\n");
+                }
+                else if (GDIMAGIC(tmp.wMagic) == BITMAP_MAGIC)
+                {
+                    BITMAPOBJ bmp_tmp;
+                    if(dbg_read_memory(local[i], &bmp_tmp, sizeof(bmp_tmp)))
+                        info_bitmap(&bmp_tmp);
+                    else
+                        dbg_printf("could not read BITMAP memory\n");
+                }
+                dbg_printf("\n");
+            }
+            else
+                dbg_printf("unreadable???\n");
+        }
+
+    }
+}
+
-- 
1.4.4