From Andy's Bookshelf: WinDbg Extension for GDI
The NT Insider, Vol 5, Issue 1, Jan-Feb 1998 | Published: 15-Feb-98| Modified: 31-Oct-02
There’s a lot of snow on the ground, its cold outside and it’s raining. If we went outside today, we’d just get wet. Mom wouldn’t be happy about us coming back in with our snow pants soaked all the way through after ten minutes. And the snow would be mushy, anyway. So, instead, we go upstairs and meander through the Bookshelf. When what to our wondering eyes should appear (sorry, guess the season got the best of me), we find a small, ochre colored (or colored) tome emblazoned with a swirly and flowery script – "The Tale of the Kinda Secret WINDBG Extension for GDI". Well, this has certainly gained a little of our attention, so I remove the book from the shelf, dust it off, and gingerly open it.
We half cover our eyes from the glare of the printed words Not Supported that pulse at us from the opening page. It’s nothing that we haven’t seen before, so we confidently continue. We’re mesmerized by the some of the section titles : "Who’s Who in DC", "What GDI Heard When You Said DrvEnablePDEV", "Partial Exposure – The GDI PDEV", and "The Joy of Fonts".
This unsupported kernel extension, which is supplied with the DDK, has what looks like an abundance of GDI debug helper elves. So, maybe we can peek inside the GDI a little bit and check out what is going on. But we must remember that this extension isn’t really around to help get object information from structures in your DDI (because WINDBG does that for you in the Locals windows), but for the GDI structures. Thus, debugging client problems or debugging a client that makes problems for the DDI is the name of the game here.
So, I boot up my used Banana Jr. 2000 (which is totally unsupported) with a checked build (because I know that this extension will not work properly with a free build) and I coerce WINDBG to start up. I bring up regedt32 just for grins and than bang a bunch of ^C’s in the command window to get WINDBG to pay attention to me.
We break, I load the extension (gdikdx.dll) and then type the always helpful !help command, and we get a list of some of the available commands.
KDx86> !load gdikdx Debugger extension library [gdikdx] loaded KDx86> !help *** Extension DLL(1367 Free) does not match target system(1381 Free) ======================================================================= GDIEXTS server debugger extentions: -------------------------------------------------------------------- - general extensions - dumphmgr -- handle manager objects dumpobj [-p pid] [type] -- all objects of specific type dh [object handle] -- HMGR entry of handle dht [object handle] -- handle type/uniqueness/index ddc [DC handle] -- DC obj (ddc -? for more info) dpdev [PDEV ptr] -- PDEV object (dpdev -? for more info) dldev [LDEV ptr] – LDEV dco [CLIPOBJ ptr] – CLIPOBJ dpo [PATHOBJ ptr] – PATHOBJ dppal [EPALOBJ ptr] – EPALOBJ dpbrush [BRUSH ptr] – BRUSH dpsurf [SURFACE ptr] – SURFACE dpso [SURFOBJ ptr] -- SURFACE struct from SURFOBJ dblt [BLTRECORD ptr] – BLTRECORD dr [REGION ptr] – REGION cr [REGION ptr] -- check REGION dddsurface [EDD_SURFACE ptr] -- EDD_SURFACE dddlocal [EDD_DIRECTDRAW_LOCAL ptr] -- EDD_DIRECTDRAW_LOCAL ddglobal [EDD_DIRECTDRAW_GLOBAL ptr] -- EDD_DIRECTDRAW_GLOBAL rgnlog nnn -- last nnn rgnlog entries stats -- accumulated statistics hdc HDC [-?gltf] dcl DCLEVEL* dca DC_ATTR* ca COLORADJUSTMENT* mx MATRIX* la LINEATTRS* ef EFLOAT* [count] mx MATRIX* - font extensions - tstats gs FD_GLYPHSET* gdata GLYPHDATA* elf EXTLOGFONTW* tm TEXTMETRICW* tmwi TMW_INTERNAL* helf HFONT ifi IFIMETRICS* fo RFONT* [-?axedtrfmoculhw] pfe PFE* pff PFF* pft PFT* stro STROBJ* [-?pheo] gb GLYPHBITS* [-?gh] gdf GLYPHDEF* gp GLYPHPOS* cache CACHE* fh FONTHASH* hb HASHBUCKET* pubft -- dumps all PUBLIC fonts devft -- dumps all DEVICE fonts dispcache -- dumps glyph cache for display PDEV client side extensions clihelp
It looks like there’s lots of neat stuff that can be obtained. But our initial joy is tempered by the footnote that says that the !stats command doesn’t seem to work properly, and the !clihelp is non-existent.
No matter. I start up Explorer and I note that its PID is 0x68. First thing I do, however, is check out a catalog of all of the GDI objects that are currently active, using the !dumphmgr command.
KDx86> !dumphmgr *** Extension DLL(1367 Free) does not match target system(1381 Checked) Max handles out so far 339 handles, (objects) TYPE current maximum allocated LookAside LAB Cur LAB Max DEF_TYPE 13, 0 - 0, 0 - 0, 0 - 0 - 0 0 DC_TYPE 41, 0 - 0, 0 - 0, 0 - 0 - 0 0 DD_DRAW_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 DD_SURF_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 RGN_TYPE 25, 0 - 0, 0 - 0, 0 - 0 - 0 0 SURF_TYPE 88, 0 - 0, 0 - 0, 0 - 0 - 0 0 CLIOBJ_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 PATH_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 PAL_TYPE 7, 0 - 0, 0 - 0, 0 - 0 - 0 0 ICMLCS_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 LFONT_TYPE 45, 0 - 0, 0 - 0, 0 - 0 - 0 0 RFONT_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 PFE_TYPE 62, 0 - 0, 0 - 0, 0 - 0 - 0 0 PFT_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 ICMCXF_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 ICMDLL_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 BRUSH_TYPE 58, 0 - 0, 0 - 0, 0 - 0 - 0 0 PFF_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 CACHE_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 SPACE_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 DBRUSH_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 META_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 EFSTATE_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 BMFD_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 VTFD_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 TTFD_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 RC_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 TEMP_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 DRVOBJ_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 DCIOBJ_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 SPOOL_TYPE 0, 0 - 0, 0 - 0, 0 - 0 - 0 0 TOTALS 339, 0 - 0, 0 - 0, 0 - 0 - 0 0 cUnused objects 13 cUnknown objects 0 0
Knowing that the PID for Explorer is 0x68, I can then look at the GDI objects that are associated only with Explorer, using the !dumpobj command.
KDx86> !dumpobj -p 68 *** Extension DLL(1367 Free) does not match target system(1381 Checked) object list for ALL type objects owned by PID 0x68 I, handle, sCount, pid, pv, objt, unique, Flags, pUser -------------------------------------------------------------------- 88, 3f0a0088, 0, 68, e110c090, LFONT, 3f0a, 0, 00144af0 89, 14010089, 0, 68, e10fbbe0, DC, 1401, 0, 010b0000 ec, 1d0a00ec, 0, 68, e110c780, LFONT, 1d0a, 0, 00144ad8 f2, 10100f2, 0, 68, e10fabc0, DC, 101, 0, 007c0000 f3, 20500f3, 1, 68, e1105400, SURF, 205, 0, 00000000 f4, 11000f4, 0, 68, e1107c60, BRUSH, 110, 0, 007d0000 f5, 10100f5, 0, 68, e10fb120, DC, 101, 0, 007c0190 f6, c0a00f6, 0, 68, e110c530, LFONT, c0a, 0, 00144ae0 f7, b0500f7, 1, 68, e1104be0, SURF, b05, 0, 00000000 f8, 1d0400f8, 0, 68, e1120e88, RGN, 1d04, 0, 007d0060 f9, 60100f9, 0, 68, e10fb680, DC, 601, 0, 007c0e10 fa, 21000fa, 0, 68, e1107d80, BRUSH, 210, 0, 00000000 fb, 30500fb, 0, 68, e1105540, SURF, 305, 0, 00000000 fc, 21000fc, 0, 68, e1107cf0, BRUSH, 210, 0, 00000000 fd, 20500fd, 0, 68, e11055e0, SURF, 205, 0, 00000000 fe, 30100fe, 0, 68, e10fc140, DC, 301, 4, 007c07d0 ff, d0500ff, 0, 68, e1105680, SURF, d05, 0, 00000000 101, ba100101, 0, 68, e1107ca8, BRUSH, ba10, 0, 007d0048 102, 50a0102, 0, 68, e110c9d0, LFONT, 50a, 0, 00144ad0 103, 8050103, 1, 68, e13f0008, SURF, 805, 0, 00000000 104, 3010104, 0, 68, e10fd6c0, DC, 301, 0, 007c04b0 105, 29040105, 0, 68, e1101260, RGN, 2904, 0, 007d0078 107, 1010107, 0, 68, e10fdc20, DC, 101, 0, 007c0640 108, 3010108, 0, 68, e10fc6a0, DC, 301, 4, 007c0320 109, 1010109, 0, 68, e10fe180, DC, 101, 4, 007c0960 10a, 101010a, 0, 68, e10fe6e0, DC, 101, 4, 007c0af0 10b, b60a010b, 0, 68, e110c2e0, LFONT, b60a, 0, 00144ae8 10d, 8d05010d, 1, 68, e13ed008, SURF, 8d05, 0, 00000000 10e, 110010e, 0, 68, e1107dc8, BRUSH, 110, 0, 007d0018 10f, 110010f, 0, 68, e1107e10, BRUSH, 110, 0, 007d0030 110, 6e040110, 0, 68, e11020d0, RGN, 6e04, 0, 007d0090 112, 5f010112, 0, 68, e141c008, DC, 5f01, 4, 010b0190 114, 88050114, 1, 68, e1105720, SURF, 8805, 0, 00000000 117, 20a0117, 0, 68, e110cc20, LFONT, 20a, 0, 00144ac8 118, 4050118, 0, 68, e13e0c88, SURF, 405, 0, 00000000 11b, 80a011b, 0, 68, e110ce70, LFONT, 80a, 0, 00144ac0 11c, 2a10011c, 1, 68, e1107d38, BRUSH, 2a10, 0, 007d00a8 11d, 701011d, 0, 68, e10fd160, DC, 701, 0, 007c0c80 11e, f10011e, 0, 68, e1107ab0, BRUSH, f10, 0, 007d00c0 134, 45050134, 1, 68, e115f6a8, SURF, 4505, 0, 00000000 139, 930a0139, 0, 68, e110ea30, LFONT, 930a, 0, 00144ab0 13a, 4205013a, 1, 68, e1164000, SURF, 4205, 0, 00000000 13b, 130a013b, 0, 68, e110e7e0, LFONT, 130a, 0, 00144ab8 13c, 405013c, 1, 68, e112e708, SURF, 405, 0, 00000000 13d, 20a013d, 0, 68, e110ec80, LFONT, 20a, 0, 00144aa8 13e, 20a013e, 0, 68, e110eed0, LFONT, 20a, 0, 0014eb20 13f, 105013f, 0, 68, e117d8e8, SURF, 105, 0, 00000000 140, 10a0140, 0, 68, e110f120, LFONT, 10a, 0, 0014eb18 141, 1010141, 0, 68, e141e008, DC, 101, 4, 010b04b0 142, 1010142, 0, 68, e141f008, DC, 101, 4, 010b0640 143, 3050143, 1, 68, e1171108, SURF, 305, 0, 00000000 148, 7050148, 1, 68, e1422008, SURF, 705, 0, 00000000 14a, 80a014a, 0, 68, e110f370, LFONT, 80a, 0, 0014eb10 14b, 40a014b, 0, 68, e110f5c0, LFONT, 40a, 0, 0014eb08 Total objects = 54
Choosing a DC at random, we can see its structure. However, note that the !ddc and !hdc commands take the handle to the DC and not the pointer to the data structure.
KDx86> !ddc 1010142 *** Extension DLL(1367 Free) does not match target system(1381 Checked) -------------------------------------------------- V 2.0 Dump DC 0x1010142: PidOwner = 0x68 hdc = 0x1010142 pdcattr = 0x010b0640 pdcLevel = 0xe141f3ac(3a4) psurf = 0x01900010 ppdev = 0xe12b2008 dctype = 0x00000000 = DCTYPE_DIRECT prgnVis = 0xe11003f0 sizl (-515760120, 64) erclClip (0, 0), (64, 144) erclWindow (0, 0), (64, 144) erclBounds (0, 0), (0, 0) -------------------------------------------------- KDx86> !hdc 1010142 *** Extension DLL(1367 Free) does not match target system(1381 Checked) DC address ------- [e141f01c] ppdev_ 0xe12b2008 [e141f018] dhpdev_ 0xe12b3008 [e141f024] flGraphicsCaps_ 0x20056c GCAPS_ALTERNATEFILL GCAPS_WINDINGFILL GCAPS_COLOR_DITHER GCAPS_HORIZSTRIKE GCAPS_OPAQUERECT GCAPS_MONO_DITHER GCAPS_DITHERONREALIZE [e141f028] hdcNext_ 0 [e141f02c] hdcPrev_ 0 [e141f030] erclClip 0 0 64 144 [e141f040] erclWindow 0 0 64 144 [e141f050] erclBounds_ 0 0 0 0 [e141f060] erclBoundsApp_ 0 0 0 0 [e141f070] prgnAPI_ 0 [e141f074] prgnVis_ 0xe11003f0 [e141f078] prgnRao_ 0 [e141f07c] ipfdDevMax_ [e141f080] ptlFillOrigin 0 0 [e141f088] eboFill_ [e141f0c8] eboLine_ [e141f108] eboText_ [e141f148] eboBackground_ [e141f188] hlfntCur_ 0 [e141f18c] flSimulationFlags_ 0 [e141f190] lEscapement_ 0 [e141f194] prfnt_ 0 [e141f198] pPFFList 0 [e141f19c] co_ !gdikdx.dco e141f19c [e141f218] pDCAttr 0x10b0640 [e141f21c] dcattr !gdikdx.ca e141f21c [e141f3ac] dclevel !gdikdx.cl e141f3ac [e141f550] ulCopyCount_ 144 [e141f554] pSurfInfo 0xffffffff [e141f558] dctp_ 0 DCTYPE_DIRECT [e141f55c] fs_ 0x1 DC_DISPLAY
And now, given the inside of the DC, we can get at the GDI pdev.
KDx86> !dpdev -? *** Extension DLL(1367 Free) does not match target system(1381 Checked) ---------- PDEV dumper ------------ dpdev -abdfhnp ppdev a - All info (dump everything) b - Brush info d - DEVINFO struct f - Font info g - GDIINFO struct h – HELP j - Printing and journalling info n - Default patterns p - Pointer info r - Drag rect and redraw info w - DirectDraw info ----------------------------------- KDx86> !dpdev -a 0xe12b2008 *** Extension DLL(1367 Free) does not match target system(1381 Checked) Unknown option -------------------------------------------------- pdev = 0xe12b2008 ppdevNext = 0xe129bb68 flags = 0x43 PDEV_DISPLAY PDEV_POINTER_NEEDS_EXCLUDING PDEV_GOTFONTS cPdevRefs = 42 fmPointer = 0x8084fb48 pldev = 0xe12aa968 dhpdev = 0xe12b3008 pSurface = 0xe1104500 ppalSurf = 0xe1106098 peDirectDrawGlobal = 0x0 Pointer stuff: ptlPointer = (0x140, 0xf0) rclPointerOffset = [(0x0, 0x0), (0x20, 0x20)] rclPointer = [(0x140, 0xf0), (0x158, 0x104)] pfnDrvSetPointerShape = 0xfcd5f9b0 pfnDrvMovePointer = 0xfcd5f940 pfnMovePointer = 0xfcd5f940 pfnSync = 0x0 Font stuff: hlfntDefault = 0x10a0025 hlfntAnsiVariable = 0x10a0026 hlfntAnsiFixed = 0x10a0027 prfntActive = 0xe1290540 prfntInactive = 0xe12902a0 cInactive = 0x12 Default patterns: ahsurf[0] = 0x105001f ahsurf[1] = 0x1050020 ahsurf[2] = 0x1050021 ahsurf[3] = 0x1050022 ahsurf[4] = 0x1050023 ahsurf[5] = 0x1050024 Printing/journalling stuff: hSpooler = 0x8086f7c0 pDevHTInfo = 0x0 Drag/redraw stuff: rclDrag = [(0x0, 0x0), (0x0, 0x0)] rclDragClip = [(0x0, 0x0), (0x0, 0x0)] rclRedraw = [(0x0, 0x0), (0x0, 0x0)] ulDragDimension = 0x4 DEVINFO: flGraphicsCaps = 0x20056c cFonts = 0x0 iDitherFormat = 0x2 cxDither = 0x8 cyDither = 0x8 hpalDefault = 0x108001e GDIINFO: ulVersion = 0x4000 ulTechnology = 0x1 ulHorzSize = 0x4e200 = 320.000 mm ulVertSize = 0x3a980 = 240.000 mm ulHorzRes = 0x280 = 640 ulVertRes = 0x1e0 = 480 cBitsPixel = 0x4 cPlanes = 0x1 ulNumColors = 0x10 ulLogPixelsX = 0x60 ulLogPixelsY = 0x60 flRaster = 0x7e99 RC_BITBLT RC_BITMAP64 RC_GDI20_OUTPUT RC_DI_BITMAP RC_DIBTODEV RC_BIGFONT RC_STRETCHBLT RC_FLOODFILL RC_STRETCHDIB RC_OP_DX_OUTPUT flTextCaps = 0x12000 TC_RA_ABLE TC_SCROLLBLT ulDACRed = 0x6 ulDACGreen = 0x6 ulDACBlue = 0x6 ulAspectX = 0x24 ulAspectY = 0x24 ulAspectXY = 0x33 xStyleStep = 0x1 yStyleStep = 0x1 denStyleStep = 0x3 ptlPhysOffset = (0x0, 0x0) szlPhysSize = (0x0, 0x0) ulNumPalReg = 0x3 ciDevice = 0x1a2c ulDevicePelsDPI = 0x43 ulPrimaryOrder = 0x4 ulHTPatternSize = 0x3 ulHTOutputFormat = 0x3 flHTFlags = 0x4 HT_FLAG_ADDITIVE_PRIMS ------------------------------
The following are some other interesting structure side trips.
KDx86> !dpsurf e1422008 *** Extension DLL(1367 Free) does not match target system(1381 Checked) SURFACE structure at 0xe1422008: -------------------------------------------------- DHSURF dhsurf 0x0 HSURF hsurf 0x7050148 DHPDEV dhpdev 0xe12b3008 HDEV hdev 0xe12b2008 SIZEL sizlBitmap.cx 0x40 SIZEL sizlBitmap.cy 0x90 ULONG cjBits 0x480 PVOID pvBits 0xe1422084 PVOID pvScan0 0xe1422084 LONG lDelta 0x8 ULONG iUniq 0xe ULONG iBitmapFormat 0x1, BMF_1BPP USHORT iType 0x0, STYPE_BITMAP USHORT fjBitmap 0x1 Extension function faulted addr=0x7800ecd0, ec=0xc0000005 KDx86> !dpbrush e1107ab0 *** Extension DLL(1367 Free) does not match target system(1381 Checked) BRUSH structure at 0xe1107ab0: -------------------------------------------------- HANDLE hbrush 0xf10011e ULONG _ulBrushUnique 0x77 ULONG _ulStyle 0x7 HBITMAP _hbmPattern 0x0 HBITMAP _hbmClient 0x0 FLONG _flAttrs 0x80000014 BR_DITHER_OK BR_IS_SOLID BOOL _bCacheGrabbed 0x1 COLORREF _crFore 0x0 COLORREF _crBack 0xffffff ULONG _ulPalTime 0x4 ULONG _ulSurfTime 0x7 ULONG _ulRealization 0xf PVOID _pBrushattr 0x7d00c0 COLORREF crColor 0xffffff -------------------------------------------------- KDx86> !dr e1101260 *** Extension DLL(1367 Free) does not match target system(1381 Checked) hHmgr, 0x29040105 cExLock 0 tid, 0x8079ea20 sizeObj 0xa8 sizeRgn 0x70 cRefs 0 cScans 3 rcl {5 375 70 428} pscnHead 0xe11012a8 pscnTail 0xe11012d0 Rectangle #0 { 5, 375, 70, 428 } --------------------
And there just seems to be a wealth of font information available.
KDx86> !helf 40a014b *** Extension DLL(1367 Free) does not match target system(1381 Checked) LOGFONTW address -------- [e110f5d8] lfHeight -8 [e110f5dc] lfWidth 0 [e110f5e0] lfEscapement 0 [e110f5e4] lfOrientation 0 [e110f5e8] lfWeight 400 = FW_NORMAL [e110f5ec] lfItalic 0x00 [e110f5ed] lfUnderline 0x01 [e110f5ee] lfStrikeOut 0x00 [e110f5ef] lfCharSet 0x00 = ANSI_CHARSET [e110f5f0] lfOutPrecision 0x00 = OUT_DEFAULT_PRECIS [e110f5f1] lfClipPrecision 0x00 = CLIP_DEFAULT_PRECIS [e110f5f2] lfQuality 0x00 = DEFAULT_QUALITY [e110f5f3] lfPitchAndFamily 0x00 = DEFAULT_PITCH | FF_DONTCARE [e110f5f4] lfFaceName "MS Sans Serif" KDx86> !pubft *** Extension DLL(1367 Free) does not match target system(1381 Checked) pfhFamily = 0xe11db8e8 pfhFace = 0xe11fa4e8 cBuckets = 100 cFiles = 33 apPFF[5] 0xe12f88e8 0xe10df6c8 (HDEV) PFE* IFI* 0xe12fef08 0xe12f5c40 "Script" 37 17 apPFF[7] 0xe1372a68 0xe129b008 (HDEV) PFE* IFI* 0xe136d3e8 0xe13761d4 "Symbol" 13 5 0xe13729c8 0xe13762e4 "Symbol" 16 6 0xe136a8a8 0xe13763f4 "Symbol" 19 8 0xe136e188 0xe1376504 "Symbol" 21 9 0xe136d348 0xe1376614 "Symbol" 27 12 0xe1372928 0xe1376724 "Symbol" 35 15 0xe1354548 0xe129bb68 (HDEV) PFE* IFI* 0xe135bba8 0xe135d0f8 "Lucida Sans Unicode" 3147 1003 0xe13222c8 0xe129bb68 (HDEV) PFE* IFI* 0xe132bd08 0xe132e0f8 "Courier New Bold Italic" 2320 1229 KDx86> !devft *** Extension DLL(1367 Free) does not match target system(1381 Checked) pfhFamily = 0 pfhFace = 0 cBuckets = 5 cFiles = 0
So, with a smile, even though there are more pages and commands that might be usable, we close this book on peeking inside the GDI structures. But, we make a mental note of its whereabouts, because it might come in handy if our application friends start having problems with our driver and we decide to give them a hand. We put it back on the shelf, next to the big blue and green book, the one with the singed pages.
Who’s Andy?
The title of this column created some stir among some of the folks here at OSR. Basically, because they thought that this might be some sort of homage to some of the well known Andy’s of the graphics world. But, alas, this column is not written (nor dedicated to) Mr. vanDam nor Mr. Glassner. However, any good graphics geek should know exactly the Andy who’s the owner of this Bookshelf.
Related Articles
From Andy's Bookshelf: Loading Video Drivers, a Mystery Solved
From Andy's Bookshelf: So you Wanna Write a Video Driver
From Andy's Bookshelf: Floating Point Triage
Loading DLLs for Graphics Drivers
From Andy's Bookshelf: Video Drivers and the Registry
User Comments
Rate this article and give us feedback. Do you find anything missing? Share your opinion with the community!
Post Your Comment
|
|