Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

981 lines
30 KiB

/******************************Module*Header*******************************\
* Module Name: debug.c
*
* This file is for debugging tools and extensions.
*
* Created: 22-Dec-1991
* Author: John Colleran
*
* Copyright (c) 1990 Microsoft Corporation
\**************************************************************************/
#if defined(_X86_)
#define FASTCALL __fastcall
#else
#define FASTCALL
#endif
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stddef.h>
#include <windows.h>
#include <winspool.h>
#include <limits.h>
#include <string.h>
#include <nlsconv.h>
#include <wingdip.h>
#include "winddi.h"
#include "firewall.h"
#include "ntgdistr.h"
#include "ntgdi.h"
#include "xfflags.h"
#include "hmgshare.h"
#include "local.h"
#include "metarec.h"
#include "mfrec16.h"
#include "metadef.h"
#include "font.h"
#include <excpt.h>
#include <ntstatus.h>
#include <wdbgexts.h>
#include <ntsdexts.h>
#define NOEXTAPI
#include <dbgext.h>
#include <ntcsrmsg.h>
/**************************************************************************\
*
\**************************************************************************/
typedef struct _FLAGDEF {
char *psz; // description
FLONG fl; // flag
} FLAGDEF;
FLAGDEF afdLDC_FL[] = {
{ "LDC_SAP_CALLBACK ", LDC_SAP_CALLBACK },
{ "LDC_DOC_STARTED ", LDC_DOC_STARTED },
{ "LDC_PAGE_STARTED ", LDC_PAGE_STARTED },
{ "LDC_CALL_STARTPAGE ", LDC_CALL_STARTPAGE },
{ "LDC_NEXTBAND ", LDC_NEXTBAND },
{ "LDC_EMPTYBAND ", LDC_EMPTYBAND },
{ "LDC_META_ARCDIR_CLOCKWISE ", LDC_META_ARCDIR_CLOCKWISE },
{ "LDC_FONT_CHANGE ", LDC_FONT_CHANGE },
{ "LDC_DOC_CANCELLED ", LDC_DOC_CANCELLED },
{ "LDC_META_PRINT ", LDC_META_PRINT },
{ "LDC_PRINT_DIRECT ", LDC_PRINT_DIRECT },
{ "LDC_BANDING ", LDC_BANDING },
{ "LDC_DOWNLOAD_FONTS ", LDC_DOWNLOAD_FONTS },
{ "LDC_RESETDC_CALLED ", LDC_RESETDC_CALLED },
{ "LDC_FORCE_MAPPING ", LDC_FORCE_MAPPING },
{ "LDC_INFO ", LDC_INFO },
{ "NULL ", 0 },
};
FLAGDEF afdDirty[] = {
{ "DIRTY_FILL ", DIRTY_FILL },
{ "DIRTY_LINE ", DIRTY_LINE },
{ "DIRTY_TEXT ", DIRTY_TEXT },
{ "DIRTY_BACKGROUND ", DIRTY_BACKGROUND },
{ "DIRTY_CHARSET ", DIRTY_CHARSET },
{ "SLOW_WIDTHS ", SLOW_WIDTHS },
{ "DC_CACHED_TM_VALID ", DC_CACHED_TM_VALID },
{ "DISPLAY_DC ", DISPLAY_DC },
{ "DIRTY_PTLCURRENT ", DIRTY_PTLCURRENT },
{ "DIRTY_PTFXCURRENT ", DIRTY_PTFXCURRENT },
{ "DIRTY_STYLESTATE ", DIRTY_STYLESTATE },
{ "DC_PLAYMETAFILE ", DC_PLAYMETAFILE },
{ "DC_BRUSH_DIRTY ", DC_BRUSH_DIRTY },
{ "DC_DIBSECTION ", DC_DIBSECTION },
{ "DC_LAST_CLIPRGN_VALID ", DC_LAST_CLIPRGN_VALID },
{ 0, 0 }
};
FLAGDEF afdIcmMode[] = {
{ "ICM_ON ", ICM_ON },
{ "ICM_OFF ", ICM_OFF },
{ 0, 0 }
};
FLAGDEF afdBrushAttr[] = {
{ "ATTR_CACHED ", ATTR_CACHED },
{ "ATTR_TO_BE_DELETED ", ATTR_TO_BE_DELETED },
{ "ATTR_NEW_COLOR ", ATTR_NEW_COLOR },
{ "ATTR_CANT_SELECT ", ATTR_CANT_SELECT },
{ 0, 0 }
};
#define PRINT_FLAGS(ulIn,sSpace,afd) \
{ \
ULONG ul = ulIn; \
FLAGDEF *pfd; \
\
for (pfd=afd; pfd->psz; pfd++) \
if (ul & pfd->fl) \
Print(" %s%s\n",sSpace, pfd->psz); \
}
char *pszMapMode(long l)
{
char *psz;
switch (l) {
case MM_TEXT : psz = "MM_TEXT" ; break;
case MM_LOMETRIC : psz = "MM_LOMETRIC" ; break;
case MM_HIMETRIC : psz = "MM_HIMETRIC" ; break;
case MM_LOENGLISH : psz = "MM_LOENGLISH" ; break;
case MM_HIENGLISH : psz = "MM_HIENGLISH" ; break;
case MM_TWIPS : psz = "MM_TWIPS" ; break;
case MM_ISOTROPIC : psz = "MM_ISOTROPIC" ; break;
case MM_ANISOTROPIC: psz = "MM_ANISOTROPIC"; break;
default : psz = "MM_?" ; break;
}
return( psz );
}
char *pszBkMode(long l)
{
char *psz;
switch (l)
{
case TRANSPARENT: psz = "TRANSPARENT"; break;
case OPAQUE : psz = "OPAQUE" ; break;
default : psz = "BKMODE_?" ; break;
}
return( psz );
}
char *pszObjType(HOBJ h)
{
char *psz;
switch (LO_TYPE(h))
{
case LO_BRUSH_TYPE : psz = "BRUSH "; break;
case LO_DC_TYPE : psz = "DC "; break;
case LO_BITMAP_TYPE : psz = "BITMAP "; break;
case LO_PALETTE_TYPE : psz = "PALETTE "; break;
case LO_FONT_TYPE : psz = "FONT "; break;
case LO_REGION_TYPE : psz = "REGION "; break;
case LO_CLIENTOBJ_TYPE : psz = "CLIENTOBJ "; break;
case LO_ALTDC_TYPE : psz = "ALTDC "; break;
case LO_PEN_TYPE : psz = "PEN "; break;
case LO_EXTPEN_TYPE : psz = "EXTPEN "; break;
case LO_DIBSECTION_TYPE: psz = "DIBSECTION"; break;
case LO_METAFILE16_TYPE: psz = "METAFILE16"; break;
case LO_METAFILE_TYPE : psz = "METAFILE "; break;
case LO_METADC16_TYPE : psz = "METADC16 "; break;
default:
switch (GRE_TYPE(h))
{
case DEF_TYPE : psz = "DEF "; break;
case DC_TYPE : psz = "DC "; break;
case DD_DIRECTDRAW_TYPE: psz = "DD_DIRECTDRAW"; break;
case DD_SURFACE_TYPE : psz = "DD_SURFACE "; break;
case RGN_TYPE : psz = "RGN "; break;
case SURF_TYPE : psz = "SURF "; break;
case CLIENTOBJ_TYPE : psz = "CLIENTOBJ "; break;
case PATH_TYPE : psz = "PATH "; break;
case PAL_TYPE : psz = "PAL "; break;
case ICMLCS_TYPE : psz = "ICMLCS "; break;
case LFONT_TYPE : psz = "LFONT "; break;
case RFONT_TYPE : psz = "RFONT "; break;
case PFE_TYPE : psz = "PFE "; break;
case PFT_TYPE : psz = "PFT "; break;
case ICMCXF_TYPE : psz = "ICMCXF "; break;
case ICMDLL_TYPE : psz = "ICMDLL "; break;
case BRUSH_TYPE : psz = "BRUSH "; break;
case PFF_TYPE : psz = "PFF "; break;
case CACHE_TYPE : psz = "CACHE "; break;
case SPACE_TYPE : psz = "SPACE "; break;
case META_TYPE : psz = "META "; break;
case EFSTATE_TYPE : psz = "EFSTATE "; break;
case BMFD_TYPE : psz = "BMFD "; break;
case VTFD_TYPE : psz = "VTFD "; break;
case TTFD_TYPE : psz = "TTFD "; break;
case RC_TYPE : psz = "RC "; break;
case TEMP_TYPE : psz = "TEMP "; break;
case DRVOBJ_TYPE : psz = "DRVOBJ "; break;
case DCIOBJ_TYPE : psz = "DCIOBJ "; break;
case SPOOL_TYPE : psz = "SPOOL "; break;
default : psz = "unknown "; break;
}
}
return( psz );
}
/******************************Public*Routine******************************\
*
* History:
* 03-Nov-1993 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
char *gaszHelpCli[] = {
"=======================================================================\n"
,"GDIEXTS client debugger extentions:\n"
,"-----------------------------------------------------------------------\n"
,"dh [object handle] -- dump HMGR entry of handle\n"
,"ddc [DC handle] -- dump DC obj (ddc -? for more info)\n"
,"hbr [brush handle] -- dump DC brush object\n"
,"dcfont -- dumps all logfont/cfontsinfo\n"
,"dcache -- dump client side object cache info\n"
,"\n"
,"use gdikdx.dll extensions for kernel debuging\n"
,"=======================================================================\n"
,NULL
};
VOID
help(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString
)
{
PNTSD_OUTPUT_ROUTINE Print;
char **ppsz = gaszHelpCli;
// Avoid warnings.
hCurrentProcess = hCurrentProcess;
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
Print = lpExtensionApis->lpOutputRoutine;
// The help info is formatted as a doubly NULL-terminated array of strings.
// So, until we hit the NULL, print each string.
while (*ppsz)
Print(*ppsz++);
}
/******************************Public*Routine******************************\
* dumphandle
*
* Dumps the contents of a GDI client handle
*
* History:
* 23-Dec-1991 -by- John Colleran
* Wrote it.
\**************************************************************************/
void dh(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
PENTRY pent;
DWORD ho;
ENTRY ent; // copy of handle entry
ULONG ulTemp;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
// do some real work
ho = (ULONG)EvalExpression(lpArgumentString);
GetValue(pent,"&gdi32!pGdiSharedHandleTable");
pent += HANDLE_TO_INDEX(ho);
move(ent,pent);
// just incase they just gave us the index
ho = MAKE_HMGR_HANDLE(HANDLE_TO_INDEX(ho),ent.FullUnique);
// Print the entry.
Print("--------------------------------------------------\n");
Print("Entry from ghmgr for handle 0x%08lx, pent = %lx\n", ho,pent);
Print(" objt = 0x%x, %s\n" , ent.Objt,pszObjType(ho));
Print(" puser = 0x%x\n" , ent.pUser);
Print(" ObjectOwner = 0x%08lx\n" , ent.ObjectOwner.ulObj);
Print(" pidOwner = 0x%x\n" , ent.ObjectOwner.Share.Pid);
Print(" usUnique = 0x%hx\n" , ent.FullUnique);
Print(" pobj krnl = 0x%08lx\n" , ent.einfo.pobj);
Print(" ShareCount = 0x%x\n" , ent.ObjectOwner.Share.Count);
Print(" lock = %s\n" , ent.ObjectOwner.Share.Lock ? "LOCKED" : "UNLOCKED");
Print(" fsHmgr = 0x%hx\n" , ent.Flags);
Print("--------------------------------------------------\n");
}
/******************************Public*Routine******************************\
* dcfonts
*
* Dumps the contents of a GDI client handle
*
* History:
* 23-Dec-1991 -by- John Colleran
* Wrote it.
\**************************************************************************/
void dcfont(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
int i;
PENTRY pent;
ENTRY ent;
ULONG pid;
ULONG h;
ULONG ho;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
// do some real work
GetValue(pent,"&gdi32!pGdiSharedHandleTable");
GetValue(pid,"&gdi32!gW32PID");
ho = (ULONG)EvalExpression(lpArgumentString);
i = 0;
if (ho)
i = HANDLE_TO_INDEX(ho);
Print("pent = %lx, pid = %lx, lf type = %lx\n",pent,pid,LFONT_TYPE);
for (;i < 1000/*MAX_HANDLE_COUNT*/; ++i)
{
move(ent,pent+i);
if ((ent.Objt == LFONT_TYPE) &&
((ent.ObjectOwner.Share.Pid == pid) || ho))
{
LOCALFONT lf;
h = MAKE_HMGR_HANDLE(i,ent.FullUnique);
Print("\n");
Print("%3lx: h = %lx, puser = %lx, owner = %lx\n",i,h,ent.pUser,ent.ObjectOwner.Share.Pid);
if (ent.pUser)
{
CFONT cf;
PCFONT pcf;
move(lf,ent.pUser);
for (pcf = lf.pcf; pcf; pcf = cf.pcfNext)
{
move(cf,pcf);
Print(" pcf = 0x%lx, fl = 0x%lx, lHeight = %d\n",
pcf,cf.fl,cf.lHeight);
Print(" efm11 = 0x%08lx, efm22 = 0x%08lx, hdc = 0x%08lx\n",
lEfToF(cf.efM11),lEfToF(cf.efM22),cf.hdc);
}
}
}
if (ho)
break;
}
}
/******************************Public*Routine******************************\
*
* History:
* 10-Apr-1993 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
void ddc(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
PENTRY pent;
DWORD ho;
ENTRY ent; // copy of handle entry
ULONG ulTemp;
BOOL bVerbose = FALSE;
BOOL bLDC = FALSE;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
if (*lpArgumentString == '-')
{
char chOpt;
do {
chOpt = *(++lpArgumentString);
switch (chOpt) {
case 'v':
case 'V':
bVerbose = TRUE;
break;
case 'L':
case 'l':
bLDC = TRUE;
break;
}
} while ((chOpt != ' ') && (chOpt != '\0'));
}
// do some real work
ho = (ULONG)EvalExpression(lpArgumentString);
GetValue(pent,"&gdi32!pGdiSharedHandleTable");
pent += HANDLE_TO_INDEX(ho);
move(ent,pent);
// now get the dcAttr
Print("DC dump for handle %lx, pUser = %lx\n",ho,ent.pUser);
if (ent.pUser != NULL)
{
DC_ATTR dca;
move(dca,ent.pUser);
Print(" objt = 0x%x\n" , ent.Objt);
Print(" pldc = 0x%x\n" , dca.pvLDC);
Print(" ulDirty_ = 0x%08x\n" , dca.ulDirty_);
PRINT_FLAGS(dca.ulDirty_," ",afdDirty);
Print(" hbrush = 0x%08x\n" , dca.hbrush);
Print(" hpen = 0x%08x\n" , dca.hpen);
Print(" hfont = 0x%08x\n" , dca.hlfntNew);
Print(" bkColor = 0x%x, (0x%x)\n", dca.crBackgroundClr,dca.ulBackgroundClr);
Print(" foreColor = 0x%x, (0x%x)\n", dca.crForegroundClr,dca.ulForegroundClr);
Print(" lIcmMode = 0x%08lx\n" ,dca.lIcmMode);
PRINT_FLAGS(dca.lIcmMode," ",afdIcmMode);
Print(" hcmXform = 0x%08lx\n" ,dca.hcmXform);
Print(" hColorSpace = 0x%08lx\n" ,dca.hColorSpace);
Print(" pProfile = 0x%08lx\n" ,dca.pProfile);
Print(" hProfile = 0x%08lx\n" ,dca.hProfile);
Print(" IcmBrush = 0x%08lx\n" ,dca.IcmBrushColor);
Print(" IcmPen = 0x%08lx\n" ,dca.IcmPenColor);
if (bVerbose)
{
ULONG ul;
PSZ psz;
// REGION
Print(" REGION\n");
if (dca.VisRectRegion.AttrFlags & ATTR_RGN_VALID)
{
switch (dca.VisRectRegion.Flags)
{
case NULLREGION:
Print(" NULLREGION\n");
break;
SIMPLEREGION;
Print(" SIMPLEREGION, 1rect\n");
Print(" AttrFlags = 0x%x,%s\n",
dca.VisRectRegion.AttrFlags,
(dca.VisRectRegion.AttrFlags & ATTR_RGN_DIRTY) ? "DIRTY" : "CLEAN");
Print(" RECT = 0x%x, 0x%x, 0x%x, 0x%x\n",
dca.VisRectRegion.Rect.left,
dca.VisRectRegion.Rect.top,
dca.VisRectRegion.Rect.right,
dca.VisRectRegion.Rect.bottom);
break;
case COMPLEXREGION:
Print(" COMPLEXREGION\n");
break;
default:
Print(" ERROR in region\n");
break;
}
}
else
{
Print(" invalid cached region\n");
}
Print(" Other attributes\n");
Print(" BkMode = 0x%x, (0x%x)\n", dca.lBkMode,dca.jBkMode);
Print(" FillMode = 0x%x, (0x%x)\n", dca.lFillMode,dca.jFillMode);
Print(" StretchMode = 0x%x, (0x%x)\n", dca.lStretchBltMode,dca.jStretchBltMode);
Print(" PtlCurrent(L)= 0x%x,0x%x\n" , dca.ptlCurrent.x,dca.ptlCurrent.y);
Print(" PtlCurrent(D)= 0x%x,0x%x\n" , dca.ptfxCurrent.x,dca.ptfxCurrent.y);
Print(" ROP2 = 0x%x\n" , dca.jROP2);
Print(" GraphicsMode = 0x%x\n" , dca.iGraphicsMode);
Print(" Text attributes\n");
Print(" code page = 0x%x\n" , dca.iCS_CP);
Print(" flTextAlign = 0x%x\n" , dca.flTextAlign);
Print(" lTextAlign = 0x%x\n" , dca.lTextAlign );
Print(" lTextExtra = 0x%x\n" , dca.lTextExtra );
Print(" lRelAbs = 0x%x\n" , dca.lRelAbs );
Print(" lBreakExtra = 0x%x\n" , dca.lBreakExtra);
Print(" cBreak = 0x%x\n" , dca.cBreak );
Print(" XFORMS\n");
Print(" flXform = 0x%08lx\n", dca.flXform);
Print(" Map Mode = %ld, %s\n", dca.iMapMode, pszMapMode(dca.iMapMode));
Print(" Window Org = (%8ld, %8ld)\n", dca.ptlWindowOrg.x,
dca.ptlWindowOrg.y);
Print(" Window Ext = (%8ld, %8ld)\n", dca.szlWindowExt.cx,
dca.szlWindowExt.cy);
Print(" Viewport Org = (%8ld, %8ld)\n", dca.ptlViewportOrg.x,
dca.ptlViewportOrg.y);
Print(" Viewport Ext = (%8ld, %8ld)\n", dca.szlViewportExt.cx,
dca.szlViewportExt.cy);
Print(" Virtual Pix = (%8ld, %8ld)\n", dca.szlVirtualDevicePixel.cx,
dca.szlVirtualDevicePixel.cy);
Print(" Virtual mm = (%8ld, %8ld)\n", dca.szlVirtualDeviceMm.cx,
dca.szlVirtualDeviceMm.cy);
Print("\tMatrix\n");
Print("\t\tM11 = 0x%08lx\n", lEfToF(dca.mxWtoD.efM11));
Print("\t\tM12 = 0x%08lx\n", lEfToF(dca.mxWtoD.efM12));
Print("\t\tM21 = 0x%08lx\n", lEfToF(dca.mxWtoD.efM21));
Print("\t\tM22 = 0x%08lx\n", lEfToF(dca.mxWtoD.efM22));
Print("\t\tDx = 0x%08lx\n", lEfToF(dca.mxWtoD.efDx));
Print("\t\tDy = 0x%08lx\n", lEfToF(dca.mxWtoD.efDy));
Print("\t\tFDx = 0x%08lx\n", dca.mxWtoD.fxDx);
Print("\t\tFDy = 0x%08lx\n", dca.mxWtoD.fxDy);
}
if (bLDC && dca.pvLDC)
{
LDC ldc;
move(ldc,dca.pvLDC);
Print(" LDC\n");
Print(" hdc = 0x%08x\n" , ldc.hdc);
Print(" fl = 0x%x\n" , ldc.fl);
PRINT_FLAGS(ldc.fl," ",afdLDC_FL);
Print(" iType = 0x%x, %s\n" , ldc.iType, ldc.iType == LO_DC ? "LO_DC" : "LO_METADC");
Print(" PMDC = 0x%x\n" , ldc.pvPMDC);
Print(" pwszPort = %ws\n" , ldc.pwszPort ? ldc.pwszPort : L"NULL");
Print(" pfnAbort = 0x%08x\n" , ldc.pfnAbort);
Print(" hSpooler = 0x%x\n" , ldc.hSpooler);
Print(" pdm = 0x%x\n" , ldc.pDevMode);
Print(" pdm.devname = %ws\n" , ldc.pDevMode ? ldc.pDevMode->dmDeviceName : L"NULL");
}
}
}
/******************************Public*Routine******************************\
*
* History:
* 10-Apr-1993 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
void hbrush(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
PENTRY pent;
DWORD ho;
ENTRY ent; // copy of handle entry
ULONG ulTemp;
BOOL bVerbose = FALSE;
BOOL bLDC = FALSE;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
if (*lpArgumentString == '-')
{
char chOpt;
do {
chOpt = *(++lpArgumentString);
switch (chOpt) {
case 'v':
case 'V':
bVerbose = TRUE;
break;
case 'L':
case 'l':
bLDC = TRUE;
break;
}
} while ((chOpt != ' ') && (chOpt != '\0'));
}
// do some real work
ho = (ULONG)EvalExpression(lpArgumentString);
GetValue(pent,"&gdi32!pGdiSharedHandleTable");
pent += HANDLE_TO_INDEX(ho);
move(ent,pent);
// now get the dcAttr
Print("BRUSH dump for handle %lx, pUser = %lx\n",ho,ent.pUser);
if (ent.pUser != NULL)
{
BRUSHATTR bra;
move(bra,ent.pUser);
Print(" objt = 0x%x\n" , ent.Objt);
Print(" AttrFlags = 0x%x, (0x%x)\n", bra.AttrFlags);
PRINT_FLAGS(bra.AttrFlags," ",afdBrushAttr);
Print(" lbColor = 0x%x, (0x%x)\n", bra.lbColor);
}
}
void dcache(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
PCFONT pcf;
CFONT cf;
int i;
PGDI_SHARED_MEMORY pshare;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
// do some real work
GetValue(pshare,"&gdi32!pGdiSharedMemory");
pcf = pshare->acfPublic;
Print("Public CFONT Table, %lx\n",pcf);
for (i = 0; i < MAX_PUBLIC_CFONT; ++i)
{
move(cf,pcf);
if (cf.hf)
{
Print("%2d: hf = 0x%lx, pcf = 0x%lx, fl = 0x%lx, lHeight = %d\n",
i,cf.hf,pcf,cf.fl,cf.lHeight);
}
cf.hf = 0;
pcf++;
}
}
#if 0
/******************************Public*Routine******************************\
*
* History:
* 10-Apr-1993 -by- Eric Kutter [erick]
* Wrote it.
\**************************************************************************/
void clidumphmgr(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
LHE lhe;
LHE *pLocalTable;
ULONG aulCount[LO_LAST];
int i;
int c;
for (i = 0; i < LO_LAST; ++i)
aulCount[i] = 0;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
GetValue(c,"&gdi32!cLheCommitted");
Print("cLheCommitted = %ld\n",c);
GetValue(pLocalTable,"&gdi32!pLocalTable");
for (i = 0; i < (int)c; ++i)
{
int iType;
move(lhe,(pLocalTable+i));
iType = lhe.iType & 0x0f;
if (iType < LO_LAST)
aulCount[iType]++;
else
Print("Invalid handle %lx, type = %ld\n",i,lhe.iType);
}
for (i = 0; i < LO_LAST; ++i)
Print("\t%s - %ld\n",aszType[i],aulCount[i]);
return;
}
void clidumpcache(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PNTSD_OUTPUT_ROUTINE Print;
PNTSD_GET_EXPRESSION EvalExpression;
PNTSD_GET_SYMBOL GetSymbol;
LDC ldc;
HCACHE hc;
PVOID apv[CACHESIZE];
int i;
BOOL b;
PVOID pv;
PLDC *gapldc;
PHCACHE gaphcBrushes;
PHCACHE gaphcFonts;
// eliminate warnings
hCurrentThread = hCurrentThread;
dwCurrentPc = dwCurrentPc;
lpArgumentString = lpArgumentString;
// set up function pointers
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
// do the dc's
Print("Cached objects - bucket: client handle, client handle, ...\n");
Print("Cached DC's\n");
GetAddress(gapldc,"gdi32!gapldc");
move(apv,gapldc);
for (i = 0; i < CACHESIZE; ++i)
{
b = FALSE;
if (apv[i])
{
if (!b)
{
Print("\t%d: ",i);
b = TRUE;
}
for (pv = apv[i]; pv; pv = ldc.pldcNext)
{
move(ldc,pv);
Print("%x, ",ldc.lhdc);
}
}
if (b)
Print("\n");
}
// do the brushes
Print("Cached Brushes\n");
GetAddress(gaphcBrushes,"gdi32!gaphcBrushes");
move(apv,gaphcBrushes);
for (i = 0; i < CACHESIZE; ++i)
{
b = FALSE;
if (apv[i])
{
if (!b)
{
Print("\t%d: ",i);
b = TRUE;
}
for (pv = apv[i]; pv; pv = hc.phcNext)
{
move(hc,pv);
Print("%x, ",hc.hLocal);
}
}
if (b)
Print("\n");
}
// do the fonts
Print("Cached Fonts\n");
GetAddress(gaphcFonts,"gdi32!gaphcFonts");
move(apv,gaphcFonts);
for (i = 0; i < CACHESIZE; ++i)
{
b = FALSE;
if (apv[i])
{
if (!b)
{
Print("\t%d: ",i);
b = TRUE;
}
for (pv = apv[i]; pv; pv = hc.phcNext)
{
move(hc,pv);
Print("%x, ",hc.hLocal);
}
}
if (b)
Print("\n");
}
return;
}
#endif