Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

7548 lines
219 KiB

/****************************** Module Header ******************************\
* Module Name: userexts.c
*
* Copyright (c) 1985-96, Microsoft Corporation
*
* This module contains user related debugging extensions.
*
* History:
* 17-May-1991 DarrinM Created.
* 22-Jan-1992 IanJa ANSI/Unicode neutral (all debug output is ANSI)
* 23-Mar-1993 JerrySh Moved from winsrv.dll to userexts.dll
* 21-Oct-1993 JerrySh Modified to work with WinDbg
* 18-Oct-1994 ChrisWil Added Object Tracking extent.
* 26-May-1995 Sanfords Made it more general for the good of humanity.
* 6/9/1995 SanfordS made to fit stdexts motif and to dual compile for
* either USER or KERNEL mode.
\***************************************************************************/
#include "userkdx.h"
#ifdef KERNEL
PSTR pszExtName = "USERKDX";
#else
PSTR pszExtName = "USEREXTS";
#endif
#include <stdexts.h>
#include <stdexts.c>
/***************************************************************************\
* Constants
\***************************************************************************/
#define CDWORDS 16
/***************************************************************************\
* Global variables
\***************************************************************************/
BOOL bServerDebug = TRUE;
BOOL bShowFlagNames = TRUE;
char gach1[80];
char gach2[80];
CLS gcls;
PGETEPROCESSDATAFUNC GetEProcessData;
SHAREDINFO gShi;
SERVERINFO gSi;
/***************************************************************************\
* Macros
\***************************************************************************/
#ifdef KERNEL // ########### KERNEL MODE ONLY MACROS ###############
#define VAR(v) "win32k!" #v
#define FIXKP(p) p
#define FOREACHWINDOWSTATION(pwinsta) \
moveExpValue(&pwinsta, "win32k!grpwinstaList"); \
SAFEWHILE (pwinsta != NULL) {
#define NEXTEACHWINDOWSTATION(pwinsta) \
move(pwinsta, &pwinsta->rpwinstaNext); \
}
#define FOREACHDESKTOP(pdesk) \
{ \
WINDOWSTATION *pwinsta; \
\
FOREACHWINDOWSTATION(pwinsta) \
move(pdesk, &pwinsta->rpdeskList); \
SAFEWHILE (pdesk != NULL) {
#define NEXTEACHDESKTOP(pdesk) \
move(pdesk, &pdesk->rpdeskNext); \
} \
NEXTEACHWINDOWSTATION(pwinsta) \
}
#define FOREACHPPI(ppi) \
{ \
PLIST_ENTRY ProcessHead; \
LIST_ENTRY List; \
PLIST_ENTRY NextProcess; \
PEPROCESS pEProcess; \
PW32PROCESS pW32Process; \
\
ProcessHead = EvalExp( "PsActiveProcessHead" ); \
if (!ProcessHead) { \
Print("Unable to get value of PsActiveProcessHead\n"); \
return FALSE; \
} \
\
if (!tryMove(List, ProcessHead)) { \
Print("Unable to get value of PsActiveProcessHead\n"); \
return FALSE; \
} \
NextProcess = List.Flink; \
if (NextProcess == NULL) { \
Print("PsActiveProcessHead->Flink is NULL!\n"); \
return FALSE; \
} \
\
SAFEWHILE(NextProcess != ProcessHead) { \
pEProcess = GetEProcessData((PEPROCESS)NextProcess, \
PROCESS_PROCESSHEAD, \
NULL); \
\
if (GetEProcessData(pEProcess, PROCESS_PROCESSLINK, \
&List) == NULL) { \
Print("Unable to read _EPROCESS at %lx\n",pEProcess); \
break; \
} \
NextProcess = List.Flink; \
\
if (GetEProcessData(pEProcess, PROCESS_WIN32PROCESS, \
&pW32Process) == NULL || pW32Process == NULL) { \
continue; \
} \
\
ppi = (PPROCESSINFO)pW32Process;
#define NEXTEACHPPI() } }
#define FOREACHPTI(pti) { \
PPROCESSINFO ppi; \
\
FOREACHPPI(ppi) \
if (!tryMove(pti, &ppi->ptiList)) { \
DEBUGPRINT("FOREACHPTI:Cant get ptiList from %x.\n", &ppi->ptiList); \
} \
SAFEWHILE (pti != NULL) {
#define NEXTEACHPTI(pti) \
if (!tryMove(pti, &pti->ptiSibling)) { \
DEBUGPRINT("NEXTEACHPTI:Cant get ptiSibling from %x.\n", &pti->ptiSibling); \
} \
} \
NEXTEACHPPI() }
#else //!KERNEL ############## USER MODE ONLY MACROS ################
#define VAR(v) "user32!" #v
#define FIXKP(p) FixKernelPointer(p)
#endif //!KERNEL ############## EITHER MODE MACROS ###################
#define GETSHAREDINFO(psi) moveExp(&psi, VAR(gSharedInfo))
#define FOREACHHANDLEENTRY(phe, he, i) \
{ \
PSHAREDINFO pshi; \
SHAREDINFO shi; \
SERVERINFO si; \
\
GETSHAREDINFO(pshi); \
if (!tryMove(shi, pshi)) { \
Print("FOREACHHANDLEENTRY:Could not get SHAREDINFO.\n"); \
return(FALSE); \
} \
if (!tryMove(si, shi.psi)) { \
Print("FOREACHHANDLEENTRY:Could not get SERVERINFO.\n"); \
} \
phe = shi.aheList; \
for (i = 0; si.cHandleEntries; si.cHandleEntries--, i++, phe++) { \
if (IsCtrlCHit()) { \
break; \
} \
if (!tryMove(he, phe)) { \
Print("FOREACHHANDLEENTRY:Cant get handle entry from %x.\n", phe); \
continue; \
}
#define NEXTEACHHANDLEENTRY() \
} \
}
#define DUMPHOOKS(s, hk) \
if (di.asphkStart[hk + 1]) { \
Print("\t" s " @0x%08lx\n", di.asphkStart[hk + 1]); \
SAFEWHILE (di.asphkStart[hk + 1]) { \
move(hook, di.asphkStart[hk + 1]); \
if (di.asphkStart[hk + 1] == hook.sphkNext) \
break; \
di.asphkStart[hk + 1] = hook.sphkNext; \
Print("\t iHook %d, offPfn=0x%08lx, flags=0x%04lx, ihmod=%d\n", \
hook.iHook, hook.offPfn, hook.flags, hook.ihmod); \
} \
}
#define DUMPLHOOKS(s, hk) \
if (ti.asphkStart[hk + 1]) { \
Print("\t" s " @0x%08lx\n", ti.asphkStart[hk + 1]); \
SAFEWHILE (ti.asphkStart[hk + 1]) { \
move(hook, ti.asphkStart[hk + 1]); \
if (ti.asphkStart[hk + 1] == hook.sphkNext) \
break; \
ti.asphkStart[hk + 1] = hook.sphkNext; \
Print("\t iHook %d, offPfn=0x%08lx, flags=0x%04lx, ihmod=%d\n", \
hook.iHook, hook.offPfn, hook.flags, hook.ihmod); \
} \
}
#define STRWD "20"
#define DWSTR "%-" STRWD "s%#10lx"
#define PRTDW1(p, f1) Print(DWSTR "\n", #f1, (DWORD)##p##f1)
#define PRTDW2(p, f1, f2) Print(DWSTR "\t" DWSTR "\n", #f1, (DWORD)##p##f1, #f2, (DWORD)##p##f2)
#define PRTRC(p, rc) Print("%-" STRWD "s{%#lx, %#lx, %#lx, %#lx}\n", #rc, ##p##rc.left, ##p##rc.top, ##p##rc.right, ##p##rc.bottom)
#define PRTPT(p, pt) Print("%-" STRWD "s{%#lx, %#lx}\n", #pt, ##p##pt.x, ##p##pt.y)
#define PRTFLG(p, f) if (##p##f) Print(#f "\n");
/****************************************************************************\
* PROTOTYPES
* Note that all Ixxx proc prototypes are generated by stdexts.h
\****************************************************************************/
#ifdef KERNEL
PETHREAD DummyGetCurrentThreadAddress(USHORT Processor, HANDLE hCurrentThread);
PEPROCESS GetCurrentProcessAddress(DWORD Processor, HANDLE hCurrentThread, PETHREAD CurrentThread);
BOOL PrintMessages(PQMSG pqmsgRead);
BOOL GetAndDumpHE(DWORD dwT, PHE phe, BOOL fPointerTest);
LPSTR ProcessName(PPROCESSINFO ppi);
#else // !KERNEL
PVOID FixKernelPointer(PVOID pKernel);
BOOL DumpConvInfo(PCONV_INFO pcoi);
BOOL GetTargetTEB(PTEB pteb, PTEB *ppteb);
#endif // !KERNEL
LPSTR GetFlags(WORD wType, DWORD dwFlags, LPSTR pszBuf);
BOOL HtoHE(DWORD h, HANDLEENTRY *phe, HANDLEENTRY **pphe);
BOOL dbgPtoH(PVOID p, DWORD *ph);
BOOL dbgHtoP(DWORD h, PVOID *pp);
PVOID GetPfromH(DWORD h, HANDLEENTRY **pphe, HANDLEENTRY *phe);
BOOL getHEfromP(HANDLEENTRY **pphe, HANDLEENTRY *phe, PVOID p);
PVOID HorPtoP(PVOID p, int type);
BOOL DebugGetWindowTextA(PWND pwnd, char *achDest);
BOOL DebugGetClassNameA(LPSTR lpszClassName, char *achDest);
BOOL dwrWorker(PWND pwnd, int tab);
/****************************************************************************\
* Flags stuff
\****************************************************************************/
typedef struct _WFLAGS {
int offset;
BYTE mask;
PSZ pszText;
} WFLAGS;
WFLAGS aFlags[] = { // sorted alphabetically
0x0D, 0x0F, "BFALIGNMASK",
0x0D, 0x80, "BFBITMAP",
0x0D, 0x08, "BFBOTTOM",
0x0D, 0x03, "BFCENTER",
0x0D, 0x80, "BFFLAT",
0x0D, 0x03, "BFHORZMASK",
0x0D, 0x40, "BFICON",
0x0D, 0xC0, "BFIMAGEMASK",
0x0D, 0x01, "BFLEFT",
0x0D, 0x20, "BFMULTILINE",
0x0D, 0x40, "BFNOTIFY",
0x0D, 0x10, "BFPUSHLIKE",
0x0D, 0x02, "BFRIGHT",
0x0D, 0x20, "BFRIGHTBUTTON",
0x0D, 0x04, "BFTOP",
0x0C, 0x0F, "BFTYPEMASK",
0x0D, 0x0C, "BFVCENTER",
0x0D, 0x0C, "BFVERTMASK",
0x0C, 0x40, "CBFAUTOHSCROLL",
0x0D, 0x10, "CBFBUTTONUPTRACK",
0x0D, 0x08, "CBFDISABLENOSCROLL",
0x0C, 0x02, "CBFDROPDOWN",
0x0C, 0x03, "CBFDROPDOWNLIST",
0x0C, 0x02, "CBFDROPPABLE",
0x0C, 0x03, "CBFDROPTYPE",
0x0C, 0x01, "CBFEDITABLE",
0x0D, 0x02, "CBFHASSTRINGS",
0x0D, 0x40, "CBFLOWERCASE",
0x0D, 0x04, "CBFNOINTEGRALHEIGHT",
0x0C, 0x80, "CBFOEMCONVERT",
0x0C, 0x30, "CBFOWNERDRAW",
0x0C, 0x10, "CBFOWNERDRAWFIXED",
0x0C, 0x20, "CBFOWNERDRAWVAR",
0x0C, 0x01, "CBFSIMPLE",
0x0D, 0x01, "CBFSORT",
0x0D, 0x20, "CBFUPPERCASE",
0x0C, 0x04, "DF3DLOOK",
0x0D, 0x04, "DFCONTROL",
0x0C, 0x20, "DFLOCALEDIT",
0x0C, 0x10, "DFNOFAILCREATE",
0x0C, 0x02, "DFSYSMODAL",
0x0C, 0x80, "EFAUTOHSCROLL",
0x0C, 0x40, "EFAUTOVSCROLL",
0x0D, 0x02, "EFCOMBOBOX",
0x0C, 0x10, "EFLOWERCASE",
0x0C, 0x04, "EFMULTILINE",
0x0D, 0x01, "EFNOHIDESEL",
0x0D, 0x04, "EFOEMCONVERT",
0x0C, 0x20, "EFPASSWORD",
0x0D, 0x08, "EFREADONLY",
0x0C, 0x08, "EFUPPERCASE",
0x0D, 0x10, "EFWANTRETURN",
0x0C, 0x08, "SBFSIZEBOX",
0x0C, 0x04, "SBFSIZEBOXBOTTOMRIGHT",
0x0C, 0x02, "SBFSIZEBOXTOPLEFT",
0x0C, 0x10, "SBFSIZEGRIP",
0x0D, 0x02, "SFCENTER",
0x0C, 0x80, "SFNOPREFIX",
0x0D, 0x01, "SFNOTIFY",
0x0D, 0x08, "SFREALSIZE",
0x0D, 0x04, "SFRIGHT",
0x0D, 0x10, "SFSUNKEN",
0x0C, 0x1F, "SFTYPEMASK",
0x08, 0x10, "WEFACCEPTFILES",
0x0A, 0x04, "WEFAPPWINDOW",
0x09, 0x02, "WEFCLIENTEDGE",
0x09, 0x04, "WEFCONTEXTHELP",
0x0A, 0x01, "WEFCONTROLPARENT",
0x08, 0x01, "WEFDLGMODALFRAME",
0x08, 0x02, "WEFDRAGOBJECT",
0x09, 0x03, "WEFEDGEMASK",
0x09, 0x40, "WEFLEFTSCROLL",
0x08, 0x40, "WEFMDICHILD",
0x08, 0x04, "WEFNOPARENTNOTIFY",
0x09, 0x10, "WEFRIGHT",
0x09, 0x20, "WEFRTLREADING",
0x0A, 0x02, "WEFSTATICEDGE",
0x08, 0x80, "WEFTOOLWINDOW",
0x08, 0x08, "WEFTOPMOST",
0x08, 0x20, "WEFTRANSPARENT",
0x09, 0x01, "WEFWINDOWEDGE",
0x02, 0x10, "WF16BIT",
0x03, 0x01, "WFALWAYSSENDNCPAINT",
0x03, 0x20, "WFANSICREATOR",
0x02, 0x08, "WFANSIPROC",
0x03, 0x18, "WFANYHUNGREDRAW",
0x05, 0x02, "WFBEINGACTIVATED",
0x0E, 0x80, "WFBORDER",
0x0E, 0xC0, "WFBORDERMASK",
0x04, 0x20, "WFBOTTOMMOST",
0x0E, 0xC0, "WFCAPTION",
0x04, 0x10, "WFCEPRESENT",
0x0F, 0x40, "WFCHILD",
0x0F, 0x02, "WFCLIPCHILDREN",
0x0F, 0x04, "WFCLIPSIBLINGS",
0x00, 0x08, "WFCPRESENT",
0x03, 0x80, "WFDESTROYED",
0x02, 0x01, "WFDIALOGWINDOW",
0x0F, 0x08, "WFDISABLED",
0x0E, 0x40, "WFDLGFRAME",
0x04, 0x02, "WFDONTVALIDATE",
0x01, 0x04, "WFERASEBKGND",
0x00, 0x40, "WFFRAMEON",
0x04, 0x40, "WFFULLSCREEN",
0x0E, 0x02, "WFGROUP",
0x02, 0x20, "WFHASPALETTE",
0x00, 0x80, "WFHASSPB",
0x01, 0x40, "WFHIDDENPOPUP",
0x00, 0x04, "WFHPRESENT",
0x0E, 0x10, "WFHSCROLL",
0x0F, 0xC0, "WFICONICPOPUP",
0x05, 0x04, "WFINDESTROY",
0x01, 0x10, "WFINTERNALPAINT",
0x0E, 0x01, "WFMAXBOX",
0x0F, 0x01, "WFMAXIMIZED",
0x01, 0x80, "WFMENUDRAW",
0x0E, 0x02, "WFMINBOX",
0x0F, 0x20, "WFMINIMIZED",
0x00, 0x01, "WFMPRESENT",
0x0D, 0x01, "WFNOIDLEMSG",
0x01, 0x01, "WFNONCPAINT",
0x00, 0x20, "WFNOPAINT",
0x04, 0x08, "WFOLDUI",
0x02, 0x40, "WFPAINTNOTPROCESSED",
0x03, 0x40, "WFPALETTEWINDOW",
0x03, 0x02, "WFPIXIEHACK",
0x0F, 0x80, "WFPOPUP",
0x03, 0x10, "WFREDRAWFRAMEIFHUNG",
0x03, 0x08, "WFREDRAWIFHUNG",
0x01, 0x02, "WFSENDERASEBKGND",
0x01, 0x08, "WFSENDNCPAINT",
0x00, 0x10, "WFSENDSIZEMOVE",
0x02, 0x04, "WFSERVERSIDEPROC",
0x0A, 0x80, "WFSHELLHOOKWND",
0x0E, 0x04, "WFSIZEBOX",
0x0A, 0x20, "WFSMQUERYDRAGICON",
0x04, 0x04, "WFSTARTPAINT",
0x05, 0x01, "WFSYNCPAINTPENDING",
0x0E, 0x08, "WFSYSMENU",
0x0E, 0x01, "WFTABSTOP",
0x0F, 0x00, "WFTILED",
0x02, 0x02, "WFTITLESET",
0x03, 0x04, "WFTOGGLETOPMOST",
0x0E, 0x40, "WFTOPLEVEL",
0x0F, 0xC0, "WFTYPEMASK",
0x01, 0x20, "WFUPDATEDIRTY",
0x0F, 0x10, "WFVISIBLE",
0x00, 0x02, "WFVPRESENT",
0x0E, 0x20, "WFVSCROLL",
0x02, 0x80, "WFWIN31COMPAT",
0x04, 0x80, "WFWIN40COMPAT",
0x04, 0x01, "WFWMPAINTSENT",
};
#define N_AFLAGS (sizeof(aFlags) / sizeof(aFlags[0]))
LPSTR aszTypeNames[TYPE_CTYPES] = {
"Free",
"Window",
"Menu",
"Icon/Cursor",
"WPI(SWP) structure",
"Hook",
"ThreadInfo",
"Clipboard Data",
"CallProcData",
"Accelerator",
"DDE access",
"DDE conv",
"DDE Transaction",
"Zombie",
"Keyboard Layout",
#ifdef FE_IME
"Keyboard File",
"Input Context",
#endif
};
#define NO_FLAG (LPSTR)0xFFFFFFFF // use this for non-meaningful entries.
#define GF_SMS 1
LPSTR apszSmsFlags[] = {
"SMF_REPLY" , // 0x0001
"SMF_RECEIVERDIED" , // 0x0002
"SMF_SENDERDIED" , // 0x0004
"SMF_RECEIVERFREE" , // 0x0008
"SMF_RECEIVEDMESSAGE" , // 0x0010
NO_FLAG , // 0x0020
NO_FLAG , // 0x0040
NO_FLAG , // 0x0080
"SMF_CB_REQUEST" , // 0x0100
"SMF_CB_REPLY" , // 0x0200
"SMF_CB_CLIENT" , // 0x0400
"SMF_CB_SERVER" , // 0x0800
"SMF_WOWRECEIVE" , // 0x1000
"SMF_WOWSEND" , // 0x2000
"SMF_RECEIVERBUSY" , // 0x4000
NULL // 0x8000
};
#define GF_TIF 2
LPSTR apszTifFlags[] = {
"TIF_INCLEANUP" , // 0x00000001
"TIF_16BIT" , // 0x00000002
"TIF_SYSTEMTHREAD" , // 0x00000004
"TIF_CSRSSTHREAD" , // 0x00000008
"TIF_TRACKRECTVISIBLE" , // 0x00000010
"TIF_ALLOWFOREGROUNDACTIVATE" , // 0x00000020
"TIF_DONTATTACHQUEUE" , // 0x00000040
"TIF_DONTJOURNALATTACH" , // 0x00000080
"TIF_SCREENSAVER" , // 0x00000100
"TIF_INACTIVATEAPPMSG" , // 0x00000200
"TIF_SPINNING" , // 0x00000400
"TIF_PALETTEAWARE" , // 0x00000800
"TIF_SHAREDWOW" , // 0x00001000
"TIF_FIRSTIDLE" , // 0x00002000
"TIF_WAITFORINPUTIDLE" , // 0x00004000
"TIF_MOVESIZETRACKING" , // 0x00008000
"TIF_VDMAPP" , // 0x00010000
"TIF_DOSEMULATOR" , // 0x00020000
"TIF_GLOBALHOOKER" , // 0x00040000
"TIF_DELAYEDEVENT" , // 0x00080000
"TIF_ALLOWSHUTDOWN" , // 0x00100000
"TIF_SHUTDOWNCOMPLETE" , // 0x00200000
"TIF_IGNOREPLAYBACKDELAY" , // 0x00400000
"TIF_ALLOWOTHERACCOUNTHOOK" , // 0x00800000
"TIF_GUITHREADINITIALIZED" , // 0x02000000
#ifdef FE_IME
"TIF_DISABLEIME" , // 0x04000000
#endif
NULL // no more
};
#define GF_QS 3
LPSTR apszQsFlags[] = {
"QS_KEY" , // 0x0001
"QS_MOUSEMOVE" , // 0x0002
"QS_MOUSEBUTTON" , // 0x0004
"QS_POSTMESSAGE" , // 0x0008
"QS_TIMER" , // 0x0010
"QS_PAINT" , // 0x0020
"QS_SENDMESSAGE" , // 0x0040
"QS_HOTKEY" , // 0x0080
"QS_ALLPOSTMESSAGE" , // 0x0100
"QS_SMSREPLY" , // 0x0200
"QS_SYSEXPUNGE" , // 0x0400
"QS_THREADATTACHED" , // 0x0800
"QS_EXCLUSIVE" , // 0x1000
"QS_EVENT" , // 0x2000
"QS_TRANSFER" , // 0X4000
NULL // 0x8000
};
#define GF_MF 4
LPSTR apszMfFlags[] = {
"MF_GRAYED" , // 0x0001
"MF_DISABLED" , // 0x0002
"MF_BITMAP" , // 0x0004
"MF_CHECKED" , // 0x0008
"MF_POPUP" , // 0x0010
"MF_MENUBARBREAK" , // 0x0020
"MF_MENUBREAK" , // 0x0040
"MF_HILITE" , // 0x0080
"MF_OWNERDRAW" , // 0x0100
"MF_USECHECKBITMAPS" , // 0x0200
NO_FLAG , // 0x0400
"MF_SEPARATOR" , // 0x0800
"MF_DEFAULT" , // 0x1000
"MF_SYSMENU" , // 0x2000
"MF_RIGHTJUSTIFY" , // 0x4000
"MF_MOUSESELECT" , // 0x8000
NULL
};
#define GF_CSF 5
LPSTR apszCsfFlags[] = {
"CSF_SERVERSIDEPROC" , // 0x0001
"CSF_ANSIPROC" , // 0x0002
"CSF_WOWDEFERDESTROY" , // 0x0004
"CSF_SYSTEMCLASS" , // 0x0008
NULL // 0x0010
};
#define GF_CS 6
LPSTR apszCsFlags[] = {
"CS_VREDRAW" , // 0x0001
"CS_HREDRAW" , // 0x0002
"CS_KEYCVTWINDOW" , // 0x0004
"CS_DBLCLKS" , // 0x0008
NO_FLAG , // 0x0010
"CS_OWNDC" , // 0x0020
"CS_CLASSDC" , // 0x0040
"CS_PARENTDC" , // 0x0080
"CS_NOKEYCVT" , // 0x0100
"CS_NOCLOSE" , // 0x0200
NO_FLAG , // 0x0400
"CS_SAVEBITS" , // 0x0800
"CS_BYTEALIGNCLIENT" , // 0x1000
"CS_BYTEALIGNWINDOW" , // 0x2000
"CS_GLOBALCLASS" , // 0x4000
#ifdef FE_IME
NO_FLAG , // 0x8000
"CS_IME" , // 0x10000
NULL // no more
#else
NULL // 0x8000
#endif
};
#define GF_QF 7
LPSTR apszQfFlags[] = {
"QF_UPDATEKEYSTATE" , // 0x00001
"QF_INALTTAB" , // 0x00002
"QF_FMENUSTATUSBREAK" , // 0x00004
"QF_FMENUSTATUS" , // 0x00008
"QF_FF10STATUS" , // 0x00010
"QF_MOUSEMOVED" , // 0x00020
"QF_ACTIVATIONCHANGE" , // 0x00040
"QF_TABSWITCHING" , // 0x00080
"QF_KEYSTATERESET" , // 0x00100
"QF_INDESTROY" , // 0x00200
"QF_LOCKNOREMOVE" , // 0x00400
"QF_FOCUSNULLSINCEACTIVE" , // 0x00800
NO_FLAG , // 0x01000
NO_FLAG , // 0x02000
"QF_DIALOGACTIVE" , // 0x04000
"QF_EVENTDEACTIVATEREMOVED" , // 0x08000
NO_FLAG , // 0x10000
"QF_TRACKMOUSELEAVE" , // 0x20000
"QF_TRACKMOUSEHOVER" , // 0x40000
"QF_TRACKMOUSEFIRING" , // 0x80000
NULL
};
#define GF_W32PF 8
LPSTR apszW32pfFlags[] = {
"W32PF_CONSOLEAPPLICATION" , // 0x00000001
"W32PF_FORCEOFFFEEDBACK" , // 0x00000002
"W32PF_STARTGLASS" , // 0x00000004
"W32PF_WOW" , // 0x00000008
"W32PF_READSCREENACCESSGRANTED" , // 0x00000010
"W32PF_INITIALIZED" , // 0x00000020
"W32PF_APPSTARTING" , // 0x00000040
"W32PF_HAVECOMPATFLAGS" , // 0x00000080
"W32PF_ALLOWFOREGROUNDACTIVATE" , // 0x00000100
"W32PF_OWNDCCLEANUP" , // 0x00000200
"W32PF_SHOWSTARTGLASSCALLED" , // 0x00000400
"W32PF_FORCEBACKGROUNDPRIORITY" , // 0x00000800
"W32PF_TERMINATED" , // 0x00001000
"W32PF_CLASSESREGISTERED" , // 0x00002000
"W32PF_THREADCONNECTED" , // 0x00004000
"W32PF_PROCESSCONNECTED" , // 0x00008000
"W32PF_WAKEWOWEXEC" , // 0x00010000
"W32PF_WAITFORINPUTIDLE" , // 0x00020000
"W32PF_IOWINSTA" , // 0x00040000
NULL
};
#define GF_HE 10
LPSTR apszHeFlags[] = {
"HANDLEF_DESTROY" , // 0x0001
"HANDLEF_INDESTROY" , // 0x0002
"HANDLEF_INWAITFORDEATH" , // 0x0004
"HANDLEF_FINALDESTROY" , // 0x0008
"HANDLEF_MARKED_OK" , // 0x0010
NULL // 0x0020
};
#define GF_HDATA 11
LPSTR apszHdataFlags[] = {
"HDATA_APPOWNED" , // 0x0001
NO_FLAG , // 0x0002
NO_FLAG , // 0x0004
NO_FLAG , // 0x0008
NO_FLAG , // 0x0010
NO_FLAG , // 0x0020
NO_FLAG , // 0x0040
NO_FLAG , // 0x0080
"HDATA_EXECUTE" , // 0x0100
"HDATA_INITIALIZED" , // 0x0200
NO_FLAG , // 0x0400
NO_FLAG , // 0x0800
NO_FLAG , // 0x1000
NO_FLAG , // 0x2000
"HDATA_NOAPPFREE" , // 0x4000
"HDATA_READONLY" , // 0x8000
NULL
};
#define GF_XI 12
LPSTR apszXiFlags[] = {
"XIF_SYNCHRONOUS" , // 0x0001
"XIF_COMPLETE" , // 0x0002
"XIF_ABANDONED" , // 0x0004
NULL
};
#define GF_IIF 13
LPSTR apszIifFlags[] = {
"IIF_IN_SYNC_XACT" , // 0x0001
NO_FLAG , // 0x0002
NO_FLAG , // 0x0004
NO_FLAG , // 0x0008
NO_FLAG , // 0x0010
NO_FLAG , // 0x0020
NO_FLAG , // 0x0040
NO_FLAG , // 0x0080
NO_FLAG , // 0x0100
NO_FLAG , // 0x0200
NO_FLAG , // 0x0400
NO_FLAG , // 0x0800
NO_FLAG , // 0x1000
NO_FLAG , // 0x2000
NO_FLAG , // 0x4000
"IIF_UNICODE" , // 0x8000
NULL
};
#define GF_TMRF 14
LPSTR apszTmrfFlags[] = {
"TMRF_READY" , // 0x0001
"TMRF_SYSTEM" , // 0x0002
"TMRF_RIT" , // 0x0004
"TMRF_INIT" , // 0x0008
"TMRF_ONESHOT" , // 0x0010
"TMRF_WAITING" , // 0x0020
NULL , // 0x0040
};
#define GF_SB 15
LPSTR apszSbFlags[] = {
"SB_VERT" , // 0x0001
"SB_CTL" , // 0x0002
NULL , // 0x0004
};
#ifdef KERNEL
#define GF_CHARSETS 16
LPSTR apszCSFlags[] = {
"FS_LATIN1" , // 0x00000001L
"FS_LATIN2" , // 0x00000002L
"FS_CYRILLIC" , // 0x00000004L
"FS_GREEK" , // 0x00000008L
"FS_TURKISH" , // 0x00000010L
"FS_HEBREW" , // 0x00000020L
"FS_ARABIC" , // 0x00000040L
"FS_BALTIC" , // 0x00000080L
"FS_THAI" , // 0x00010000L
"FS_JISJAPAN" , // 0x00020000L
"FS_CHINESESIMP" , // 0x00040000L
"FS_WANSUNG" , // 0x00080000L
"FS_CHINESETRAD" , // 0x00100000L
"FS_JOHAB" , // 0x00200000L
"FS_SYMBOL" , // 0x80000000L
NULL
};
#endif // KERNEL
#define GF_MENUTYPE 17
LPSTR apszMenuTypeFlags[] = {
NO_FLAG , // 0x0001
NO_FLAG , // 0x0002
"MFT_BITMAP" , // 0x0004 MF_BITMAP
NO_FLAG , // 0x0008
"MF_POPUP" , // 0x0010
"MFT_MENUBARBREAK" , // 0x0020 MF_MENUBARBREAK
"MFT_MENUBREAK" , // 0x0040 MF_MENUBREAK
NO_FLAG , // 0x0080
"MFT_OWNERDRAW" , // 0x0100 MF_OWNERDRAW
NO_FLAG , // 0x0200
NO_FLAG , // 0x0400
"MFT_SEPARATOR" , // 0x0800 MF_SEPARATOR
NO_FLAG , // 0x1000
"MF_SYSMENU" , // 0x2000
"MFT_RIGHTJUSTIFY" , // 0x4000 MF_RIGHTJUSTIFY
NULL
};
#define GF_MENUSTATE 18
LPSTR apszMenuStateFlags[] = {
"MF_GRAYED" , // 0x0001
"MF_DISABLED" , // 0x0002
NO_FLAG , // 0x0004
"MFS_CHECKED" , // 0x0008 MF_CHECKED
NO_FLAG , // 0x0010
NO_FLAG , // 0x0020
NO_FLAG , // 0x0040
"MFS_HILITE" , // 0x0080 MF_HILITE
NO_FLAG , // 0x0100
NO_FLAG , // 0x0200
NO_FLAG , // 0x0400
NO_FLAG , // 0x0800
"MFS_DEFAULT" , // 0x1000 MF_DEFAULT
NO_FLAG , // 0x2000
NO_FLAG , // 0x4000
"MF_MOUSESELECT" , // 0x8000
NULL
};
#define GF_CURSORF 19
LPSTR apszCursorfFlags[] = {
"CURSORF_FROMRESOURCE", // 0x0001
"CURSORF_GLOBAL", // 0x0002
"CURSORF_LRSHARED", // 0x0004
"CURSORF_ACON", // 0x0008
"CURSORF_WOWCLEANUP" , // 0x0010
NO_FLAG , // 0x0020
"CURSORF_ACONFRAME", // 0x0040
"CURSORF_SECRET", // 0x0080
"CURSORF_LINKED", // 0x0100
NULL
};
/************************************************************************\
* Procedure: GetFlags
*
* Description:
*
* Converts a 32bit set of flags into an appropriate string.
* pszBuf should be large enough to hold this string, no checks are done.
* pszBuf can be NULL, allowing use of a local static buffer but note that
* this is not reentrant.
* Output string has the form: "FLAG1 | FLAG2 ..." or "0"
*
* Returns: pointer to given or static buffer with string in it.
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
LPSTR GetFlags(
WORD wType,
DWORD dwFlags,
LPSTR pszBuf)
{
static char szT[512];
WORD i;
BOOL fFirst = TRUE;
BOOL fNoMoreNames = FALSE;
LPSTR *apszFlags;
if (pszBuf == NULL) {
pszBuf = szT;
}
if (!bShowFlagNames) {
sprintf(pszBuf, "%x", dwFlags);
return(pszBuf);
}
*pszBuf = '\0';
switch (wType) {
case GF_SMS:
apszFlags = apszSmsFlags;
break;
case GF_TIF:
apszFlags = apszTifFlags;
break;
case GF_QS:
apszFlags = apszQsFlags;
break;
case GF_MF:
apszFlags = apszMfFlags;
break;
case GF_CSF:
apszFlags = apszCsfFlags;
break;
case GF_CS:
apszFlags = apszCsFlags;
break;
case GF_QF:
apszFlags = apszQfFlags;
break;
case GF_W32PF:
apszFlags = apszW32pfFlags;
break;
case GF_HE:
apszFlags = apszHeFlags;
break;
case GF_HDATA:
apszFlags = apszHdataFlags;
break;
case GF_XI:
apszFlags = apszXiFlags;
break;
case GF_IIF:
apszFlags = apszIifFlags;
break;
case GF_TMRF:
apszFlags = apszTmrfFlags;
break;
case GF_SB:
apszFlags = apszSbFlags;
break;
#ifdef KERNEL
case GF_CHARSETS:
apszFlags = apszCSFlags;
break;
#endif // KERNEL
case GF_MENUSTATE:
apszFlags = apszMenuStateFlags;
break;
case GF_MENUTYPE:
apszFlags = apszMenuTypeFlags;
break;
case GF_CURSORF:
apszFlags = apszCursorfFlags;
break;
default:
strcpy(pszBuf, "Invalid flag type.");
return(pszBuf);
}
for (i = 0; dwFlags; dwFlags >>= 1, i++) {
if (!fNoMoreNames && apszFlags[i] == NULL) {
fNoMoreNames = TRUE;
}
if (dwFlags & 1) {
if (!fFirst) {
strcat(pszBuf, " | ");
} else {
fFirst = FALSE;
}
if (fNoMoreNames || apszFlags[i] == NO_FLAG) {
char ach[16];
sprintf(ach, "0x%lx", 1 << i);
strcat(pszBuf, ach);
} else {
strcat(pszBuf, apszFlags[i]);
}
}
}
if (fFirst) {
sprintf(pszBuf, "%x", dwFlags);
}
return(pszBuf);
}
#ifdef KERNEL
PETHREAD (*GetCurrentThreadAddress)(USHORT, HANDLE) = DummyGetCurrentThreadAddress;
/************************************************************************\
* Procedure: DummyGetCurrentThreadAddress
*
* Description:
*
* Calls out to the default debug extension dll to get the current thread.
*
* Returns: pEThread of current thread.
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
/*
*/
PETHREAD
DummyGetCurrentThreadAddress(
USHORT Processor,
HANDLE hCurrentThread
)
{
WCHAR awchKDName[MAX_PATH];
LPWSTR lpszKDExts;
HANDLE hmodKDExts;
/*
* Get the kernel debugger name and map it to its
* debug extension dll.
*/
GetModuleFileNameW(NULL, awchKDName, MAX_PATH);
_wcslwr(awchKDName);
if (wcsstr(awchKDName, L"alphakd.exe"))
lpszKDExts = L"kdextalp.dll";
else if (wcsstr(awchKDName, L"i386kd.exe"))
lpszKDExts = L"kdextx86.dll";
else if (wcsstr(awchKDName, L"mipskd.exe"))
lpszKDExts = L"kdextmip.dll";
else if (wcsstr(awchKDName, L"ppckd.exe"))
lpszKDExts = L"kdextppc.dll";
else {
Print("Unknown kernel debugger: %s\n", awchKDName);
return NULL;
}
/*
* Load the extension dll and get the real procedure name
*/
hmodKDExts = LoadLibraryW(lpszKDExts);
if (hmodKDExts == NULL) {
Print("Could not load %s\n", lpszKDExts);
return NULL;
}
GetCurrentThreadAddress = (PVOID)GetProcAddress(hmodKDExts, "GetCurrentThreadAddress");
if (GetCurrentThreadAddress == NULL) {
Print("Could not find GetCurrentThreadAddress\n");
FreeLibrary(hmodKDExts);
GetCurrentThreadAddress = DummyGetCurrentThreadAddress;
return NULL;
}
/*
* Make the call
*/
return GetCurrentThreadAddress(Processor, hCurrentThread);
}
/************************************************************************\
* Procedure: GetCurrentProcessAddress
*
* Description:
*
* Returns: Current EProcess pointer.
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
PEPROCESS
GetCurrentProcessAddress(
DWORD Processor,
HANDLE hCurrentThread,
PETHREAD CurrentThread
)
{
ETHREAD Thread;
if (CurrentThread == NULL) {
CurrentThread = (PETHREAD)GetCurrentThreadAddress( (USHORT)Processor, hCurrentThread );
if (CurrentThread == NULL) {
DEBUGPRINT("GetCurrentProcessAddress: failed to get thread addr.\n");
return NULL;
}
}
if (!tryMove(Thread, CurrentThread)) {
DEBUGPRINT("GetCurrentProcessAddress: failed to read thread memory.\n");
return NULL;
}
return CONTAINING_RECORD(Thread.Tcb.ApcState.Process,EPROCESS,Pcb);
}
/************************************************************************\
* Procedure: GetAppName
*
* Description:
*
* Returns: TRUE for success, FALSE for failure.
*
* 10/6/1995 Created JimA
*
\************************************************************************/
BOOL
GetAppName(
PETHREAD pEThread,
PTHREADINFO pti,
LPWSTR lpBuffer,
DWORD cbBuffer)
{
PUNICODE_STRING pstrAppName;
UNICODE_STRING strAppName;
UCHAR ImageFileName[16];
BOOL fRead = FALSE;
if (pti->pstrAppName != NULL) {
pstrAppName = pti->pstrAppName;
if (pstrAppName != NULL && tryMove(strAppName, pstrAppName)) {
cbBuffer = min(cbBuffer - sizeof(WCHAR), strAppName.Length);
if (tryMoveBlock(lpBuffer, strAppName.Buffer, cbBuffer)) {
lpBuffer[cbBuffer / sizeof(WCHAR)] = 0;
fRead = TRUE;
}
}
} else {
if (GetEProcessData(pEThread->ThreadsProcess, PROCESS_IMAGEFILENAME,
ImageFileName) == NULL) {
Print("Unable to read _EPROCESS at %lx\n", pEThread->ThreadsProcess);
} else {
swprintf(lpBuffer, L"%.16hs", ImageFileName);
return TRUE;
}
}
if (!fRead) {
wcsncpy(lpBuffer, L"<unknown name>", cbBuffer / sizeof(WCHAR));
}
return fRead;
}
#endif // KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: PrintMessages
*
* Description: Prints out qmsg structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL PrintMessages(
PQMSG pqmsgRead)
{
QMSG qmsg;
ASYNCSENDMSG asm;
char *aszEvents[QMF_MAXEVENT] = {
"MSG", //"MESSAGE" ,
"SHO", //"SHOWWINDOW" ,
"CMD", //"CANCLEMODE" ,
"SWP", //"SETWINDOWPOS" ,
"UKS", //"UPDATEKEYSTATE",
"DEA", //"DEACTIVATE" ,
"ACT", //"ACTIVATE" ,
"PST", //"POSTMESSAGE" ,
"EXE", //"EXECSHELL" ,
"CMN", //"CANCELMENU" ,
"DSW", //"DESTROYWINDOW" ,
"ASY", //"ASYNCSENDMSG" ,
"? ", //"?" ,
"? ", //"?" ,
"? " //"?" ,
};
Print("typ pqmsg hwnd msg wParam lParam time ExInfo dwQEvent pti\n");
Print("--------------------------------------------------------------------------------\n");
SAFEWHILE (TRUE) {
move(qmsg, FIXKP(pqmsgRead));
if (qmsg.dwQEvent < QMF_MAXEVENT)
Print("%s %08lx ", aszEvents[qmsg.dwQEvent], pqmsgRead);
else
Print("??? %08lx ", pqmsgRead);
switch (qmsg.dwQEvent) {
case QEVENT_ASYNCSENDMSG:
move(asm, (PVOID)qmsg.msg.wParam);
Print("%08lx %04lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
asm.hwnd, asm.message, asm.wParam, asm.lParam,
qmsg.msg.time, qmsg.ExtraInfo, qmsg.dwQEvent, qmsg.pti);
break;
case 0:
default:
Print("%08lx %04lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
qmsg.msg.hwnd, qmsg.msg.message, qmsg.msg.wParam, qmsg.msg.lParam,
qmsg.msg.time, qmsg.ExtraInfo, qmsg.dwQEvent, qmsg.pti);
break;
}
if (qmsg.pqmsgNext != NULL) {
if (pqmsgRead == qmsg.pqmsgNext) {
Print("loop found in message list!");
return FALSE;
}
pqmsgRead = qmsg.pqmsgNext;
} else {
return TRUE;
}
}
}
#endif // KERNEL
/************************************************************************\
* Procedure: GetAndDumpHE
*
* Description: Dumps given handle (dwT) and returns its phe.
*
* Returns: fSuccess
*
* 6/9/1995 Documented SanfordS
*
\************************************************************************/
BOOL
GetAndDumpHE(
DWORD dwT,
PHE phe,
BOOL fPointerTest)
{
DWORD dw;
HEAD head;
PHE pheT;
PSHAREDINFO pshi;
SHAREDINFO shi;
SERVERINFO si;
DWORD cHandleEntries;
/*
* Evaluate the argument string and get the address of the object to
* dump. Take either a handle or a pointer to the object.
*/
dw = HMIndexFromHandle(dwT);
/*
* First see if it is a pointer because the handle index is only part of
* the 32 bit DWORD, and we may mistake a pointer for a handle.
* HACK: If dwCurPc == 0, then we've recursed with a handle.
*/
if (!fPointerTest && HIWORD(dwT) != 0) {
head.h = NULL;
move(head, (PVOID)dwT);
if (head.h != NULL) {
if (GetAndDumpHE((DWORD)head.h, phe, TRUE)) {
return TRUE;
}
}
}
/*
* Is it a handle? Does it's index fit our table length?
*/
GETSHAREDINFO(pshi);
move(shi, pshi);
move(si, shi.psi);
cHandleEntries = si.cHandleEntries;
if (dw >= cHandleEntries)
return FALSE;
/*
* Grab the handle entry and see if it is ok.
*/
pheT = shi.aheList;
pheT = &pheT[dw];
move(*phe, pheT);
/*
* If the type is too big, it's not a handle.
*/
if (phe->bType >= TYPE_CTYPES) {
pheT = NULL;
} else {
move(head, phe->phead);
if (phe->bType != TYPE_FREE) {
/*
* See if the object references this handle entry: the clincher
* for a handle, if it is not FREE.
*/
if (HMIndexFromHandle(head.h) != dw)
pheT = NULL;
}
}
if (pheT == NULL) {
if (!fPointerTest)
Print("0x%08lx is not a valid object or handle.\n", dwT);
return FALSE;
}
/*
* Dump the ownership info and the handle entry info
*/
Idhe(0, head.h);
Print("\n");
return TRUE;
}
/************************************************************************\
* Procedure: HtoHE
*
* Description:
*
* Extracts HE and phe from given handle. Handle cao be just an index.
* Assumes h is a valid handle. Returns FALSE only if it's totally wacko.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL HtoHE(
DWORD h,
HANDLEENTRY *phe,
HANDLEENTRY **pphe) // Optional
{
SHAREDINFO si, *psi;
SERVERINFO svi;
DWORD index;
index = HMIndexFromHandle(h);
GETSHAREDINFO(psi);
if (!tryMove(si, psi)) {
DEBUGPRINT("HtoHE(%x): SHAREDINFO move failed.\n", h);
return(FALSE);
}
if (!tryMove(svi, si.psi)) {
DEBUGPRINT("HtoHE(%x): SERVERINFO move failed.\n", h);
return(FALSE);
}
if (index >= svi.cHandleEntries) {
DEBUGPRINT("HtoHE(%x): index %d is too large.\n", h, index);
return(FALSE);
}
if (pphe != NULL) {
*pphe = &si.aheList[index];
}
if (!tryMove(*phe, &si.aheList[index])) {
DEBUGPRINT("HtoHE(%x): aheList[%d] move failed.\n", h, index);
return(FALSE);
}
return(TRUE);
}
/************************************************************************\
* Procedure: dbgPtoH
*
* Description: quick conversion of pointer to handle
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL dbgPtoH(
PVOID p,
DWORD *ph)
{
THROBJHEAD head;
if (tryMove(head, p)) {
*ph = (DWORD)head.h;
return(TRUE);
}
DEBUGPRINT("dbgPtoH(%x): failed.\n", p);
return(FALSE);
}
/************************************************************************\
* Procedure: dbgHtoP
*
* Description: Quick conversion of handle to pointer
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL dbgHtoP(
DWORD h,
PVOID *pp)
{
HANDLEENTRY he;
if (HtoHE(h, &he, NULL)) {
*pp = FIXKP(he.phead);
return(TRUE);
}
DEBUGPRINT("dbgHtoP(%x): failed.\n", h);
return(FALSE);
}
/************************************************************************\
* Procedure: GetPfromH
*
* Description: Converts a handle to a pointer and extracts he and phe info.
*
* Returns: pointer for object or NULL on failure.
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
PVOID GetPfromH(
DWORD h,
HANDLEENTRY **pphe, // optional
HANDLEENTRY *phe) // optional
{
HANDLEENTRY he, *pheT;
HEAD head;
if (!HtoHE(h, &he, &pheT)) {
DEBUGPRINT("GetPfromH(%x): failed to get HE.\n", h);
return(NULL);
}
if (!tryMove(head, FIXKP(he.phead))) {
DEBUGPRINT("GetPfromH(%x): failed to get phead.\n", h);
return(NULL);
}
if (head.h != (HANDLE)h) {
Print("WARNING: Full handle for 0x%x is 0x%08lx.\n", h, head.h);
}
if (pphe != NULL) {
*pphe = pheT;
}
if (phe != NULL) {
*phe = he;
}
return(FIXKP(he.phead));
}
/************************************************************************\
* Procedure: getHEfromP
*
* Description: Converts a pointer to a handle and extracts the he and
* phe info.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL getHEfromP(
HANDLEENTRY **pphe, // optional
HANDLEENTRY *phe,
PVOID p)
{
PVOID pLookup;
THROBJHEAD head;
p = FIXKP(p);
if (!tryMove(head, p)) {
return(FALSE);
}
pLookup = GetPfromH((DWORD)head.h, pphe, phe);
if (FIXKP(pLookup) != p) {
DEBUGPRINT("getHEfromP(%x): invalid.\n", p);
return(FALSE);
}
return(TRUE);
}
/************************************************************************\
* Procedure: HorPtoP
*
* Description:
*
* Generic function to accept either a user handle or pointer value and
* validate it and convert it to a pointer. type=-1 to allow any non-free
* type. type=-2 to allow any type.
*
* Returns: pointer or NULL on error.
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
PVOID HorPtoP(
PVOID p,
int type)
{
HANDLEENTRY he;
PVOID pT;
if (p == NULL) {
DEBUGPRINT("HorPtoP(%x, %d): failed. got NULL.\n", p, type);
return(NULL);
}
p = FIXKP(p);
if (tryMove(pT, p) && getHEfromP(NULL, &he, p)) {
/*
* It was a pointer
*/
if ((type == -2 || he.bType != TYPE_FREE) &&
he.bType < TYPE_CTYPES &&
((int)type < 0 || he.bType == type)) {
return (PVOID)FIXKP(he.phead);
}
}
pT = GetPfromH((DWORD)p, NULL, &he);
if (pT == NULL) {
Print("WARNING: 0x%08lx is not a valid pointer or handle!\n", p);
return(p); // let it pass anyway so we can see how it got corrupted.
}
return FIXKP(pT);
}
/************************************************************************\
* Procedure: DebugGetWindowTextA
*
* Description: Places pwnd title into achDest. No checks for size are
* made.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL DebugGetWindowTextA(
PWND pwnd,
char *achDest)
{
WND wnd;
WCHAR awch[80];
if (pwnd == NULL) {
achDest[0] = '\0';
return(FALSE);
}
if (!tryMove(wnd, FIXKP(pwnd))) {
strcpy(achDest, "<< Can't get WND >>");
return FALSE;
}
if (wnd.strName.Buffer == NULL) {
strcpy(achDest, "<null>");
} else {
ULONG cbText;
cbText = min(sizeof(awch), wnd.strName.Length + sizeof(WCHAR));
if (!(tryMoveBlock(awch, FIXKP(wnd.strName.Buffer), cbText))) {
strcpy(achDest, "<< Can't get title >>");
return FALSE;
}
awch[sizeof(awch) / sizeof(WCHAR) - 1] = L'\0';
RtlUnicodeToMultiByteN(achDest, cbText / sizeof(WCHAR), NULL,
awch, cbText);
}
return TRUE;
}
/************************************************************************\
* Procedure: DebugGetClassNameA
*
* Description: Placed pcls name into achDest. No checks for size are
* made.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL DebugGetClassNameA(
LPSTR lpszClassName,
char *achDest)
{
CHAR ach[80];
if (lpszClassName == NULL) {
strcpy(achDest, "<null>");
} else {
move(ach, FIXKP(lpszClassName));
strcpy(achDest, ach);
}
return(TRUE);
}
char *pszObjStr[] = {
"Free",
"Window",
"Menu",
"Cursor",
"SetWindowPos",
"Hook",
"Thread Info",
"Clip Data",
"Call Proc",
"Accel Table",
"WindowStation",
"DeskTop",
"DdeAccess",
"DdeConv",
"DdeExact",
"Zombie",
"Ctypes",
"Console",
"Generic"
};
#ifdef KERNEL
/***********************************************************************\
* DumpGdiHandleType
*
* Returns: a static buffer address which will contain a >0 length
* string if the type makes sense.
*
* 12/1/1995 Created SanfordS
\***********************************************************************/
LPCSTR GetGDIHandleType(
HANDLE handle)
{
HOBJ ho; // dump this handle
PENTRY pent; // base address of hmgr entries
ENTRY ent; // copy of handle entry
BASEOBJECT obj;
ULONG ulTemp;
static CHAR szT[20];
ULONG gcMaxHmgr, index;
// filched from gre\hmgr.h
#define INDEX_MASK ((1 << INDEX_BITS) - 1)
#define HmgIfromH(h) ((ULONG)(h) & INDEX_MASK)
szT[0] = '\0';
ho = (HOBJ) handle;
moveExpValue(&pent, "win32k!gpentHmgr");
moveExp(&gcMaxHmgr, "win32k!gcMaxHmgr");
index = HmgIfromH((ULONG) ho);
if (index > gcMaxHmgr) {
return szT;
}
if (!tryMove(ent, &(pent[index]))) {
return szT;
}
if (ent.FullUnique != ((ULONG)ho >> 16)) {
return szT;
}
if (!tryMove(obj, ent.einfo.pobj)) {
return szT;
}
if (obj.hHmgr != ho) {
return szT;
}
ulTemp = (ULONG) ent.Objt;
switch(ulTemp) {
case DEF_TYPE:
strcpy(szT, "DEF");
break;
case DC_TYPE:
strcpy(szT, "DC");
break;
case DD_DIRECTDRAW_TYPE:
strcpy(szT, "DD_DRAW");
break;
case DD_SURFACE_TYPE:
strcpy(szT, "DD_SURF");
break;
case RGN_TYPE:
strcpy(szT, "RGN");
break;
case SURF_TYPE:
strcpy(szT, "SURF");
break;
case PATH_TYPE:
strcpy(szT, "PATH");
break;
case PAL_TYPE:
strcpy(szT, "PAL");
break;
case ICMLCS_TYPE:
strcpy(szT, "ICMLCS");
break;
case LFONT_TYPE:
strcpy(szT, "LFONT");
break;
case RFONT_TYPE:
strcpy(szT, "RFONT");
break;
case PFE_TYPE:
strcpy(szT, "PFE");
break;
case PFT_TYPE:
strcpy(szT, "PFT");
break;
case ICMCXF_TYPE:
strcpy(szT, "ICMCXF");
break;
case ICMDLL_TYPE:
strcpy(szT, "ICMDLL");
break;
case PFF_TYPE:
strcpy(szT, "PFF");
break;
case CACHE_TYPE:
strcpy(szT, "CACHE");
break;
case SPACE_TYPE:
strcpy(szT, "SPACE");
break;
case DBRUSH_TYPE:
strcpy(szT, "DBRUSH");
break;
case META_TYPE:
strcpy(szT, "META");
break;
case EFSTATE_TYPE:
strcpy(szT, "EFSTATE");
break;
case BMFD_TYPE:
strcpy(szT, "BMFD");
break;
case VTFD_TYPE:
strcpy(szT, "VTFD");
break;
case TTFD_TYPE:
strcpy(szT, "TTFD");
break;
case RC_TYPE:
strcpy(szT, "RC");
break;
case TEMP_TYPE:
strcpy(szT, "TEMP");
break;
case DRVOBJ_TYPE:
strcpy(szT, "DRVOBJ");
break;
case DCIOBJ_TYPE:
strcpy(szT, "DCIOBJ");
break;
case SPOOL_TYPE:
strcpy(szT, "SPOOL");
break;
default:
ulTemp = LO_TYPE(ent.FullUnique << TYPE_SHIFT);
switch (ulTemp) {
case LO_BRUSH_TYPE:
strcpy(szT, "BRUSH");
break;
case LO_PEN_TYPE:
strcpy(szT, "LO_PEN");
break;
case LO_EXTPEN_TYPE:
strcpy(szT, "LO_EXTPEN");
break;
case CLIENTOBJ_TYPE:
strcpy(szT, "CLIENTOBJ");
break;
case LO_METAFILE16_TYPE:
strcpy(szT, "LO_METAFILE16");
break;
case LO_METAFILE_TYPE:
strcpy(szT, "LO_METAFILE");
break;
case LO_METADC16_TYPE:
strcpy(szT, "LO_METADC16");
break;
}
}
return szT;
}
#endif // KERNEL
/***********************************************************************\
* Isas
*
* Analyzes the stack. Looks at a range of dwords and tries to make
* sense out of them. Identifies handles, user objects, and code
* addresses.
*
* Returns: fSuccess
*
* 11/30/1995 Created SanfordS
\***********************************************************************/
VOID DirectAnalyze(
DWORD dw,
DWORD adw,
BOOL fNoSym)
{
PHE phe;
HANDLEENTRY he;
DWORD index, dwOffset;
WORD uniq, w, aw;
HEAD head;
CHAR ach[80];
#ifdef KERNEL
LPCSTR psz;
#endif
Print("%08lx ", dw);
if (HIWORD(dw) != 0) {
/*
* See if its a handle
*/
index = HMIndexFromHandle(dw);
if (index < gSi.cHandleEntries) {
uniq = HMUniqFromHandle(dw);
phe = &gShi.aheList[index];
move(he, phe);
if (he.wUniq == uniq) {
Print("= a %s handle. ", pszObjStr[he.bType]);
fNoSym = TRUE;
}
}
#ifdef KERNEL
/*
* See if its a GDI object handle
*/
psz = GetGDIHandleType((HANDLE)dw);
if (*psz) {
Print("= a GDI %s type handle. ", psz);
fNoSym = TRUE;
}
#endif // KERNEL
/*
* See if its an object pointer
*/
if (tryMove(head, (PVOID)dw)) {
if (head.h) {
index = HMIndexFromHandle(head.h);
if (index < gSi.cHandleEntries) {
phe = &gShi.aheList[index];
move(he, phe);
if (he.phead == (PVOID)dw) {
Print("= a pointer to a %s.", pszObjStr[he.bType]);
fNoSym = TRUE;
}
}
}
/*
* Does this reference the stack itself?
*/
w = HIWORD(dw);
aw = HIWORD(adw);
if (w == aw || w == aw - 1 || w == aw + 1) {
Print("= Stack Reference ");
fNoSym = TRUE;
}
if (!fNoSym) {
/*
* Its accessible so print its symbolic reference
*/
GetSymbol((PVOID)dw, ach, &dwOffset);
if (*ach) {
Print("= symbol \"%s\"", ach);
if (dwOffset) {
Print(" + %x", dwOffset);
}
}
}
}
}
Print("\n");
}
BOOL Isas(
DWORD opts,
PVOID param1,
PVOID param2)
{
PSHAREDINFO pshi;
DWORD count = (DWORD)param2;
LPDWORD pdw;
DWORD dw;
if (param1 == 0) {
return FALSE;
}
/*
* Set up globals for speed.
*/
GETSHAREDINFO(pshi);
move(gShi, pshi);
if (!tryMove(gSi, gShi.psi)) {
Print("Could not access shared info\n");
return TRUE;
}
if (opts & OFLAG(d)) {
DirectAnalyze((DWORD)param1, 0, OFLAG(s) & opts);
} else {
pdw = param1;
if (pdw == NULL) {
Print("Hay bud, give me an address to look analyze.\n");
return FALSE;
}
if (count == 0) {
count = 25; // default span
}
Print("--- Stack analysis ---\n");
for ( ; count; count--, pdw++) {
if (IsCtrlCHit()) {
break;
}
Print("[%08lx]: ", pdw);
if (tryMove(dw, pdw))
DirectAnalyze(dw, (DWORD)pdw, OFLAG(s) & opts);
else
Print("No access\n");
}
}
return TRUE;
}
#ifdef KERNEL
/************************************************************************\
* Procedure: DumpAtomTable
*
* Description: Dumps an atom or entire atom table.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
VOID DumpAtomTable(
PRTL_ATOM_TABLE *ppat,
ATOM a)
{
RTL_ATOM_TABLE at, *pat;
RTL_ATOM_TABLE_ENTRY ate, *pate;
int iBucket;
LPWSTR pwsz;
BOOL fFirst;
move(pat, ppat);
if (pat == NULL) {
Print("is not initialized.\n");
return;
}
move(at, pat);
if (a) {
Print("\n");
} else {
Print("at %x\n", pat);
}
for (iBucket = 0; iBucket < (int)at.NumberOfBuckets; iBucket++) {
move(pate, &pat->Buckets[iBucket]);
if (pate != NULL && !a) {
Print("Bucket %2d:", iBucket);
}
fFirst = TRUE;
SAFEWHILE (pate != NULL) {
if (!fFirst && !a) {
Print(" ");
}
fFirst = FALSE;
move(ate, pate);
pwsz = (LPWSTR)LocalAlloc(LPTR, (ate.NameLength + 1) * sizeof(WCHAR));
moveBlock(pwsz, FIXKP(&pate->Name), ate.NameLength * sizeof(WCHAR));
pwsz[ate.NameLength] = L'\0';
if (a == 0 || a == (ATOM)(ate.HandleIndex | MAXINTATOM)) {
Print("%hx(%2d) = %ls (%d)%s\n",
(ATOM)(ate.HandleIndex | MAXINTATOM),
ate.ReferenceCount,
pwsz, ate.NameLength,
ate.Flags & RTL_ATOM_PINNED ? " pinned" : "");
if (a) {
LocalFree(pwsz);
return;
}
}
LocalFree(pwsz);
if (pate == ate.HashLink) {
Print("Bogus hash link at %x\n", pate);
break;
}
pate = ate.HashLink;
}
}
if (a)
Print("\n");
}
/************************************************************************\
* Procedure: Iatom
*
* Description: Dumps an atom or the entire local USER atom table.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Iatom(
DWORD opts,
PVOID param1)
{
PRTL_ATOM_TABLE *ppat;
ATOM a;
PWINDOWSTATION pwinsta;
try {
a = (ATOM)param1;
ppat = EvalExp(VAR(UserAtomTableHandle));
if (ppat != NULL) {
Print("\nPrivate atom table for WIN32K ");
DumpAtomTable(ppat, a);
}
FOREACHWINDOWSTATION(pwinsta)
ppat = (PRTL_ATOM_TABLE *)&pwinsta->pGlobalAtomTable;
if (ppat != NULL) {
Print("\nGlobal atom table for window station %lx ",
pwinsta);
DumpAtomTable(ppat, a);
}
NEXTEACHWINDOWSTATION(pwinsta);
} except (EXCEPTION_EXECUTE_HANDLER) {
;
}
return(TRUE);
}
#endif // KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: DumpConvInfo
*
* Description: Dumps DDEML client conversation info structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL DumpConvInfo(
PCONV_INFO pcoi)
{
CL_CONV_INFO coi;
ADVISE_LINK al;
XACT_INFO xi;
move(coi, pcoi);
Print(" next = 0x%08lx\n", coi.ci.next);
Print(" pcii = 0x%08lx\n", coi.ci.pcii);
Print(" hUser = 0x%08lx\n", coi.ci.hUser);
Print(" hConv = 0x%08lx\n", coi.ci.hConv);
Print(" laService = 0x%04x\n", coi.ci.laService);
Print(" laTopic = 0x%04x\n", coi.ci.laTopic);
Print(" hwndPartner = 0x%08lx\n", coi.ci.hwndPartner);
Print(" hwndConv = 0x%08lx\n", coi.ci.hwndConv);
Print(" state = 0x%04x\n", coi.ci.state);
Print(" laServiceRequested= 0x%04x\n", coi.ci.laServiceRequested);
Print(" pxiIn = 0x%08lx\n", coi.ci.pxiIn);
Print(" pxiOut = 0x%08lx\n", coi.ci.pxiOut);
SAFEWHILE (coi.ci.pxiOut) {
move(xi, coi.ci.pxiOut);
Print(" hXact = (0x%08lx)->0x%08lx\n", xi.hXact, coi.ci.pxiOut);
coi.ci.pxiOut = xi.next;
}
Print(" dmqIn = 0x%08lx\n", coi.ci.dmqIn);
Print(" dmqOut = 0x%08lx\n", coi.ci.dmqOut);
Print(" aLinks = 0x%08lx\n", coi.ci.aLinks);
Print(" cLinks = 0x%08lx\n", coi.ci.cLinks);
SAFEWHILE (coi.ci.cLinks--) {
move(al, coi.ci.aLinks++);
Print(" pLinkCount = 0x%08x\n", al.pLinkCount);
Print(" wType = 0x%08x\n", al.wType);
Print(" state = 0x%08x\n", al.state);
if (coi.ci.cLinks) {
Print(" ---\n");
}
}
if (coi.ci.state & ST_CLIENT) {
Print(" hwndReconnect = 0x%08lx\n", coi.hwndReconnect);
Print(" hConvList = 0x%08lx\n", coi.hConvList);
}
return TRUE;
}
#endif // !KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: GetTargetTEB
*
* Description: Retrieves the target thread's TEB
*
* Returns: fSuccess
*
* 6/15/1995 Created SanfordS
*
\************************************************************************/
BOOL
GetTargetTEB(
PTEB pteb,
PTEB *ppteb) // OPTIONAL
{
NTSTATUS Status;
THREAD_BASIC_INFORMATION ThreadInformation;
Status = NtQueryInformationThread( hCurrentThread,
ThreadBasicInformation,
&ThreadInformation,
sizeof( ThreadInformation ),
NULL);
if (NT_SUCCESS( Status )) {
if (ppteb != NULL) {
*ppteb = (PTEB)ThreadInformation.TebBaseAddress;
}
return(tryMove(*pteb, (LPVOID)ThreadInformation.TebBaseAddress));
}
return(FALSE);
}
#endif // !KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: FixKernelPointer
*
* Description: Used to convert a kernel object pointer into its client-
* side equivalent. Client pointers and NULL are unchanged.
*
* Returns: pClient
*
* 6/15/1995 Created SanfordS
*
\************************************************************************/
PVOID
FixKernelPointer(
PVOID pKernel)
{
static TEB teb;
static PTEB pteb = NULL;
if (pKernel == NULL) {
return(NULL);
}
if (pKernel < (PVOID)0x7FFF0000) {
return(pKernel);
}
if (pteb == NULL) {
GetTargetTEB(&teb, &pteb);
}
return((PVOID)(((PBYTE)pKernel) - ((PCLIENTINFO)(&teb.Win32ClientInfo[0]))->ulClientDelta));
}
#endif // !KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: Idcls
*
* Description: Dumps window class structures
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idcls(
DWORD opts,
PVOID param1)
{
char ach[120];
DWORD dwOffset;
CLS localCLS;
PCLS pcls = param1;
PROCESSINFO pi;
PPROCESSINFO ppi;
if (param1 == 0) {
PCLS pcls, pclsClone;
CLS cls, clsClone;
FOREACHPPI(ppi)
Print("\nClasses for process %x:\n", ppi);
move(pi, ppi);
pcls = pi.pclsPrivateList;
SAFEWHILE (pcls != NULL) {
move(cls, pcls);
Print(" Private class\t\t");
Idcls(opts, pcls);
for (pclsClone = cls.pclsClone;
pclsClone != NULL;
pclsClone = clsClone.pclsNext) {
move(clsClone, pclsClone);
Print(" Private class clone\t");
Idcls(opts, pcls);
}
pcls = cls.pclsNext;
}
pcls = pi.pclsPublicList;
SAFEWHILE (pcls != NULL) {
move(cls, pcls);
Print(" Public class\t\t");
Idcls(opts, pcls);
for (pclsClone = cls.pclsClone; pclsClone != NULL;
pclsClone = clsClone.pclsNext) {
move(clsClone, pclsClone);
Print(" Public class clone\t");
Idcls(opts, pcls);
}
pcls = cls.pclsNext;
}
NEXTEACHPPI()
Print("\nGlobal Classes:\n");
moveExpValue(&pcls, "win32k!gpclsList");
SAFEWHILE (pcls) {
Print(" Global class\t\t");
Idcls(opts, pcls);
move(pcls, &pcls->pclsNext);
}
return(TRUE);
}
move(localCLS, pcls);
DebugGetClassNameA(localCLS.lpszAnsiClassName, ach);
Print("PCLS @ 0x%lx \t(%s)\n", pcls, ach);
if (opts & OFLAG(v)) {
Print("\t pclsNext @0x%08lx\n"
"\t atomClassNameAtom 0x%04x\n"
"\t fnid 0x%04x\n"
"\t pDCE @0x%08lx\n"
"\t cWndReferenceCount 0x%08lx\n"
"\t flags %s\n",
localCLS.pclsNext,
localCLS.atomClassName,
localCLS.fnid,
localCLS.pdce,
localCLS.cWndReferenceCount,
GetFlags(GF_CSF, (WORD)localCLS.flags, NULL));
if (localCLS.lpszClientAnsiMenuName) {
move(ach, localCLS.lpszClientAnsiMenuName);
ach[sizeof(ach) - 1] = '\0';
} else {
ach[0] = '\0';
}
Print("\t lpszClientMenu @0x%08lx (%s)\n"
"\t pclsBase @0x%08lx\n"
"\t pclsClone @0x%08lx\n",
localCLS.lpszClientUnicodeMenuName,
ach,
localCLS.pclsBase,
localCLS.pclsClone);
Print("\t adwWOW 0x%08lx 0x%08lx\n"
"\t hTaskWow 0x%08lx\n"
"\t spcpdFirst @0x%08lx\n"
"\t pclsBase @0x%08lx\n"
"\t pclsClone @0x%08lx\n"
"\t lpfnWorker @0x%08lx\n",
localCLS.adwWOW[0], localCLS.adwWOW[1],
localCLS.hTaskWow,
localCLS.spcpdFirst,
localCLS.pclsBase,
localCLS.pclsClone,
localCLS.lpfnWorker);
GetSymbol((LPVOID)localCLS.lpfnWndProc, ach, &dwOffset);
Print("\t style %s\n"
"\t lpfnWndProc @0x%08lx = \"%s\" \n"
"\t cbclsExtra 0x%08lx\n"
"\t cbwndExtra 0x%08lx\n"
"\t hModule 0x%08lx\n"
"\t spicn @0x%08lx\n"
"\t spcur @0x%08lx\n"
"\t hbrBackground 0x%08lx\n"
"\t spicnSm @0x%08lx\n",
GetFlags(GF_CS, (WORD)localCLS.style, NULL),
localCLS.lpfnWndProc, ach,
localCLS.cbclsExtra,
localCLS.cbwndExtra,
localCLS.hModule,
localCLS.spicn,
localCLS.spcur,
localCLS.hbrBackground,
localCLS.spicnSm);
}
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
LPSTR ProcessName(
PPROCESSINFO ppi)
{
W32PROCESS w32p;
static UCHAR ImageFileName[16];
move(w32p, ppi);
GetEProcessData(w32p.Process, PROCESS_IMAGEFILENAME, ImageFileName);
if (ImageFileName[0]) {
return(ImageFileName);
} else {
return("System");
}
}
VOID PrintCurHeader()
{
Print("P = Process Owned.\n");
Print("P .pcursor flg rt ..lpName aMod bpp ..cx ..cy xHot yHot .hbmMask hbmColor\n");
}
VOID PrintCurData(
PCURSOR pcur,
DWORD opts)
{
CURSOR cur;
move(cur, pcur);
if ((opts & OFLAG(x)) &&
cur.CURSORF_flags & (CURSORF_ACONFRAME | CURSORF_LINKED)) {
return; // skip acon frame or linked objects.
}
if (cur.CURSORF_flags & CURSORF_ACON) {
ACON acon;
if (opts & OFLAG(a)) {
Print("--------------\n");
}
if (opts & OFLAG(o)) {
Print("Owner:%x(%s)\n", cur.head.ppi, ProcessName(cur.head.ppi));
}
move(acon, pcur);
if (opts & OFLAG(v)) {
Print("\nACON @%x:\n", pcur);
Print(" ppiOwner = %x\n", (DWORD)cur.head.ppi);
Print(" CURSORF_flags = %s\n", GetFlags(GF_CURSORF, cur.CURSORF_flags, NULL));
Print(" strName = %x\n", (DWORD)cur.strName.Buffer);
Print(" atomModName = %x\n", cur.atomModName);
Print(" rt = %x\n", cur.rt);
} else {
Print("%c %8x %3x %2x %8x %4x --- ACON (%d frames)\n",
cur.head.ppi ? 'P' : ' ',
pcur,
cur.CURSORF_flags,
cur.rt,
cur.strName.Buffer,
cur.atomModName,
acon.cpcur);
}
if (opts & OFLAG(a)) {
Print("%d animation sequences, currently at step %d.\n",
acon.cicur,
acon.iicur);
while (acon.cpcur--) {
move(pcur, acon.aspcur++);
PrintCurData(pcur, opts & ~(OFLAG(x) | OFLAG(o)));
}
Print("--------------\n");
}
} else {
if (opts & OFLAG(v)) {
Print("\nCursor/Icon @%x:\n", pcur);
Print(" ppiOwner = %x(%s)\n",
(DWORD)cur.head.ppi,
ProcessName(cur.head.ppi));
Print(" pcurNext = %x\n", cur.pcurNext);
Print(" CURSORF_flags = %s\n", GetFlags(GF_CURSORF, cur.CURSORF_flags, NULL));
Print(" strName = %x\n", (DWORD)cur.strName.Buffer);
Print(" atomModName = %x\n", cur.atomModName);
Print(" rt = %x\n", cur.rt);
Print(" bpp = %x\n", cur.bpp);
Print(" cx = %x\n", cur.cx);
Print(" cy = %x\n", cur.cy);
Print(" xHotspot = %x\n", cur.xHotspot);
Print(" yHotspot = %x\n", cur.yHotspot);
Print(" hbmMask = %x\n", cur.hbmMask);
Print(" hbmColor = %x\n", cur.hbmColor);
} else {
if (opts & OFLAG(o)) {
Print("Owner:%x(%s)\n", cur.head.ppi, ProcessName(cur.head.ppi));
}
Print("%c %8x %3x %2x %8x %4x %3x %4x %4x %4x %4x %8x %8x\n",
cur.head.ppi ? 'P' : ' ',
pcur,
cur.CURSORF_flags,
cur.rt,
cur.strName.Buffer,
cur.atomModName,
cur.bpp,
cur.cx,
cur.cy,
cur.xHotspot,
cur.yHotspot,
cur.hbmMask,
cur.hbmColor);
}
}
}
/************************************************************************\
* Procedure: Idcur
*
* Description: Dump cursor structures
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idcur(
DWORD opts,
PVOID param1)
{
PROCESSINFO pi, *ppi, *ppiDesired = NULL;
CURSOR cur, *pcur;
int cCursors = 0;
int idDesired = 0;
HANDLEENTRY he, *phe;
int i;
if (OFLAG(p) & opts) {
ppiDesired = (PPROCESSINFO)param1;
param1 = NULL;
} else if (OFLAG(i) & opts) {
idDesired = (int)param1;
param1 = NULL;
}
if (param1 == NULL) {
if (!(OFLAG(v) & opts)) {
PrintCurHeader();
}
moveExpValue(&pcur, "win32k!gpcurFirst");
if (pcur != NULL && ppiDesired == NULL) {
Print("Global cache:\n");
while (pcur) {
move(cur, pcur);
if (!idDesired || ((int)cur.strName.Buffer == idDesired)) {
if (cur.head.ppi != NULL) {
Print("Wrong cache! Owned by %x! --v\n", cur.head.ppi);
}
PrintCurData((PCURSOR)pcur, opts);
}
pcur = cur.pcurNext;
}
}
FOREACHPPI(ppi)
if (ppiDesired == NULL || ppiDesired == ppi) {
if (tryMove(pi, ppi)) {
if (pi.pCursorCache) {
Print("Cache for process %x(%s):\n", ppi, ProcessName(ppi));
pcur = pi.pCursorCache;
while (pcur) {
if (tryMove(cur, pcur)) {
if (!idDesired || ((int)cur.strName.Buffer == idDesired)) {
if (cur.head.ppi != ppi) {
Print("Wrong cache! Owned by %x! --v\n", cur.head.ppi);
}
PrintCurData((PCURSOR)pcur, opts);
}
pcur = cur.pcurNext;
} else {
Print("Could not access %x.\n", pcur);
break;
}
}
}
} else {
Print("Failed to access ppi %x.\n", ppi);
}
}
NEXTEACHPPI();
Print("Non-cached cursor objects:\n");
FOREACHHANDLEENTRY(phe, he, i)
if (he.bType == TYPE_CURSOR) {
CURSOR cur;
if (tryMove(cur, he.phead)) {
if (!(cur.CURSORF_flags & (CURSORF_LINKED | CURSORF_ACONFRAME)) &&
(!idDesired || (int)cur.strName.Buffer == idDesired) &&
(ppiDesired == NULL || ppiDesired == cur.head.ppi)) {
Print("%x:", i);
PrintCurData((PCURSOR)he.phead, opts | OFLAG(x) | OFLAG(o));
}
} else {
Print("Could not access phead(%x) of handle %x.\n", he.phead, i);
}
cCursors++;
}
NEXTEACHHANDLEENTRY()
Print("%d Cursors/Icons Total.\n", cCursors);
return(TRUE);
}
pcur = HorPtoP(param1, TYPE_CURSOR);
if (pcur == NULL) {
Print("%8x : Invalid cursor handle or pointer.\n", param1);
return(FALSE);
}
if (!(OFLAG(v) & opts)) {
PrintCurHeader();
}
PrintCurData(pcur, opts);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: ddeexact
*
* Description: Dumps DDEML transaction structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL dddexact(
DWORD pOrg,
PXSTATE pxs,
DWORD opts)
{
if (opts & OFLAG(v)) {
Print(" XACT:0x%08lx\n", pOrg);
Print(" snext = 0x%08lx\n", pxs->snext);
Print(" fnResponse = 0x%08lx\n", pxs->fnResponse);
Print(" hClient = 0x%08lx\n", pxs->hClient);
Print(" hServer = 0x%08lx\n", pxs->hServer);
Print(" pIntDdeInfo = 0x%08lx\n", pxs->pIntDdeInfo);
} else {
Print("0x%08lx(0x%08lx) ", pOrg, pxs->flags);
}
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: ddeconv
*
* Description: Dumps DDE tracking layer conversation structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL dddeconv(
DWORD pOrg,
PDDECONV pddeconv,
DWORD opts)
{
DDEIMP ddei;
XSTATE xs;
PXSTATE pxs;
int cX;
Print(" CONVERSATION-PAIR(0x%08lx:0x%08lx)\n", pOrg, pddeconv->spartnerConv);
if (opts & OFLAG(v)) {
Print(" snext = 0x%08lx\n", pddeconv->snext);
Print(" spwnd = 0x%08lx\n", pddeconv->spwnd);
Print(" spwndPartner = 0x%08lx\n", pddeconv->spwndPartner);
}
if (opts & (OFLAG(v) | OFLAG(r))) {
if (pddeconv->spxsOut) {
pxs = pddeconv->spxsOut;
cX = 0;
SAFEWHILE (pxs) {
move(xs, pxs);
if ((opts & OFLAG(r)) && !cX++) {
Print(" Transaction chain:");
} else {
Print(" ");
}
dddexact((DWORD)pxs, &xs, opts);
if (opts & OFLAG(r)) {
pxs = xs.snext;
} else {
pxs = NULL;
}
if (!pxs) {
Print("\n");
}
}
}
}
if (opts & OFLAG(v)) {
Print(" pfl = 0x%08lx\n", pddeconv->pfl);
Print(" flags = 0x%08lx\n", pddeconv->flags);
if ((opts & OFLAG(v)) && (opts & OFLAG(r)) && pddeconv->pddei) {
Print(" pddei = 0x%08lx\n", pddeconv->pddei);
move(ddei, pddeconv->pddei);
Print(" Impersonation info:\n");
Print(" qos.Length = 0x%08lx\n", ddei.qos.Length);
Print(" qos.ImpersonationLevel = 0x%08lx\n", ddei.qos.ImpersonationLevel);
Print(" qos.ContextTrackingMode = 0x%08lx\n", ddei.qos.ContextTrackingMode);
Print(" qos.EffectiveOnly = 0x%08lx\n", ddei.qos.EffectiveOnly);
Print(" ClientContext = 0x%08lx\n", &ddei.ClientContext);
Print(" cRefInit = 0x%08lx\n", ddei.cRefInit);
Print(" cRefConv = 0x%08lx\n", ddei.cRefConv);
}
}
return TRUE;
}
#endif // KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: Idde
*
* Description: Dumps DDE tracking layer state and structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idde(
DWORD opts,
PVOID param1)
{
HEAD head;
DDECONV ddeconv;
PSHAREDINFO pshi;
SHAREDINFO shi;
SERVERINFO si;
HANDLEENTRY he;
DWORD cHandleEntries;
HANDLE h;
WND wnd;
UINT cObjs = 0, i;
PVOID pObj = NULL;
PHE pheList;
PROP propList;
PPROP ppropList;
DWORD atomDdeTrack;
XSTATE xs;
moveExpValue(&atomDdeTrack, "win32k!atomDDETrack");
GETSHAREDINFO(pshi);
move(shi, pshi);
move(si, shi.psi);
cHandleEntries = si.cHandleEntries;
pheList = shi.aheList;
if (param1) {
/*
* get object param.
*/
h = (HANDLE)param1;
i = HMIndexFromHandle(h);
if (i >= cHandleEntries) {
move(head, h);
i = HMIndexFromHandle(head.h);
}
if (i >= cHandleEntries) {
Print("0x%08lx is not a valid object.\n", h);
return(FALSE);
}
move(he, &pheList[i]);
pObj = FIXKP(he.phead);
/*
* verify type.
*/
switch (he.bType) {
case TYPE_WINDOW:
move(wnd, pObj);
ppropList = wnd.ppropList;
SAFEWHILE (ppropList != NULL) {
cObjs++;
if (cObjs == 1) {
Print("Window 0x%08lx conversations:\n", h);
}
move(propList, ppropList);
if (propList.atomKey == (ATOM)MAKEINTATOM(atomDdeTrack)) {
move(ddeconv, (PDDECONV)propList.hData);
Print(" ");
dddeconv((DWORD)propList.hData,
&ddeconv,
opts);
}
ppropList = propList.ppropNext;
}
return(TRUE);
case TYPE_DDECONV:
case TYPE_DDEXACT:
break;
default:
Print("0x%08lx is not a valid window, conversation or transaction object.\n", h);
return(FALSE);
}
}
/*
* look for all qualifying objects in the object table.
*/
Print("DDE objects:\n");
for (i = 0; i < cHandleEntries; i++) {
move(he, &pheList[i]);
if (he.bType == TYPE_DDECONV && (pObj == FIXKP(he.phead) || pObj == NULL)) {
cObjs++;
move(ddeconv, FIXKP(he.phead));
dddeconv((DWORD)FIXKP(he.phead),
(PDDECONV)&ddeconv,
opts);
}
if (he.bType == TYPE_DDEXACT && (pObj == NULL || pObj == FIXKP(he.phead))) {
cObjs++;
move(xs, FIXKP(he.phead));
if (!(opts & OFLAG(v))) {
Print(" XACT:");
}
dddexact((DWORD)FIXKP(he.phead),
(PXSTATE)&xs,
opts);
Print("\n");
}
}
return(TRUE);
}
#endif // KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: Iddeml
*
* Description: Dumps the DDEML state for this client process.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Iddeml(
DWORD opts,
LPSTR lpas)
{
CHANDLEENTRY he, *phe;
int cHandles, ch, i;
DWORD Instance, Type, Object, Pointer;
CL_INSTANCE_INFO cii, *pcii;
ATOM ns;
SERVER_LOOKUP sl;
LINK_COUNT lc;
CL_CONV_INFO cci;
PCL_CONV_INFO pcci;
CONVLIST cl;
HWND hwnd, *phwnd;
XACT_INFO xi;
DDEMLDATA dd;
CONV_INFO ci;
moveExpValue(&cHandles, "user32!cHandlesAllocated");
Instance = 0;
Type = 0;
Object = 0;
Pointer = 0;
SAFEWHILE (*lpas) {
SAFEWHILE (*lpas == ' ')
lpas++;
if (*lpas == 'i') {
lpas++;
Instance = (DWORD)EvalExp(lpas);
SAFEWHILE (*lpas != ' ' && *lpas != 0)
lpas++;
continue;
}
if (*lpas == 't') {
lpas++;
Type = (DWORD)EvalExp(lpas);
SAFEWHILE (*lpas != ' ' && *lpas != 0)
lpas++;
continue;
}
if (*lpas) {
Object = Pointer = (DWORD)EvalExp(lpas);
SAFEWHILE (*lpas != ' ' && *lpas != 0)
lpas++;
}
}
/*
* for each instance for this process...
*/
moveExpValue(&pcii, "user32!pciiList");
if (pcii == NULL) {
Print("No Instances exist.\n");
return(TRUE);
}
move(cii, pcii);
SAFEWHILE(pcii != NULL) {
pcii = cii.next;
if (Instance == 0 || (Instance == (DWORD)cii.hInstClient)) {
Print("Objects for instance 0x%08lx:\n", cii.hInstClient);
ch = cHandles;
moveExpValue(&phe, "user32!aHandleEntry");
SAFEWHILE (ch--) {
move(he, phe++);
if (he.handle == 0) {
continue;
}
if (InstFromHandle(cii.hInstClient) != InstFromHandle(he.handle)) {
continue;
}
if (Type && TypeFromHandle(he.handle) != Type) {
continue;
}
if (Object && (he.handle != (HANDLE)Object) &&
Pointer && he.dwData != Pointer) {
continue;
}
Print(" (0x%08lx)->0x%08lx ", he.handle, he.dwData);
switch (TypeFromHandle(he.handle)) {
case HTYPE_INSTANCE:
Print("Instance\n");
if (opts & OFLAG(v)) {
Print(" next = 0x%08lx\n", cii.next);
Print(" hInstServer = 0x%08lx\n", cii.hInstServer);
Print(" hInstClient = 0x%08lx\n", cii.hInstClient);
Print(" MonitorFlags = 0x%08lx\n", cii.MonitorFlags);
Print(" hwndMother = 0x%08lx\n", cii.hwndMother);
Print(" hwndEvent = 0x%08lx\n", cii.hwndEvent);
Print(" hwndTimeout = 0x%08lx\n", cii.hwndTimeout);
Print(" afCmd = 0x%08lx\n", cii.afCmd);
Print(" pfnCallback = 0x%08lx\n", cii.pfnCallback);
Print(" LastError = 0x%08lx\n", cii.LastError);
Print(" tid = 0x%08lx\n", cii.tid);
Print(" plaNameService = 0x%08lx\n", cii.plaNameService);
Print(" cNameServiceAlloc = 0x%08lx\n", cii.cNameServiceAlloc);
SAFEWHILE (cii.cNameServiceAlloc--) {
move(ns, cii.plaNameService++);
Print(" 0x%04lx\n", ns);
}
Print(" aServerLookup = 0x%08lx\n", cii.aServerLookup);
Print(" cServerLookupAlloc = 0x%08lx\n", cii.cServerLookupAlloc);
SAFEWHILE (cii.cServerLookupAlloc--) {
move(sl, cii.aServerLookup++);
Print(" laService = 0x%04x\n", sl.laService);
Print(" laTopic = 0x%04x\n", sl.laTopic);
Print(" hwndServer = 0x%08lx\n", sl.hwndServer);
if (cii.cServerLookupAlloc) {
Print(" ---\n");
}
}
Print(" ConvStartupState = 0x%08lx\n", cii.ConvStartupState);
Print(" flags = %s\n",
GetFlags(GF_IIF, cii.flags, NULL));
Print(" cInDDEMLCallback = 0x%08lx\n", cii.cInDDEMLCallback);
Print(" pLinkCount = 0x%08lx\n", cii.pLinkCount);
SAFEWHILE (cii.pLinkCount) {
move(lc, cii.pLinkCount);
cii.pLinkCount = lc.next;
Print(" next = 0x%08lx\n", lc.next);
Print(" laTopic = 0x%04x\n", lc.laTopic);
Print(" gaItem = 0x%04x\n", lc.gaItem);
Print(" laItem = 0x%04x\n", lc.laItem);
Print(" wFmt = 0x%04x\n", lc.wFmt);
Print(" Total = 0x%04x\n", lc.Total);
Print(" Count = 0x%04x\n", lc.Count);
if (cii.pLinkCount != NULL) {
Print(" ---\n");
}
}
}
break;
case HTYPE_ZOMBIE_CONVERSATION:
Print("Zombie Conversation\n");
if (opts & OFLAG(v)) {
DumpConvInfo((PCONV_INFO)he.dwData);
}
break;
case HTYPE_SERVER_CONVERSATION:
Print("Server Conversation\n");
if (opts & OFLAG(v)) {
DumpConvInfo((PCONV_INFO)he.dwData);
}
break;
case HTYPE_CLIENT_CONVERSATION:
Print("Client Conversation\n");
if (opts & OFLAG(v)) {
DumpConvInfo((PCONV_INFO)he.dwData);
}
break;
case HTYPE_CONVERSATION_LIST:
Print("Conversation List\n");
if (opts & OFLAG(v)) {
move(cl, (PVOID)he.dwData);
Print(" pcl = 0x%08lx\n", he.dwData);
Print(" chwnd = 0x%08lx\n", cl.chwnd);
i = 0;
phwnd = (HWND *)&((PCONVLIST)he.dwData)->ahwnd;
SAFEWHILE(cl.chwnd--) {
move(hwnd, phwnd++);
Print(" ahwnd[%d] = 0x%08lx\n", i, hwnd);
pcci = (PCL_CONV_INFO)GetWindowLong(hwnd, GWL_PCI);
SAFEWHILE (pcci) {
move(cci, pcci);
pcci = (PCL_CONV_INFO)cci.ci.next;
Print(" hConv = 0x%08lx\n", cci.ci.hConv);
}
i++;
}
}
break;
case HTYPE_TRANSACTION:
Print("Transaction\n");
if (opts & OFLAG(v)) {
move(xi, (PVOID)he.dwData);
Print(" next = 0x%08lx\n", xi.next);
Print(" pcoi = 0x%08lx\n", xi.pcoi);
move(ci, xi.pcoi);
Print(" hConv = 0x%08lx\n", ci.hConv);
Print(" hUser = 0x%08lx\n", xi.hUser);
Print(" hXact = 0x%08lx\n", xi.hXact);
Print(" pfnResponse = 0x%08lx\n", xi.pfnResponse);
Print(" gaItem = 0x%04x\n", xi.gaItem);
Print(" wFmt = 0x%04x\n", xi.wFmt);
Print(" wType; = 0x%04x\n", xi.wType);
Print(" wStatus; = 0x%04x\n", xi.wStatus);
Print(" flags; = %s\n",
GetFlags(GF_XI, xi.flags, NULL));
Print(" state; = 0x%04x\n", xi.state);
Print(" hDDESent = 0x%08lx\n", xi.hDDESent);
Print(" hDDEResult = 0x%08lx\n", xi.hDDEResult);
}
break;
case HTYPE_DATA_HANDLE:
Print("Data Handle\n");
if (opts & OFLAG(v)) {
move(dd, (PVOID)he.dwData);
Print(" hDDE = 0x%08lx\n", dd.hDDE);
Print(" flags = %s\n",
GetFlags(GF_HDATA, (WORD)dd.flags, NULL));
}
break;
}
}
}
if (pcii != NULL) {
move(cii, pcii);
}
}
return(TRUE);
}
#endif // !KERNEL
#ifdef KERNEL
/***************************************************************************\
* ddesk - dumps list of desktops
* ddesk address - dumps simple statistics for desktop
* ddesk v address - dumps verbose statistics for desktop
* ddesk h address - dumps statistics for desktop plus handle list
*
* Dump handle table statistics.
*
* 02-21-92 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Iddesk(
DWORD opts,
PVOID param1)
{
PWINDOWSTATION pwinsta = NULL;
PWINDOWSTATION pwinstaOne = NULL;
WINDOWSTATION winsta;
PDESKTOP pdesk;
DESKTOP desk;
WND wnd;
MENU menu;
CALLPROCDATA cpd;
HOOK hook;
DESKTOPINFO di;
DWORD cClasses = 0;
DWORD acHandles[TYPE_CTYPES];
BOOL abTrack[TYPE_CTYPES];
HANDLEENTRY he;
PHE phe;
DWORD i;
WCHAR ach[80];
OBJECT_HEADER Head;
OBJECT_HEADER_NAME_INFO NameInfo;
BOOL fMatch;
if (opts & OFLAG(w)) {
pwinstaOne = (PWINDOWSTATION)param1;
}
/*
* If there is no address, list all desktops.
*/
if (!param1) {
if (pwinstaOne == NULL) {
moveExpValue(&pwinsta, VAR(grpwinstaList));
} else
pwinsta = pwinstaOne;
SAFEWHILE (pwinsta != NULL) {
DEBUGPRINT("WINSTA @ %x\n", pwinsta);
move(winsta, pwinsta);
move(Head, OBJECT_TO_OBJECT_HEADER(pwinsta));
move(NameInfo, ((PCHAR)(OBJECT_TO_OBJECT_HEADER(pwinsta)) - Head.NameInfoOffset));
move(ach, NameInfo.Name.Buffer);
ach[NameInfo.Name.Length / sizeof(WCHAR)] = 0;
Print("Windowstation: %ws\n", ach);
Print("Logon desktop = %x\n", winsta.rpdeskLogon);
if (winsta.rpdeskLogon != NULL) {
Iddesk(opts & OFLAG(v) | OFLAG(h), winsta.rpdeskLogon);
}
Print("Other desktops:\n");
pdesk = winsta.rpdeskList;
SAFEWHILE (pdesk) {
if (pdesk != winsta.rpdeskLogon) {
Print("Desktop at %x\n", pdesk);
Iddesk(opts & OFLAG(v) | OFLAG(h), pdesk);
}
move(desk, pdesk);
pdesk = desk.rpdeskNext;
}
if (pwinstaOne != NULL)
break;
Print("\n");
pwinsta = winsta.rpwinstaNext;
}
return(TRUE);
}
pdesk = (PDESKTOP)param1;
move(desk, pdesk);
move(Head, OBJECT_TO_OBJECT_HEADER(pdesk));
move(NameInfo, ((PCHAR)(OBJECT_TO_OBJECT_HEADER(pdesk)) - Head.NameInfoOffset));
move(ach, NameInfo.Name.Buffer);
ach[NameInfo.Name.Length / sizeof(WCHAR)] = 0;
Print("Name: %ws\n", ach);
move(Head, OBJECT_TO_OBJECT_HEADER(pdesk));
Print("# Opens = %d\n", Head.HandleCount);
Print("Heap = %08x\n", desk.hheapDesktop);
Print("Menu pwnd = %08x\n", desk.spwndMenu);
Print("System pmenu = %08x\n", desk.spmenuSys);
Print("Console thread = %x\n", desk.dwConsoleThreadId);
Print("PtiList.Flink %08x\n", desk.PtiList.Flink);
if (!tryMove(di, desk.pDeskInfo)) {
Print("Unable to get DESKTOPINFO at %x\n", desk.pDeskInfo);
} else {
Print("Desktop pwnd = %08x\n", di.spwnd);
Print("\tfsHooks 0x%08lx\n"
"\tasphkStart\n",
di.fsHooks);
DUMPHOOKS("WH_MSGFILTER", WH_MSGFILTER);
DUMPHOOKS("WH_JOURNALRECORD", WH_JOURNALRECORD);
DUMPHOOKS("WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK);
DUMPHOOKS("WH_KEYBOARD", WH_KEYBOARD);
DUMPHOOKS("WH_GETMESSAGE", WH_GETMESSAGE);
DUMPHOOKS("WH_CALLWNDPROC", WH_CALLWNDPROC);
DUMPHOOKS("WH_CALLWNDPROCRET", WH_CALLWNDPROCRET);
DUMPHOOKS("WH_CBT", WH_CBT);
DUMPHOOKS("WH_SYSMSGFILTER", WH_SYSMSGFILTER);
DUMPHOOKS("WH_MOUSE", WH_MOUSE);
DUMPHOOKS("WH_HARDWARE", WH_HARDWARE);
DUMPHOOKS("WH_DEBUG", WH_DEBUG);
DUMPHOOKS("WH_SHELL", WH_SHELL);
DUMPHOOKS("WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE);
}
/*
* Find all objects allocated from the desktop.
*/
for (i = 0; i < TYPE_CTYPES; i++) {
abTrack[i] = FALSE;
acHandles[i] = 0;
}
abTrack[TYPE_WINDOW] = abTrack[TYPE_MENU] =
abTrack[TYPE_CALLPROC] =
abTrack[TYPE_HOOK] = TRUE;
if (opts & OFLAG(v)) {
Print("Handle Type\n");
Print("--------------------\n");
}
FOREACHHANDLEENTRY(phe, he, i)
fMatch = FALSE;
try {
switch (he.bType) {
case TYPE_WINDOW:
move(wnd, FIXKP(he.phead));
if (wnd.head.rpdesk == pdesk)
fMatch = TRUE;
break;
case TYPE_MENU:
move(menu, FIXKP(he.phead));
if (menu.head.rpdesk == pdesk)
fMatch = TRUE;
break;
case TYPE_CALLPROC:
move(cpd, FIXKP(he.phead));
if (cpd.head.rpdesk == pdesk)
fMatch = TRUE;
break;
case TYPE_HOOK:
move(hook, FIXKP(he.phead));
if (hook.head.rpdesk == pdesk)
fMatch = TRUE;
break;
default:
break;
}
} except (EXCEPTION_EXECUTE_HANDLER) {
;
}
if (!fMatch)
continue;
acHandles[he.bType]++;
if (opts & OFLAG(v)) {
Print("0x%08lx %c %s\n",
i,
(he.bFlags & HANDLEF_DESTROY) ? '*' : ' ',
aszTypeNames[he.bType]);
}
NEXTEACHHANDLEENTRY()
if (!(opts & OFLAG(v))) {
Print("Count Type\n");
Print("--------------------\n");
Print("0x%08lx Class\n", cClasses);
for (i = 0; i < TYPE_CTYPES; i++) {
if (abTrack[i])
Print("0x%08lx %s\n", acHandles[i], aszTypeNames[i]);
}
}
Print("\n");
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
BOOL Idf(DWORD opts, LPSTR pszName)
{
static char *szLevels[8] = {
"<none>",
"Errors",
"Warnings",
"Errors and Warnings",
"Verbose",
"Errors and Verbose",
"Warnings and Verbose",
"Errors, Warnings, and Verbose"
};
NTSTATUS status;
ULONG ulFlags;
BOOL fSet;
PSERVERINFO psi;
DWORD dwRipFlags;
moveExpValue(&psi, VAR(gpsi));
move(dwRipFlags, &psi->RipFlags);
fSet = FALSE;
for (;;) {
if ('0' <= *pszName && *pszName <= '9') {
fSet = TRUE;
break;
}
if (*pszName != ' ' && *pszName != '\t') {
break;
}
pszName++;
}
if (fSet) {
status = RtlCharToInteger(pszName, 16, &ulFlags);
if (NT_SUCCESS(status) && !(ulFlags & ~RIPF_VALIDUSERFLAGS)) {
dwRipFlags = (dwRipFlags & ~RIPF_VALIDUSERFLAGS) | ulFlags;
(lpExtensionApis->lpWriteProcessMemoryRoutine)(
(ULONG) (&psi->RipFlags),
(void *) &dwRipFlags,
sizeof(dwRipFlags),
NULL);
move(dwRipFlags, &psi->RipFlags);
}
}
Print("Flags = %x\n", dwRipFlags & RIPF_VALIDUSERFLAGS);
Print(" Print File/Line %sabled\n", (dwRipFlags & RIPF_PRINTFILELINE) ? "en" : "dis");
Print(" Print on %s\n", szLevels[(dwRipFlags & 0x70) >> 4]);
Print(" Prompt on %s\n", szLevels[dwRipFlags & 0x07]);
return TRUE;
}
#endif
/************************************************************************\
* Procedure: Idhe
*
* Description: Dump Handle Entry
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idhe(
DWORD opts,
PVOID param1)
{
THROBJHEAD head;
DWORD dw;
PHE pheT;
HANDLEENTRY he, *phe;
int i;
PBYTE pabObjectCreateFlags = NULL;
#ifdef KERNEL
BYTE abObjectCreateFlags[TYPE_CTYPES];
#endif // KERNEL
if (param1 != NULL) {
dw = (DWORD)HorPtoP(param1, -2);
if (dw == 0) {
Print("0x%08lx is not a valid object or handle.\n", param1);
return(FALSE);
}
} else {
FOREACHHANDLEENTRY(phe, he, i)
if (he.bType != TYPE_FREE) {
Idhe(opts, he.phead);
Print("\n");
}
NEXTEACHHANDLEENTRY()
return(FALSE);
}
if (!getHEfromP(&pheT, &he, (PVOID)dw)) {
Print("%x is not a USER handle manager object.\n", param1);
return(FALSE);
}
#ifdef KERNEL
if (he.pOwner != NULL) {
pabObjectCreateFlags = EvalExp(VAR(gabObjectCreateFlags));
move(abObjectCreateFlags, pabObjectCreateFlags);
if (!(abObjectCreateFlags[he.bType] & OCF_PROCESSOWNED) && he.pOwner) {
Idt(OFLAG(p), (PVOID)he.pOwner);
}
}
#endif // KERNEL
move(head, (PVOID)dw);
Print("phe =@0x%08lx\n", pheT);
Print("handle = 0x%08lx\n", head.h);
Print("cLockObj = 0x%08lx\n", head.cLockObj);
Print("phead =@0x%08lx\n", FIXKP(he.phead));
Print("pOwner =@0x%08lx\n", FIXKP(he.pOwner));
Print("bType = 0x%08lx (%s)\n", he.bType, aszTypeNames[he.bType]);
Print("bFlags = %s\n", GetFlags(GF_HE, he.bFlags, NULL));
Print("wUniq = 0x%08lx\n", he.wUniq);
return(TRUE);
}
#ifdef KERNEL
/***************************************************************************\
* dhk - dump hooks
*
* dhk - dumps local hooks on the foreground thread
* dhk g - dumps global hooks
* dhk address - dumps local hooks on THREADINFO at address
* dhk g address - dumps global hooks and local hooks on THREADINFO at address
* dhk * - dumps local hooks for all threads
* dhk g * - dumps global hooks and local hooks for all threads
*
* 10/21/94 IanJa Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idhk(
DWORD opts,
PVOID param1)
{
DWORD dwFlags;
PTHREADINFO pti;
THREADINFO ti;
HOOK hook;
#define DHKF_GLOBAL_HOOKS 1
#define DHKF_PTI_GIVEN 2
dwFlags = 0;
pti = NULL;
if (opts & OFLAG(g)) { // global hooks
dwFlags |= DHKF_GLOBAL_HOOKS;
}
#ifdef LATER
if (opts & OFLAG(a)) {
moveExpValue(&pti, VAR(gptiFirst));
SAFEWHILE (pti != NULL) {
char ach[80];
sprintf(ach, "%lx", pti);
dhk(hCurrentProcess, hCurrentThread, dwCurPc,
dwCurrentPc, ach);
move(pti, &(pti->ptiNext));
}
if (dwFlags & DHKF_GLOBAL_HOOKS) {
dhk(hCurrentProcess, hCurrentThread, dwCurPc,
dwCurrentPc, "g");
}
return(TRUE);
}
#endif
if (param1 == NULL) {
PQ pq;
Q q;
moveExpValue(&pq, VAR(gpqForeground));
if (pq == NULL) {
// Happens during winlogon
Print("No foreground queue!\n");
return(TRUE);
}
move(q, pq);
pti = q.ptiKeyboard;
} else {
dwFlags |= DHKF_PTI_GIVEN;
pti = (PTHREADINFO)param1;
}
move(ti, pti);
if (dwFlags & DHKF_PTI_GIVEN || !(dwFlags & DHKF_GLOBAL_HOOKS)) {
Print("Local hooks on PTHREADINFO @ 0x%08lx%s:\n", pti,
(dwFlags & DHKF_PTI_GIVEN ? "" : " (foreground thread)"));
DUMPLHOOKS("WH_MSGFILTER", WH_MSGFILTER);
DUMPLHOOKS("WH_JOURNALRECORD", WH_JOURNALRECORD);
DUMPLHOOKS("WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK);
DUMPLHOOKS("WH_KEYBOARD", WH_KEYBOARD);
DUMPLHOOKS("WH_GETMESSAGE", WH_GETMESSAGE);
DUMPLHOOKS("WH_CALLWNDPROC", WH_CALLWNDPROC);
DUMPLHOOKS("WH_CALLWNDPROCRET", WH_CALLWNDPROCRET);
DUMPLHOOKS("WH_CBT", WH_CBT);
DUMPLHOOKS("WH_SYSMSGFILTER", WH_SYSMSGFILTER);
DUMPLHOOKS("WH_MOUSE", WH_MOUSE);
DUMPLHOOKS("WH_HARDWARE", WH_HARDWARE);
DUMPLHOOKS("WH_DEBUG", WH_DEBUG);
DUMPLHOOKS("WH_SHELL", WH_SHELL);
DUMPLHOOKS("WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE);
}
if (dwFlags & DHKF_GLOBAL_HOOKS) {
DESKTOPINFO di;
move(di, ti.pDeskInfo);
Print("Global hooks for Desktop @ %lx:\n", ti.rpdesk);
Print("\tfsHooks 0x%08lx\n"
"\tasphkStart\n", di.fsHooks);
DUMPHOOKS("WH_MSGFILTER", WH_MSGFILTER);
DUMPHOOKS("WH_JOURNALRECORD", WH_JOURNALRECORD);
DUMPHOOKS("WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK);
DUMPHOOKS("WH_KEYBOARD", WH_KEYBOARD);
DUMPHOOKS("WH_GETMESSAGE", WH_GETMESSAGE);
DUMPHOOKS("WH_CALLWNDPROC", WH_CALLWNDPROC);
DUMPHOOKS("WH_CALLWNDPROCRET", WH_CALLWNDPROCRET);
DUMPHOOKS("WH_CBT", WH_CBT);
DUMPHOOKS("WH_SYSMSGFILTER", WH_SYSMSGFILTER);
DUMPHOOKS("WH_MOUSE", WH_MOUSE);
DUMPHOOKS("WH_HARDWARE", WH_HARDWARE);
DUMPHOOKS("WH_DEBUG", WH_DEBUG);
DUMPHOOKS("WH_SHELL", WH_SHELL);
DUMPHOOKS("WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE);
}
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dhot - dump hotkeys
*
* dhot - dumps all hotkeys
*
* 10/21/94 IanJa Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idhot()
{
PHOTKEY phk;
HOTKEY hk;
moveExpValue(&phk, VAR(gphkFirst));
SAFEWHILE (phk != NULL) {
move(hk, phk);
Print("%s%s%sVK:%x\n",
hk.fsModifiers & MOD_SHIFT ? "Shift + " : "",
hk.fsModifiers & MOD_ALT ? "Alt + " : "",
hk.fsModifiers & MOD_CONTROL ? "Ctrl + " : "",
hk.vk);
Print(" id %x\n", hk.id);
Print(" pti %lx\n", hk.pti);
Print(" pwnd %lx = ", hk.spwnd);
if (hk.spwnd == PWND_FOCUS) {
Print("PWND_FOCUS\n");
} else if (hk.spwnd == PWND_INPUTOWNER) {
Print("PWND_INPUTOWNER\n");
} else {
CHAR ach[80];
/*
* Print title string.
*/
DebugGetWindowTextA(hk.spwnd,ach);
Print("\"%s\"\n", ach);
}
Print("\n");
phk = hk.phkNext;
}
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dhs - dumps simple statistics for whole table
* dhs t id - dumps simple statistics for objects created by thread id
* dhs p id - dumps simple statistics for objects created by process id
* dhs v - dumps verbose statistics for whole table
* dhs v t id - dumps verbose statistics for objects created by thread id.
* dhs v p id - dumps verbose statistics for objects created by process id.
* dhs y type - just dumps that type
*
* Dump handle table statistics.
*
* 02-21-92 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idhs(
DWORD opts,
PVOID param1)
{
HANDLEENTRY *phe, he;
DWORD dwT;
DWORD acHandles[TYPE_CTYPES];
DWORD cHandlesUsed, cHandlesSkipped;
DWORD idThread, idProcess;
DWORD i;
PBYTE pabObjectCreateFlags;
BYTE abObjectCreateFlags[TYPE_CTYPES];
int Type, cHandleEntries = 0;
PROCESSINFO pi;
THREADINFO ti;
/*
* Evaluate the argument string and get the address of the object to
* dump. Take either a handle or a pointer to the object.
*/
if (opts & OFLAG(y)) {
Type = (int)param1;
} else if (opts & (OFLAG(t) | OFLAG(p))) {
dwT = (DWORD)param1;
}
cHandlesSkipped = 0;
cHandlesUsed = 0;
for (i = 0; i < TYPE_CTYPES; i++)
acHandles[i] = 0;
pabObjectCreateFlags = EvalExp(VAR(gabObjectCreateFlags));
if (!tryMove(abObjectCreateFlags, pabObjectCreateFlags)) {
Print("Could not get pagfProcessOwned data.\n");
return(FALSE);
}
if (param1) {
if (opts & OFLAG(p)) {
Print("Handle dump for client process id 0x%lx only:\n\n", dwT);
} else if (opts & OFLAG(t)) {
Print("Handle dump for client thread id 0x%lx only:\n\n", dwT);
} else if (opts & OFLAG(y)) {
Print("Handle dump for %s objects:\n\n", aszTypeNames[Type]);
}
} else {
Print("Handle dump for all processes and threads:\n\n");
}
if (opts & OFLAG(v)) {
Print("Handle Type\n");
Print("--------------------\n");
}
FOREACHHANDLEENTRY(phe, he, i)
cHandleEntries++;
if ((opts & OFLAG(y)) && he.bType != Type) {
continue;
}
if (opts & OFLAG(p) &&
(abObjectCreateFlags[he.bType] & OCF_PROCESSOWNED)) {
if (he.pOwner == NULL) {
continue;
}
move(pi, he.pOwner);
if (GetEProcessData(pi.Process, PROCESS_PROCESSID, &idProcess) == NULL) {
Print("Unable to read _EPROCESS at %lx\n",pi.Process);
continue;
}
if (idProcess != dwT) {
continue;
}
} else if ((opts & OFLAG(t)) &&
!(abObjectCreateFlags[he.bType] & OCF_PROCESSOWNED)) {
if (he.pOwner == NULL) {
continue;
}
move(ti, he.pOwner);
move(idThread, &(ti.Thread->Cid.UniqueThread));
if (idThread != dwT) {
continue;
}
}
acHandles[he.bType]++;
if (he.bType == TYPE_FREE) {
continue;
}
cHandlesUsed++;
if (opts & OFLAG(v)) {
Print("0x%08lx %c %s\n",
i,
(he.bFlags & HANDLEF_DESTROY) ? '*' : ' ',
aszTypeNames[he.bType]);
}
NEXTEACHHANDLEENTRY()
if (!(opts & OFLAG(v))) {
Print("Count Type\n");
Print("--------------------\n");
for (i = 0; i < TYPE_CTYPES; i++) {
if ((opts & OFLAG(y)) && Type != (int)i) {
continue;
}
Print("0x%08lx (%d) %s\n", acHandles[i], i, aszTypeNames[i]);
}
}
if (!(opts & OFLAG(y))) {
Print("\nTotal Accessible Handles: 0x%lx\n", cHandleEntries);
Print("Used Accessible Handles: 0x%lx\n", cHandlesUsed);
Print("Free Accessible Handles: 0x%lx\n", cHandleEntries - cHandlesUsed);
}
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* di - dumps interesting globals in USER related to input.
*
*
* 11-14-91 DavidPe Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
/*
* Make sure ptCursor isn't defined so we can use it in structure below
*/
#ifdef ptCursor
#undef ptCursor
#endif
BOOL Idi()
{
char ach[80];
PQ pq;
Q q;
DWORD dw;
PSERVERINFO psi;
SERVERINFO si;
moveExpValue(&pq, VAR(gpqForeground));
Print("gpqForeground 0x%08lx\n", pq);
move(q, pq);
DebugGetWindowTextA(q.spwndFocus, ach);
Print("...->spwndFocus 0x%08lx \"%s\"\n", q.spwndFocus, ach);
DebugGetWindowTextA(q.spwndActive, ach);
Print("...->spwndActive 0x%08lx \"%s\"\n", q.spwndActive, ach);
moveExpValue(&pq, VAR(gpqForegroundPrev));
Print("gpqForegroundPrev 0x%08lx\n", pq);
moveExpValue(&dw, VAR(gspwndMouseOwner));
DebugGetWindowTextA((PWND)dw, ach);
Print("gspwndMouseOwner 0x%08lx \"%s\"\n", dw, ach);
moveExpValue(&dw, VAR(wMouseOwnerButton));
Print("wMouseOwnerButton 0x%08lx\n", dw);
moveExpValue(&dw, VAR(timeLastInputMessage));
Print("timeLastInputMessage 0x%08lx\n", dw);
moveExpValue(&psi, VAR(gpsi));
move(si, psi);
Print("ptCursor { %d, %d }\n", si.ptCursor.x, si.ptCursor.y);
moveExpValue(&dw, VAR(gpqCursor));
Print("gpqCursor 0x%08lx\n", dw);
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Idll
*
* Description: Dump Linked Lists
*
* Returns: fSuccess
*
* ???????? Scottlu Created
* 6/9/1995 SanfordS made to fit stdexts motif
*
\************************************************************************/
BOOL Idll(
DWORD opts,
LPSTR lpas)
{
static DWORD iOffset;
static DWORD cStructs;
static DWORD cDwords;
static DWORD dw;
DWORD dwT;
DWORD i, j;
BOOL fIndirectFirst;
DWORD adw[CDWORDS];
/*
* Evaluate the argument string and get the address of the object to
* dump. Take either a handle or a pointer to the object.
*/
while (*lpas == ' ')
lpas++;
/*
* If there are no arguments, keep walking from the last
* pointer.
*/
if (*lpas != 0) {
/*
* If the address has a '*' in front of it, it means start with the
* pointer stored at that address.
*/
fIndirectFirst = FALSE;
if (*lpas == '*') {
lpas++;
fIndirectFirst = TRUE;
}
/*
* Scan past the address.
*/
dw = (DWORD)EvalExp(lpas);
if (fIndirectFirst)
move(dw, (PVOID)dw);
while (*lpas && *lpas != ' ')
lpas++;
iOffset = 0;
cStructs = (DWORD)25;
cDwords = 8;
SAFEWHILE (TRUE) {
while (*lpas == ' ')
lpas++;
switch(*lpas) {
case 'l':
/*
* length of each structure.
*/
lpas++;
cDwords = (DWORD)EvalExp(lpas);
if (cDwords > CDWORDS) {
cDwords = CDWORDS;
Print("\n%d DWORDs maximum\n\n", CDWORDS);
}
break;
case 'o':
/*
* Offset of 'next' pointer.
*/
lpas++;
iOffset = (DWORD)EvalExp(lpas);
break;
case 'c':
/*
* Count of structures to dump
*/
lpas++;
cStructs = (DWORD)EvalExp(lpas);
break;
default:
break;
}
while (*lpas && *lpas != ' ')
lpas++;
if (*lpas == 0)
break;
}
for (i = 0; i < CDWORDS; i++)
adw[i] = 0;
}
for (i = 0; i < cStructs; i++) {
moveBlock(adw, (PVOID)dw, sizeof(DWORD) * cDwords);
for (j = 0; j < cDwords; j += 4) {
switch (cDwords - j) {
case 1:
Print("%08lx: %08lx\n",
dw + j * sizeof(DWORD),
adw[j + 0]);
break;
case 2:
Print("%08lx: %08lx %08lx\n",
dw + j * sizeof(DWORD),
adw[j + 0], adw[j + 1]);
break;
case 3:
Print("%08lx: %08lx %08lx %08lx\n",
dw + j * sizeof(DWORD),
adw[j + 0], adw[j + 1], adw[j + 2]);
break;
default:
Print("%08lx: %08lx %08lx %08lx %08lx\n",
dw + j * sizeof(DWORD),
adw[j + 0], adw[j + 1], adw[j + 2], adw[j + 3]);
}
}
dwT = dw + iOffset * sizeof(DWORD);
move(dw, (PVOID)dwT);
if (dw == 0)
break;
Print("--------\n");
}
return(TRUE);
}
/************************************************************************\
* Procedure: Ifind
*
* Description: Find Linked List Element
*
* Returns: fSuccess
*
* 11/22/95 JimA Created.
\************************************************************************/
BOOL Ifind(
DWORD opts,
LPSTR lpas)
{
DWORD iOffset = 0;
LPDWORD adw;
DWORD cbDwords;
DWORD dwBase;
DWORD dwLast = 0;
DWORD dwAddr;
DWORD dwTest;
DWORD dwT;
/*
* Evaluate the argument string and get the address of the object to
* dump. Take either a handle or a pointer to the object.
*/
while (*lpas == ' ')
lpas++;
/*
* If there are no arguments, keep walking from the last
* pointer.
*/
if (*lpas != 0) {
/*
* Scan past the addresses.
*/
dwBase = (DWORD)EvalExp(lpas);
while (*lpas && *lpas != ' ')
lpas++;
dwAddr = (DWORD)EvalExp(lpas);
while (*lpas && *lpas != ' ')
lpas++;
iOffset = 0;
SAFEWHILE (TRUE) {
if (IsCtrlCHit())
return TRUE;
while (*lpas == ' ')
lpas++;
switch(*lpas) {
case 'o':
/*
* Offset of 'next' pointer.
*/
lpas++;
iOffset = (DWORD)EvalExp(lpas);
break;
default:
break;
}
while (*lpas && *lpas != ' ')
lpas++;
if (*lpas == 0)
break;
}
}
cbDwords = (iOffset + 1) * sizeof(DWORD);
adw = LocalAlloc(LPTR, cbDwords);
dwTest = dwBase;
while (dwTest && dwTest != dwAddr) {
moveBlock(adw, (PVOID)dwTest, cbDwords);
dwLast = dwTest;
dwT = dwTest + iOffset * sizeof(DWORD);
move(dwTest, (PVOID)dwT);
}
if (dwTest == 0)
Print("Address %x not found\n", dwAddr);
else
Print("Address %x found, previous = %x\n", dwAddr, dwLast);
LocalFree(adw);
return(TRUE);
}
#ifdef KERNEL
/***************************************************************************\
* dlr handle|pointer
*
* Dumps lock list for object
*
* 02-27-92 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idlr(
DWORD opts,
PVOID param1)
{
HANDLEENTRY he;
PLR plrT;
DWORD c;
BOOL bTrackLock;
moveExpValue(&bTrackLock, VAR(gfTrackLocks));
if (!bTrackLock) {
Print("dlr works better if gfTrackLocks != 0\n");
return(TRUE);
}
if (!GetAndDumpHE((DWORD)param1, &he, FALSE)) {
return(FALSE);
}
/*
* We have the handle entry: 'he' is filled in. Now dump the
* lock records. Remember the 1st record is the last transaction!!
*/
c = 0;
#ifdef DEBUG
plrT = he.plr;
SAFEWHILE (plrT != NULL) {
BOOL bAlert = FALSE;
DWORD dw;
LOCKRECORD lr;
char ach[80];
char achT[80];
move(lr, plrT);
GetSymbol((LPVOID)lr.pfn, ach, &dw);
if (lr.pfn == NULL) {
sprintf(achT, "%s", "mark ");
GetSymbol((LPVOID)lr.ppobj, ach, &dw);
} else if ((int)lr.cLockObj <= 0) {
sprintf(achT, "unlock #%-3ld", c);
} else {
/*
* Find corresponding unlock;
*/
{
LOCKRECORD lr2;
PLR plrT2;
DWORD cT;
DWORD cUnlock;
plrT2 = he.plr;
cT = 0;
cUnlock = (DWORD)-1;
SAFEWHILE (plrT2 != plrT) {
move(lr2, plrT2);
if (lr2.ppobj == lr.ppobj) {
if ((int)lr2.cLockObj <= 0) {
// matching unlock found
cUnlock = cT;
} else {
// cUnlock matches this lock (plrT2), not plrT
cUnlock = (DWORD)-1;
}
}
plrT2 = lr2.plrNext;
cT++;
}
if (cUnlock == (DWORD)-1) {
/*
* Corresponding unlock not found
*/
sprintf(achT, "UNMATCHED LOCK!");
bAlert = TRUE;
} else {
sprintf(achT, "lock #%-3ld", cUnlock);
}
}
}
if (!(opts & OFLAG(v)) || bAlert) {
Print("0x%04lx: %s(0x%08lx) 0x%08lx=%s+0x%lx\n",
abs((int)lr.cLockObj), achT, lr.ppobj, lr.pfn, ach, dw);
bAlert = FALSE;
}
plrT = lr.plrNext;
c++;
}
#endif // DEBUG
Print("\n0x%lx transactions\n", c);
c;
plrT;
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Idm
*
* Description: Dumps Menu structures
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
void DumpMenu( UINT uIndent, DWORD opts, PMENU pMenu )
{
MENU localMenu;
ITEM localItem;
PITEM pitem;
LPDWORD lpdw;
DWORD localDW;
UINT i;
WCHAR szBufW[128];
char szIndent[256];
/*
* Compute our indent
*/
for (i=0; i < uIndent; szIndent[i++]=' ');
szIndent[i] = '\0';
/*
* Print the menu header
*/
if (!(opts & OFLAG(v))) {
Print("0x%08lX %s", pMenu, szIndent);
} else {
Print("%sPMENU @0x%08lX:\n", szIndent, pMenu);
}
/*
* Try and get the menu
*/
if (!tryMove(localMenu, pMenu)) {
return;
}
/*
* Print the information for this menu
*/
if (!(opts & OFLAG(v))) {
Print("PMENU: fFlags=0x%lX, cItems=%lu, iItem=%lu, spwndNotify=0x%lX\n",
localMenu.fFlags, localMenu.cItems, localMenu.iItem, localMenu.spwndNotify);
} else {
Print("%s fFlags............ %s\n"
"%s selection......... iItem=0x%08lX, iPopupMenuItem=0x%08lX\n"
"%s location.......... (%lu, %lu)\n",
szIndent, GetFlags(GF_MF, (WORD)localMenu.fFlags, NULL),
szIndent, localMenu.iItem, localMenu.iPopupMenuItem,
szIndent, localMenu.cxMenu, localMenu.cyMenu);
Print("%s spwndNotify....... 0x%08lX\n"
"%s dwContextHelpId... 0x%08lX\n"
"%s items............. %lu items in block of %lu\n",
szIndent, localMenu.spwndNotify,
szIndent, localMenu.dwContextHelpId,
szIndent, localMenu.cItems, localMenu.cAlloced);
}
lpdw = (LPDWORD)(((DWORD)pMenu) + FIELD_OFFSET(MENU, rgItems));
if (tryMove(localDW, FIXKP(lpdw))) {
pitem = (PITEM)localDW;
i = 0;
SAFEWHILE (i < localMenu.cItems) {
/*
* Get the menu item
*/
if (tryMove(localItem, FIXKP(pitem))) {
if (!(opts & OFLAG(i))) {
/*
* Print the info for this item.
*/
if (!(opts & OFLAG(v))) {
Print("0x%08lX %sITEM #%lu: ID=0x%08lX", pitem, szIndent, i, localItem.wID);
if (localItem.cch && tryMoveBlock(szBufW, FIXKP(localItem.hTypeData), (localItem.cch*sizeof(WCHAR)))) {
szBufW[localItem.cch] = 0;
Print(" %ws%\n", szBufW);
} else {
Print(", fType=%s",GetFlags(GF_MENUTYPE, (WORD)localItem.fType, NULL));
if (! (localItem.fType & MF_SEPARATOR)) {
Print(", hTypeData=0x%lX", localItem.hTypeData);
}
Print("\n");
}
} else {
Print("%s Item #%d @0x%08lX:\n", szIndent, i, pitem);
/*
* Print the details for this item.
*/
Print("%s ID........... 0x%08lX (%lu)\n"
"%s hTypeData.... 0x%08lX",
szIndent, localItem.wID, localItem.wID,
szIndent, localItem.hTypeData);
if (localItem.cch && tryMoveBlock(szBufW, FIXKP(localItem.hTypeData), (localItem.cch*sizeof(WCHAR)))) {
szBufW[localItem.cch] = 0;
Print(" %ws%\n", szBufW);
} else {
Print("\n");
}
Print("%s fType........ %s\n"
"%s fState....... %s\n"
"%s dwItemData... 0x%08lX\n",
szIndent, GetFlags(GF_MENUTYPE, (WORD)localItem.fType, NULL),
szIndent, GetFlags(GF_MENUSTATE, (WORD)localItem.fState, NULL),
szIndent, localItem.dwItemData);
Print("%s checks....... on=0x%08lX, off=0x%08lX\n"
"%s location..... @(%lu,%lu) size=(%lu,%lu)\n",
szIndent, localItem.hbmpChecked, localItem.hbmpUnchecked,
szIndent, localItem.xItem, localItem.yItem, localItem.cxItem, localItem.cyItem);
Print("%s underline.... x=%lu, width=%lu\n"
"%s dxTab........ %lu\n"
"%s spSubMenu.... 0x%08lX\n",
szIndent, localItem.ulX, localItem.ulWidth,
szIndent, localItem.dxTab,
szIndent, localItem.spSubMenu);
}
}
/*
* If requested, traverse through sub-menus
*/
if (opts & OFLAG(r)) {
pMenu = HorPtoP(localItem.spSubMenu, TYPE_MENU);
if (pMenu && tryMove(localMenu, pMenu)) {
DumpMenu(uIndent+8, opts, pMenu);
}
}
}
pitem++;
i++;
}
}
}
BOOL Idm(
DWORD opts,
PVOID param1)
{
HANDLEENTRY he;
PVOID pvObject;
if (param1 == NULL)
return FALSE;
pvObject = HorPtoP(FIXKP(param1), -1);
if (pvObject == NULL) {
Print("dm: Could not convert 0x%08X to an object.\n", pvObject);
return TRUE;
}
if (!getHEfromP(NULL, &he, pvObject)) {
Print("dm: Could not get header for object 0x%08X.\n", pvObject);
return TRUE;
}
switch (he.bType) {
case TYPE_WINDOW:
{
WND wnd;
Print("--- Dump Menu for %s object @%08X ---\n", pszObjStr[he.bType], FIXKP(pvObject));
if (!tryMove(wnd, pvObject)) {
Print("dm: Could not get copy of object 0x%08X.\n", pvObject);
return TRUE;
}
if (opts & OFLAG(s)) {
/*
* Display window's system menu
*/
if ((pvObject = (PVOID)wnd.spmenuSys) == NULL) {
Print("dm: This window does not have a system menu.\n");
return TRUE;
}
} else {
if (wnd.style & WS_CHILD) {
/*
* Child windows don't have menus
*/
Print("dm: Child windows do not have menus.\n");
return TRUE;
}
if ((pvObject = (PVOID)wnd.spmenu) == NULL) {
Print("dm: This window does not have a menu.\n");
return TRUE;
}
}
}
/* >>>> F A L L T H R O U G H <<<< */
case TYPE_MENU:
DumpMenu(0, opts, (PMENU)pvObject);
break;
default:
return FALSE;
}
return TRUE;
}
#ifdef KERNEL
/***************************************************************************\
* dmq - dump messages on queue
*
* dmq address - dumps messages in queue structure at address.
*
* 11-13-91 DavidPe Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idmq(
DWORD opts,
PVOID param1)
{
THREADINFO ti;
PQ pq;
Q q;
if (opts & OFLAG(a)) {
PTHREADINFO pti;
FOREACHPTI(pti);
move(pq, &pti->pq);
Idmq(0, pq);
NEXTEACHPTI(pti);
return(TRUE);
}
pq = (PQ)FIXKP(param1);
Print("Messages for queue %x:\n", pq);
move(q, pq);
if (q.ptiKeyboard != NULL) {
move(ti, FIXKP(q.ptiKeyboard));
if (ti.mlPost.pqmsgRead) {
Print("==== PostMessage queue ====\n");
if (ti.mlPost.pqmsgRead != NULL) {
PrintMessages(FIXKP(ti.mlPost.pqmsgRead));
}
}
}
if (q.mlInput.pqmsgRead) {
Print( "==== Input queue ==========\n");
if (q.mlInput.pqmsgRead != NULL) {
PrintMessages(FIXKP(q.mlInput.pqmsgRead));
}
}
Print("\n");
return(TRUE);
}
#endif KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: Idped
*
* Description: Dumps Edit Control Structures (PEDs)
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idped(
DWORD opts,
PVOID param1)
{
PED ped;
ED ed;
DWORD pText;
ped = param1;
move(ed, ped);
move(pText, ed.hText);
Print("PED Handle: %lX\n", ped);
Print("hText %lX (%lX)\n", ed.hText, pText);
PRTDW2(ed., cchAlloc, cchTextMax);
PRTDW2(ed., cch, cLines);
PRTDW2(ed., ichMinSel, ichMaxSel);
PRTDW2(ed., ichCaret, iCaretLine);
PRTDW2(ed., ichScreenStart, ichLinesOnScreen);
PRTDW2(ed., xOffset, charPasswordChar);
PRTDW2(ed., cPasswordCharWidth, hwnd);
PRTDW1(ed., pwnd);
PRTRC(ed., rcFmt);
PRTDW1(ed., hwndParent);
PRTPT(ed., ptPrevMouse);
PRTDW1(ed., prevKeys);
PRTFLG(ed., fSingle);
PRTFLG(ed., fNoRedraw);
PRTFLG(ed., fMouseDown);
PRTFLG(ed., fFocus);
PRTFLG(ed., fDirty);
PRTFLG(ed., fDisabled);
PRTFLG(ed., fNonPropFont);
PRTFLG(ed., fBorder);
PRTFLG(ed., fAutoVScroll);
PRTFLG(ed., fAutoHScroll);
PRTFLG(ed., fNoHideSel);
PRTFLG(ed., fKanji);
PRTFLG(ed., fFmtLines);
PRTFLG(ed., fWrap);
PRTFLG(ed., fCalcLines);
PRTFLG(ed., fEatNextChar);
PRTFLG(ed., fStripCRCRLF);
PRTFLG(ed., fInDialogBox);
PRTFLG(ed., fReadOnly);
PRTFLG(ed., fCaretHidden);
PRTFLG(ed., fTrueType);
PRTFLG(ed., fAnsi);
PRTFLG(ed., fWin31Compat);
PRTFLG(ed., f40Compat);
PRTFLG(ed., fFlatBorder);
PRTFLG(ed., fSawRButtonDown);
PRTDW2(ed., cbChar, chLines);
PRTDW2(ed., format, lpfnNextWord);
PRTDW1(ed., maxPixelWidth);
PRTDW2(ed., undoType, hDeletedText);
PRTDW2(ed., ichDeleted, cchDeleted);
PRTDW2(ed., ichInsStart, ichInsEnd);
PRTDW2(ed., hFont, aveCharWidth);
PRTDW2(ed., lineHeight, charOverhang);
PRTDW2(ed., cxSysCharWidth, cySysCharHeight);
PRTDW2(ed., listboxHwnd, pTabStops);
PRTDW2(ed., charWidthBuffer, charSet);
PRTDW2(ed., hkl, wMaxNegA);
PRTDW2(ed., wMaxNegAcharPos, wMaxNegC);
PRTDW2(ed., wMaxNegCcharPos, wLeftMargin);
PRTDW2(ed., wRightMargin, ichStartMinSel);
PRTDW2(ed., ichStartMaxSel, lpfnCharset);
PRTDW2(ed., dwForeign, hInstance);
PRTDW2(ed., seed, fEncoded);
PRTDW1(ed., iLockLevel);
return(TRUE);
}
#endif // !KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: Idci
*
* Description: Dumps Client Info
*
* Returns: fSuccess
*
* 6/15/1995 Created SanfordS
*
\************************************************************************/
BOOL Idci()
{
TEB teb, *pteb;
PCLIENTINFO pci;
if (GetTargetTEB(&teb, &pteb)) {
pci = (PCLIENTINFO)&teb.Win32ClientInfo[0];
Print("PCLIENTINFO @ %08lx:\n", &pteb->Win32ClientInfo[0]);
// HANDLE hEventQueueClient;
Print("\thEventQueueClient %08lx\n", pci->hEventQueueClient);
// DWORD dwExpWinVer;
Print("\tdwExpWinVer %08lx\n", pci->dwExpWinVer);
// DWORD dwCompatFlags;
Print("\tdwCompatFlags %08lx\n", pci->dwCompatFlags);
// DWORD dwTIFlags;
Print("\tdwTIFlags %08lx\n", pci->dwTIFlags);
// PDESKTOPINFO pDeskInfo;
Print("\tpDeskInfo %08lx\n", pci->pDeskInfo);
// ULONG ulClientDelta;
Print("\tulClientDelta %08lx\n", pci->ulClientDelta);
// struct tagHOOK *phkCurrent;
Print("\tphkCurrent %08lx\n", pci->phkCurrent);
// DWORD fsHooks;
Print("\tfsHooks %08lx\n", pci->fsHooks);
// CALLBACKWND CallbackWnd;
Print("\tCallbackWnd %08lx\n", pci->CallbackWnd);
// DWORD cSpins;
Print("\tcSpins %08lx\n", pci->cSpins);
Print("\tCodePage %d\n", pci->CodePage);
} else {
Print("Unable to get TEB info.\n");
}
return(TRUE);
}
#endif // !KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: Idpi
*
* Description: Dumps ProcessInfo structs
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idpi(
DWORD opts,
PVOID param1)
{
PW32PROCESS pW32Process;
PPROCESSINFO ppi;
PROCESSINFO pi;
SERVERINFO si;
SHAREDINFO shi;
PSHAREDINFO pshi;
DESKTOPVIEW dv;
DWORD idProcess;
/*
* If he just wants the current process, located it.
*/
if (opts & OFLAG(c)) {
Print("Current Process:\n");
param1 = (PVOID)GetCurrentProcessAddress(
(USHORT)dwProcessor, hCurrentThread, NULL );
if (param1 == 0) {
Print("Unable to get current process pointer.\n");
return FALSE;
}
if (GetEProcessData(param1, PROCESS_WIN32PROCESS, &pW32Process) == NULL) {
Print("Unable to read _EPROCESS at %lx\n", param1);
return FALSE;
}
param1 = pW32Process;
} else if (param1 == 0) {
Print("**** NT ACTIVE WIN32 PROCESSINFO DUMP ****\n");
FOREACHPPI(ppi)
Idpi(0, ppi);
Print("\n");
NEXTEACHPPI()
return(TRUE);
}
ppi = FIXKP(param1);
if (!tryMove(pi, ppi)) {
Print("Can't get PROCESSINFO from %x.\n", ppi);
return(FALSE);
}
if (GetEProcessData(pi.Process, PROCESS_PROCESSID, &idProcess) == NULL) {
Print("Unable to read _EPROCESS at %lx\n",pi.Process);
return(FALSE);
}
Print("---PPROCESSINFO @ 0x%08lx for process %x(%s):\n",
ppi,
idProcess,
ProcessName(ppi));
Print("\tppiNext @0x%08lx\n", pi.ppiNext);
Print("\trpwinsta @0x%08lx\n", pi.rpwinsta);
Print("\thwinsta 0x%08lx\n", pi.hwinsta);
Print("\tamwinsta 0x%08lx\n", pi.amwinsta);
Print("\tptiMainThread @0x%08lx\n", pi.ptiMainThread);
Print("\tcThreads 0x%08lx\n", pi.cThreads);
Print("\trpdeskStartup @0x%08lx\n", pi.rpdeskStartup);
Print("\thdeskStartup 0x%08lx\n", pi.hdeskStartup);
Print("\tpclsPrivateList @0x%08lx\n", pi.pclsPrivateList);
Print("\tpclsPublicList @0x%08lx\n", pi.pclsPublicList);
Print("\tflags %s\n",
GetFlags(GF_W32PF, pi.W32PF_Flags, NULL));
Print("\tdwCompatFlags 0x%08lx\n", pi.dwCompatFlags);
Print("\tdwHotkey 0x%08lx\n", pi.dwHotkey);
Print("\tpWowProcessInfo @0x%08lx\n", pi.pwpi);
Print("\tluidSession 0x%08lx:0x%08lx\n", pi.luidSession.HighPart,
pi.luidSession.LowPart);
Print("\tdwX,dwY (0x%x,0x%x)\n", pi.usi.dwX, pi.usi.dwY);
Print("\tdwXSize,dwYSize (0x%x,0x%x)\n", pi.usi.dwXSize, pi.usi.dwYSize);
Print("\tdwFlags 0x%08x\n", pi.usi.dwFlags);
Print("\twShowWindow 0x%04x\n", pi.usi.wShowWindow);
Print("\tpCursorCache 0x%08x\n", pi.pCursorCache);
/*
* List desktop views
*/
dv.pdvNext = pi.pdvList;
Print("Desktop views:\n");
while (dv.pdvNext != NULL) {
if (!tryMove(dv, dv.pdvNext))
break;
Print("\tpdesk = %08x, ulClientDelta = %08x\n", dv.pdesk, dv.ulClientDelta);
}
/*
* List all the open objects for this process.
*/
GETSHAREDINFO(pshi);
move(shi, pshi);
move(si, shi.psi);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dpm - dump popupmenu
*
* dpm address - dumps menu info for menu at address
* (takes handle too)
*
* 13-Feb-1995 johnc Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idpm(
DWORD opts,
PVOID param1)
{
PPOPUPMENU ppopupmenu;
POPUPMENU localPopupMenu;
ppopupmenu = (PPOPUPMENU)FIXKP(param1);
move(localPopupMenu, ppopupmenu);
Print("PPOPUPMENU @ 0x%lX\n", ppopupmenu);
PRTFLG(localPopupMenu., fIsMenuBar);
PRTFLG(localPopupMenu., fHasMenuBar);
PRTFLG(localPopupMenu., fIsSysMenu);
PRTFLG(localPopupMenu., fIsTrackPopup);
PRTFLG(localPopupMenu., fDroppedLeft);
PRTFLG(localPopupMenu., fHierarchyDropped);
PRTFLG(localPopupMenu., fHierarchyVisible);
PRTFLG(localPopupMenu., fRightButton);
PRTFLG(localPopupMenu., fToggle);
PRTFLG(localPopupMenu., fSynchronous);
PRTFLG(localPopupMenu., fFirstClick);
PRTFLG(localPopupMenu., fDropNextPopup);
PRTFLG(localPopupMenu., fNoNotify);
PRTFLG(localPopupMenu., fAboutToHide);
PRTFLG(localPopupMenu., fShowTimer);
PRTFLG(localPopupMenu., fHideTimer);
PRTFLG(localPopupMenu., fDestroyed);
PRTFLG(localPopupMenu., fDelayedFree);
PRTFLG(localPopupMenu., fFlushDelayedFree);
PRTFLG(localPopupMenu., fFreed);
PRTFLG(localPopupMenu., fInCancel);
PRTFLG(localPopupMenu., fInClose);
PRTFLG(localPopupMenu., dwUnused);
PRTDW2(localPopupMenu., spwndNotify, spwndPopupMenu);
PRTDW2(localPopupMenu., spwndNextPopup, spwndPrevPopup);
PRTDW2(localPopupMenu., spmenu, spmenuAlternate);
PRTDW2(localPopupMenu., spwndActivePopup, ppopupmenuRoot);
PRTDW2(localPopupMenu., ppmDelayedFree, posSelectedItem);
PRTDW1(localPopupMenu., posDropped);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dms - dump pMenuState
*
* dms address
*
* 05-15-96 Created GerardoB
\***************************************************************************/
BOOL Idms(
DWORD opts,
PVOID param1)
{
MENUSTATE *pms;
MENUSTATE localms;
pms = (PMENUSTATE)FIXKP(param1);
move(localms, pms);
Print("PMENUSTATE @ 0x%lX\n", pms);
PRTFLG(localms., fMenuStarted);
PRTFLG(localms., fIsSysMenu);
PRTFLG(localms., fInsideMenuLoop);
PRTFLG(localms., fButtonDown);
PRTFLG(localms., fInEndMenu);
PRTDW1(localms., pGlobalPopupMenu);
PRTPT(localms., ptMouseLast);
PRTDW2(localms., mnFocus, cmdLast);
PRTDW1(localms., ptiMenuStateOwner);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dq - dump queue
*
* dq address - dumps queue structure at address
* dq t address - dumps queue structure at address plus THREADINFO
*
* 06-20-91 ScottLu Created.
* 11-14-91 DavidPe Added THREADINFO option.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idq(
DWORD opts,
PVOID param1)
{
char ach[80];
PQ pq;
Q q;
if (param1 == 0) {
#ifdef LATER
HANDLEENTRY he, *phe;
int i;
Print("Dumping all queues:\n");
FOREACHHANDLEENTRY(phe, he, i)
if (he.bType == TYPE_INPUTQUEUE) {
Idq(opts & ~OFLAG(a), FIXKP(he.phead));
Print("\n");
}
NEXTEACHHANDLEENTRY()
#endif
return(TRUE);
}
pq = (PQ)FIXKP(param1);
/*
* Print out simple thread info for pq->ptiKeyboard
*/
move(q, pq);
if (q.ptiKeyboard) {
Idt(OFLAG(p), q.ptiKeyboard);
}
/*
* Don't Print() with more than 16 arguments at once because it'll blow
* up.
*/
Print("PQ @ 0x%08lx\n", pq);
Print(
"\tmlInput.pqmsgRead 0x%08lx\n"
"\tmlInput.pqmsgWriteLast 0x%08lx\n"
"\tmlInput.cMsgs 0x%08lx\n",
q.mlInput.pqmsgRead,
q.mlInput.pqmsgWriteLast,
q.mlInput.cMsgs);
Print("\tptiSysLock 0x%08lx\n"
"\tidSysLock 0x%08lx\n"
"\tidSysPeek 0x%08lx\n",
q.ptiSysLock,
q.idSysLock,
q.idSysPeek);
Print("\tptiMouse 0x%08lx\n"
"\tptiKeyboard 0x%08lx\n",
q.ptiMouse,
q.ptiKeyboard);
Print("\tspcurCurrent 0x%08lx\n"
"\tiCursorLevel 0x%08lx\n",
q.spcurCurrent,
q.iCursorLevel);
DebugGetWindowTextA(q.spwndCapture, ach);
Print("\tspwndCapture 0x%08lx \"%s\"\n",
q.spwndCapture, ach);
DebugGetWindowTextA(q.spwndFocus, ach);
Print("\tspwndFocus 0x%08lx \"%s\"\n",
q.spwndFocus, ach);
DebugGetWindowTextA(q.spwndActive, ach);
Print("\tspwndActive 0x%08lx \"%s\"\n",
q.spwndActive, ach);
DebugGetWindowTextA(q.spwndActivePrev, ach);
Print("\tspwndActivePrev 0x%08lx \"%s\"\n",
q.spwndActivePrev, ach);
Print("\tcodeCapture 0x%04lx\n"
"\tmsgDblClk 0x%04lx\n"
"\ttimeDblClk 0x%08lx\n",
q.codeCapture,
q.msgDblClk,
q.timeDblClk);
Print("\thwndDblClk 0x%08lx\n",
q.hwndDblClk);
Print("\trcDblClk { %d, %d, %d, %d }\n",
q.rcDblClk.left,
q.rcDblClk.top,
q.rcDblClk.right,
q.rcDblClk.bottom);
Print("\tspwndAltTab 0x%08lx\n",
q.spwndAltTab);
Print("\tQF_flags 0x%08lx %s\n"
"\tcThreads 0x%08lx\n"
"\tcLockCount 0x%08lx\n",
q.QF_flags, GetFlags(GF_QF, q.QF_flags, NULL),
(DWORD) q.cThreads,
(DWORD) q.cLockCount);
Print("\tmsgJournal 0x%08lx\n"
"\thcurCurrent 0x%08lx\n"
"\tExtraInfo 0x%08lx\n",
q.msgJournal,
q.hcurCurrent,
q.ExtraInfo);
Print("\tspwndLastMouseMessage 0x%08lx\n"
"\trcMouseHover { %d, %d, %d, %d }\n"
"\tdwMouseHoverTime 0x%08lx\n",
q.spwndLastMouseMessage,
q.rcMouseHover,
q.dwMouseHoverTime);
/*
* Dump THREADINFO if user specified 't'.
*/
if (opts & OFLAG(t)) {
Idti(0, q.ptiKeyboard);
}
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Idsbt
*
* Description: Dumps Scrollbar track structures.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idsbt(
DWORD opts,
PVOID param1)
{
SBTRACK sbt, *psbt;
SBCALC sbc;
if (param1 == 0) {
Print("Expected pSBTrack address\n");
return(FALSE);
}
psbt = (PSBTRACK)param1;
move(sbt, psbt);
Print("SBTrack:\n");
Print(" fHitOld %d\n", sbt.fHitOld);
Print(" fTrackVert %d\n", sbt.fTrackVert);
Print(" fCtlSB %d\n", sbt.fCtlSB);
Print(" fTrackRecalc %d\n", sbt.fTrackRecalc);
Print(" spwndSB 0x%08lx\n", sbt.spwndSB);
Print(" spwndSBNotify 0x%08lx\n", sbt.spwndSBNotify);
Print(" spwndTrack 0x%08lx\n", sbt.spwndTrack);
Print(" cmdSB 0x%08lx\n", sbt.cmdSB);
Print(" dpxThumb 0x%08lx\n", sbt.dpxThumb);
Print(" posOld 0x%08lx\n", sbt.posOld);
Print(" posNew 0x%08lx\n", sbt.posNew);
Print(" pxOld 0x%08lx\n", sbt.pxOld );
Print(" rcTrack (0x%08lx,0x%08lx,0x%08lx,0x%08lx)\n",
sbt.rcTrack.left,
sbt.rcTrack.top,
sbt.rcTrack.right,
sbt.rcTrack.bottom);
Print(" hTimerSB 0x%08lx\n", sbt.hTimerSB );
Print(" xxxpfnSB 0x%08lx\n", sbt.xxxpfnSB );
Print(" nBar %d\n", sbt.nBar );
Print(" pSBCalc 0x%08lx\n", sbt.pSBCalc );
move(sbc, sbt.pSBCalc);
Print(" pxTop 0x%08lx\n", sbc.pxTop );
Print(" pxBottom 0x%08lx\n", sbc.pxBottom);
Print(" pxLeft 0x%08lx\n", sbc.pxLeft);
Print(" pxRight 0x%08lx\n", sbc.pxRight);
Print(" cpxThumb 0x%08lx\n", sbc.cpxThumb );
Print(" pxUpArrow 0x%08lx\n", sbc.pxUpArrow );
Print(" pxDownArrow 0x%08lx\n", sbc.pxDownArrow);
Print(" pxStart 0x%08lx\n", sbc.pxStart);
Print(" pxThumbBottom 0x%08lx\n", sbc.pxThumbBottom);
Print(" pxThumbTop 0x%08lx\n", sbc.pxThumbTop );
Print(" cpx 0x%08lx\n", sbc.cpx );
Print(" pxMin 0x%08lx\n", sbc.pxMin );
Print(" pos 0x%08lx\n", sbc.pos );
Print(" posMin 0x%08lx\n", sbc.posMin );
Print(" posMax 0x%08lx\n", sbc.posMax );
Print(" page 0x%08lx\n", sbc.page );
return(TRUE);
}
/************************************************************************\
* Procedure: Idsbwnd
*
* Description: Dumps Scrollbar windows struct extra fields
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idsbwnd(
DWORD opts,
PVOID param1)
{
SBWND sbw, *psbw;
if (param1 == 0) {
Print("Expected SB pwnd address\n");
return(FALSE);
}
psbw = (PSBWND)param1;
move(sbw, psbw);
Print("SBWnd:\n");
Print(" min %d\n", sbw.SBCalc.posMin);
Print(" max %d\n", sbw.SBCalc.posMax);
Print(" page %d\n", sbw.SBCalc.page);
Print(" pos %d\n", sbw.SBCalc.pos);
Print(" fVert %d\n", sbw.fVert);
Print(" wDisableFlags %d\n", sbw.wDisableFlags);
Print(" pxTop 0x%08lx\n", sbw.SBCalc.pxTop );
Print(" pxBottom 0x%08lx\n", sbw.SBCalc.pxBottom);
Print(" pxLeft 0x%08lx\n", sbw.SBCalc.pxLeft);
Print(" pxRight 0x%08lx\n", sbw.SBCalc.pxRight);
Print(" cpxThumb 0x%08lx\n", sbw.SBCalc.cpxThumb );
Print(" pxUpArrow 0x%08lx\n", sbw.SBCalc.pxUpArrow );
Print(" pxDownArrow 0x%08lx\n", sbw.SBCalc.pxDownArrow);
Print(" pxStart 0x%08lx\n", sbw.SBCalc.pxStart);
Print(" pxThumbBottom 0x%08lx\n", sbw.SBCalc.pxThumbBottom);
Print(" pxThumbTop 0x%08lx\n", sbw.SBCalc.pxThumbTop );
Print(" cpx 0x%08lx\n", sbw.SBCalc.cpx );
Print(" pxMin 0x%08lx\n", sbw.SBCalc.pxMin );
Print(" pos 0x%08lx\n", sbw.SBCalc.pos );
Print(" posMin 0x%08lx\n", sbw.SBCalc.posMin );
Print(" posMax 0x%08lx\n", sbw.SBCalc.posMax );
Print(" page 0x%08lx\n", sbw.SBCalc.page );
return(TRUE);
}
/***************************************************************************\
* dsi dump serverinfo struct
*
* 02-27-92 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idsi(DWORD opts)
{
SERVERINFO si;
PSERVERINFO psi;
int i;
moveExpValue(&psi, VAR(gpsi));
Print("PSERVERINFO @ 0x%08lx\n", psi);
move(si, psi);
Print(
"\tRipFlags 0x%08lx\n"
"\tcHandleEntries 0x%08lx\n",
si.RipFlags,
si.cHandleEntries);
if (opts & OFLAG(p)) {
Print("\tmpFnidPfn:\n");
for (i = 0; i < FNID_ARRAY_SIZE; i++) {
Print("\t\t[%d] = %08lx\n", i, si.mpFnidPfn[i]);
}
}
if (opts & OFLAG(w)) {
Print("\taStoCidPfn:\n");
for (i = 0; i < FNID_WNDPROCEND - FNID_START + 1; i++) {
Print("\t\t[%d] = %08lx\n", i, si.aStoCidPfn[i]);
}
}
if (opts & OFLAG(b)) {
Print("\tmpFnid_serverCBWndProc:\n");
for (i = 0; i < FNID_END - FNID_START + 1; i++) {
Print("\t\t[%d] = %08lx\n", i, si.mpFnid_serverCBWndProc[i]);
}
}
Print(
"\tdwDebugErrorLevel 0x%08lx\n",
si.dwDebugErrorLevel);
if (opts & OFLAG(m)) {
static LPSTR aszSysMet[SM_CMETRICS] = {
//12345678901234567890
"CXSCREEN",
"CYSCREEN",
"CXVSCROLL",
"CYHSCROLL",
"CYCAPTION",
"CXBORDER",
"CYBORDER",
"CXDLGFRAME",
"CYDLGFRAME",
"CYVTHUMB",
"CXHTHUMB",
"CXICON",
"CYICON",
"CXCURSOR",
"CYCURSOR",
"CYMENU",
"CXFULLSCREEN",
"CYFULLSCREEN",
"CYKANJIWINDOW",
"MOUSEPRESENT",
"CYVSCROLL",
"CXHSCROLL",
"DEBUG",
"SWAPBUTTON",
"RESERVED1",
"RESERVED2",
"RESERVED3",
"RESERVED4",
"CXMIN",
"CYMIN",
"CXSIZE",
"CYSIZE",
"CXFRAME",
"CYFRAME",
"CXMINTRACK",
"CYMINTRACK",
"CXDOUBLECLK",
"CYDOUBLECLK",
"CXICONSPACING",
"CYICONSPACING",
"MENUDROPALIGNMENT",
"PENWINDOWS",
"DBCSENABLED",
"CMOUSEBUTTONS",
"SECURE",
"CXEDGE",
"CYEDGE",
"CXMINSPACING",
"CYMINSPACING",
"CXSMICON",
"CYSMICON",
"CYSMCAPTION",
"CXSMSIZE",
"CYSMSIZE",
"CXMENUSIZE",
"CYMENUSIZE",
"ARRANGE",
"CXMINIMIZED",
"CYMINIMIZED",
"CXMAXTRACK",
"CYMAXTRACK",
"CXMAXIMIZED",
"CYMAXIMIZED",
"NETWORK",
"KEYBOARDPREF",
"HIGHCONTRAST",
"SCREENREADER",
"CLEANBOOT",
"CXDRAG",
"CYDRAG",
"SHOWSOUNDS",
"CXMENUCHECK",
"CYMENUCHECK",
"SLOWMACHINE",
"MIDEASTENABLED",
"MOUSEWHEELPRESENT",
};
Print("\taiSysMet:\n");
for (i = 0; i < SM_CMETRICS; i++) {
Print("\t\tSM_%-18s = 0x%08lx = %d\n", aszSysMet[i], si.aiSysMet[i], si.aiSysMet[i]);
}
}
if (opts & OFLAG(c)) {
static LPSTR aszSysColor[COLOR_MAX] = {
//012345678901234567890
"SCROLLBAR",
"BACKGROUND",
"ACTIVECAPTION",
"INACTIVECAPTION",
"MENU",
"WINDOW",
"WINDOWFRAME",
"MENUTEXT",
"WINDOWTEXT",
"CAPTIONTEXT",
"ACTIVEBORDER",
"INACTIVEBORDER",
"APPWORKSPACE",
"HIGHLIGHT",
"HIGHLIGHTTEXT",
"BTNFACE",
"BTNSHADOW",
"GRAYTEXT",
"BTNTEXT",
"INACTIVECAPTIONTEXT",
"BTNHIGHLIGHT",
"3DDKSHADOW",
"3DLIGHT",
"INFOTEXT",
"INFOBK",
};
HBRUSH ahbr[COLOR_MAX];
HBRUSH *phbr;
moveExp(&phbr, VAR(ahbrSystem));
move(ahbr, phbr);
Print("\targbSystem:\n\t\tCOLOR%24sSYSRGB\tSYSHBR\n", "");
for (i = 0; i < COLOR_MAX; i++) {
Print("\t\tCOLOR_%-21s: 0x%08lx\t0x%08lx\n",
aszSysColor[i], si.argbSystem[i], ahbr[i]);
}
}
if (opts & OFLAG(v)) {
#undef ptCursor
Print(
"\tptCursor (%d, %d)\n",
si.ptCursor.x,
si.ptCursor.y);
}
Print(
"\tcbHandleTable 0x%08lx\n"
"\tnEvents 0x%08lx\n",
si.cbHandleTable,
si.nEvents);
if (opts & OFLAG(o)) {
#undef oemInfo
Print("\tobmInfo @ 0x%08lx:\n\t\tx \ty \tcx \tcy\n", &psi->oemInfo);
for (i = 0; i < OBI_COUNT; i++) {
Print("\tbm[%d]:\t%08x\t%08x\t%08x\t%08x\n",
i,
si.oemInfo.bm[i].x ,
si.oemInfo.bm[i].y ,
si.oemInfo.bm[i].cx,
si.oemInfo.bm[i].cy);
}
Print(
"\t\tcyPixelsPerInch = %x\n"
"\t\tDispDrvExpWinVer = %x\n"
"\t\tPlanes = %x\n"
"\t\tBitsPixel = %x\n"
"\t\tBitCount = %x\n"
"\t\tcxPixelsPerInch = %x\n"
"\t\tfMouse = %x\n"
"\t\tBitCount = %x\n"
,
si.oemInfo.cyPixelsPerInch ,
si.oemInfo.DispDrvExpWinVer ,
si.oemInfo.Planes ,
si.oemInfo.BitsPixel ,
si.oemInfo.BitCount ,
si.oemInfo.cxPixelsPerInch ,
si.oemInfo.fMouse ,
si.oemInfo.BitCount);
}
if (opts & OFLAG(v)) {
Print(
"\tgclBorder 0x%08lx\n"
"\tdtScroll 0x%08lx\n"
"\tdtLBSearch 0x%08lx\n"
"\tdtCaretBlink 0x%08lx\n"
"\tfSnapTo 0x%08lx\n"
"\tfPaletteDisplay 0x%08lx\n"
"\tdwDefaultHeapBase 0x%08lx\n"
"\tdwDefaultHeapSize 0x%08lx\n"
"\twMaxLeftOverlapChars 0x%08lx\n"
"\twMaxRightOverlapchars 0x%08lx\n"
"\trcWork (%x,%x)-(%x,%x)\n"
"\tuiShellMsg 0x%08lx\n"
"\tcxSysFontChar 0x%08lx\n"
"\tcySysFontChar 0x%08lx\n"
"\tcxMsgFontChar 0x%08lx\n"
"\tcyMsgFontChar 0x%08lx\n",
si.gclBorder,
si.dtScroll,
si.dtLBSearch,
si.dtCaretBlink,
si.fSnapTo,
si.fPaletteDisplay,
si.dwDefaultHeapBase,
si.dwDefaultHeapSize,
si.wMaxLeftOverlapChars,
si.wMaxRightOverlapChars,
si.rcWork,
si.uiShellMsg,
si.cxSysFontChar,
si.cySysFontChar,
si.cxMsgFontChar,
si.cyMsgFontChar);
}
if (opts & OFLAG(v)) {
Print(
"\ttmSysFont @ 0x%08lx\n"
"\tatomIconSmProp 0x%04lx\n"
"\tatomIconProp 0x%04lx\n"
"\thIconSmWindows 0x%08lx\n"
"\thIcoWindows 0x%08lx\n"
"\thCaptionFont 0x%08lx\n"
"\thMsgFont 0x%08lx\n"
"\tcntMBox 0x%08lx\n"
"\tatomContextHelpIdProp 0x%08lx\n",
&psi->tmSysFont,
si.atomIconSmProp,
si.atomIconProp,
si.hIconSmWindows,
si.hIcoWindows,
si.hCaptionFont,
si.hMsgFont,
si.cntMBox,
si.atomContextHelpIdProp);
}
if (opts & OFLAG(h)) {
SHAREDINFO shi;
PSHAREDINFO pshi;
GETSHAREDINFO(pshi);
move(shi, pshi);
Print("\nSHAREDINFO @ 0x%08lx:\n", pshi);
Print(
"\taheList 0x%08lx\n"
"\tpszDllList 0x%08lx\n",
shi.aheList,
shi.pszDllList);
}
return(TRUE);
}
#ifdef KERNEL
/***************************************************************************\
* dsms - dump send message structures
*
* dsms - dumps all send message structures
* dsms v - dumps all verbose
* dsms address - dumps specific sms
* dsms v address - dumps verbose
* dsms l [address] - dumps sendlist of sms
*
*
* 06-20-91 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idsms(
DWORD opts,
PVOID param1)
{
SMS sms;
PSMS psms;
if (param1 == 0) {
moveExpValue(&psms, VAR(gpsmsList));
if (psms == NULL) {
Print("No send messages currently in the list.\n");
return(TRUE);
}
SAFEWHILE (psms != NULL) {
if (!Idsms(opts, psms)) {
return(FALSE);
}
move(psms, &psms->psmsNext);
}
return(TRUE);
}
psms = (PSMS)param1;
Print("PSMS @ 0x%08lx\n", psms);
move(sms, psms);
Print("SEND: ");
if (sms.ptiSender != NULL) {
Idt(OFLAG(p), sms.ptiSender);
} else {
Print("NULL\n");
}
if (sms.ptiReceiver != NULL) {
Print("RECV: ");
Idt(OFLAG(p), sms.ptiReceiver);
} else {
Print("NULL\n");
}
if (opts & OFLAG(v)) {
char ach[80];
Print("\tpsmsNext 0x%08lx\n"
#if DBG
"\tpsmsSendList 0x%08lx\n"
"\tpsmsSendNext 0x%08lx\n"
#endif
"\tpsmsReceiveNext 0x%08lx\n"
"\ttSent 0x%08lx\n"
"\tptiSender 0x%08lx\n"
"\tptiReceiver 0x%08lx\n"
"\tlRet 0x%08lx\n"
"\tflags %s\n"
"\twParam 0x%08lx\n"
"\tlParam 0x%08lx\n"
"\tmessage 0x%08lx\n",
sms.psmsNext,
#if DBG
sms.psmsSendList,
sms.psmsSendNext,
#endif
sms.psmsReceiveNext,
sms.tSent,
sms.ptiSender,
sms.ptiReceiver,
sms.lRet,
GetFlags(GF_SMS, (WORD)sms.flags, NULL),
sms.wParam,
sms.lParam,
sms.message);
DebugGetWindowTextA(sms.spwnd, ach);
Print("\tspwnd 0x%08lx \"%s\"\n", sms.spwnd, ach);
}
#if DBG
if (opts & OFLAG(l)) {
DWORD idThread;
PSMS psmsList;
DWORD idThreadSender, idThreadReceiver;
THREADINFO ti;
psmsList = sms.psmsSendList;
if (psmsList == NULL) {
Print("%x : Empty List\n", psms);
} else {
Print("%x : [tidSender](msg)[tidReceiver]\n", psms);
}
SAFEWHILE (psmsList != NULL) {
move(sms, psmsList);
if (sms.ptiSender == NULL) {
idThread = 0;
} else {
move(ti, sms.ptiSender);
move(idThreadSender, &(ti.Thread->Cid.UniqueThread));
}
if (sms.ptiReceiver == NULL) {
idThread = 0;
} else {
move(ti, sms.ptiReceiver);
move(idThreadReceiver, &(ti.Thread->Cid.UniqueThread));
}
Print("%x : [%x](%x)[%x]\n", psmsList, idThreadSender, sms.message,
idThreadReceiver);
if (psmsList == sms.psmsSendNext) {
Print("Loop in list?\n");
return(FALSE);
}
psmsList = sms.psmsSendNext;
}
Print("\n");
}
#endif
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dt - dump thread
*
* dt - dumps simple thread info of all threads which have queues
* on server
* dt v - dumps verbose thread info of all threads which have queues
* on server
* dt id - dumps simple thread info of single server thread id
* dt v id - dumps verbose thread info of single server thread id
*
* 06-20-91 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL DumpThread(
DWORD opts,
PETHREAD pEThread)
{
ETHREAD EThread;
WCHAR ach[256];
THREADINFO ti;
PTHREADINFO pti;
if (!tryMove(EThread, pEThread)) {
Print("Unable to read _ETHREAD at %lx\n",pEThread);
return FALSE;
}
pti = EThread.Tcb.Win32Thread;
if (!tryMove(ti, pti)) {
Print("et 0x%08lx t 0x???????? q 0x???????? i %2x.%-3lx <unknown name>\n",
pEThread,
EThread.Cid.UniqueProcess,
EThread.Cid.UniqueThread);
return TRUE;
}
if (ti.Thread != pEThread || pti == NULL) {
return FALSE;
} else { // Good thread
/*
* Print out simple thread info if this is in simple mode. Print
* out queue info if in verbose mode (printing out queue info
* also prints out simple thread info).
*/
if (!(opts & OFLAG(v))) {
PWCHAR pwch;
GetAppName(&EThread, &ti, ach, sizeof(ach));
pwch = wcsrchr(ach, L'\\');
if (pwch == NULL) {
pwch = ach;
} else {
pwch++;
}
Print("et 0x%08lx t 0x%08lx q 0x%08lx i %2x.%-3lx %ws\n",
pEThread,
pti,
ti.pq,
EThread.Cid.UniqueProcess,
EThread.Cid.UniqueThread,
pwch);
} else {
Idti(0, pti);
Print("--------\n");
}
}
return TRUE;
}
BOOL Idt(
DWORD opts,
PVOID param1)
{
ULONG ThreadToDump;
LIST_ENTRY List;
LIST_ENTRY ThreadList;
PLIST_ENTRY NextProcess;
PLIST_ENTRY NextThread;
PLIST_ENTRY ProcessHead;
PLIST_ENTRY ThreadListHead;
PEPROCESS pEProcess;
PW32PROCESS pW32Process;
PETHREAD pEThread;
ETHREAD EThread;
THREADINFO ti;
PTHREADINFO pti;
ThreadToDump = (ULONG)param1;
/*
* If its a pti, validate it, and turn it into and idThread.
*/
if (opts & OFLAG(p)) {
if (!param1) {
Print("Expected a pti parameter.\n");
return(FALSE);
}
pti = FIXKP(param1);
if (pti == NULL) {
Print("WARNING: bad pti given!\n");
pti = param1;
} else {
move(ti, pti);
if (!DumpThread(opts, ti.Thread)) {
/*
* This thread either doesn't have a pti or something
* is whacked out. Just skip it if we want all
* threads.
*/
Print("Sorry, EThread %x is not a Win32 thread.\n",
ti.Thread);
return FALSE;
}
return TRUE;
}
}
/*
* If he just wants the current thread, located it.
*/
if (opts & OFLAG(c)) {
Print("Current Thread:");
ThreadToDump = (ULONG)GetCurrentThreadAddress(
(USHORT)dwProcessor, hCurrentThread );
if (ThreadToDump == 0) {
Print("Unable to get current thread pointer.\n");
return FALSE;
}
pEThread = (PETHREAD)ThreadToDump;
if (!DumpThread(opts, pEThread)) {
/*
* This thread either doesn't have a pti or something
* is whacked out. Just skip it if we want all
* threads.
*/
Print("Sorry, EThread %x is not a Win32 thread.\n",
pEThread);
return FALSE;
}
return TRUE;
/*
* else he must want all window threads.
*/
} else if (ThreadToDump == 0) {
Print("**** NT ACTIVE WIN32 THREADINFO DUMP ****\n");
}
ProcessHead = EvalExp( "PsActiveProcessHead" );
if (!ProcessHead) {
Print("Unable to get value of PsActiveProcessHead\n");
return FALSE;
}
if (!tryMove(List, ProcessHead)) {
Print("Unable to get value of PsActiveProcessHead\n");
return FALSE;
}
NextProcess = List.Flink;
if (NextProcess == NULL) {
Print("PsActiveProcessHead->Flink is NULL!\n");
return FALSE;
}
SAFEWHILE(NextProcess != ProcessHead) {
pEProcess = GetEProcessData((PEPROCESS)NextProcess,
PROCESS_PROCESSHEAD,
NULL);
if (GetEProcessData(pEProcess, PROCESS_PROCESSLINK,
&List) == NULL) {
Print("Unable to read _EPROCESS at %lx\n",pEProcess);
break;
}
NextProcess = List.Flink;
/*
* Dump threads of Win32 Processes only
*/
if (GetEProcessData(pEProcess, PROCESS_WIN32PROCESS,
&pW32Process) == NULL || pW32Process == NULL) {
continue;
}
ThreadListHead = GetEProcessData(pEProcess, PROCESS_THREADLIST, &ThreadList);
if (ThreadListHead == NULL)
continue;
NextThread = ThreadList.Flink;
SAFEWHILE ( NextThread != ThreadListHead) {
pEThread = (PETHREAD)(CONTAINING_RECORD(NextThread, KTHREAD, ThreadListEntry));
if (!tryMove(EThread, pEThread)) {
Print("Unable to read _ETHREAD at %lx\n",pEThread);
break;
}
NextThread = ((PKTHREAD)&EThread)->ThreadListEntry.Flink;
/*
* ThreadToDump is either 0 (all windows threads) or its
* a TID ( < MM_USER_PROBE_ADDRESS) or its a pEThread.
*/
if (ThreadToDump == 0 ||
(ThreadToDump < MM_USER_PROBE_ADDRESS &&
ThreadToDump == (ULONG)EThread.Cid.UniqueThread) ||
(ThreadToDump > MM_USER_PROBE_ADDRESS &&
ThreadToDump == (ULONG)pEThread)) {
if (!DumpThread(opts, pEThread) && ThreadToDump != 0) {
Print("Sorry, EThread %x is not a Win32 thread.\n",
pEThread);
}
if (ThreadToDump != 0) {
return TRUE;
}
} // Chosen Thread
} // NextThread
} // NextProcess
if (opts & OFLAG(c)) {
Print("%x is not a windows thread.\n", ThreadToDump);
}
return TRUE;
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dtdb - dump TDB
*
* dtdb address - dumps TDB structure at address
*
* 14-Sep-1993 DaveHart Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idtdb(
DWORD opts,
PVOID param1)
{
PTDB ptdb;
TDB tdb;
PTHREADINFO pti;
if (param1 == 0) {
Print("Dumping all ptdbs:\n");
FOREACHPTI(pti)
move(ptdb, &pti->ptdb);
SAFEWHILE (ptdb) {
Idtdb(0, ptdb);
move(ptdb, &ptdb->ptdbNext);
}
NEXTEACHPTI(pti)
return(TRUE);
}
ptdb = (PTDB)param1;
if (ptdb == NULL) {
Print("Must supply a TDB address.\n");
return(FALSE);
}
move(tdb, ptdb);
Print("TDB (non preemptive scheduler task database) @ 0x%08lx\n", ptdb);
Print("\tptdbNext @0x%08lx\n", tdb.ptdbNext);
Print("\tnEvents 0x%08lx\n", tdb.nEvents);
Print("\tnPriority 0x%08lx\n", tdb.nPriority);
Print("\tpti @0x%08lx\n", tdb.pti);
return(TRUE);
}
#endif // KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: Ikbp
*
* Description: Breaks into the kernel debugger
*
* Returns: fSuccess
*
* 7/2/96 Fritz Sands
*
\************************************************************************/
void PrivateKDBreakPoint(void);
BOOL Ikbp()
{
PrivateKDBreakPoint();
return(TRUE);
}
#endif // !KERNEL
#ifndef KERNEL
/************************************************************************\
* Procedure: Idteb
*
* Description: Dumps the target process's TEB
*
* Returns: fSuccess
*
* 6/15/1995 Created SanfordS
*
\************************************************************************/
BOOL Idteb()
{
TEB teb, *pteb;
if (GetTargetTEB(&teb, &pteb)) {
Print("TEB @ 0x%08lx:\n", pteb);
// NT_TIB NtTib;
// struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
// PVOID StackBase;
// PVOID StackLimit;
// PVOID SubSystemTib;
// ULONG Version;
// PVOID ArbitraryUserPointer;
// struct _NT_TIB *Self;
// PVOID EnvironmentPointer;
// CLIENT_ID ClientId;
Print("\tClientId %08lx\n", teb.ClientId);
// PVOID ActiveRpcHandle;
// PVOID ThreadLocalStoragePointer;
// PPEB ProcessEnvironmentBlock;
// ULONG LastErrorValue;
Print("\tLastErrorValue %08lx\n", teb.LastErrorValue);
// ULONG CountOfOwnedCriticalSections;
Print("\tCountOfOwnedCriticalSections %08lx\n", teb.CountOfOwnedCriticalSections);
// PVOID Win32ThreadInfo; // PtiCurrent
Print("\tWin32ThreadInfo(pti) %08lx\n", teb.Win32ThreadInfo);
// PVOID CsrQlpcStack;
// UCHAR SpareBytes[124];
// LCID CurrentLocale;
// ULONG FpSoftwareStatusRegister;
// PVOID Win32ClientInfo[54];
Print("\tWin32ClientInfo[0](pci) %08lx\n", teb.Win32ClientInfo[0]);
// PVOID Spare1; // User Debug info
// NTSTATUS ExceptionCode; // for RaiseUserException
// PVOID CsrQlpcTeb[QLPC_TEB_LENGTH];
// PVOID Win32ClientInfo[WIN32_CLIENT_INFO_LENGTH];
Print("\tWin32ClientInfo(pcti) @%08lx\n", &pteb->Win32ClientInfo[0]);
// PVOID SystemReserved2[322];
// ULONG gdiRgn;
Print("\tgdiRgn %08lx\n", teb.gdiRgn);
// ULONG gdiPen;
Print("\tgdiPen %08lx\n", teb.gdiPen);
// ULONG gdiBrush;
Print("\tgdiBrush %08lx\n", teb.gdiBrush);
// CLIENT_ID RealClientId;
Print("\tRealClientId %08lx\n", teb.RealClientId);
// HANDLE GdiCachedProcessHandle;
Print("\tGdiCachedProcessHandle %08lx\n", teb.GdiCachedProcessHandle);
// ULONG GdiClientPID;
Print("\tGdiClientPID %08lx\n", teb.GdiClientPID);
// ULONG GdiClientTID;
Print("\tGdiClientTID %08lx\n", teb.GdiClientTID);
// PVOID GdiThreadLocalInfo;
Print("\tGdiThreadLocalInfo %08lx\n", teb.GdiThreadLocalInfo);
// PVOID User32Reserved0; // User app spin count
// PVOID User32Reserved1;
// PVOID UserReserved[3];
// PVOID glDispatchTable[307]; // OpenGL
// PVOID glSectionInfo; // OpenGL
// PVOID glSection; // OpenGL
// PVOID glTable; // OpenGL
// PVOID glCurrentRC; // OpenGL
// PVOID glContext; // OpenGL
// ULONG LastStatusValue;
// UNICODE_STRING StaticUnicodeString;
// WCHAR StaticUnicodeBuffer[STATIC_UNICODE_BUFFER_LENGTH];
// PVOID DeallocationStack;
// PVOID TlsSlots[TLS_MINIMUM_AVAILABLE];
// LIST_ENTRY TlsLinks;
// PVOID Vdm;
// PVOID ReservedForNtRpc;
// PVOID DbgSsReserved[2];
} else {
Print("Unable to get TEB info.\n");
}
return(TRUE);
}
#endif // !KERNEL
#ifdef KERNEL
typedef struct _tagBASECHARSET {
LPSTR pstrCS;
DWORD dwValue;
} BASECHARSET;
BASECHARSET CrackCS[] = {
{"ANSI_CHARSET" ,0 },
{"DEFAULT_CHARSET" ,1 },
{"SYMBOL_CHARSET" ,2 },
{"SHIFTJIS_CHARSET" ,128 },
{"HANGEUL_CHARSET" ,129 },
{"GB2312_CHARSET" ,134 },
{"CHINESEBIG5_CHARSET" ,136 },
{"OEM_CHARSET" ,255 },
{"JOHAB_CHARSET" ,130 },
{"HEBREW_CHARSET" ,177 },
{"ARABIC_CHARSET" ,178 },
{"GREEK_CHARSET" ,161 },
{"TURKISH_CHARSET" ,162 },
{"THAI_CHARSET" ,222 },
{"EASTEUROPE_CHARSET" ,238 },
{"RUSSIAN_CHARSET" ,204 },
{"MAC_CHARSET" ,77 }};
/***************************************************************************\
* dkl - dump keyboard layout
*
* dkl address - dumps keyboard layout structure at address
*
* 05/21/95 GregoryW Created.
\***************************************************************************/
BOOL Idkl(
DWORD opts,
PVOID param1)
{
LIST_ENTRY List;
LIST_ENTRY ThreadList;
PLIST_ENTRY NextProcess;
PLIST_ENTRY NextThread;
PLIST_ENTRY ProcessHead;
PLIST_ENTRY ThreadListHead;
PEPROCESS pEProcess;
PW32PROCESS pW32Process;
PETHREAD pEThread;
ETHREAD EThread;
WCHAR ach[256];
THREADINFO ti;
PTHREADINFO pti;
KL kl, *pkl, *pklAnchor;
KBDFILE kf;
int i;
int nThread;
if (opts & OFLAG(k)) {
goto display_layouts;
}
if (param1 == 0) {
Print("Using gspklBaseLayout\n");
moveExpValue(&pkl, "win32k!gspklBaseLayout");
if (!pkl) {
return(FALSE);
}
} else {
pkl = (PKL)FIXKP(param1);
}
if (pkl == NULL) {
return(FALSE);
}
move(kl, pkl);
Print("KL @ 0x%08lx (cLockObj = %d)\n", pkl, kl.head.cLockObj);
Print(" pklNext @0x%08lx\n", kl.pklNext);
Print(" pklPrev @0x%08lx\n", kl.pklPrev);
Print(" dwFlags 0x%08lx\n", kl.dwFlags);
Print(" hkl 0x%08lx\n", kl.hkl);
#ifdef FE_IME
Print(" piiex @0x%08lx\n", kl.piiex);
#endif
if (kl.spkf == NULL) {
Print(" spkf @0x%08lx (NONE!)\n", kl.spkf);
}else {
move(kf, kl.spkf);
Print(" spkf @0x%08lx (cLockObj = %d)\n", kl.spkf, kf.head.cLockObj);
Print(" pkfNext @0x%08lx\n", kf.pkfNext);
Print(" awchKF[] L\"%ws\"\n", &kf.awchKF[0]);
Print(" hBase 0x%08lx\n", kf.hBase);
Print(" pKbdTbl @0x%08lx\n", kf.pKbdTbl);
Print(" bCharsets %s\n", GetFlags(GF_CHARSETS, kl.bCharsets, NULL));
}
for (i = 0; i < (sizeof(CrackCS) / sizeof(BASECHARSET)); i++) {
if (CrackCS[i].dwValue == kl.iBaseCharset) {
break;
}
}
Print(" iBaseCharset %s\n",
(i < (sizeof(CrackCS) / sizeof(BASECHARSET))) ? CrackCS[i].pstrCS : "ILLEGAL VALUE");
Print(" Codepage %d\n", kl.CodePage);
if (opts & OFLAG(a)) {
pklAnchor = pkl;
SAFEWHILE (kl.pklNext != pklAnchor) {
pkl = kl.pklNext;
if (!Idkl(0, pkl)) {
return(FALSE);
}
move(kl, pkl);
}
}
return TRUE;
display_layouts:
ProcessHead = EvalExp( "PsActiveProcessHead" );
if (!ProcessHead) {
Print("Unable to get value of PsActiveProcessHead\n");
return FALSE;
}
Print("ProcessHead = %lx\n", ProcessHead);
if (!tryMove(List, ProcessHead)) {
Print("Unable to get value of PsActiveProcessHead\n");
return FALSE;
}
NextProcess = List.Flink;
if (NextProcess == NULL) {
Print("PsActiveProcessHead->Flink is NULL!\n");
return FALSE;
}
Print("NextProcess = %lx\n", NextProcess);
nThread = 0;
SAFEWHILE(NextProcess != ProcessHead) {
pEProcess = GetEProcessData((PEPROCESS)NextProcess,
PROCESS_PROCESSHEAD,
NULL);
Print("pEProcess = %lx\n", pEProcess);
if (GetEProcessData(pEProcess, PROCESS_PROCESSLINK,
&List) == NULL) {
Print("Unable to read _EPROCESS at %lx\n",pEProcess);
break;
}
NextProcess = List.Flink;
/*
* Dump threads of Win32 Processes only
*/
if (GetEProcessData(pEProcess, PROCESS_WIN32PROCESS,
&pW32Process) == NULL || pW32Process == NULL) {
continue;
}
ThreadListHead = GetEProcessData(pEProcess, PROCESS_THREADLIST, &ThreadList);
if (ThreadListHead == NULL)
continue;
NextThread = ThreadList.Flink;
SAFEWHILE ( NextThread != ThreadListHead) {
pEThread = (PETHREAD)(CONTAINING_RECORD(NextThread, KTHREAD, ThreadListEntry));
if (!tryMove(EThread, pEThread)) {
Print("Unable to read _ETHREAD at %lx\n",pEThread);
break;
}
NextThread = ((PKTHREAD)&EThread)->ThreadListEntry.Flink;
pti = EThread.Tcb.Win32Thread;
if (!tryMove(ti, pti)) {
Print("Idt: Unable to move pti from %x.\n",
pti);
return(FALSE);
}
if (ti.Thread != pEThread || pti == NULL) {
/*
* This thread either doesn't have a pti or something
* is whacked out. Just skip it if we want all
* threads.
*/
} else { // Good thread
PWCHAR pwch;
if (!GetAppName(&EThread, &ti, ach, sizeof(ach))) {
Print("Idt: Unable to get app name for ETHREAD %x.\n",
pEThread);
return(FALSE);
}
pwch = wcsrchr(ach, L'\\');
if (pwch == NULL) {
pwch = ach;
} else {
pwch++;
}
nThread++;
Print("t 0x%08lx i %2x.%-3lx k 0x%08lx %ws\n",
pti,
EThread.Cid.UniqueProcess,
EThread.Cid.UniqueThread,
ti.spklActive,
pwch);
if (opts & OFLAG(v)) {
Idkl(0, ti.spklActive);
}
} // Good Thread
} // NextThread
} // NextProcess
Print(" %d threads total.\n", nThread);
moveExpValue(&pkl, "win32k!gspklBaseLayout");
Print(" gspklBaseLayout = %lx\n", pkl);
if (opts & OFLAG(v)) {
Idkl(0, pkl);
}
return TRUE;
}
/***************************************************************************\
* ddk - dump deadkey table
*
* ddk address - dumps deadkey table address
*
* 09/28/95 GregoryW Created.
\***************************************************************************/
BOOL Iddk(
DWORD opts,
PVOID param1)
{
KBDTABLES KbdTbl;
PKBDTABLES pKbdTbl;
DEADKEY DeadKey;
PDEADKEY pDeadKey;
if (param1 == 0) {
Print("Expected address\n");
return(FALSE);
} else {
pKbdTbl = (PKBDTABLES)FIXKP(param1);
}
move(KbdTbl, pKbdTbl);
pDeadKey = KbdTbl.pDeadKey;
if (!pDeadKey) {
Print("No deadkey table for this layout\n");
return TRUE;
}
do {
move(DeadKey, pDeadKey);
if (DeadKey.dwBoth == 0) {
break;
}
Print("d 0x%04x ch 0x%04x => 0x%04x\n", HIWORD(DeadKey.dwBoth), LOWORD(DeadKey.dwBoth), DeadKey.wchComposed);
pDeadKey++;
} while (TRUE);
return TRUE;
}
#ifdef FE_IME
/***************************************************************************\
* dii - dump IMEINFOEX
*
* dii address - dumps extended IME information at address
*
* 01/30/96 WKwok Created.
\***************************************************************************/
BOOL Idii(
DWORD opts,
PVOID param1)
{
IMEINFOEX iiex, *piiex;
if (param1 == NULL) {
Print("Expected address\n");
return(FALSE);
}
piiex = (PIMEINFOEX)FIXKP(param1);
move(iiex, piiex);
Print("IIEX @ 0x%08lx\n", piiex);
Print(" hKL 0x%08lx\n", iiex.hkl);
Print(" ImeInfo\n");
Print(" dwPrivateDataSize 0x%08lx\n", iiex.ImeInfo.dwPrivateDataSize);
Print(" fdwProperty 0x%08lx\n", iiex.ImeInfo.fdwProperty);
Print(" fdwConversionCaps 0x%08lx\n", iiex.ImeInfo.fdwConversionCaps);
Print(" fdwSentenceCaps 0x%08lx\n", iiex.ImeInfo.fdwSentenceCaps);
Print(" fdwUICaps 0x%08lx\n", iiex.ImeInfo.fdwUICaps);
Print(" fdwSCSCaps 0x%08lx\n", iiex.ImeInfo.fdwSCSCaps);
Print(" fdwSelectCaps 0x%08lx\n", iiex.ImeInfo.fdwSelectCaps);
Print(" wszImeDescription[] L\"%ws\"\n", &iiex.wszImeDescription[0]);
Print(" wszImeFile[] L\"%ws\"\n", &iiex.wszImeFile[0]);
return TRUE;
}
#endif
/***************************************************************************\
* dti - dump THREADINFO
*
* dti address - dumps THREADINFO structure at address
*
* 11-13-91 DavidPe Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idti(
DWORD opts,
PVOID param1)
{
PTHREADINFO pti;
THREADINFO ti;
CLIENTTHREADINFO cti;
PETHREAD pThread;
ETHREAD Thread;
UCHAR PriorityClass;
if (param1 == NULL) {
PQ pq;
Q q;
Print("No pti specified: using foreground thread\n");
moveExpValue(&pq, VAR(gpqForeground));
if (pq == NULL) {
Print("No foreground queue!\n");
return FALSE;
}
move(q, FIXKP(pq));
pti = FIXKP(q.ptiKeyboard);
} else {
pti = (PTHREADINFO)FIXKP(param1);
}
if (pti == NULL) {
return(FALSE);
}
Idt(OFLAG(p), pti);
move(ti, pti);
move(cti, ti.pcti);
Print("PTHREADINFO @ 0x%08lx\n", pti);
Print("\tPtiLink.Flink @0x%08lx\n"
"\tptl @0x%08lx\n"
"\tptlOb @0x%08lx\n"
"\tppi @0x%08lx\n"
"\tpq @0x%08lx\n"
"\tspklActive @0x%08lx\n"
"\tmlPost.pqmsgRead @0x%08lx\n"
"\tmlPost.pqmsgWriteLast @0x%08lx\n"
"\tmlPost.cMsgs 0x%08lx\n",
ti.PtiLink.Flink,
ti.ptl,
ti.ptlOb,
ti.ppi,
ti.pq,
ti.spklActive,
ti.mlPost.pqmsgRead,
ti.mlPost.pqmsgWriteLast,
ti.mlPost.cMsgs);
#ifdef FE_IME
Print("\tspwndDefaultIme @0x%08lx\n"
"\tspDefaultImc @0x%08lx\n"
"\thklPrev 0x%08lx\n",
ti.spwndDefaultIme,
ti.spDefaultImc,
ti.hklPrev);
#endif
Print("\trpdesk @0x%08lx\n",
ti.rpdesk);
Print("\thdesk 0x%08lx\n",
ti.hdesk);
Print("\tamdesk 0x%08lx\n",
ti.amdesk);
Print("\tpDeskInfo @0x%08lx\n"
"\tpClientInfo @0x%08lx\n",
ti.pDeskInfo,
ti.pClientInfo);
Print("\tTIF_flags %s\n",
GetFlags(GF_TIF, ti.TIF_flags, NULL));
Print("\tsphkCurrent @0x%08lx\n"
"\tpEventQueueServer @0x%08lx\n"
"\thEventQueueClient 0x%08lx\n",
ti.sphkCurrent,
ti.pEventQueueServer,
ti.hEventQueueClient);
Print("\tfsChangeBits %s\n",
GetFlags(GF_QS, (WORD)cti.fsChangeBits, NULL));
Print("\tfsChangeBitsRemovd %s\n",
GetFlags(GF_QS, (WORD)ti.fsChangeBitsRemoved, NULL));
Print("\tfsWakeBits %s\n",
GetFlags(GF_QS, (WORD)cti.fsWakeBits, NULL));
Print("\tfsWakeMask %s\n",
GetFlags(GF_QS, (WORD)cti.fsWakeMask, NULL));
Print("\tcPaintsReady 0x%04x\n"
"\tcTimersReady 0x%04x\n"
"\ttimeLast 0x%08lx\n"
"\tptLast.x 0x%08lx\n"
"\tptLast.y 0x%08lx\n"
"\tidLast 0x%08lx\n"
"\tcQuit 0x%08lx\n"
"\texitCode 0x%08lx\n"
"\tpSBTrack 0x%08lx\n"
"\tpsmsSent @0x%08lx\n"
"\tpsmsCurrent @0x%08lx\n",
ti.cPaintsReady,
ti.cTimersReady,
ti.timeLast,
ti.ptLast.x,
ti.ptLast.y,
ti.idLast,
ti.cQuit,
ti.exitCode,
ti.pSBTrack,
ti.psmsSent,
ti.psmsCurrent);
Print("\tfsHooks 0x%08lx\n"
"\tasphkStart @0x%08lx l%ld\n"
"\tsphkCurrent @0x%08lx\n",
ti.fsHooks,
&(pti->asphkStart), CWINHOOKS,
ti.sphkCurrent);
Print("\tpsmsReceiveList @0x%08lx\n",
ti.psmsReceiveList);
Print("\tptdb @0x%08lx\n"
"\tThread @0x%08lx\n",
ti.ptdb, ti.Thread);
pThread = (PETHREAD)ti.Thread;
move(Thread, pThread);
GetEProcessData(Thread.ThreadsProcess, PROCESS_PRIORITYCLASS, &PriorityClass);
Print("\t PriorityClass %d\n",
PriorityClass);
Print("\tcWindows 0x%08lx\n"
"\tcVisWindows 0x%08lx\n"
"\tpqAttach @0x%08lx\n"
"\tiCursorLevel 0x%08lx\n",
ti.cWindows,
ti.cVisWindows,
ti.pqAttach,
ti.iCursorLevel);
Print("\tpMenuState @0x%08lx\n",
ti.pMenuState);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dtl handle|pointer
*
* !dtl <addr> Dumps all THREAD locks for object at <addr>
* !dtl -t <pti> Dumps all THREAD locks made by thread <pti>
* !dtl Dumps all THREAD locks made by all threads
*
* 02-27-92 ScottLu Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idtl(
DWORD opts,
PVOID param1)
{
TL tl;
PTHREADINFO pti;
THREADINFO ti;
if (param1 == 0) {
Print("Dumping all thread locks:\npti pObj Caller\n");
FOREACHPTI(pti)
Idtl(OFLAG(t) | OFLAG(x), pti);
NEXTEACHPTI(pti);
return(TRUE);
}
if (opts & OFLAG(t)) {
PTL ptl;
pti = HorPtoP(param1, TYPE_THREADINFO);
if (pti == NULL) {
return(FALSE);
}
if (!(opts & OFLAG(x))) { // x is not legal from user - internal only
Print("pti pObj Caller\n");
}
if (!tryMove(ti, pti)) {
Print("Idtl: Can't get pti data from %x.\n", pti);
return(FALSE);
}
ptl = ti.ptl;
SAFEWHILE(ptl) {
#ifdef DEBUG
char ach[80];
DWORD dwOffset;
#endif // DEBUG
if (!tryMove(tl, ptl)) {
Print("Idtl: Can't get ptl data from %x.\n", ti.ptl);
return(FALSE);
}
#ifdef DEBUG
GetSymbol(tl.pfn, ach, &dwOffset);
Print("%08lx %08lx %s+%lx\n", pti, tl.pobj, ach, dwOffset);
#else // !DEBUG
Print("%08lx %08lx\n", pti, tl.pobj);
#endif // !DEBUG
ptl = tl.next;
}
return(TRUE);
}
if (!param1) {
return(FALSE);
}
Print("Thread Locks for object %x:\n", param1);
Print("pti pObj Caller\n");
FOREACHPTI(pti)
move(ti, pti);
if (ti.ptl != NULL) {
#ifdef DEBUG
char ach[80];
DWORD dwOffset;
#endif
move(tl, ti.ptl);
if (tl.pobj == param1) {
#ifdef DEBUG
GetSymbol(tl.pfn, ach, &dwOffset);
Print("%08lx %08lx %s+%lx\n", pti, tl.pobj, ach, dwOffset);
#else // !DEBUG
Print("%08lx %08lx\n", pti, tl.pobj);
#endif // !DEBUG
}
}
NEXTEACHPTI(pti);
Print("--- End Thread Lock List ---\n");
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/************************************************************************\
* Procedure: Idtmr
*
* Description: Dumps timer structures
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idtmr(
DWORD opts,
PVOID param1)
{
PTIMER ptmr;
TIMER tmr;
if (param1 == 0) {
moveExpValue(&ptmr, VAR(gptmrFirst));
SAFEWHILE (ptmr) {
Idtmr(0, ptmr);
Print("\n");
move(ptmr, &ptmr->ptmrNext);
}
return(TRUE);
}
ptmr = (PTIMER)param1;
if (ptmr == NULL) {
Print("Expected ptmr address.\n");
return(FALSE);
}
move(tmr, ptmr);
Print("Timer %08x:\n"
" ptmrNext = %x\n"
" pti = %x\n"
" spwnd = %x\n"
" nID = %x\n"
" cmsCountdown = %x\n"
" cmsRate = %x\n"
" flags = %s\n"
" pfn = %x\n"
" ptiOptCreator = %x\n",
ptmr,
tmr.ptmrNext,
tmr.pti,
tmr.spwnd,
tmr.nID,
tmr.cmsCountdown,
tmr.cmsRate,
GetFlags(GF_TMRF, (WORD)tmr.flags, NULL),
tmr.pfn,
tmr.ptiOptCreator);
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Idu
*
* Description: Dump unknown object. Does what it can figure out.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idu(
DWORD opts,
PVOID param1)
{
HANDLEENTRY he, *phe;
int i;
DWORD dw;
if (param1 == NULL) {
FOREACHHANDLEENTRY(phe, he, i)
if (he.bType != TYPE_FREE && tryDword(&dw, FIXKP(he.phead))) {
Idu(OFLAG(x), he.phead);
}
NEXTEACHHANDLEENTRY()
return(TRUE);
}
param1 = HorPtoP(FIXKP(param1), -1);
if (param1 == NULL) {
return(FALSE);
}
if (!getHEfromP(NULL, &he, param1)) {
return(FALSE);
}
Print("--- %s object @%x ---\n", pszObjStr[he.bType], FIXKP(param1));
switch (he.bType) {
case TYPE_WINDOW:
return(Idw(0, param1));
case TYPE_MENU:
return(Idm(0, param1));
#ifdef KERNEL
case TYPE_CURSOR:
return(Idcur(0, param1));
case TYPE_THREADINFO:
return(Idti(0, param1));
#ifdef LATER
case TYPE_INPUTQUEUE:
return(Idq(0, param1));
#endif
case TYPE_HOOK:
return(Idhk(OFLAG(a) | OFLAG(g), NULL));
case TYPE_DDECONV:
case TYPE_DDEXACT:
return(Idde(0, param1));
#endif // KERNEL
case TYPE_CALLPROC:
case TYPE_ACCELTABLE:
case TYPE_SETWINDOWPOS:
case TYPE_ZOMBIE:
case TYPE_DDEACCESS:
default:
Print("not supported.\n", pszObjStr[he.bType]);
}
return(TRUE);
}
#ifdef KERNEL
/***************************************************************************\
* dumphmgr - dumps object allocation counts for handle-table.
*
*
* 10-18-94 ChrisWil Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
#define TRACE_OBJECT_ALLOCS 0
#define TYPE_MAXTYPES 19
BOOL Idumphmgr(
DWORD opts)
{
ULONG idx,ulCurTotal,ulMaxTotal,ulBasTotal,ulAllTotal,ulSizTotal;
LONG lPctDiff;
PULONG pObjCurCount,pObjMaxCount,pObjBasCount,pObjTotCount,pObjSizCount;
ULONG gacObjCur[TYPE_MAXTYPES];
ULONG gacObjMax[TYPE_MAXTYPES];
ULONG gacObjBas[TYPE_MAXTYPES];
ULONG gacObjTot[TYPE_MAXTYPES];
ULONG gacObjSiz[TYPE_MAXTYPES];
static BOOL bFirstTime = TRUE;
pObjCurCount =
pObjMaxCount =
pObjBasCount =
pObjTotCount =
pObjSizCount = NULL;
/*
* Zero out the temp-buffer array of object counts.
*
*/
RtlFillMemory(gacObjCur,sizeof(gacObjCur),0);
RtlFillMemory(gacObjMax,sizeof(gacObjMax),0);
RtlFillMemory(gacObjBas,sizeof(gacObjBas),0);
RtlFillMemory(gacObjTot,sizeof(gacObjTot),0);
RtlFillMemory(gacObjSiz,sizeof(gacObjSiz),0);
#if (DBG || TRACE_OBJECT_ALLOCS)
/*
* Retreive pointers to the server buffers.
*
*/
pObjCurCount = EvalExp(VAR(acurObjectCount));
pObjMaxCount = EvalExp(VAR(amaxObjectCount));
pObjBasCount = EvalExp(VAR(abasObjectCount));
pObjTotCount = EvalExp(VAR(atotObjectCount));
pObjSizCount = EvalExp(VAR(asizObjectCount));
/*
* Grab the handle-allocation buffers from the server.
*
*/
if((pObjCurCount && pObjBasCount) && (pObjMaxCount && pObjTotCount)) {
move(gacObjCur,pObjCurCount);
move(gacObjMax,pObjMaxCount);
move(gacObjBas,pObjBasCount);
move(gacObjTot,pObjTotCount);
move(gacObjSiz,pObjSizCount);
}
/*
* If the argument-list contains the Snap option,
* then copy the current-object-count to the
* base-object-count.
*
*/
if((opts & OFLAG(s)) || bFirstTime) {
NtWriteVirtualMemory(hCurrentProcess ,
pObjBasCount ,
gacObjCur ,
sizeof(gacObjCur),
NULL
);
bFirstTime = FALSE;
move(gacObjBas,pObjBasCount);
}
#else
pObjCurCount = 0;
pObjMaxCount = 0;
pObjBasCount = 0;
pObjTotCount = 0;
pObjSizCount = 0;
#endif
/*
* Output table of objects.
*
*/
ulCurTotal = 0;
ulMaxTotal = 0;
ulBasTotal = 0;
ulAllTotal = 0;
ulSizTotal = 0;
Print("Type Allocated Maximum Cur Base %% Diff (Bytes)\n");
Print("---- --------- ------- ------- ---- ------ -------\n");
for(idx=0; idx < TYPE_MAXTYPES; idx++) {
if(gacObjBas[idx])
lPctDiff = (((LONG)(gacObjCur[idx] - gacObjBas[idx]) * 100) / (LONG)gacObjBas[idx]);
else
lPctDiff = ((LONG)(gacObjCur[idx] - gacObjBas[idx]) * 100);
Print("%s %6lu %5lu %5lu %5lu %5ld%% %6lu\n",
pszObjStr[idx],
gacObjTot[idx],
gacObjMax[idx],
gacObjCur[idx],
gacObjBas[idx],
lPctDiff ,
gacObjSiz[idx]
);
ulCurTotal += gacObjCur[idx];
ulBasTotal += gacObjBas[idx];
ulMaxTotal += gacObjMax[idx];
ulAllTotal += gacObjTot[idx];
ulSizTotal += gacObjSiz[idx];
}
/*
* Output the totals.
*
*/
if(ulBasTotal)
lPctDiff = (((LONG)(ulCurTotal - ulBasTotal) * 100) / (LONG)ulBasTotal);
else
lPctDiff = ((LONG)(ulCurTotal - ulBasTotal) * 100);
Print(" --------- ------- ------- ---- ------ -------\n");
Print("Totals %7lu %5lu %5lu %5lu %5ld%% %7lu\n\n",
ulAllTotal,ulMaxTotal,ulCurTotal,ulBasTotal,lPctDiff,ulSizTotal);
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: dwrWorker
*
* Description: Dumps pwnd structures compactly to show relationships.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL dwrWorker(
PWND pwnd,
int tab)
{
WND wnd;
if (pwnd == 0) {
return(FALSE);
}
do {
pwnd = FIXKP(pwnd);
move(wnd, pwnd);
DebugGetWindowTextA(pwnd, gach1);
move(gcls, FIXKP(wnd.pcls));
if (gcls.atomClassName < 0xC000) {
switch (gcls.atomClassName) {
case WC_DIALOG:
strcpy(gach1, "WC_DIALOG");
break;
case DESKTOPCLASS:
strcpy(gach1, "DESKTOP");
break;
case SWITCHWNDCLASS:
strcpy(gach1, "SWITCHWND");
break;
case ICONTITLECLASS:
strcpy(gach1, "ICONTITLE");
break;
default:
if (gcls.atomClassName == 0) {
move(gach1, FIXKP(gcls.lpszAnsiClassName));
} else {
sprintf(gach2, "0x%04x", gcls.atomClassName);
}
}
} else {
DebugGetClassNameA(gcls.lpszAnsiClassName, gach2);
}
Print("%08x%*s [%s|%s]", pwnd, tab, "", gach1, gach2);
if (wnd.spwndOwner != NULL) {
Print(" <- Owned by:%08x", FIXKP(wnd.spwndOwner));
}
Print("\n");
if (wnd.spwndChild != NULL) {
dwrWorker(wnd.spwndChild, tab + 2);
}
} SAFEWHILE ((pwnd = wnd.spwndNext) && tab > 0);
return(TRUE);
}
/************************************************************************\
* Procedure: Idw
*
* Description: Dumps pwnd structures
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idw(
DWORD opts,
PVOID param1)
{
WND wnd;
CLS cls;
PWND pwnd = param1;
char ach[80];
DWORD dwOffset;
int ix;
DWORD tempDWord;
if (opts & OFLAG(a)) {
#ifdef KERNEL
DESKTOP desk, *pdesk;
PWND pwnd;
WCHAR wach[80];
if (param1 != 0) {
Print("window parameter ignored with -a option.\n");
}
FOREACHDESKTOP(pdesk)
if (tryMove(desk, pdesk)) {
OBJECT_HEADER_NAME_INFO NameInfo;
OBJECT_HEADER Head;
move(Head, OBJECT_TO_OBJECT_HEADER(pdesk));
move(NameInfo, ((PCHAR)(OBJECT_TO_OBJECT_HEADER(pdesk)) - Head.NameInfoOffset));
moveBlock(wach, FIXKP(NameInfo.Name.Buffer), NameInfo.Name.Length);
wach[NameInfo.Name.Length / sizeof(WCHAR)] = L'\0';
Print("\n----Windows for %ws desktop @%08lx:\n\n", wach, pdesk);
move(pwnd, &(desk.pDeskInfo->spwnd));
if (!Idw((opts & ~OFLAG(a)) | OFLAG(p), pwnd)) {
return(FALSE);
}
}
NEXTEACHDESKTOP(pdesk)
#else // !KERNEL
TEB teb;
if (GetTargetTEB(&teb, NULL)) {
PDESKTOPINFO pdi;
DESKTOPINFO di;
pdi = ((PCLIENTINFO)&teb.Win32ClientInfo[0])->pDeskInfo;
move(di, pdi);
return(Idw(opts & ~OFLAG(a) | OFLAG(p), FIXKP(di.spwnd)));
}
#endif // !KERNEL
return(TRUE);
}
/*
* See if the user wants all top level windows.
*/
if (param1 == NULL || opts & (OFLAG(p) | OFLAG(s))) {
/*
* Make sure there was also a window argument if p or s.
*/
if (param1 == NULL && (opts & (OFLAG(p) | OFLAG(s)))) {
Print("Must specify window with '-p' or '-s' options.\n");
return(FALSE);
}
if (param1 && (pwnd = HorPtoP(pwnd, TYPE_WINDOW)) == NULL) {
return(FALSE);
}
if (opts & OFLAG(p)) {
Print("pwndParent = %08lx\n", pwnd);
if (!tryMove(pwnd, FIXKP(&pwnd->spwndChild))) {
Print("<< Can't get WND >>\n");
return TRUE; // we don't need to have the flags explained!
}
SAFEWHILE (pwnd) {
if (!Idw(opts & ~OFLAG(p), pwnd)) {
return FALSE;
}
move(pwnd, FIXKP(&pwnd->spwndNext));
}
return TRUE;
} else if (opts & OFLAG(s)) {
move(pwnd, FIXKP(&pwnd->spwndParent));
return Idw((opts | OFLAG(p)) & ~OFLAG(s), pwnd);
} else { // pwnd == NULL & !p & !s
#ifdef KERNEL
Q q;
PQ pq;
THREADINFO ti;
PWND pwnd;
moveExpValue(&pq, "win32k!gpqForeground");
move(q, pq);
move(ti, q.ptiKeyboard);
if (ti.rpdesk == NULL) {
Print("Foreground thread doesn't have a desktop.\n");
return(FALSE);
}
move(pwnd, &(ti.pDeskInfo->spwnd));
Print("pwndDesktop = %08lx\n", pwnd);
return(Idw(opts | OFLAG(p), pwnd));
#else // !KERNEL
return(Idw(opts | OFLAG(a), 0));
#endif // !KERNEL
}
}
if (param1 && (pwnd = HorPtoP(param1, TYPE_WINDOW)) == NULL) {
Print("Idw: %x is not a pwnd.\n", param1);
return(FALSE);
}
if (opts & OFLAG(r)) {
dwrWorker(FIXKP(pwnd), 0);
return(TRUE);
}
move(wnd, FIXKP(pwnd));
#ifdef KERNEL
/*
* Print simple thread info.
*/
if (wnd.head.pti) {
Idt(OFLAG(p), (PVOID)wnd.head.pti);
}
#endif // KERNEL
/*
* Print pwnd.
*/
Print("pwnd = %08lx\n", pwnd);
if (opts & OFLAG(w)) {
Print("%d window bytes: ", wnd.cbwndExtra);
if (wnd.cbwndExtra) {
for (ix=0; ix < wnd.cbwndExtra; ix += 4) {
DWORD UNALIGNED *pdw;
pdw = (DWORD UNALIGNED *) ((BYTE *) (pwnd+1) + ix);
move(tempDWord, pdw);
Print("%08x ", tempDWord);
}
}
Print("\n");
}
if (!(opts & OFLAG(v))) {
/*
* Print title string.
*/
DebugGetWindowTextA(pwnd, ach);
Print("title = \"%s\"\n", ach);
/*
* Print wndproc symbol string.
*/
if (opts & OFLAG(h)) {
GetSymbol((LPVOID)wnd.lpfnWndProc, ach, &dwOffset);
Print("wndproc = %08lx = \"%s\" (%s)\n", wnd.lpfnWndProc, ach,
TestWF(&wnd, WFANSIPROC) ? "ANSI" : "Unicode" );
} else {
Print("wndproc = %08lx (%s)\n", wnd.lpfnWndProc,
TestWF(&wnd, WFANSIPROC) ? "ANSI" : "Unicode" );
}
} else {
/*
* Get the PWND structure. Ignore class-specific data for now.
*/
Print("\tpti @0x%08lx\n", FIXKP(wnd.head.pti));
Print("\thandle 0x%08lx\n", wnd.head.h);
DebugGetWindowTextA(wnd.spwndNext, ach);
Print("\tspwndNext @0x%08lx \"%s\"\n", wnd.spwndNext, ach);
DebugGetWindowTextA(wnd.spwndParent, ach);
Print("\tspwndParent @0x%08lx \"%s\"\n", wnd.spwndParent, ach);
DebugGetWindowTextA(wnd.spwndChild, ach);
Print("\tspwndChild @0x%08lx \"%s\"\n", wnd.spwndChild, ach);
DebugGetWindowTextA(wnd.spwndOwner, ach);
Print("\tspwndOwner @0x%08lx \"%s\"\n", wnd.spwndOwner, ach);
Print("\trcWindow { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n",
wnd.rcWindow.left, wnd.rcWindow.top,
wnd.rcWindow.right, wnd.rcWindow.bottom);
Print("\trcClient { 0x%lx, 0x%lx, 0x%lx, 0x%lx }\n",
wnd.rcClient.left, wnd.rcClient.top,
wnd.rcClient.right, wnd.rcClient.bottom);
GetSymbol((LPVOID)wnd.lpfnWndProc, ach, &dwOffset);
Print("\tlpfnWndProc @0x%08lx (%s) %s\n", wnd.lpfnWndProc, ach,
TestWF(&wnd, WFANSIPROC) ? "ANSI" : "Unicode" );
move(cls, FIXKP(wnd.pcls));
if (cls.atomClassName < 0xC000) {
sprintf(ach, "0x%04x", cls.atomClassName);
} else {
DebugGetClassNameA(cls.lpszAnsiClassName, ach);
}
Print("\tpcls @0x%08lx (%s)\n",
wnd.pcls, ach);
Print("\thrgnUpdate 0x%08lx\n",
wnd.hrgnUpdate);
DebugGetWindowTextA(wnd.spwndLastActive, ach);
Print("\tspwndLastActive @0x%08lx \"%s\"\n",
wnd.spwndLastActive, ach);
Print("\tppropList @0x%08lx\n"
"\tpSBInfo @0x%08lx\n",
wnd.ppropList,
wnd.pSBInfo);
if (wnd.pSBInfo) {
SBINFO asb;
moveBlock(&asb, FIXKP(wnd.pSBInfo), sizeof(asb));
Print("\t SBO_FLAGS = %s\n"
"\t SBO_HMIN = 0x%08lX\n"
"\t SBO_HMAX = 0x%08lX\n"
"\t SBO_HPAGE = 0x%08lX\n"
"\t SBO_HPOS = 0x%08lX\n"
"\t SBO_VMIN = 0x%08lX\n"
"\t SBO_VMAX = 0x%08lX\n"
"\t SBO_VPAGE = 0x%08lX\n"
"\t SBO_VPOS = 0x%08lX\n",
GetFlags(GF_SB, (WORD)asb.WSBflags, NULL),
asb.Horz.posMin,
asb.Horz.posMax,
asb.Horz.page,
asb.Horz.pos,
asb.Vert.posMin,
asb.Vert.posMax,
asb.Vert.page,
asb.Vert.pos);
}
Print("\tspmenuSys @0x%08lx\n"
"\tspmenu/id @0x%08lx\n",
wnd.spmenuSys,
wnd.spmenu);
Print("\thdcOwn 0x%08lx\n"
"\thrgnClip 0x%08lx\n",
wnd.hdcOwn,
wnd.hrgnClip);
/*
* Print title string.
*/
DebugGetWindowTextA(pwnd, ach);
Print("\tpName \"%s\"\n",
ach);
Print("\tdwUserData 0x%08lx\n",
wnd.dwUserData);
Print("\tstate 0x%08lx\n"
"\tstate2 0x%08lx\n"
"\tExStyle 0x%08lx\n"
"\tstyle 0x%08lx\n"
"\tfnid 0x%08lx\n"
#ifdef FE_IME
"\thImc 0x%08lx\n"
#endif
"\tbFullScreen 0x%08lx\n"
"\thModule 0x%08lx\n",
wnd.state,
wnd.state2,
wnd.ExStyle,
wnd.style,
(DWORD)wnd.fnid,
#ifdef FE_IME
(DWORD)wnd.hImc,
#endif
(DWORD)wnd.bFullScreen,
wnd.hModule);
}
/*
* Print out all the flags
*/
if (opts & OFLAG(f)) {
int i;
PBYTE pbyte = (PBYTE)(&(wnd.state));
for (i=0; i<N_AFLAGS; i++) {
if (pbyte[aFlags[i].offset] & aFlags[i].mask) {
Print("\t%-18s\t%lx:%02lx\n", aFlags[i].pszText,
(PBYTE)&(pwnd->state) + aFlags[i].offset,
aFlags[i].mask);
}
}
}
Print("---\n");
return(TRUE);
}
#ifdef KERNEL
/************************************************************************\
* Procedure: Idwpi
*
* Description: Dumps WOWPROCESSINFO structs
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Idwpi(
DWORD opts,
PVOID param1)
{
PWOWPROCESSINFO pwpi;
WOWPROCESSINFO wpi;
PPROCESSINFO ppi;
if (param1 == 0) {
FOREACHPPI(ppi)
Print("Process %x.\n", FIXKP(ppi));
move(pwpi, FIXKP(&ppi->pwpi));
SAFEWHILE (pwpi) {
Idwpi(0, pwpi);
Print("\n");
move(pwpi, FIXKP(&pwpi->pwpiNext));
}
NEXTEACHPPI()
return(TRUE);
}
if (opts & OFLAG(p)) {
ppi = (PPROCESSINFO)FIXKP(param1);
move(pwpi, &ppi->pwpi);
if (pwpi == NULL) {
Print("No pwpis for this process.\n");
return(TRUE);
}
SAFEWHILE (pwpi) {
Idwpi(0, pwpi);
Print("\n");
move(pwpi, &pwpi->pwpiNext);
}
return(TRUE);
}
pwpi = (PWOWPROCESSINFO)FIXKP(param1);
move(wpi, pwpi);
Print("PWOWPROCESSINFO @ 0x%08lx\n", pwpi);
Print("\tpwpiNext 0x%08lx\n", wpi.pwpiNext);
Print("\tptiScheduled 0x%08lx\n", wpi.ptiScheduled);
Print("\tnTaskLock 0x%08lx\n", wpi.nTaskLock);
Print("\tptdbHead 0x%08lx\n", wpi.ptdbHead);
Print("\tlpfnWowExitTask 0x%08lx\n", wpi.lpfnWowExitTask);
Print("\tpEventWowExec 0x%08lx\n", wpi.pEventWowExec);
Print("\thEventWowExecClient 0x%08lx\n", wpi.hEventWowExecClient);
Print("\tnSendLock 0x%08lx\n", wpi.nSendLock);
Print("\tnRecvLock 0x%08lx\n", wpi.nRecvLock);
Print("\tCSOwningThread 0x%08lx\n", wpi.CSOwningThread);
Print("\tCSLockCount 0x%08lx\n", wpi.CSLockCount);
return(TRUE);
}
#endif // KERNEL
#ifdef KERNEL
/***************************************************************************\
* dws - dump windows stations
* dws h - dump windows stations plus handle list
*
* Dump WindowStation
*
* 8-11-94 SanfordS Created
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
BOOL Idws(
DWORD opts,
PVOID param1)
{
WINDOWSTATION winsta, *pwinsta;
WCHAR ach[80];
OBJECT_HEADER Head;
OBJECT_HEADER_NAME_INFO NameInfo;
if (param1 == 0) {
moveExpValue(&pwinsta, VAR(grpwinstaList));
SAFEWHILE (pwinsta != NULL) {
Idws(0, pwinsta);
Print("\n");
move(pwinsta, &pwinsta->rpwinstaNext);
}
return(TRUE);
}
pwinsta = param1;
move(winsta, pwinsta);
move(Head, OBJECT_TO_OBJECT_HEADER(pwinsta));
move(NameInfo, ((PCHAR)(OBJECT_TO_OBJECT_HEADER(pwinsta)) - Head.NameInfoOffset));
move(ach, NameInfo.Name.Buffer);
ach[NameInfo.Name.Length / sizeof(WCHAR)] = 0;
Print("Windowstation: %ws @%0lx\n", ach, pwinsta);
Print(" # Opens = %d\n", Head.HandleCount);
Print(" rpdeskList = %0lx\n", winsta.rpdeskList);
Print(" rpdeskLogon = %0lx\n", winsta.rpdeskLogon);
Print(" rpdeskCurrent = %0lx\n", winsta.rpdeskCurrent);
Print(" spwndDesktopOwner = %0lx\n", winsta.spwndDesktopOwner);
Print(" spwndLogonNotify = %0lx\n", winsta.spwndLogonNotify);
Print(" ptiDesktop = %0lx\n", winsta.ptiDesktop);
Print(" dwFlags = %0lx\n", winsta.dwFlags);
Print(" spklList = %0lx\n", winsta.spklList);
Print(" pEventInputReady = %0lx\n", winsta.pEventInputReady);
Print(" ptiClipLock = %0lx\n", winsta.ptiClipLock);
Print(" spwndClipOpen = %0lx\n", winsta.spwndClipOpen);
Print(" spwndClipViewer = %0lx\n", winsta.spwndClipViewer);
Print(" spwndClipOwner = %0lx\n", winsta.spwndClipOwner);
Print(" pClipBase = %0lx\n", winsta.pClipBase);
Print(" cNumClipFormats = %0lx\n", winsta.cNumClipFormats);
Print(" fClipboardChanged = %d\n", winsta.fClipboardChanged);
Print(" fDrawingClipboard = %d\n", winsta.fDrawingClipboard);
Print(" pGlobalAtomTable = %0lx\n", winsta.pGlobalAtomTable);
Print(" pEventSwitchNotify = %0lx\n", winsta.pEventSwitchNotify);
Print(" luidUser = %0lx.%lx\n", winsta.luidUser.HighPart,
winsta.luidUser.LowPart);
// Print(" psidUser = @%0lx\n", winsta.psidUser);
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Ifno
*
* Description: Find Nearest Objects - helps in figureing out references
* to freed objects or stale pointers.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Ifno(
DWORD opts,
PVOID param1)
{
HANDLEENTRY he, heBest, heAfter, *phe;
DWORD i;
DWORD dw, hBest, hAfter;
if (param1 == NULL) {
Print("Expected an address.\n");
return(FALSE);
}
dw = (DWORD)FIXKP(param1);
heBest.phead = NULL;
heAfter.phead = (PVOID)-1;
if (dw != (DWORD)param1) {
/*
* no fixups needed - he's looking the kernel address range.
*/
FOREACHHANDLEENTRY(phe, he, i)
if ((DWORD)he.phead <= dw &&
heBest.phead < he.phead &&
he.bType != TYPE_FREE) {
heBest = he;
hBest = i;
}
if ((DWORD)he.phead > dw &&
heAfter.phead > he.phead &&
he.bType != TYPE_FREE) {
heAfter = he;
hAfter = i;
}
NEXTEACHHANDLEENTRY()
if (heBest.phead != NULL) {
Print("Nearest guy before %x is a %s object located at %x (i=%x).\n",
dw, aszTypeNames[heBest.bType], heBest.phead, hBest);
}
if (heAfter.phead != (PVOID)-1) {
Print("Nearest guy after %x is a %s object located at %x. (i=%x)\n",
dw, aszTypeNames[heAfter.bType], heAfter.phead, hAfter);
}
} else {
/*
* fixups are needed.
*/
FOREACHHANDLEENTRY(phe, he, i)
if ((DWORD)FIXKP(he.phead) <= dw &&
heBest.phead < he.phead &&
he.bType != TYPE_FREE) {
heBest = he;
hBest = i;
}
if ((DWORD)FIXKP(he.phead) > dw &&
heAfter.phead > he.phead &&
he.bType != TYPE_FREE) {
heAfter = he;
hAfter = i;
}
NEXTEACHHANDLEENTRY()
if (heBest.phead != NULL) {
Print("Nearest guy before %x is a %s object located at %x (i=%x).\n",
dw, aszTypeNames[heBest.bType], FIXKP(heBest.phead), hBest);
}
if (heAfter.phead != (PVOID)-1) {
Print("Nearest guy after %x is a %s object located at %x. (i=%x)\n",
dw, aszTypeNames[heAfter.bType], FIXKP(heAfter.phead), hAfter);
}
}
return(TRUE);
}
/************************************************************************\
* Procedure: Ifrr
*
* Description: Finds Range References - helpfull for finding stale
* pointers.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Ifrr(
DWORD opts,
PVOID param1,
PVOID param2,
PVOID param3,
PVOID param4)
{
DWORD pSrc1 = (DWORD)param1;
DWORD pSrc2 = (DWORD)param2;
DWORD pRef1 = (DWORD)param3;
DWORD pRef2 = (DWORD)param4;
DWORD dw;
DWORD buffer[PAGE_SIZE / sizeof(DWORD)];
if (pSrc2 < pSrc1) {
Print("Source range improper. Values reversed.\n");
dw = pSrc1;
pSrc1 = pSrc2;
pSrc2 = dw;
}
if (pRef2 == 0) {
pRef2 = pRef1;
}
if (pRef2 < pRef1) {
Print("Reference range improper. Values reversed.\n");
dw = pRef1;
pRef1 = pRef2;
pRef2 = dw;
}
pSrc1 &= 0xFFFFFFFFF - PAGE_SIZE + 1; // PAGE aligned
pSrc2 = (pSrc2 + 3) & 0xFFFFFFFC; // dword aligned
Print("Searching range (%08lx-%08lx) for references to (%08lx-%08lx)...",
pSrc1, pSrc2, pRef1, pRef2);
for (; pSrc1 < pSrc2; pSrc1 += PAGE_SIZE) {
BOOL fSuccess;
if (!(pSrc1 & 0xFFFFFF)) {
Print("\nSearching %x...", pSrc1);
}
fSuccess = tryMoveBlock(buffer, (PVOID)pSrc1, sizeof(buffer));
if (!fSuccess) {
/*
* Skip to next page
*/
} else {
for (dw = 0; dw < sizeof(buffer) / sizeof(DWORD); dw++) {
if (buffer[dw] >= pRef1 && buffer[dw] <= pRef2) {
Print("\n[%08lx] = %08lx ",
pSrc1 + dw * sizeof(DWORD),
buffer[dw]);
}
}
}
if (IsCtrlCHit()) {
Print("\nSearch aborted.\n");
return(TRUE);
}
}
Print("\nSearch complete.\n");
return(TRUE);
}
#ifdef KERNEL
/***************************************************************************\
* kbd [queue]
*
* Loads a DLL containing more debugging extensions
*
* 10/27/92 IanJa Created.
* 6/9/1995 SanfordS made to fit stdexts motif
\***************************************************************************/
typedef struct {
int iVK;
LPSTR pszVK;
} VK, *PVK;
VK aVK[] = {
{ VK_SHIFT, "SHIFT" },
{ VK_LSHIFT, "LSHIFT" },
{ VK_RSHIFT, "RSHIFT" },
{ VK_CONTROL, "CONTROL" },
{ VK_LCONTROL, "LCONTROL" },
{ VK_RCONTROL, "RCONTROL" },
{ VK_MENU, "MENU" },
{ VK_LMENU, "LMENU" },
{ VK_RMENU, "RMENU" },
{ VK_NUMLOCK, "NUMLOCK" },
{ VK_CAPITAL, "CAPITAL" },
{ VK_LBUTTON, "LBUTTON" },
{ VK_RBUTTON, "RBUTTON" },
{ VK_RETURN , "ENTER" },
{ 0, NULL }
};
BOOL Ikbd(
DWORD opts,
PVOID param1)
{
PQ pq;
Q q;
PBYTE pb;
BYTE gafAsyncKeyState[CBKEYSTATE];
PBYTE pgafAsyncKeyState;
BYTE gafPhysKeyState[CBKEYSTATE];
PBYTE pgafPhysKeyState;
int i;
BYTE afUpdateKeyState[CBKEYSTATE + CBKEYSTATERECENTDOWN];
if (opts & OFLAG(a)) {
#ifdef LATER
HANDLEENTRY he, *phe;
int i;
FOREACHHANDLEENTRY(phe, he, i)
if (he.bType == TYPE_INPUTQUEUE) {
Ikbd(0, FIXKP(he.phead));
Print("\n");
}
NEXTEACHHANDLEENTRY()
#endif
return(TRUE);
}
pgafAsyncKeyState = EvalExp(VAR(gafAsyncKeyState));
move(gafAsyncKeyState, pgafAsyncKeyState);
pgafPhysKeyState = EvalExp(VAR(gafPhysKeyState));
move(gafPhysKeyState, pgafPhysKeyState);
/*
* If 'u' was specified, make sure there was also an address
*/
if (opts & OFLAG(u)) {
if (param1 == NULL) {
Print("Must specify 2nd arg of ProcessUpdateKeyEvent() with 'u' option.\n");
return(FALSE);
}
pb = (PBYTE)param1;
move(afUpdateKeyState, pb);
pb = afUpdateKeyState;
Print("Key State: NEW STATE Asynchronous Physical\n");
} else {
if (param1) {
pq = (PQ)param1;
} else {
moveExpValue(&pq, VAR(gpqForeground));
}
/*
* Print out simple thread info for pq->ptiLock.
*/
move(q, pq);
if (q.ptiKeyboard) {
Idt(OFLAG(p), q.ptiKeyboard);
}
pb = (PBYTE)&(q.afKeyState);
Print("Key State: QUEUE %lx Asynchronous Physical\n", pq);
}
Print(" Down Toggle Down Toggle Down Toggle\n");
for (i = 0; aVK[i].pszVK != NULL; i++) {
Print("VK_%s:\t%d %d %d %d %d %d\n",
aVK[i].pszVK,
TestKeyDownBit(pb, aVK[i].iVK) != 0,
TestKeyToggleBit(pb, aVK[i].iVK) != 0,
TestAsyncKeyStateDown(aVK[i].iVK) != 0,
TestAsyncKeyStateToggle(aVK[i].iVK) != 0,
TestKeyDownBit(gafPhysKeyState, aVK[i].iVK) != 0,
TestKeyToggleBit(gafPhysKeyState, aVK[i].iVK) != 0);
}
if (opts & OFLAG(u)) {
/*
* Which keys are to be updated?
*/
pb = afUpdateKeyState + CBKEYSTATE;
Print("Keys to Update: ");
for (i = 0; aVK[i].pszVK != NULL; i++) {
if (TestKeyRecentDownBit(pb, aVK[i].iVK)) {
Print("VK_%s ", aVK[i].pszVK);
}
}
Print("\n");
}
return(TRUE);
}
#endif // KERNEL
/************************************************************************\
* Procedure: Itest
*
* Description: Tests the basic stdexts macros and functions - a good check
* on the debugger extensions in general before you waste time debuging
* entensions.
*
* Returns: fSuccess
*
* 6/9/1995 Created SanfordS
*
\************************************************************************/
BOOL Itest()
{
PVOID p;
DWORD cch;
CHAR ach[80];
Print("Print test!\n");
SAFEWHILE(TRUE) {
Print("SAFEWHILE test... Hit Ctrl-C NOW!\n");
}
p = EvalExp(VAR(gpsi));
Print("EvalExp(%s) = %x\n", VAR(gpsi), p);
GetSymbol(p, ach, &cch);
Print("GetSymbol(%x) = %s\n", p, ach);
if (IsWinDbg()) {
Print("I think windbg is calling me.\n");
} else {
Print("I don't think windbg is calling me.\n");
}
Print("MoveBlock test...\n");
moveBlock(&p, EvalExp(VAR(gpsi)), sizeof(PVOID));
Print("MoveBlock(%x) = %x.\n", EvalExp(VAR(gpsi)), p);
Print("moveExp test...\n");
moveExp(&p, VAR(gpsi));
Print("moveExp(%s) = %x.\n", VAR(gpsi), p);
Print("moveExpValue test...\n");
moveExpValue(&p, VAR(gpsi));
Print("moveExpValue(%s) = %x.\n", VAR(gpsi), p);
Print("Basic tests complete.\n");
return(TRUE);
}
/************************************************************************\
* Procedure: Iuver
*
* Description: Dumps versions of extensions and winsrv/win32k
*
* Returns: fSuccess
*
* 6/15/1995 Created SanfordS
*
\************************************************************************/
BOOL Iuver()
{
PSERVERINFO psi;
DWORD dwRipFlags;
#if DBG
Print("USEREXTS version: KERNEL Checked.\n"
"WINSRV version:");
#else
Print("USEREXTS version: KERNEL Free.\n"
"WINSRV version:");
#endif
moveExpValue(&psi, VAR(gpsi));
move(dwRipFlags, &psi->RipFlags);
switch (dwRipFlags & (RIPF_DAYTONA | RIPF_CAIRO | RIPF_KERNEL)) {
case RIPF_DAYTONA:
Print(" DAYTONA");
break;
case RIPF_CAIRO:
Print(" CAIRO");
break;
case RIPF_KERNEL:
Print(" KERNEL");
break;
default:
Print(" ???");
break;
}
switch (dwRipFlags & (RIPF_FREE | RIPF_CHECKED)) {
case RIPF_FREE:
Print(" Free");
break;
case RIPF_CHECKED:
Print(" Checked");
break;
default:
Print(" ???");
return(TRUE);
}
Print(".\n");
return(TRUE);
}