summaryrefslogtreecommitdiffstats
path: root/private/mvdm/vdmexts/wow.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/vdmexts/wow.c')
-rw-r--r--private/mvdm/vdmexts/wow.c1575
1 files changed, 1575 insertions, 0 deletions
diff --git a/private/mvdm/vdmexts/wow.c b/private/mvdm/vdmexts/wow.c
new file mode 100644
index 000000000..d799c5162
--- /dev/null
+++ b/private/mvdm/vdmexts/wow.c
@@ -0,0 +1,1575 @@
+/******************************Module*Header*******************************\
+* Module Name: debug.c
+*
+* This file is for debugging tools and extensions.
+*
+* Created: 24-Jan-1992
+* Author: John Colleran
+*
+* History:
+* Feb 17 92 Matt Felton (mattfe) lots of additional exentions for filtering
+* Jul 13 92 (v-cjones) Added API & MSG profiling debugger extensions, fixed
+* other extensions to handle segment motion correctly,
+* & cleaned up the file in general
+* Jan 3 96 Neil Sandlin (neilsa) integrated this routine into vdmexts
+*
+* Copyright (c) 1992 Microsoft Corporation
+\**************************************************************************/
+
+#include "precomp.h"
+#pragma hdrstop
+#include <ctype.h>
+#define DEBUG_OR_WOWPROFILE 1
+#include <wow32.h>
+#include <wmdisp32.h>
+#include <wcuricon.h>
+#include <wucomm.h>
+#include <doswow.h>
+
+
+#define MALLOC(cb) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, cb)
+#define FREE(addr) HeapFree(GetProcessHeap(), 0, addr)
+
+
+//
+// Local function prototypes
+//
+
+INT WDahtoi(LPSZ lpsz);
+
+
+INT WDParseArgStr(LPSZ lpszArgStr, CHAR **argv, INT iMax) {
+/*
+ * Parse a string looking for SPACE, TAB, & COMMA as delimiters
+ * INPUT:
+ * lpszArgStr - ptr to input arg string
+ * iMax - maximum number of substrings to parse
+ * OUTPUT:
+ * argv - ptrs to strings
+ *
+ * RETURN: # of vectors in argv
+ * NOTE: substrings are converted to uppercase
+ */
+ INT nArgs;
+ BOOL bStrStart;
+
+ nArgs = 0;
+ bStrStart = 1;
+ while( *lpszArgStr ) {
+ if( (*lpszArgStr == ' ') || (*lpszArgStr == '\t') || (*lpszArgStr == ',') ) {
+ *lpszArgStr = '\0';
+ bStrStart = 1;
+ }
+ else {
+ if( bStrStart ) {
+ if( nArgs >= iMax ) {
+ break;
+ }
+ argv[nArgs++] = lpszArgStr;
+ bStrStart = 0;
+ }
+ *lpszArgStr = toupper(*lpszArgStr);
+ }
+ lpszArgStr++;
+ }
+ return(nArgs);
+}
+
+
+
+
+VOID
+dwp(
+ CMD_ARGLIST
+ )
+{
+ PWOWPORT pwp;
+ WOWPORT wp;
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+
+ while (' ' == lpArgumentString[0]) {
+ lpArgumentString++;
+ }
+
+ pwp = (PWOWPORT) WDahtoi(lpArgumentString);
+
+ PRINTF("Dump of WOWPORT structure at 0x%x:\n\n", (unsigned)pwp);
+
+
+ try {
+
+ READMEM_XRET(wp, pwp);
+
+ } except (EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()
+ ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
+
+ PRINTF("Access violation reading WOWPORT structure!\n\n");
+ return;
+ }
+
+ PRINTF("idComDev 0x%x\n", (unsigned)wp.idComDev);
+ PRINTF("h32 0x%x\n", (unsigned)wp.h32);
+ PRINTF("hREvent 0x%x\n", (unsigned)wp.hREvent);
+ PRINTF("csWrite OwningThread 0x%x RecursionCount 0x%x\n",
+ (unsigned)wp.csWrite.OwningThread, (unsigned)wp.csWrite.RecursionCount);
+ PRINTF("pchWriteBuf 0x%x\n", (unsigned)wp.pchWriteBuf);
+ PRINTF("cbWriteBuf 0x%x\n", (unsigned)wp.cbWriteBuf);
+ PRINTF("pchWriteHead 0x%x\n", (unsigned)wp.pchWriteHead);
+ PRINTF("pchWriteTail 0x%x\n", (unsigned)wp.pchWriteTail);
+ PRINTF("cbWriteFree 0x%x\n", (unsigned)wp.cbWriteFree);
+ PRINTF("hWriteThread 0x%x\n", (unsigned)wp.hWriteThread);
+ PRINTF("hWriteEvent 0x%x\n", (unsigned)wp.hWriteEvent);
+ PRINTF("dwThreadID 0x%x\n", (unsigned)wp.dwThreadID);
+ PRINTF("dwErrCode 0x%x\n", (unsigned)wp.dwErrCode);
+ PRINTF("COMSTAT addr: 0x%x\n", (unsigned)(((char *)&wp.cs - (char *)&wp) + (char *)pwp));
+ PRINTF("fChEvt 0x%x\n", (unsigned)wp.fChEvt);
+ PRINTF("pdcb16 0x%x\n", (unsigned)wp.pdcb16);
+ PRINTF("fUnGet %s\n", wp.fUnGet ? "TRUE" : "FALSE");
+ PRINTF("cUnGet 0x%x (%c)\n", (unsigned)wp.cUnGet, wp.cUnGet);
+ PRINTF("hMiThread 0x%x\n", (unsigned)wp.hMiThread);
+ PRINTF("fClose %s\n", wp.fClose ? "TRUE" : "FALSE");
+ PRINTF("dwComDEB16 0x%x\n", (unsigned)wp.dwComDEB16);
+ PRINTF("lpComDEB16 0x%x\n", (unsigned)wp.lpComDEB16);
+
+ PRINTF("\n");
+
+ return;
+}
+
+
+//
+// Dump Taskinfo;
+//
+// If no argument, dump all wow tasks.
+// If 0, dump current WOW task
+// Else dump the specifies task {which is thread-id as shown by
+// ~ command under ntsd like 37.6b so thread-id is 6b)
+//
+
+void DumpTaskInfo (ptd,mode)
+PTD ptd;
+int mode;
+{
+
+ ULONG Base;
+ TDB tdb;
+ BOOL b;
+ char ModName[9];
+ int i;
+ BOOL fTDBValid = TRUE;
+
+ Base = GetInfoFromSelector( ptd->htask16, mode, NULL );
+ b = READMEM( (LPVOID) (Base+GetIntelBase()), &tdb, sizeof(tdb));
+
+ if ( !b ) {
+ fTDBValid = FALSE;
+ }
+
+ for (b=FALSE, i=0; i<8; i++) {
+ if (!fTDBValid || !tdb.TDB_ModName[i]) {
+ b = TRUE;
+ }
+ if (b) {
+ ModName[i] = ' ';
+ } else {
+ ModName[i] = tdb.TDB_ModName[i];
+ }
+ }
+ ModName[i] = 0;
+
+ PRINTF("%.4x",ptd->dwThreadID);
+ PRINTF(" %.4x:%.4x",HIWORD(ptd->vpStack),LOWORD(ptd->vpStack));
+ PRINTF(" %.4x", ptd->htask16);
+ PRINTF(" %.4x", ptd->hInst16);
+ PRINTF(" %.4x", ptd->hMod16);
+ PRINTF(" %8s",ModName);
+ PRINTF(" %.8x",ptd->dwWOWCompatFlags);
+ PRINTF(" %.8x",ptd->hThread);
+ if (fTDBValid) {
+ PRINTF(" %.8x",tdb.TDB_flags);
+ PRINTF(" %.3x",tdb.TDB_ExpWinVer);
+ PRINTF(" %.4x:%.4x\n",HIWORD(tdb.TDB_DTA),LOWORD(tdb.TDB_DTA));
+ } else {
+ PRINTF(" Failure reading TDB at %X\n", Base );
+ }
+}
+
+
+void
+DumpTask(
+ void
+ )
+{
+ VDMCONTEXT ThreadContext;
+ DWORD ThreadId;
+ PTD ptd,ptdHead;
+ TD td;
+ int mode;
+ BOOL b,fFound=FALSE;
+
+
+ mode = GetContext( &ThreadContext );
+
+ ThreadId = (DWORD)-1; // Assume Dump All Tasks
+ if (GetNextToken()) {
+ ThreadId = (DWORD) EXPRESSION( lpArgumentString );
+ }
+
+ ptdHead = (PTD)EXPRESSION("wow32!gptdTaskHead");
+
+ // get the pointer to first TD
+ b = READMEM((LPVOID) (ptdHead), &ptd, sizeof(DWORD));
+
+ if ( !b ) {
+ PRINTF("Failure reading gptdTaskHead at %08lX\n", ptdHead );
+ return;
+ }
+
+ PRINTF("Thrd Stack task inst hmod Module Compat hThread Tdbflags Ver Dta\n");
+
+
+ // enumerate td list to find the match(es)
+ while (ptd) {
+ b = READMEM((LPVOID) (ptd), &td, sizeof(TD));
+ if ( !b ) {
+ PRINTF("Failure reading TD At %08lX\n", ptd );
+ return;
+ }
+
+ if (ThreadId == -1) {
+ DumpTaskInfo (&td,mode);
+ fFound = TRUE;
+ }
+ else {
+ if (ThreadId == td.dwThreadID) {
+ DumpTaskInfo (&td,mode);
+ fFound = TRUE;
+ break;
+ }
+ }
+ ptd = td.ptdNext;
+ }
+
+ if (!fFound) {
+ if (ThreadId == -1) {
+ PRINTF("No WOW Task Found.\n");
+ }
+ else
+ PRINTF("WOW Task With Thread Id = %02x Not Found.\n",ThreadId);
+ }
+ return;
+}
+
+
+
+VOID DumpTaskVerbose( ) // dump WOW32 task database entry
+{
+
+ TD td;
+ PTD ptd;
+ PWOAINST pWOA, pWOALast;
+ PTDB ptdb;
+ BOOL fAll = FALSE;
+ BYTE SavedByte;
+
+ ptd = (PTD) WDahtoi(lpArgumentString);
+
+
+ if (!ptd) {
+
+ fAll = TRUE;
+ GETEXPRVALUE(ptd, "wow32!gptdTaskHead", PTD);
+ if (!ptd) {
+ Print("Could not get wow32!gptdTaskHead");
+ return;
+ }
+ Print("Dump WOW task list\n\n");
+
+ } else if ((ULONG)ptd < 65536) {
+ ULONG dwId = (ULONG) ptd;
+
+ // Here, I'm making the assumption that if the argument is a value
+ // that is less than 64k, then it can't be a TD address.
+ // So, try it out as a thread id
+
+ GETEXPRVALUE(ptd, "wow32!gptdTaskHead", PTD);
+ if (!ptd) {
+ Print("Could not get wow32!gptdTaskHead");
+ return;
+ }
+
+ while(ptd) {
+ READMEM_XRET(td, ptd);
+ if (td.dwThreadID == dwId) {
+ break;
+ }
+
+ ptd = td.ptdNext;
+ }
+ if (!ptd) {
+ Print("Could not find tread id %s\n", lpArgumentString);
+ return;
+ }
+ }
+
+ do {
+
+ Print("Dump of TD at 0x%08x:\n\n", (unsigned)ptd);
+
+
+ READMEM_XRET(td, ptd);
+
+ Print("vpStack %04x:%04x\n", HIWORD(td.vpStack), LOWORD(td.vpStack));
+ Print("vpCBStack %04x:%04x\n", HIWORD(td.vpCBStack), LOWORD(td.vpCBStack));
+ Print("ptdNext 0x%08x\n", td.ptdNext);
+ Print("dwFlags 0x%08x\n", td.dwFlags);
+
+ //
+ // Dump symbolic names for TDF_ manifests
+ //
+
+ if (td.dwFlags & TDF_INITCALLBACKSTACK) {
+ Print(" TDF_INITCALLBACKSTACK\n");
+ }
+ if (td.dwFlags & TDF_IGNOREINPUT) {
+ Print(" TDF_IGNOREINPUT\n");
+ }
+ if (td.dwFlags & TDF_FORCETASKEXIT) {
+ Print(" TDF_FORCETASKEXIT\n");
+ }
+ if (td.dwFlags & TDF_TASKCLEANUPDONE) {
+ Print(" TDF_TASKCLEANUPDONE\n");
+ }
+
+ Print("VDMInfoiTaskID 0x%08x\n", td.VDMInfoiTaskID);
+ Print("CommDlgTd (ptr) 0x%08x\n", td.CommDlgTd);
+
+ //
+ // Dump CommDlgTd structure if present
+ //
+
+ if (td.CommDlgTd) {
+
+ COMMDLGTD CommDlgTd;
+ BOOL fCopySuccessful = TRUE;
+
+ READMEM_XRET(CommDlgTd, td.CommDlgTd);
+
+ if (fCopySuccessful) {
+
+ Print("\n");
+ Print(" Dump of CommDlgTd at 0x%08x:\n", td.CommDlgTd);
+ Print(" hdlg 0x04x\n", CommDlgTd.hdlg);
+ Print(" vpfnHook 0x04x:0x04x\n", HIWORD(CommDlgTd.vpfnHook), LOWORD(CommDlgTd.vpfnHook));
+ Print(" vpData 0x04x:0x04x\n", HIWORD(CommDlgTd.vpData), LOWORD(CommDlgTd.vpData));
+ Print(" ExtendedErr 0x08x\n", CommDlgTd.ExtendedErr);
+ Print(" vpfnSetupHook (union) 0x04x:0x04x\n", HIWORD(CommDlgTd.vpfnSetupHook), LOWORD(CommDlgTd.vpfnSetupHook));
+ Print(" pRes (union) 0x08x\n", CommDlgTd.pRes);
+ Print(" SetupHwnd 0x04x\n", CommDlgTd.SetupHwnd);
+ Print(" Previous 0x08x\n", CommDlgTd.Previous);
+ Print(" pData32 0x08x\n", CommDlgTd.pData32);
+ Print(" Flags 0x08x\n", CommDlgTd.Flags);
+
+ //
+ // Dump symbolic names for WOWCD_ manifests
+ //
+
+ if (CommDlgTd.Flags & WOWCD_ISCHOOSEFONT) {
+ Print(" WOWCD_ISCHOOSEFONT\n");
+ }
+ if (CommDlgTd.Flags & WOWCD_ISOPENFILE) {
+ Print(" WOWCD_ISOPENFILE\n");
+ }
+
+ Print("\n");
+
+ }
+ }
+
+
+ Print("dwWOWCompatFlags 0x%08x\n", td.dwWOWCompatFlags);
+
+ //
+ // Dump symbolic names for WOWCF_ manifests
+ //
+
+ if (td.dwWOWCompatFlags & WOWCF_GWLCLRTOPMOST) {
+ Print(" WOWCF_GWLCLRTOPMOST\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_UNIQUEHDCHWND) {
+ Print(" WOWCF_UNIQUEHDCHWND\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_WMMDIACTIVATEBUG) {
+ Print(" WOWCF_WMMDIACTIVATEBUG\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NOCBDIRTHUNK) {
+ Print(" WOWCF_NOCBDIRTHUNK\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_DBASEHANDLEBUG) {
+ Print(" WOWCF_DBASEHANDLEBUG\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_GETDUMMYDC) {
+ Print(" WOWCF_GETDUMMYDC\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_UNLOADNETFONTS) {
+ Print(" WOWCF_UNLOADNETFONTS\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_ADD_MSTT) {
+ Print(" WOWCF_ADD_MSTT\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NOFIRSTSAVE) {
+ Print(" WOWCF_NOFIRSTSAVE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NOPC_RECTANGLE) {
+ Print(" WOWCF_NOPC_RECTANGLE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NEEDIGNORESTARTPAGE) {
+ Print(" WOWCF_NEEDIGNORESTARTPAGE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NEEDSTARTPAGE) {
+ Print(" WOWCF_NEEDSTARTPAGE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_GWLINDEX2TO4) {
+ Print(" WOWCF_GWLINDEX2TO4\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_SETNULLMESSAGE) {
+ Print(" WOWCF_SETNULLMESSAGE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_FORCENOPOSTSCRIPT) {
+ Print(" WOWCF_FORCENOPOSTSCRIPT\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_LB_NONNULLLPARAM) {
+ Print(" WOWCF_LB_NONNULLLPARAM\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_FORCETWIPSESCAPE) {
+ Print(" WOWCF_FORCETWIPSESCAPE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_DONTRELEASECACHEDDC) {
+ Print(" WOWCF_DONTRELEASECACHEDDC\n");
+ }
+ // This one is up for grabs
+ // if (td.dwWOWCompatFlags & WOWCF_ACTION_SAVEPTR) {
+ // Print(" WOWCF_ACTION_SAVEPTR\n");
+ // }
+ if (td.dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
+ Print(" WOWCF_DSBASEDSTRINGPOINTERS\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NOWAITFORINPUTIDLE) {
+ Print(" WOWCF_NOWAITFORINPUTIDLE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_SIMPLEREGION) {
+ Print(" WOWCF_SIMPLEREGION\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_SANITIZEDOTWRSFILES) {
+ Print(" WOWCF_SANITIZEDOTWRSFILES\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_HIRES) {
+ Print(" WOWCF_HIRES\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_MGX_ESCAPES) {
+ Print(" WOWCF_MGX_ESCAPES\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_4PLANECONVERSION) {
+ Print(" WOWCF_4PLANECONVERSION\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_RESETPAPER29ANDABOVE) {
+ Print(" WOWCF_RESETPAPER29ANDABOVE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_NOTDOSSPAWNABLE) {
+ Print(" WOWCF_NOTDOSSPAWNABLE\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_SYNCHRONOUSDOSAPP) {
+ Print(" WOWCF_SYNCHRONOUSDOSAPP\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_EDITCTRLWNDWORDS) {
+ Print(" WOWCF_EDITCTRLWNDWORDS\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_FAKEJOURNALRECORDHOOK) {
+ Print(" WOWCF_FAKEJOURNALRECORDHOOK\n");
+ }
+ if (td.dwWOWCompatFlags & WOWCF_GRAINYTICS) {
+ Print(" WOWCF_GRAINYTICS\n");
+ }
+
+
+ Print("dwWOWCompatFlagsEx 0x%08x\n", td.dwWOWCompatFlagsEx);
+
+ //
+ // Dump symbolic names for WOWCFEX_ manifests
+ //
+
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_FORMFEEDHACK) {
+ Print(" WOWCFEX_FORMFEEDHACK\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_DEFWNDPROCNCCALCSIZE) {
+ Print(" WOWCFEX_DEFWNDPROCNCCALCSIZE\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_PIXELMETRICS) {
+ Print(" WOWCFEX_PIXELMETRICS\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_NODIBSHERE) {
+ Print(" WOWCFEX_NODIBSHERE\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_SETCAPSTACK) {
+ Print(" WOWCFEX_SETCAPSTACK\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_FORCEINCDPMI) {
+ Print(" WOWCFEX_FORCEINCDPMI\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_LONGWINEXECTAIL) {
+ Print(" WOWCFEX_LONGWINEXECTAIL\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_RESTOREEXPLORER) {
+ Print(" WOWCFEX_RESTOREEXPLORER\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_FIXDCFONT4MENUSIZE) {
+ Print(" WOWCFEX_FIXDCFONT4MENUSIZE\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_GETVERSIONHACK) {
+ Print(" WOWCFEX_GETVERSIONHACK\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_BOGUSPOINTER) {
+ Print(" WOWCFEX_BOGUSPOINTER\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_SENDPOSTEDMSG) {
+ Print(" WOWCFEX_SENDPOSTEDMSG\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_GLOBALDELETEATOM) {
+ Print(" WOWCFEX_GLOBALDELETEATOM\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_IGNORECLIENTSHUTDOWN) {
+ Print(" WOWCFEX_IGNORECLIENTSHUTDOWN\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_ZAPGPPSDEFBLANKS) {
+ Print(" WOWCFEX_ZAPGPPSDEFBLANKS\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_FAKECLASSINFOFAIL) {
+ Print(" WOWCFEX_FAKECLASSINFOFAIL\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_SAMETASKFILESHARE) {
+ Print(" WOWCFEX_SAMETASKFILESHARE\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_SAYITSNOTTHERE) {
+ Print(" WOWCFEX_SAYITSNOTTHERE\n");
+ }
+ if (td.dwWOWCompatFlagsEx & WOWCFEX_BROKENFLATPOINTER) {
+ Print(" WOWCFEX_BROKENFLATPOINTER\n");
+ }
+
+ Print("dwThreadID 0x%08x\n", td.dwThreadID);
+ Print("hThread 0x%08x\n", td.hThread);
+ Print("hIdleHook 0x%08x\n", td.hIdleHook);
+ Print("hrgnClip 0x%08x\n", td.hrgnClip);
+ Print("ulLastDesktophDC 0x%08x\n", td.ulLastDesktophDC);
+ Print("pWOAList 0x%08x\n", td.pWOAList);
+
+ //
+ // Dump WOATD structure if present
+ //
+
+ pWOALast = NULL;
+ pWOA = td.pWOAList;
+
+ while (pWOA && pWOA != pWOALast) {
+
+ union {
+ WOAINST WOA;
+ char buf[128+2+16];
+ } u;
+
+ READMEM_XRET(u.buf, pWOA);
+
+ Print("\n");
+ Print(" Dump of WOAINST at 0x%08x:\n", pWOA);
+ Print(" pNext 0x%08x\n", u.WOA.pNext);
+ Print(" ptdWOA 0x%08x\n", u.WOA.ptdWOA);
+ Print(" dwChildProcessID 0x%08x\n", u.WOA.dwChildProcessID);
+ Print(" hChildProcess 0x%08x\n", u.WOA.hChildProcess);
+ Print(" szModuleName %s\n", u.WOA.szModuleName);
+ Print("\n");
+
+ pWOALast = pWOA;
+ pWOA = u.WOA.pNext;
+
+ }
+
+ Print("htask16 0x%04x\n", td.htask16, td.htask16);
+
+ //
+ // Dump the most interesting TDB fields
+ //
+
+ if (ptdb = (PTDB) (GetInfoFromSelector(td.htask16, PROT_MODE, NULL) + GetIntelBase())) {
+
+ TDB tdb;
+
+ READMEM_XRET(tdb, ptdb);
+
+ Print("\n");
+ Print(" Highlights of TDB at 0x%08x:\n", ptdb);
+
+ if (tdb.TDB_sig != TDB_SIGNATURE) {
+ Print(" TDB_sig signature is 0x%04x instead of 0x%04x, halting dump.\n",
+ tdb.TDB_sig, TDB_SIGNATURE);
+ } else {
+
+ PDOSPDB pPDB;
+ DOSPDB PDB;
+ PBYTE pJFT;
+ BYTE JFT[256];
+ WORD cbJFT;
+ PDOSSF pSFTHead, pSFTHeadCopy;
+ DOSSF SFTHead;
+ PDOSSFT pSFT;
+ WORD fh;
+ WORD SFN;
+ WORD i;
+ DWORD cb;
+ PDOSWOWDATA pDosWowData;
+ DOSWOWDATA DosWowData;
+
+ SavedByte = tdb.TDB_ModName[8];
+ tdb.TDB_ModName[8] = 0;
+ Print(" Module name \"%s\"\n", tdb.TDB_ModName);
+ tdb.TDB_ModName[8] = SavedByte;
+
+ Print(" ExpWinVer 0x%04x\n", tdb.TDB_ExpWinVer);
+ Print(" Directory \"%s\"\n", tdb.TDB_LFNDirectory);
+ Print(" PDB (aka PSP) 0x%04x\n", tdb.TDB_PDB);
+
+ //
+ // Dump open file handle info
+ //
+
+ pPDB = (PDOSPDB) (GetInfoFromSelector(tdb.TDB_PDB, PROT_MODE, NULL) + GetIntelBase());
+ READMEM_XRET(PDB, pPDB);
+
+ pJFT = (PBYTE) (GetIntelBase() +
+ (HIWORD(PDB.PDB_JFN_Pointer)<<4) +
+ LOWORD(PDB.PDB_JFN_Pointer));
+
+
+ cbJFT = PDB.PDB_JFN_Length;
+
+ Print(" JFT %04x:%04x (%08x), size 0x%x\n",
+ HIWORD(PDB.PDB_JFN_Pointer),
+ LOWORD(PDB.PDB_JFN_Pointer),
+ pJFT,
+ cbJFT);
+
+ try {
+ READMEM(pJFT, JFT, cbJFT);
+ } except (1) {
+ Print("Unable to read JFT from 0x%08x!\n", pJFT);
+ return;
+ }
+
+ for (fh = 0; fh < cbJFT; fh++) {
+
+ if (JFT[fh] != 0xFF) {
+
+ //
+ // Walk the SFT chain to find Nth entry
+ // where N == JFT[fh]
+ //
+
+ SFN = 0;
+ i = 0;
+
+ GETEXPRVALUE(pSFTHead, "ntvdm!pSFTHead", PDOSSF);
+
+ GETEXPRADDR(pDosWowData, "wow32!DosWowData");
+ READMEM_XRET(DosWowData, pDosWowData);
+
+ if ((DWORD)pSFTHead != DosWowData.lpSftAddr) {
+ Print("ntvdm!pSFTHead is 0x%08x, DosWowData.lpSftAddr ix 0x%08x.\n",
+ pSFTHead, DosWowData.lpSftAddr);
+ }
+
+ try {
+ READMEM(pSFTHead, &SFTHead, sizeof(SFTHead));
+ } except (1) {
+ Print("Unable to read SFTHead from 0x%08x!\n", pSFTHead);
+ return;
+ }
+
+ cb = sizeof(DOSSF) + SFTHead.SFCount * sizeof(DOSSFT);
+ pSFTHeadCopy = MALLOC(cb);
+
+ //Print("First DOSSF at 0x%08x, SFCount 0x%x, SFLink 0x%08x.\n",
+ // pSFTHead, SFTHead.SFCount, SFTHead.SFLink);
+
+ try {
+ READMEM(pSFTHead, pSFTHeadCopy, cb);
+ } except (1) {
+ Print("Unable to read SFTHead from 0x%08x!\n", pSFTHead);
+ return;
+ }
+
+ pSFT = (PDOSSFT) &(pSFTHeadCopy->SFTable);
+
+ while (SFN < JFT[fh]) {
+ SFN++;
+ i++;
+ pSFT++;
+ if (i >= pSFTHeadCopy->SFCount) {
+
+ if (LOWORD(pSFTHeadCopy->SFLink) == 0xFFFF) {
+ SFN = JFT[fh] - 1;
+ break;
+ }
+
+ pSFTHead = (PDOSSF) (GetIntelBase() +
+ HIWORD(pSFTHeadCopy->SFLink)<<4 +
+ LOWORD(pSFTHeadCopy->SFLink));
+
+ i = 0;
+
+ try {
+ READMEM(pSFTHead, &SFTHead, sizeof(SFTHead));
+ } except (1) {
+ Print("Unable to read SFTHead from 0x%08x!\n", pSFTHead);
+ return;
+ }
+
+ cb = sizeof(DOSSF) + SFTHead.SFCount * sizeof(DOSSFT);
+ FREE(pSFTHeadCopy);
+ pSFTHeadCopy = MALLOC(cb);
+
+ //Print("Next DOSSF at 0x%08x, SFCount 0x%x, SFLink 0x%08x.\n",
+ // pSFTHead, SFTHead.SFCount, SFTHead.SFLink);
+
+ try {
+ READMEM(pSFTHead, pSFTHeadCopy, cb);
+ } except (1) {
+ Print("Unable to read SFTHead from 0x%08x!\n", pSFTHead);
+ return;
+ }
+
+ pSFT = (PDOSSFT) &(pSFTHeadCopy->SFTable);
+ }
+ }
+
+ if (SFN != JFT[fh]) {
+ Print(" Unable to local SFT entry 0x%x for handle 0x%x.\n",
+ pJFT[fh], fh);
+ } else {
+ Print(" Handle 0x%02x SFN 0x%02x Refs 0x%x Mode 0x%04x Attr 0x%04x NT Handle 0x%08x\n",
+ fh, SFN, pSFT->SFT_Ref_Count, pSFT->SFT_Mode, pSFT->SFT_Attr, pSFT->SFT_NTHandle);
+ }
+
+ FREE(pSFTHeadCopy);
+ }
+ }
+
+ Print("\n");
+ }
+
+ }
+
+ Print("hInst16 0x%04x\n", td.hInst16);
+ Print("hMod16 0x%04x\n", td.hMod16);
+
+ Print("\n");
+
+ ptd = td.ptdNext;
+
+ } while (fAll && ptd);
+
+ return;
+}
+
+
+void
+dt(
+ CMD_ARGLIST
+ )
+{
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ if (!GetNextToken()) {
+ DumpTask();
+ } else {
+ if ((lpArgumentString[0] == '-') &&
+ (tolower(lpArgumentString[1]) == 'v')) {
+ SkipToNextWhiteSpace();
+ GetNextToken();
+ DumpTaskVerbose();
+ } else {
+ DumpTaskVerbose();
+ }
+ }
+
+}
+
+
+
+VOID
+ddte(
+ CMD_ARGLIST
+ )
+// dump dispatch table entry
+{
+ W32 dte;
+ PW32 pdte;
+ char szW32[32];
+ char szSymbol[256];
+ DWORD dwOffset;
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ while (' ' == lpArgumentString[0]) {
+ lpArgumentString++;
+ }
+
+ pdte = (PW32) WDahtoi(lpArgumentString);
+
+
+ if (pdte) {
+
+ PRINTF("Dump of dispatch table entry at 0x%08x:\n\n", (unsigned)pdte);
+
+ } else {
+
+ GETEXPRADDR(pdte, "wow32!aw32WOW");
+ PRINTF("Dump of first dispatch table entry at 0x%08x:\n\n", (unsigned)pdte);
+
+ }
+
+ try {
+
+ READMEM_XRET(dte, pdte);
+
+ if (dte.lpszW32) {
+ READMEM_XRET(szW32, dte.lpszW32);
+ dte.lpszW32 = szW32;
+ szW32[sizeof(szW32)-1] = '\0';
+ }
+
+ } except (1) {
+
+ PRINTF("Exception 0x%08x reading dispatch table entry at 0x%08x!\n\n",
+ GetExceptionCode(), pdte);
+ return;
+ }
+
+ PRINTF("Dispatches to address 0x%08x, ", (unsigned)dte.lpfnW32);
+ PRINTF("supposedly function '%s'.\n", dte.lpszW32);
+
+ szSymbol[0] = '\0';
+ GetSymbol((LPVOID)dte.lpfnW32, szSymbol, &dwOffset);
+
+ PRINTF("Debugger finds symbol '%s' for that address.\n", szSymbol);
+ PRINTF("\n");
+
+ return;
+}
+
+
+
+PSTR aszWOWCLASS[] =
+{
+ "UNKNOWN",
+ "WIN16",
+ "BUTTON",
+ "COMBOBOX",
+ "EDIT",
+ "LISTBOX",
+ "MDICLIENT",
+ "SCROLLBAR",
+ "STATIC",
+ "DESKTOP",
+ "DIALOG",
+ "MENU",
+ "ACCEL",
+ "CURSOR",
+ "ICON",
+ "DC",
+ "FONT",
+ "METAFILE",
+ "RGN",
+ "BITMAP",
+ "BRUSH",
+ "PALETTE",
+ "PEN",
+ "OBJECT"
+};
+
+
+INT WDahtoi(LPSZ lpsz)
+{
+ char c;
+ int tot, pow, len, dig, i;
+
+
+ len = strlen(lpsz) - 1;
+ tot = 0;
+ pow = 1;
+
+ for(i = len; i >= 0; i--) {
+
+ c = toupper(lpsz[i]);
+
+ if(c == '0') dig = 0;
+ else if(c == '1') dig = 1;
+ else if(c == '2') dig = 2;
+ else if(c == '3') dig = 3;
+ else if(c == '4') dig = 4;
+ else if(c == '5') dig = 5;
+ else if(c == '6') dig = 6;
+ else if(c == '7') dig = 7;
+ else if(c == '8') dig = 8;
+ else if(c == '9') dig = 9;
+ else if(c == 'A') dig = 10;
+ else if(c == 'B') dig = 11;
+ else if(c == 'C') dig = 12;
+ else if(c == 'D') dig = 13;
+ else if(c == 'E') dig = 14;
+ else if(c == 'F') dig = 15;
+ else return(-1);
+
+ if(pow > 1) {
+ tot += pow * dig;
+ }
+ else {
+ tot = dig;
+ }
+ pow *= 16;
+ }
+ return(tot);
+}
+
+
+
+
+void
+at(
+ CMD_ARGLIST
+ )
+{
+ UINT i;
+ ATOM atom;
+ CHAR pszGAtomName[128];
+ CHAR pszLAtomName[128];
+ CHAR pszCAtomName[128];
+ CHAR *argv[2], *psz;
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ if(WDParseArgStr(lpArgumentString, argv, 1) == 1) {
+
+ atom = (ATOM)LOWORD(WDahtoi(argv[0]));
+
+ pszGAtomName[0] = 'G'; // put a random value in 1st byte so we can
+ pszLAtomName[0] = 'L'; // tell if it got replaced with a '\0' for
+ pszCAtomName[0] = 'C'; // an "undetermined" type
+
+ psz = NULL;
+ PRINTF("\n%s: ", argv[0]);
+ if(GlobalGetAtomName(atom, pszGAtomName, 128) > 0) {
+ PRINTF("<Global atom> \"%s\" ", pszGAtomName);
+ psz = pszGAtomName;
+ }
+ else if(GetAtomName(atom, pszLAtomName, 128) > 0) {
+ PRINTF("<Local atom> \"%s\" ", pszLAtomName);
+ psz = pszLAtomName;
+ }
+ else if(GetClipboardFormatName((UINT)atom, pszCAtomName, 128) > 0) {
+ PRINTF("<Clipboard format> \"%s\" ", pszCAtomName);
+ psz = pszCAtomName;
+ }
+ if(psz) {
+ i = 0;
+ while(psz[i] && i < 128) {
+ PRINTF(" %2X", psz[i++] & 0x000000FF);
+ }
+ }
+ else {
+ PRINTF("<Undetermined type>\n");
+ PRINTF(" GlobalGetAtomName string: \"%c\" ", pszGAtomName[0]);
+ for(i = 0; i < 8; i++) {
+ PRINTF(" %2X", pszGAtomName[i] & 0x000000FF);
+ }
+ PRINTF("\n GetAtomName string: \"%c\" ", pszLAtomName[0]);
+ for(i = 0; i < 8; i++) {
+ PRINTF(" %2X", pszLAtomName[i] & 0x000000FF);
+ }
+ PRINTF("\n GetClipboardFormatName string: \"%c\" ", pszCAtomName[0]);
+ for(i = 0; i < 8; i++) {
+ PRINTF(" %2X", pszCAtomName[i] & 0x000000FF);
+ }
+ }
+ PRINTF("\n\n");
+ }
+ else {
+ PRINTF("Usage: at hex_atom_number\n");
+ }
+}
+
+
+
+
+void
+ww(
+ CMD_ARGLIST
+ )
+{
+ PWW pww;
+ INT h16;
+ CHAR *argv[2];
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ if(WDParseArgStr(lpArgumentString, argv, 1)) {
+
+ if((h16 = WDahtoi(argv[0])) >= 0) {
+
+ try {
+
+ pww = (PWW)GetWindowLong((HWND)HWND32((HAND16)h16),GWL_WOWWORDS);
+
+ PRINTF("16:16 WndProc : %08lX\n", pww->vpfnWndProc);
+ PRINTF("16:16 DlgProc : %08lX\n", pww->vpfnDlgProc);
+ PRINTF("iClass : %#lx (%s) \n", pww->iClass, aszWOWCLASS[pww->iClass]);
+ PRINTF("dwStyle : %08lX\n", pww->dwStyle);
+ PRINTF("hInstance : %08lX\n", pww->hInstance);
+ PRINTF("16 bit handle : %#x\n", h16);
+
+ }
+ except (EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()) {
+
+ PRINTF("!wow32.ww: Invalid HWND16 %04x\n", h16);
+
+ }
+ }
+ else {
+ PRINTF("Usage: ww hwnd16\n");
+ }
+ }
+ else {
+ PRINTF("Usage: ww hwnd16\n");
+ }
+}
+
+
+
+void
+wc(
+ CMD_ARGLIST
+ )
+{
+ PWC pwc;
+
+ INT h16;
+ CHAR *argv[2];
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ if(WDParseArgStr(lpArgumentString, argv, 1)) {
+
+ if((h16 = WDahtoi(argv[0])) >= 0){
+
+ try {
+
+ pwc = (PWC)GetClassLong((HWND)HWND32((HAND16)h16),GCL_WOWWORDS);
+
+ PRINTF("16:16 WndProc : %08lX\n", pwc->vpfnWndProc);
+ PRINTF("VPSZ : %08lX\n", pwc->vpszMenu);
+ PRINTF("PWC : %08lX\n\n", pwc);
+
+ }
+ except (EXCEPTION_ACCESS_VIOLATION == GetExceptionCode()) {
+
+ PRINTF("!wow32.wc: Invalid HWND16 %04x\n", h16);
+
+ }
+ }
+ else {
+ PRINTF("Usage: wc hwnd16\n");
+ }
+ }
+ else {
+ PRINTF("Usage: wc hwnd16\n");
+ }
+}
+
+
+
+
+
+
+//
+// Dump Last Logged APIs
+//
+void
+lastlog(
+ CMD_ARGLIST
+ )
+{
+ INT iCircBuffer;
+ CHAR achTmp[TMP_LINE_LEN], *pachTmp;
+ INT i;
+
+ CMD_INIT();
+ ASSERT_CHECKED_WOW_PRESENT;
+
+ GETEXPRVALUE(iCircBuffer, "wow32!iCircBuffer", INT);
+ GETEXPRVALUE(pachTmp, "wow32!pachTmp", PCHAR);
+
+ for (i = iCircBuffer; i >= 0; i--) {
+ READMEM_XRET(achTmp, &pachTmp[i*TMP_LINE_LEN]);
+ PRINTF("%s",achTmp);
+ }
+
+ for (i = CIRC_BUFFERS-1; i > iCircBuffer; i--) {
+ READMEM_XRET(achTmp, &pachTmp[i*TMP_LINE_LEN]);
+ PRINTF("%s",achTmp);
+ }
+
+ return;
+}
+
+
+// creates/closes toggle for logfile for iloglevel logging in c:\ilog.log
+void
+logfile(
+ CMD_ARGLIST
+ )
+{
+ INT nArgs;
+ CHAR *argv[2], szLogFile[128];
+ DWORD fLog;
+ LPVOID lpfLog, lpszLogFile;
+
+ CMD_INIT();
+ ASSERT_CHECKED_WOW_PRESENT;
+
+ nArgs = WDParseArgStr(lpArgumentString, argv, 1);
+
+ GETEXPRADDR(lpfLog, "wow32!fLog");
+ READMEM_XRET(fLog, lpfLog);
+
+ if(nArgs) {
+ strcpy(szLogFile, argv[0]);
+ }
+ else {
+ strcpy(szLogFile, "c:\\ilog.log");
+ }
+
+ if(fLog == 0) {
+ fLog = 2;
+
+ PRINTF("\nCreating ");
+ PRINTF(szLogFile);
+ PRINTF("\n\n");
+ }
+ else {
+ fLog = 3;
+ PRINTF("\nClosing logfile\n\n");
+ }
+
+ WRITEMEM_XRET(lpfLog, fLog);
+
+ GETEXPRADDR(lpszLogFile, "wow32!szLogFile");
+ WRITEMEM_N_XRET(lpszLogFile, szLogFile, strlen(szLogFile)+1);
+
+ return;
+}
+
+
+
+
+//
+// Set iLogLevel from Debugger Extension
+//
+void
+setloglevel(
+ CMD_ARGLIST
+ )
+{
+ INT iLogLevel;
+ LPVOID lpAddress;
+
+ CMD_INIT();
+ ASSERT_CHECKED_WOW_PRESENT;
+
+ GETEXPRADDR(lpAddress, "wow32!iLogLevel");
+ iLogLevel = (INT)GetExpression(lpArgumentString);
+ WRITEMEM_XRET(lpAddress, iLogLevel);
+
+ return;
+}
+
+
+//
+// Toggle Single Step Trace Mode
+//
+void
+steptrace(
+ CMD_ARGLIST
+ )
+{
+ INT localfDebugWait;
+ LPVOID lpAddress;
+
+ CMD_INIT();
+ ASSERT_CHECKED_WOW_PRESENT;
+
+ GETEXPRADDR(lpAddress, "wow32!fDebugWait");
+ READMEM_XRET(localfDebugWait, lpAddress);
+ localfDebugWait = ~localfDebugWait;
+ WRITEMEM_XRET(lpAddress, localfDebugWait);
+
+ return;
+}
+
+/******* Misc filtering functions ********/
+//
+// Set Filter Filtering of Specific APIs ON
+//
+void FilterSpecific( )
+{
+ INT i;
+ INT fLogFilter;
+ WORD wfLogFunctionFilter;
+ LPVOID lpAddress;
+ PWORD pawfLogFunctionFilter;
+ WORD wCallId;
+
+ SkipToNextWhiteSpace();
+ if (GetNextToken()) {
+ wCallId = (WORD)GetExpression(lpArgumentString);
+ } else {
+ PRINTF("Please specify an api callid\n");
+ return;
+ }
+
+ if (!wCallId) {
+ PRINTF("Invalid callid\n");
+ return;
+ }
+
+
+ GETEXPRVALUE(pawfLogFunctionFilter, "wow32!pawfLogFunctionFilter", PWORD);
+
+ for (i = 0; i < FILTER_FUNCTION_MAX ; i++) {
+
+ // Find Empty Position In Array
+ READMEM_XRET(wfLogFunctionFilter, &pawfLogFunctionFilter[i]);
+ if ((wfLogFunctionFilter == 0xffff) ||
+ (wfLogFunctionFilter == 0x0000)) {
+
+ // Add New Filter to Array
+ wfLogFunctionFilter = wCallId;
+ WRITEMEM_XRET(&pawfLogFunctionFilter[i], wfLogFunctionFilter);
+ break;
+ }
+ }
+
+ GETEXPRADDR(lpAddress, "wow32!fLogFilter");
+ fLogFilter = 0xffffffff;
+ WRITEMEM_XRET(lpAddress, fLogFilter);
+
+}
+
+
+//
+// Clear Filter Specific Array
+//
+void FilterResetSpecific( )
+{
+ INT i;
+ WORD NEG1 = (WORD) -1;
+ WORD ZERO = 0;
+ PWORD pawfLogFunctionFilter;
+ LPVOID lpAddress;
+
+ GETEXPRVALUE(pawfLogFunctionFilter, "wow32!pawfLogFunctionFilter", PWORD);
+
+ WRITEMEM_XRET(&pawfLogFunctionFilter[0], NEG1);
+ for (i=1; i < FILTER_FUNCTION_MAX ; i++) {
+ WRITEMEM_XRET(&pawfLogFunctionFilter[i], ZERO);
+ }
+
+ GETEXPRADDR(lpAddress, "wow32!iLogFuncFiltIndex");
+ WRITEMEM_XRET(lpAddress, ZERO);
+
+}
+
+//
+// Set TaskID Filtering
+//
+void FilterTask( )
+{
+ INT fLogTaskFilter;
+ LPVOID lpAddress;
+
+ SkipToNextWhiteSpace();
+ if (GetNextToken()) {
+ GETEXPRADDR(lpAddress, "wow32!fLogTaskFilter");
+ fLogTaskFilter = (INT)GetExpression(lpArgumentString);
+ WRITEMEM_XRET(lpAddress, fLogTaskFilter);
+ } else {
+ PRINTF("Please specify a task\n");
+ }
+
+ return;
+}
+
+
+
+//
+// Turn All filtering ON
+//
+void FilterReset( )
+{
+ LPVOID lpAddress;
+ INT fLogFilter = 0xffffffff;
+ WORD fLogTaskFilter = 0xffff;
+
+ GETEXPRADDR(lpAddress, "wow32!fLogFilter");
+ WRITEMEM_XRET(lpAddress, fLogFilter);
+
+ GETEXPRADDR(lpAddress, "wow32!fLogTaskFilter");
+ WRITEMEM_XRET(lpAddress, fLogTaskFilter);
+
+ FilterResetSpecific();
+}
+
+
+//
+// Disable logging on all classes
+//
+void FilterAll( )
+{
+ INT fLogFilter;
+ LPVOID lpAddress;
+
+ GETEXPRADDR(lpAddress, "wow32!fLogFilter");
+ fLogFilter = 0x00000000;
+ WRITEMEM_XRET(lpAddress, fLogFilter);
+
+}
+
+
+VOID
+DumpFilterSettings(
+ VOID
+ )
+{
+ INT i;
+ INT fLogFilter;
+ WORD wfLogFunctionFilter;
+ WORD wfLogTaskFilter;
+ LPVOID lpAddress;
+ PWORD pawfLogFunctionFilter;
+
+ GETEXPRVALUE(pawfLogFunctionFilter, "wow32!pawfLogFunctionFilter", PWORD);
+ GETEXPRVALUE(wfLogTaskFilter, "wow32!fLogTaskFilter", WORD);
+ GETEXPRADDR(lpAddress, "wow32!fLogFilter");
+ READMEM_XRET(fLogFilter, lpAddress);
+
+
+ if (!pawfLogFunctionFilter) {
+ PRINTF("Symbol 'wow32!pawfLogFunctionFilter' not available\n");
+ return;
+ }
+
+ PRINTF("\n*** WOW log filter state ***\n");
+ if (fLogFilter & FILTER_VERBOSE) {
+ PRINTF("Verbose logging is on\n");
+ } else {
+ PRINTF("Verbose logging is off\n");
+ }
+
+ if (wfLogTaskFilter != 0xffff) {
+ PRINTF("Only API calls for task %04X will be logged\n", wfLogTaskFilter);
+ } else {
+ PRINTF("Task filtering is off\n");
+ }
+
+ READMEM_XRET(wfLogFunctionFilter, &pawfLogFunctionFilter[0]);
+ if (wfLogFunctionFilter != 0xffff) {
+
+ PRINTF("\nOnly API calls with the following CallId's will be logged:\n");
+
+ for (i = 0; i < FILTER_FUNCTION_MAX ; i++) {
+
+ // Find Empty Position In Array
+ READMEM_XRET(wfLogFunctionFilter, &pawfLogFunctionFilter[i]);
+ if ((wfLogFunctionFilter != 0xffff) &&
+ (wfLogFunctionFilter != 0x0000)) {
+ PRINTF(" %04X\n", wfLogFunctionFilter);
+ }
+ }
+ PRINTF("\n");
+ } else {
+ PRINTF("Specific API filtering is off\n");
+ }
+
+ if (!(~fLogFilter & ~FILTER_VERBOSE)) {
+ PRINTF("API class filtering if off\n");
+ } else {
+ PRINTF("Logging is disabled for the following API classes:\n");
+ }
+
+ if (!(fLogFilter & FILTER_KERNEL)) {
+ PRINTF(" KERNEL\n");
+ }
+ if (!(fLogFilter & FILTER_KERNEL16)) {
+ PRINTF(" KERNEL16\n");
+ }
+ if (!(fLogFilter & FILTER_USER)) {
+ PRINTF(" USER\n");
+ }
+ if (!(fLogFilter & FILTER_GDI)) {
+ PRINTF(" GDI\n");
+ }
+ if (!(fLogFilter & FILTER_KEYBOARD)) {
+ PRINTF(" KEYBOARD\n");
+ }
+ if (!(fLogFilter & FILTER_SOUND)) {
+ PRINTF(" SOUND\n");
+ }
+ if (!(fLogFilter & FILTER_MMEDIA)) {
+ PRINTF(" MMEDIA\n");
+ }
+ if (!(fLogFilter & FILTER_WINSOCK)) {
+ PRINTF(" WINSOCK\n");
+ }
+ if (!(fLogFilter & FILTER_COMMDLG)) {
+ PRINTF(" COMMDLG\n");
+ }
+
+ PRINTF("\n");
+
+}
+
+void
+filter(
+ CMD_ARGLIST
+ )
+{
+ ULONG Mask = 0;
+ LPVOID lpAddress;
+
+ CMD_INIT();
+ ASSERT_CHECKED_WOW_PRESENT;
+
+ while (' ' == *lpArgumentString) {
+ lpArgumentString++;
+ }
+
+ if (_strnicmp(lpArgumentString, "kernel16", 8) == 0) {
+ Mask = FILTER_KERNEL16;
+ } else if (_strnicmp(lpArgumentString, "kernel", 6) == 0) {
+ Mask = FILTER_KERNEL;
+ } else if (_strnicmp(lpArgumentString, "user", 4) == 0) {
+ Mask = FILTER_USER;
+ } else if (_strnicmp(lpArgumentString, "gdi", 3) == 0) {
+ Mask = FILTER_GDI;
+ } else if (_strnicmp(lpArgumentString, "keyboard", 8) == 0) {
+ Mask = FILTER_KEYBOARD;
+ } else if (_strnicmp(lpArgumentString, "sound", 5) == 0) {
+ Mask = FILTER_SOUND;
+ } else if (_strnicmp(lpArgumentString, "mmedia", 6) == 0) {
+ Mask = FILTER_MMEDIA;
+ } else if (_strnicmp(lpArgumentString, "winsock", 7) == 0) {
+ Mask = FILTER_WINSOCK;
+ } else if (_strnicmp(lpArgumentString, "commdlg", 7) == 0) {
+ Mask = FILTER_COMMDLG;
+ } else if (_strnicmp(lpArgumentString, "callid", 6) == 0) {
+ FilterSpecific();
+ } else if (_strnicmp(lpArgumentString, "task", 4) == 0) {
+ FilterTask();
+ } else if (_strnicmp(lpArgumentString, "*", 1) == 0) {
+ FilterAll();
+ } else if (_strnicmp(lpArgumentString, "reset", 5) == 0) {
+ FilterReset();
+ } else if (_strnicmp(lpArgumentString, "verbose", 7) == 0) {
+ Mask = FILTER_VERBOSE;
+ } else {
+ if (*lpArgumentString != 0) {
+ PRINTF("Invalid argument to Filter command: '%s'\n", lpArgumentString);
+ return;
+ }
+ }
+
+ if (Mask) {
+ INT fLogFilter;
+ GETEXPRADDR(lpAddress, "wow32!fLogFilter");
+ if (!lpAddress) {
+ PRINTF("Symbol 'wow32!fLogFilter' not available\n");
+ } else {
+ READMEM_XRET(fLogFilter, lpAddress);
+ if ((fLogFilter & Mask) == 0) {
+ fLogFilter |= Mask;
+ } else {
+ fLogFilter &= ~Mask;
+ }
+ WRITEMEM_XRET(lpAddress, fLogFilter);
+ }
+ }
+
+ DumpFilterSettings();
+}
+
+
+void
+cia(
+ CMD_ARGLIST
+ )
+{
+ CURSORICONALIAS cia;
+ PVOID lpAddress;
+ INT maxdump = 500;
+
+ CMD_INIT();
+ ASSERT_WOW_PRESENT;
+
+ GETEXPRADDR(lpAddress, "wow32!lpCIAlias");
+ READMEM_XRET(lpAddress, lpAddress);
+
+ if (!lpAddress) {
+
+ PRINTF("Cursor/Icon alias list is empty.\n");
+
+ } else {
+
+ PRINTF("Alias tp H16 H32 inst mod task res szname\n");
+
+ READMEM_XRET(cia, lpAddress);
+
+ while ((lpAddress != NULL) && --maxdump) {
+
+ if (cia.fInUse) {
+ PRINTF("%08X", lpAddress);
+ PRINTF(" %02X", cia.flType);
+ PRINTF(" %04X", cia.h16);
+ PRINTF(" %08X", cia.h32);
+ PRINTF(" %04X", cia.hInst16);
+ PRINTF(" %04X", cia.hMod16);
+ PRINTF(" %04X", cia.hTask16);
+ PRINTF(" %04X", cia.hRes16);
+ PRINTF(" %08X\n", cia.lpszName);
+ }
+
+ lpAddress = cia.lpNext;
+ READMEM_XRET(cia, lpAddress);
+
+ }
+
+ if (!maxdump) {
+ PRINTF("Dump ended prematurely - possible infinite loop\n");
+ }
+ }
+
+}