2020-09-30 17:12:32 +02:00

1684 lines
57 KiB
C

/**** Module Header *****\
* Module Name: conexts.c
* Copyright (c) 1985 - 1999, Microsoft Corporation
* This module contains random debugging related functions.
*/
#include "precomp.h"
#pragma hdrstop
#define NOEXTAPI
#include <wdbgexts.h>
/*
* Global variables
*/
PSTR pszAccessViolation = "CONEXTS: Access violation on \"%s\", switch to server context\n";
PSTR pszMoveException = "CONEXTS: exception in move()\n";
PSTR pszReadFailure = "CONEXTS: moveBlock(%x, %x, %x) failed!\n";
/*
* Macros
*/
#define move(dst, src) moveBlock(dst, src, sizeof(dst))
#define moveBlock(dst, src, size) \
try { \
if (lpExtensionApis->nSize >= sizeof(WINDBG_EXTENSION_APIS)) { \
if (!(*lpExtensionApis->lpReadProcessMemoryRoutine)((DWORD_PTR)(src), &(dst), (size), NULL)) { \
(*lpExtensionApis->lpOutputRoutine)(pszReadFailure, &dst, src, size); \
return FALSE; \
} \
} else { \
if (!NT_SUCCESS(NtReadVirtualMemory(hCurrentProcess, (LPVOID)(src), &(dst), (size), NULL))) { \
(*lpExtensionApis->lpOutputRoutine)(pszReadFailure, &dst, src, size); \
return FALSE; \
} \
} \
} except (EXCEPTION_EXECUTE_HANDLER) { \
(*lpExtensionApis->lpOutputRoutine)(pszMoveException); \
return FALSE; \
}
#define moveExpressionValue(dst, src) \
try { \
DWORD dwGlobal = (DWORD)lpExtensionApis->lpGetExpressionRoutine(src); \
if (lpExtensionApis->nSize < sizeof(WINDBG_EXTENSION_APIS)) { \
move(dwGlobal, dwGlobal); \
} \
(DWORD)dst = dwGlobal; \
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? \
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { \
(*lpExtensionApis->lpOutputRoutine)(pszAccessViolation, src); \
return FALSE; \
}
#define moveExpressionValuePtr(dst, src) \
try { \
DWORD_PTR dwGlobal = lpExtensionApis->lpGetExpressionRoutine(src);\
if (lpExtensionApis->nSize < sizeof(WINDBG_EXTENSION_APIS)) { \
move(dwGlobal, dwGlobal); \
} \
(DWORD_PTR)dst = dwGlobal; \
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? \
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { \
(*lpExtensionApis->lpOutputRoutine)(pszAccessViolation, src); \
return FALSE; \
}
#define moveExpressionAddress(dst, src) \
try { \
if (lpExtensionApis->nSize >= sizeof(WINDBG_EXTENSION_APIS)) { \
(DWORD_PTR)dst = lpExtensionApis->lpGetExpressionRoutine("&"src); \
} else { \
(DWORD_PTR)dst = lpExtensionApis->lpGetExpressionRoutine(src); \
} \
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ? \
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { \
(*lpExtensionApis->lpOutputRoutine)(pszAccessViolation, src); \
return FALSE; \
}
BOOL DebugConvertToAnsi(
HANDLE hCurrentProcess,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPWSTR psrc,
ULONG cbSrc,
LPSTR pdst,
ULONG cbDst)
{
WCHAR awch[80];
ULONG cchText;
cbSrc = min(cbSrc, sizeof(awch) - sizeof(WCHAR));
moveBlock(awch, psrc, cbSrc);
awch[cbSrc/sizeof(WCHAR)] = 0;
cchText = wcslen(awch);
if (cchText == 0) {
strcpy(pdst, "<null>");
} else {
cbSrc = min(cbSrc + sizeof(WCHAR), (cchText + 1) * sizeof(WCHAR));
RtlUnicodeToMultiByteN(pdst, cbDst, NULL,
awch, cbSrc);
pdst[cbDst-1] = 0;
}
return TRUE;
}
BOOL gbShowFlagNames = FALSE;
#define NO_FLAG (LPSTR)0xFFFFFFFF // use this for non-meaningful entries.
#define GF_CONSOLE 1
LPSTR apszConsoleFlags[] = {
"CONSOLE_IS_ICONIC" , // 0x000001
"CONSOLE_OUTPUT_SUSPENDED" , // 0x000002
"CONSOLE_HAS_FOCUS" , // 0x000004
"CONSOLE_IGNORE_NEXT_MOUSE_INPUT", // 0x000008
"CONSOLE_SELECTING" , // 0x000010
"CONSOLE_SCROLLING" , // 0x000020
"CONSOLE_DISABLE_CLOSE" , // 0x000040
"CONSOLE_NOTIFY_LAST_CLOSE" , // 0x000080
"CONSOLE_NO_WINDOW" , // 0x000100
"CONSOLE_VDM_REGISTERED" , // 0x000200
"CONSOLE_UPDATING_SCROLL_BARS" , // 0x000400
"CONSOLE_QUICK_EDIT_MODE" , // 0x000800
"CONSOLE_TERMINATING" , // 0x001000
"CONSOLE_CONNECTED_TO_EMULATOR" , // 0x002000
"CONSOLE_FULLSCREEN_NOPAINT" , // 0x004000
"CONSOLE_SHUTTING_DOWN" , // 0x008000
"CONSOLE_AUTO_POSITION" , // 0x010000
"CONSOLE_IGNORE_NEXT_KEYUP" , // 0x020000
"CONSOLE_WOW_REGISTERED" , // 0x040000
"CONSOLE_USE_PRIVATE_FLAGS" , // 0x080000
"CONSOLE_HISTORY_NODUP" , // 0x100000
"CONSOLE_SCROLLBAR_TRACKING" , // 0x200000
"CONSOLE_IN_DESTRUCTION" , // 0x400000
"CONSOLE_SETTING_WINDOW_SIZE" , // 0x800000
"CONSOLE_DEFAULT_BUFFER_SIZE" , // 0x0100000
NULL // no more
};
#define GF_CONSOLESEL 2
LPSTR apszConsoleSelectionFlags[] = {
"CONSOLE_SELECTION_NOT_EMPTY" , // 1
"CONSOLE_MOUSE_SELECTION" , // 2
"CONSOLE_MOUSE_DOWN" , // 4
"CONSOLE_SELECTION_INVERTED" , // 8
NULL // no more
};
#define GF_FULLSCREEN 3
LPSTR apszFullScreenFlags[] = {
"CONSOLE_FULLSCREEN", // 0
"CONSOLE_FULLSCREEN_HARDWARE", // 1
NULL
};
#define GF_CMDHIST 4
LPSTR apszCommandHistoryFlags[] = {
"CLE_ALLOCATED", // 0x01
"CLE_RESET", // 0x02
NULL
};
/*
* 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 ..."
*/
LPSTR GetFlags(
WORD wType,
DWORD dwFlags,
LPSTR pszBuf)
{
static char szT[400];
DWORD i;
BOOL fFirst = TRUE;
BOOL fNoMoreNames = FALSE;
LPSTR *apszFlags;
if (pszBuf == NULL) {
pszBuf = szT;
}
*pszBuf = '\0';
if (!gbShowFlagNames) {
return(pszBuf);
}
switch (wType) {
case GF_CONSOLE:
apszFlags = apszConsoleFlags;
break;
case GF_CONSOLESEL:
apszFlags = apszConsoleSelectionFlags;
break;
case GF_FULLSCREEN:
apszFlags = apszFullScreenFlags;
break;
case GF_CMDHIST:
apszFlags = apszCommandHistoryFlags;
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 {
strcat(pszBuf, " = ");
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]);
}
}
}
return pszBuf;
}
/*
* help - list help for debugger extensions in CONEXTS.
* 04-Feb-1994 IanJa Created.
*/
BOOL help(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
while (*lpArgumentString == ' ')
lpArgumentString++;
if (*lpArgumentString == '\0') {
Print("conexts help:\n\n");
Print("!help [cmd] - this list, or details about cmd\n");
Print("!dc [fvh] [pconsole] - Dump CONSOLE_INFORMATION struct\n");
Print("!dch <p> - Dump Command History\n");
Print("!dcpt [address] - Dump CPTABLEINFO (default: GlyphCP)\n");
Print("!dmem [v] [pconsole] - Dump memory usage\n");
Print("!df - Dump font cache\n");
Print("!di <p> - Dump input buffer info\n");
Print("!dir <p> - Dump input record ???\n");
Print("!ds <pscreen> - Dump SCREEN_INFORMATION struct\n");
Print("!dt [f] [v[n]] <pcon> - Dump screen buffer info\n");
} else {
if (*lpArgumentString == '!')
lpArgumentString++;
if (strcmp(lpArgumentString, "df") == 0) {
Print("!df - dumps Faces and then the cache\n");
} else if (strcmp(lpArgumentString, "dc") == 0) {
Print("!dc [fhv] - dumps CONSOLE_INFORMATION struct for all consoles\n");
Print("!dc [fhv] address - dumps CONSOLE_INFORMATION struct for console at address\n");
Print(" optional flags (must be sparated by spaces) :\n");
Print(" f - show names of flags\n");
Print(" h - show command histories\n");
Print(" v - show verbose information\n");
Print("eg: \"dc f h v\"\n");
} else if (strcmp(lpArgumentString, "dt") == 0) {
Print("!dt [fc] [v[n]] addr - dumps text buffer info for Console at addr\n");
Print("!dt - dumps text buffer info for all Consoles\n");
Print(" f - show flags\n");
Print(" c - checks text buffer integrity\n");
Print(" v[n] - show first n lines (default 10)\n");
} else if (strcmp(lpArgumentString, "di") == 0) {
Print("!di address - dumps text buffer info (INPUT_INFORMATION)\n");
Print("!di - dumps text buffer info for all Consoles\n");
} else if (strcmp(lpArgumentString, "ds") == 0) {
Print("!ds address - dumps SCREEN_INFORMATION struct at address\n");
} else if (strcmp(lpArgumentString, "dmem") == 0) {
Print("!dmem [v] - dumps memory usage for all consoles\n");
Print("!dmem [v] addr - dumps memory usage for all console at addr\n");
Print(" v - show verbose information\n");
}
}
return 0;
}
BOOL dch(HANDLE, HANDLE, DWORD, PWINDBG_EXTENSION_APIS, LPSTR);
/*
* dc - Dump Console - dump CONSOLE_INFORMATION struct
* dc address - dumps simple info for console at address
* (takes handle too)
*/
BOOL dc(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
char ach[120];
char chVerbose, chShowFlags, chHistory;
BOOL fPrintLine;
ULONG i;
ULONG NumberOfConsoleHandles;
PCONSOLE_INFORMATION *ConsoleHandles;
CONSOLE_INFORMATION Console;
PCONSOLE_INFORMATION pConsole = NULL;
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
gbShowFlagNames = FALSE;
chVerbose = ' ';
chShowFlags = ' ';
chHistory = ' ';
do {
/*
* Skip white space
*/
while (*lpArgString && *lpArgString == ' ')
lpArgString++;
/*
* f : show flags
*/
switch (*lpArgString) {
case 'f': // show flags
gbShowFlagNames = TRUE;
chShowFlags = 'f';
break;
case 'v':
chVerbose = 'v';
break;
case 'h':
chHistory = 'h';
break;
case '\0':
/*
* If no console is specified, loop through all of them
*/
moveExpressionValue(NumberOfConsoleHandles,
"winsrv!NumberOfConsoleHandles");
moveExpressionValuePtr(ConsoleHandles,
"winsrv!ConsoleHandles");
fPrintLine = FALSE;
for (i = 0; i < NumberOfConsoleHandles; i++) {
move(pConsole, ConsoleHandles);
if (pConsole != NULL) {
if (fPrintLine)
Print("==========================================\n");
sprintf(ach, "%c %c %c %p", chVerbose, chShowFlags, chHistory, pConsole);
dc(hCurrentProcess, hCurrentThread, dwCurrentPc, lpExtensionApis, ach);
fPrintLine = TRUE;
}
ConsoleHandles++;
}
return TRUE;
default:
pConsole = (PCONSOLE_INFORMATION)EvalExpression(lpArgString);
break;
}
lpArgString++;
} while (pConsole == NULL);
move(Console, pConsole);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
Console.Title,
Console.TitleLength,
ach,
sizeof(ach));
Print("PCONSOLE @ 0x%lX \"%s\"\n", pConsole, ach);
if (chHistory == 'h') {
PLIST_ENTRY ListHead, ListNext;
LIST_ENTRY ListEntry;
PCOMMAND_HISTORY History;
ListHead = &(pConsole->CommandHistoryList);
ListNext = Console.CommandHistoryList.Flink;
while (ListNext != ListHead) {
History = CONTAINING_RECORD( ListNext, COMMAND_HISTORY, ListLink );
sprintf(ach, "%p", History);
dch(hCurrentProcess, hCurrentThread, dwCurrentPc,
lpExtensionApis, ach);
move(ListEntry, ListNext);
ListNext = ListEntry.Flink;
Print("----\n");
}
return TRUE;
}
Print("\t pConsoleLock 0x%08lX\n"
"\t RefCount 0x%04lX\n"
"\t WaitCount 0x%04lX\n"
"\t pInputBuffer 0x%08lX\n"
"\t pCurrentScreenBuffer 0x%08lX\n"
"\t pScreenBuffers 0x%08lX\n"
"\t hWnd 0x%08lX\n"
"\t hDC 0x%08lX\n"
"\t LastAttributes 0x%04lX\n",
&pConsole->ConsoleLock,
Console.RefCount,
Console.WaitCount,
&pConsole->InputBuffer,
Console.CurrentScreenBuffer,
Console.ScreenBuffers,
Console.hWnd,
Console.hDC,
Console.LastAttributes);
Print("\t Flags 0x%08lX%s\n",
Console.Flags, GetFlags(GF_CONSOLE, Console.Flags, NULL));
Print("\t FullScreenFlags 0x%04lX%s\n",
Console.FullScreenFlags,
GetFlags(GF_FULLSCREEN, Console.FullScreenFlags, NULL));
Print("\t ConsoleHandle 0x%08lX\n"
"\t CtrlFlags 0x%08lX\n",
Console.ConsoleHandle,
Console.CtrlFlags
);
if (chVerbose == 'v') {
Print("\t hMenu 0x%08lX\n"
"\t hHeirMenu 0x%08lX\n"
"\t hSysPalette 0x%08lX\n"
"\t WindowRect.L T R B 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n"
"\t ResizeFlags 0x%08lX\n"
"\t OutputQueue.F B 0x%08lX 0x%08lX\n"
"\t InitEvents[] 0x%08lX 0x%08lX\n"
"\t ClientThreadHandle 0x%08lX\n"
"\t ProcessHandleList.F B 0x%08lX 0x%08lX\n"
"\t CommandHistoryList.F B 0x%08lX 0x%08lX\n"
"\t ExeAliasList.F B 0x%08lX 0x%08lX\n",
Console.hMenu,
Console.hHeirMenu,
Console.hSysPalette,
Console.WindowRect.left,
Console.WindowRect.top,
Console.WindowRect.right,
Console.WindowRect.bottom,
Console.ResizeFlags,
Console.OutputQueue.Flink,
Console.OutputQueue.Blink,
Console.InitEvents[0],
Console.InitEvents[1],
Console.ClientThreadHandle,
Console.ProcessHandleList.Flink,
Console.ProcessHandleList.Blink,
Console.CommandHistoryList.Flink,
Console.CommandHistoryList.Blink,
Console.ExeAliasList.Flink,
Console.ExeAliasList.Blink
);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
Console.OriginalTitle,
Console.OriginalTitleLength,
ach,
sizeof(ach)
);
Print("\t NumCommandHistories 0x%04lX\n"
"\t MaxCommandHistories 0x%04lX\n"
"\t CommandHistorySize 0x%04lX\n"
"\t OriginalTitleLength 0x%04lX\n"
"\t TitleLength 0x%04lX\n"
"\t OriginalTitle %s\n"
"\t dwHotKey 0x%08lX\n"
"\t hIcon 0x%08lX\n"
"\t iIcondId 0x%08lX\n"
"\t ReserveKeys 0x%02lX\n"
"\t WaitQueue 0x%08lX\n",
Console.NumCommandHistories,
Console.MaxCommandHistories,
Console.CommandHistorySize,
Console.OriginalTitleLength,
Console.TitleLength,
ach,
Console.dwHotKey,
Console.hIcon,
Console.iIconId,
Console.ReserveKeys,
Console.WaitQueue
);
Print("\t SelectionFlags 0x%08lX%s\n"
"\t SelectionRect.L T R B 0x%04lX 0x%04lX 0x%04lX 0x%04lX\n"
"\t SelectionAnchor.X Y 0x%04lX 0x%04lX\n"
"\t TextCursorPosition.X Y 0x%04lX 0x%04lX\n"
"\t TextCursorSize 0x%08lX\n"
"\t TextCursorVisible 0x%02lX\n"
"\t InsertMode 0x%02lX\n"
"\t wShowWindow 0x%04lX\n"
"\t dwWindowOriginX 0x%08lX\n"
"\t dwWindowOriginY 0x%08lX\n"
"\t PopupCount 0x%04lX\n",
Console.SelectionFlags,
GetFlags(GF_CONSOLESEL, Console.SelectionFlags, NULL),
Console.SelectionRect.Left,
Console.SelectionRect.Top,
Console.SelectionRect.Right,
Console.SelectionRect.Bottom,
Console.SelectionAnchor.X,
Console.SelectionAnchor.Y,
Console.TextCursorPosition.X,
Console.TextCursorPosition.Y,
Console.TextCursorSize,
Console.TextCursorVisible,
Console.InsertMode,
Console.wShowWindow,
Console.dwWindowOriginX,
Console.dwWindowOriginY,
Console.PopupCount
);
Print("\t VDMStartHardwareEvent 0x%08lX\n"
"\t VDMEndHardwareEvent 0x%08lX\n"
"\t VDMProcessHandle 0x%08lX\n"
"\t VDMProcessId 0x%08lX\n"
"\t VDMBufferSectionHandle 0x%08lX\n"
"\t VDMBuffer 0x%08lX\n"
"\t VDMBufferClient 0x%08lX\n"
"\t VDMBufferSize.X Y 0x%04lX 0x%04lX\n"
"\t StateSectionHandle 0x%08lX\n"
"\t StateBuffer 0x%08lX\n"
"\t StateBufferClient 0x%08lX\n"
"\t StateLength 0x%08lX\n",
Console.VDMStartHardwareEvent,
Console.VDMEndHardwareEvent,
Console.VDMProcessHandle,
Console.VDMProcessId,
Console.VDMBufferSectionHandle,
Console.VDMBuffer,
Console.VDMBufferClient,
Console.VDMBufferSize.X,
Console.VDMBufferSize.Y,
Console.StateSectionHandle,
Console.StateBuffer,
Console.StateBufferClient,
Console.StateLength
);
Print("\t CP 0x%08lX\n"
"\t OutputCP 0x%08lX\n"
"\t hWndProgMan 0x%08lX\n"
"\t bIconInit 0x%08lX\n"
"\t LimitingProcessId 0x%08lX\n"
"\t TerminationEvent 0x%08lX\n"
"\t VerticalClientToWin 0x%04lX\n"
"\t HorizontalClientToWin 0x%04lX\n",
Console.CP,
Console.OutputCP,
Console.hWndProgMan,
Console.bIconInit,
Console.LimitingProcessId,
Console.TerminationEvent,
Console.VerticalClientToWindow,
Console.HorizontalClientToWindow
);
#if defined(FE_SB)
Print("\t EudcInformation 0x%08lX\n"
"\t FontCacheInformation 0x%08lX\n",
Console.EudcInformation,
Console.FontCacheInformation
);
#if defined(FE_IME)
Print("\tConsoleIme:\n"
"\t ScrollFlag 0x%08lX\n"
"\t ScrollWaitTimeout 0x%08lX\n"
"\t ScrollWaitCountDown 0x%08lX\n"
"\t CompStrData 0x%08lX\n"
"\t ConvAreaMode 0x%08lX\n"
"\t ConvAreaSystem 0x%08lX\n"
"\t NumberOfConvAreaCompStr 0x%08lX\n"
"\t ConvAreaCompStr 0x%08lX\n"
"\t ConvAreaRoot 0x%08lX\n",
Console.ConsoleIme.ScrollFlag,
Console.ConsoleIme.ScrollWaitTimeout,
Console.ConsoleIme.ScrollWaitCountDown,
Console.ConsoleIme.CompStrData,
Console.ConsoleIme.ConvAreaMode,
Console.ConsoleIme.ConvAreaSystem,
Console.ConsoleIme.NumberOfConvAreaCompStr,
Console.ConsoleIme.ConvAreaCompStr,
Console.ConsoleIme.ConvAreaRoot
);
#endif
#endif
}
return TRUE;
}
/*
* dt - Dump Text - dump text buffer information
* dt address - dumps text buffer information for console at address
*/
BOOL dt(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
char ach[120];
BOOL fPrintLine;
ULONG i, nLines;
SHORT sh;
ULONG NumberOfConsoleHandles;
PCONSOLE_INFORMATION *ConsoleHandles;
CONSOLE_INFORMATION Console;
SCREEN_INFORMATION Screen;
PCONSOLE_INFORMATION pConsole;
DWORD FrameBufPtr;
char chVerbose = ' ';
char chShowFlags = ' ';
char chCheck = ' ';
PROW pRow;
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Get arguments
*/
pConsole = NULL;
do {
/*
* Skip white space
*/
while (*lpArgString && *lpArgString == ' ')
lpArgString++;
switch (*lpArgString) {
case 'f':
gbShowFlagNames = TRUE;
chShowFlags = 'f';
break;
case 'c':
chCheck = 'c';
break;
case 'v':
chVerbose = 'v';
nLines = 0;
lpArgString++;
while ((*lpArgString >= '0') && (*lpArgString <= '9')) {
nLines *= 10;
nLines += *lpArgString - '0';
lpArgString++;
}
lpArgString--;
if (nLines == 0) {
nLines = 10;
}
break;
case '\0':
/*
* If no console is specified, dt all of them
*/
moveExpressionValue(NumberOfConsoleHandles,
"winsrv!NumberOfConsoleHandles");
moveExpressionValuePtr(ConsoleHandles,
"winsrv!ConsoleHandles");
fPrintLine = FALSE;
for (i = 0; i < NumberOfConsoleHandles; i++) {
move(pConsole, ConsoleHandles);
if (pConsole != NULL) {
if (fPrintLine)
Print("==========================================\n");
sprintf(ach, "%c %c %p", chVerbose, chShowFlags, pConsole);
if (!dt(hCurrentProcess, hCurrentThread,
dwCurrentPc, lpExtensionApis, ach)) {
return FALSE;
}
fPrintLine = TRUE;
}
ConsoleHandles++;
}
return TRUE;
default:
pConsole = (PCONSOLE_INFORMATION)EvalExpression(lpArgString);
break;
}
lpArgString++;
} while (pConsole == NULL);
move(Console, pConsole);
Print("PCONSOLE @ 0x%lX\n", pConsole);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
Console.Title,
Console.TitleLength,
ach,
sizeof(ach));
Print("\t Title %s\n"
"\t pCurrentScreenBuffer 0x%08lX\n"
"\t pScreenBuffers 0x%08lX\n"
"\t VDMBuffer 0x%08lx\n"
"\t CP %d, OutputCP %d\n",
ach,
Console.CurrentScreenBuffer,
Console.ScreenBuffers,
Console.VDMBuffer,
Console.CP,
Console.OutputCP
);
moveExpressionValue(FrameBufPtr, "winsrv!FrameBufPtr");
move(Screen, Console.CurrentScreenBuffer);
if (Screen.Flags & CONSOLE_TEXTMODE_BUFFER) {
Print("\t TextInfo.Rows 0x%08X\n"
"\t TextInfo.TextRows 0x%08X\n"
"\t TextInfo.FirstRow 0x%08X\n"
"\t FrameBufPtr 0x%08X\n",
Screen.BufferInfo.TextInfo.Rows,
Screen.BufferInfo.TextInfo.TextRows,
Screen.BufferInfo.TextInfo.FirstRow,
FrameBufPtr);
}
pRow = Screen.BufferInfo.TextInfo.Rows;
if (chCheck) {
Print("Checking BufferInfo...\n");
for (sh = 0; sh < Screen.ScreenBufferSize.Y; sh++) {
ROW Row;
move(Row, pRow);
/*
* Check that Attrs points to the in-place AttrPair if there
* if only one AttrPair for this Row.
*/
if (Row.AttrRow.Length == 1) {
if (Row.AttrRow.Attrs != &(pRow->AttrRow.AttrPair)) {
Print("Bad Row[%lx]: Attrs %lx should be %lx\n",
sh, Row.AttrRow.Attrs, pRow->AttrRow.AttrPair);
}
}
/*
* Some other checks?
*/
pRow++;
}
Print("...check completed\n");
}
if (chVerbose == ' ') {
return TRUE;
}
pRow = Screen.BufferInfo.TextInfo.Rows;
for (i = 0; i < nLines; i++) {
ROW Row;
move(Row, pRow);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
Row.CharRow.Chars,
-1,
ach,
sizeof(ach));
Print("Row %2d: %4x %4x, %4x %4x, %lx:\"%.40s\"\n",
i,
(USHORT)Row.CharRow.Right, (USHORT)Row.CharRow.OldRight,
(USHORT)Row.CharRow.Left, (USHORT)Row.CharRow.OldLeft,
Row.CharRow.Chars, ach);
Print(" %4x %4x,%04x or %lx\n",
(USHORT)Row.AttrRow.Length,
(USHORT)Row.AttrRow.AttrPair.Length,
(WORD)Row.AttrRow.AttrPair.Attr,
Row.AttrRow.Attrs);
pRow++;
}
return TRUE;
}
/*
* df - Dump Font - dump Font information
* df address - dumps simple info for console at address
* (takes handle too)
*/
BOOL df(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
BYTE Buff[sizeof(FACENODE) + (LF_FACESIZE * sizeof(WCHAR))];
PFACENODE pFN;
DWORD NumberOfFonts;
DWORD FontInfoLength;
FONT_INFO FontInfo;
PFONT_INFO pFontInfo;
DWORD dw;
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip space
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
Print("Faces:\n");
moveExpressionValuePtr(pFN, "winsrv!gpFaceNames");
while (pFN != 0) {
move(Buff, pFN);
pFN = (PFACENODE)Buff;
Print(" \"%ls\"\t%s %s %s %s %s %s\n",
&pFN->awch[0],
pFN->dwFlag & EF_NEW ? "NEW" : " ",
pFN->dwFlag & EF_OLD ? "OLD" : " ",
pFN->dwFlag & EF_ENUMERATED ? "ENUMERATED" : " ",
pFN->dwFlag & EF_OEMFONT ? "OEMFONT" : " ",
pFN->dwFlag & EF_TTFONT ? "TTFONT" : " ",
pFN->dwFlag & EF_DEFFACE ? "DEFFACE" : " ");
pFN = pFN->pNext;
}
moveExpressionValue(FontInfoLength, "winsrv!FontInfoLength");
moveExpressionValue(NumberOfFonts, "winsrv!NumberOfFonts");
moveExpressionValuePtr(pFontInfo, "winsrv!FontInfo");
Print("0x%lx fonts cached, 0x%lx allocated:\n", NumberOfFonts, FontInfoLength);
for (dw = 0; dw < NumberOfFonts; dw++, pFontInfo++) {
WCHAR FaceName[LF_FACESIZE];
move(FontInfo, pFontInfo);
move(FaceName, FontInfo.FaceName);
Print("%04x hFont 0x%08lX \"%ls\"\n"
" SizeWant (%d;%d)\n"
" Size (%d;%d)\n"
" Family %02X\n"
" Weight 0x%08lX\n",
dw,
FontInfo.hFont,
FaceName,
FontInfo.SizeWant.X, FontInfo.SizeWant.Y,
FontInfo.Size.X, FontInfo.Size.Y,
FontInfo.Family,
FontInfo.Weight);
#if defined(FE_SB)
Print(" CharSet 0x%02X\n",
FontInfo.tmCharSet);
#endif
}
return TRUE;
}
/*
* di - Dump Input - dump input buffer
* di address - dumps simple info for input at address
*/
BOOL di(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
INPUT_INFORMATION Input;
PINPUT_INFORMATION pInput;
PCONSOLE_INFORMATION pConsole;
ULONG NumberOfConsoleHandles;
PCONSOLE_INFORMATION *ConsoleHandles;
BOOL fPrintLine;
ULONG i;
char ach[120];
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip with space
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
/*
* If no INPUT_INFORMATION is specified, dt all of them
*/
if (*lpArgumentString == 0) {
moveExpressionValue(NumberOfConsoleHandles,
"winsrv!NumberOfConsoleHandles");
moveExpressionValuePtr(ConsoleHandles,
"winsrv!ConsoleHandles");
fPrintLine = FALSE;
for (i = 0; i < NumberOfConsoleHandles; i++) {
move(pConsole, ConsoleHandles);
if (pConsole != NULL) {
if (fPrintLine)
Print("---\n");
pInput = &pConsole->InputBuffer;
#ifdef _WIN64
_i64toa((ULONG64)pInput, ach, 16);
#else
_itoa((ULONG)pInput, ach, 16);
#endif
if (!di(hCurrentProcess, hCurrentThread, dwCurrentPc, lpExtensionApis, ach)) {
return FALSE;
}
fPrintLine = TRUE;
}
ConsoleHandles++;
}
return TRUE;
} else {
pInput = (PINPUT_INFORMATION)EvalExpression(lpArgumentString);
}
move(Input, pInput);
Print("PINPUT @ 0x%lX\n", pInput);
Print("\t pInputBuffer 0x%08lX\n"
"\t InputBufferSize 0x%08lX\n"
"\t AllocatedBufferSize 0x%08lX\n"
"\t InputMode 0x%08lX\n"
"\t RefCount 0x%08lX\n"
"\t First 0x%08lX\n"
"\t In 0x%08lX\n"
"\t Out 0x%08lX\n"
"\t Last 0x%08lX\n"
"\t ReadWaitQueue.Flink 0x%08lX\n"
"\t ReadWaitQueue.Blink 0x%08lX\n"
"\t InputWaitEvent 0x%08lX\n",
Input.InputBuffer,
Input.InputBufferSize,
Input.AllocatedBufferSize,
Input.InputMode,
Input.RefCount,
Input.First,
Input.In,
Input.Out,
Input.Last,
Input.ReadWaitQueue.Flink,
Input.ReadWaitQueue.Blink,
Input.InputWaitEvent
);
return TRUE;
}
/*
* dir - Dump Input Record - dump input buffer
* dir address number - dumps simple info for input at address
*/
BOOL dir(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
INPUT_RECORD InputRecord;
PINPUT_RECORD pInputRecord;
char ach[80];
int cch;
LPSTR lpAddress;
DWORD NumRecords,i;
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip with space
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
lpAddress = lpArgumentString;
while (*lpArgumentString != ' ' && *lpArgumentString != 0)
lpArgumentString++;
cch = (int)(lpArgumentString - lpAddress);
if (cch > 79)
cch = 79;
strncpy(ach, lpAddress, cch);
pInputRecord = (PINPUT_RECORD)EvalExpression(lpAddress);
NumRecords = (DWORD)EvalExpression(lpArgumentString);
Print("%x PINPUTRECORDs @ 0x%lX\n", NumRecords, pInputRecord);
for (i=0;i<NumRecords;i++) {
move(InputRecord, pInputRecord);
switch (InputRecord.EventType) {
case KEY_EVENT:
Print("\t KEY_EVENT\n");
if (InputRecord.Event.KeyEvent.bKeyDown)
Print("\t KeyDown\n");
else
Print("\t KeyUp\n");
Print("\t wRepeatCount %d\n",
InputRecord.Event.KeyEvent.wRepeatCount);
Print("\t wVirtualKeyCode %x\n",
InputRecord.Event.KeyEvent.wVirtualKeyCode);
Print("\t wVirtualScanCode %x\n",
InputRecord.Event.KeyEvent.wVirtualScanCode);
Print("\t aChar is %c",
InputRecord.Event.KeyEvent.uChar.AsciiChar);
Print("\n");
Print("\t uChar is %x\n",
InputRecord.Event.KeyEvent.uChar.UnicodeChar);
Print("\t dwControlKeyState %x\n",
InputRecord.Event.KeyEvent.dwControlKeyState);
break;
case MOUSE_EVENT:
Print("\t MOUSE_EVENT\n"
"\t dwMousePosition %x %x\n"
"\t dwButtonState %x\n"
"\t dwControlKeyState %x\n"
"\t dwEventFlags %x\n",
InputRecord.Event.MouseEvent.dwMousePosition.X,
InputRecord.Event.MouseEvent.dwMousePosition.Y,
InputRecord.Event.MouseEvent.dwButtonState,
InputRecord.Event.MouseEvent.dwControlKeyState,
InputRecord.Event.MouseEvent.dwEventFlags
);
break;
case WINDOW_BUFFER_SIZE_EVENT:
Print("\t WINDOW_BUFFER_SIZE_EVENT\n"
"\t dwSize %x %x\n",
InputRecord.Event.WindowBufferSizeEvent.dwSize.X,
InputRecord.Event.WindowBufferSizeEvent.dwSize.Y
);
break;
case MENU_EVENT:
Print("\t MENU_EVENT\n"
"\t dwCommandId %x\n",
InputRecord.Event.MenuEvent.dwCommandId
);
break;
case FOCUS_EVENT:
Print("\t FOCUS_EVENT\n");
if (InputRecord.Event.FocusEvent.bSetFocus)
Print("\t bSetFocus is TRUE\n");
else
Print("\t bSetFocus is FALSE\n");
break;
default:
Print("\t Unknown event type %x\n",InputRecord.EventType);
break;
}
pInputRecord++;
}
return TRUE;
}
/*
* ds - Dump Screen - dump SCREEN_INFORMATION struct
* ds address - dumps simple info for input at address
*/
BOOL ds(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
SCREEN_INFORMATION Screen;
PSCREEN_INFORMATION pScreen;
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip with space
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
pScreen = (PSCREEN_INFORMATION)EvalExpression(lpArgumentString);
move(Screen, pScreen);
Print("PSCREEN @ 0x%lX\n", pScreen);
Print("\t pConsole 0x%08lX\n"
"\t Flags 0x%08lX %s | %s\n"
"\t OutputMode 0x%08lX\n"
"\t RefCount 0x%08lX\n"
"\t ScreenBufferSize.X Y 0x%08X 0x%08X\n"
"\t Window.L T R B 0x%08X 0x%08X 0x%08X 0x%08X\n"
"\t ResizingWindow 0x%08X\n",
Screen.Console,
Screen.Flags,
Screen.Flags & CONSOLE_TEXTMODE_BUFFER ? "TEXTMODE" : "GRAPHICS",
Screen.Flags & CONSOLE_OEMFONT_DISPLAY ? "OEMFONT" : "TT FONT",
Screen.OutputMode,
Screen.RefCount,
(DWORD)Screen.ScreenBufferSize.X,
(DWORD)Screen.ScreenBufferSize.Y,
(DWORD)Screen.Window.Left,
(DWORD)Screen.Window.Top,
(DWORD)Screen.Window.Right,
(DWORD)Screen.Window.Bottom,
Screen.ResizingWindow
);
Print("\t Attributes 0x%08X\n"
"\t PopupAttributes 0x%08X\n"
"\t WindowMaximizedX 0x%08X\n"
"\t WindowMaximizedY 0x%08X\n"
"\t WindowMaximized 0x%08X\n"
"\t CommandIdLow High 0x%08X 0x%08X\n"
"\t CursorHandle 0x%08X\n"
"\t hPalette 0x%08X\n"
"\t dwUsage 0x%08X\n"
"\t CursorDisplayCount 0x%08X\n"
"\t WheelDelta 0x%08X\n",
Screen.Attributes,
Screen.PopupAttributes,
Screen.WindowMaximizedX,
Screen.WindowMaximizedY,
Screen.WindowMaximized,
Screen.CommandIdLow,
Screen.CommandIdHigh,
Screen.CursorHandle,
Screen.hPalette,
Screen.dwUsage,
Screen.CursorDisplayCount,
Screen.WheelDelta
);
if (Screen.Flags & CONSOLE_TEXTMODE_BUFFER) {
Print("\t TextInfo.Rows 0x%08X\n"
"\t TextInfo.TextRows 0x%08X\n"
"\t TextInfo.FirstRow 0x%08X\n",
Screen.BufferInfo.TextInfo.Rows,
Screen.BufferInfo.TextInfo.TextRows,
Screen.BufferInfo.TextInfo.FirstRow);
Print("\t TextInfo.CurrentTextBufferFont.FontSize 0x%04X,0x%04X\n"
"\t TextInfo.CurrentTextBufferFont.FontNumber 0x%08X\n",
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.FontSize.X,
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.FontSize.Y,
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.FontNumber);
Print("\t TextInfo.CurrentTextBufferFont.Family, Weight 0x%08X, 0x%08X\n"
"\t TextInfo.CurrentTextBufferFont.FaceName %ls\n"
"\t TextInfo.CurrentTextBufferFont.FontCodePage %d\n",
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.Family,
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.Weight,
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.FaceName,
Screen.BufferInfo.TextInfo.CurrentTextBufferFont.FontCodePage);
if (Screen.BufferInfo.TextInfo.ListOfTextBufferFont != NULL) {
PTEXT_BUFFER_FONT_INFO pLinkFont;
TEXT_BUFFER_FONT_INFO LinkFont;
ULONG Count = 0;
pLinkFont = Screen.BufferInfo.TextInfo.ListOfTextBufferFont;
while (pLinkFont != 0) {
move(LinkFont, pLinkFont);
Print("\t Link Font #%d\n", Count++);
Print("\t TextInfo.LinkOfTextBufferFont.FontSize 0x%04X,0x%04X\n"
"\t TextInfo.LinkOfTextBufferFont.FontNumber 0x%08X\n",
LinkFont.FontSize.X,
LinkFont.FontSize.Y,
LinkFont.FontNumber);
Print("\t TextInfo.LinkOfTextBufferFont.Family, Weight 0x%08X, 0x%08X\n"
"\t TextInfo.LinkOfTextBufferFont.FaceName %ls\n"
"\t TextInfo.LinkOfTextBufferFont.FontCodePage %d\n",
LinkFont.Family,
LinkFont.Weight,
LinkFont.FaceName,
LinkFont.FontCodePage);
pLinkFont = LinkFont.NextTextBufferFont;
}
Print("\n");
}
Print("\t TextInfo.ModeIndex 0x%08X\n"
#ifdef i386
"\t TextInfo.WindowedWindowSize.X Y 0x%08X 0x%08X\n"
"\t TextInfo.WindowedScreenSize.X Y 0x%08X 0x%08X\n"
"\t TextInfo.MousePosition.X Y 0x%08X 0x%08X\n"
#endif
"\t TextInfo.Flags 0x%08X\n",
Screen.BufferInfo.TextInfo.ModeIndex,
#ifdef i386
Screen.BufferInfo.TextInfo.WindowedWindowSize.X,
Screen.BufferInfo.TextInfo.WindowedWindowSize.Y,
Screen.BufferInfo.TextInfo.WindowedScreenSize.X,
Screen.BufferInfo.TextInfo.WindowedScreenSize.Y,
Screen.BufferInfo.TextInfo.MousePosition.X,
Screen.BufferInfo.TextInfo.MousePosition.Y,
#endif
Screen.BufferInfo.TextInfo.Flags);
Print("\t TextInfo.CursorVisible 0x%08X\n"
"\t TextInfo.CursorOn 0x%08X\n"
"\t TextInfo.DelayCursor 0x%08X\n"
"\t TextInfo.CursorPosition.X Y 0x%08X 0x%08X\n"
"\t TextInfo.CursorSize 0x%08X\n"
"\t TextInfo.CursorYSize 0x%08X\n"
"\t TextInfo.UpdatingScreen 0x%08X\n",
Screen.BufferInfo.TextInfo.CursorVisible,
Screen.BufferInfo.TextInfo.CursorOn,
Screen.BufferInfo.TextInfo.DelayCursor,
Screen.BufferInfo.TextInfo.CursorPosition.X,
Screen.BufferInfo.TextInfo.CursorPosition.Y,
Screen.BufferInfo.TextInfo.CursorSize,
Screen.BufferInfo.TextInfo.CursorYSize,
Screen.BufferInfo.TextInfo.UpdatingScreen);
} else {
Print("\t GraphicsInfo.BitMapInfoLength 0x%08X\n"
"\t GraphicsInfo.lpBitMapInfo 0x%08X\n"
"\t GraphicsInfo.BitMap 0x%08X\n"
"\t GraphicsInfo.ClientBitMap 0x%08X\n"
"\t GraphicsInfo.ClientProcess 0x%08X\n"
"\t GraphicsInfo.hMutex 0x%08X\n"
"\t GraphicsInfo.hSection 0x%08X\n"
"\t GraphicsInfo.dwUsage 0x%08X\n",
Screen.BufferInfo.GraphicsInfo.BitMapInfoLength,
Screen.BufferInfo.GraphicsInfo.lpBitMapInfo,
Screen.BufferInfo.GraphicsInfo.BitMap,
Screen.BufferInfo.GraphicsInfo.ClientBitMap,
Screen.BufferInfo.GraphicsInfo.ClientProcess,
Screen.BufferInfo.GraphicsInfo.hMutex,
Screen.BufferInfo.GraphicsInfo.hSection,
Screen.BufferInfo.GraphicsInfo.dwUsage
);
}
return TRUE;
}
/*
* dcpt - Dump CPTABLEINFO
* dcpt address - dumps CPTABLEINFO at address
* dcpt - dumps CPTABLEINFO at GlyphCP
*/
BOOL dcpt(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
PCPTABLEINFO pcpt;
CPTABLEINFO cpt;
UNREFERENCED_PARAMETER(hCurrentProcess);
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip with space
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
/*
* If no CPTABLEINFO is specified, use the GlyphCP
*/
if (*lpArgumentString == 0) {
lpArgumentString = "winsrv!GlyphCP";
}
pcpt = (PCPTABLEINFO)EvalExpression(lpArgumentString);
move(cpt, pcpt);
Print("CPTABLEINFO @ 0x%lX\n", pcpt);
Print(" CodePage = 0x%x (%d)\n"
" MaximumCharacterSize = %x\n"
" DefaultChar = %x\n",
cpt.CodePage, cpt.CodePage,
cpt.MaximumCharacterSize,
cpt.DefaultChar);
Print(" UniDefaultChar = 0x%04x\n"
" TransDefaultChar = %x\n"
" TransUniDefaultChar = 0x%04x\n"
" DBCSCodePage = 0x%x (%d)\n",
cpt.UniDefaultChar,
cpt.TransDefaultChar,
cpt.TransUniDefaultChar,
cpt.DBCSCodePage, cpt.DBCSCodePage);
Print(" LeadByte[MAXIMUM_LEADBYTES] = %04x,%04x,%04x,...\n"
" MultiByteTable = %x\n"
" WideCharTable = %lx\n"
" DBCSRanges = %lx\n"
" DBCSOffsets = %lx\n",
cpt.LeadByte[0], cpt.LeadByte[1], cpt.LeadByte[2],
cpt.MultiByteTable,
cpt.WideCharTable,
cpt.DBCSRanges,
cpt.DBCSOffsets);
return TRUE;
}
/*
* dch - Dump Command History
* dch address - dumps COMMAND_HISTORY at address
* dch - dumps some random COMMAND_HISTORY
*/
BOOL dch(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgumentString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
PCOMMAND_HISTORY pCmdHist;
COMMAND_HISTORY CmdHist;
PCOMMAND pCmd;
union {
COMMAND Cmd;
WCHAR awch[80];
} DbgCmd;
int i;
char ach[120];
UNREFERENCED_PARAMETER(hCurrentThread);
UNREFERENCED_PARAMETER(dwCurrentPc);
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
/*
* Skip spaces
*/
while (*lpArgumentString == ' ')
lpArgumentString++;
/*
* If no COMMAND_HISTORY is specified, use something ????
*/
if (*lpArgumentString == 0) {
Print("must specify address of COMMAND_HISTORY struct\n");
Print("(a breakpoint on winsrv!AddCommand() may help)\n");
return FALSE;
}
pCmdHist = (PCOMMAND_HISTORY)EvalExpression(lpArgumentString);
move(CmdHist, pCmdHist);
Print("COMMAND_HISTORY @ 0x%lX\n", pCmdHist);
Print(" Flags = 0x%08lX%s\n",
CmdHist.Flags, GetFlags(GF_CMDHIST, CmdHist.Flags, NULL));
Print(" ListLink.F B = 0x%08lX 0x%08lX\n",
CmdHist.ListLink.Flink, CmdHist.ListLink.Blink);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
CmdHist.AppName,
-1,
ach,
sizeof(ach));
Print(" AppName = %s\n", ach);
Print(" NumberOfCommands = 0x%lx\n"
" LastAdded = 0x%lx\n"
" LastDisplayed = 0x%lx\n"
" FirstCommand = 0x%lx\n"
" MaximumNumberOfCommands = 0x%lx\n",
CmdHist.NumberOfCommands,
CmdHist.LastAdded,
CmdHist.LastDisplayed,
CmdHist.FirstCommand,
CmdHist.MaximumNumberOfCommands);
Print(" ProcessHandle = 0x%08lX\n",
CmdHist.ProcessHandle);
Print(" PopupList.F B = 0x%08lX 0x%08lX\n",
CmdHist.PopupList.Flink, CmdHist.PopupList.Blink);
for (i = 0; i < CmdHist.NumberOfCommands; i++) {
move(pCmd, &(pCmdHist->Commands[i]));
// first get the count of bytes in the string...
moveBlock(DbgCmd, pCmd, sizeof(DbgCmd.Cmd.CommandLength));
// ...then get the string (and the count of bytes again)
moveBlock(DbgCmd, pCmd,
DbgCmd.Cmd.CommandLength + sizeof(DbgCmd.Cmd.CommandLength));
// DebugConvertToAnsi(hCurrentProcess,lpExtensionApis,
// DbgCmd.Cmd.Command, ach);
DbgCmd.Cmd.CommandLength /= sizeof(WCHAR);
DbgCmd.Cmd.Command[DbgCmd.Cmd.CommandLength] = L'\0';
Print(" %03d: %d chars = \"%S\"\n", i,
DbgCmd.Cmd.CommandLength,
DbgCmd.Cmd.Command);
if (i == CmdHist.LastAdded) {
Print(" (Last Added)\n");
} else if (i == CmdHist.LastDisplayed) {
Print(" (Last Displayed)\n");
} else if (i == CmdHist.FirstCommand) {
Print(" (First Command)\n");
}
}
return TRUE;
}
/*
* dmem - Dump Memory Usage
*/
#define HEAP_GRANULARITY 8
#define HEAP_SIZE(Size) (((Size) + (HEAP_GRANULARITY - 1) + HEAP_GRANULARITY) & ~(HEAP_GRANULARITY - 1))
ULONG dmem(
HANDLE hCurrentProcess,
HANDLE hCurrentThread,
DWORD dwCurrentPc,
PWINDBG_EXTENSION_APIS lpExtensionApis,
LPSTR lpArgString)
{
PWINDBG_OUTPUT_ROUTINE Print;
PWINDBG_GET_EXPRESSION EvalExpression;
PWINDBG_GET_SYMBOL GetSymbol;
char ach[120];
char chVerbose;
ULONG i;
ULONG NumberOfConsoleHandles;
PCONSOLE_INFORMATION *ConsoleHandles;
CONSOLE_INFORMATION Console;
PCONSOLE_INFORMATION pConsole = NULL;
SCREEN_INFORMATION Screen;
PSCREEN_INFORMATION pScreen = NULL;
ULONG cbTotal = 0;
ULONG cbConsole = 0;
ULONG cbInput = 0;
ULONG cbOutput = 0;
ULONG cbFE = 0;
Print = lpExtensionApis->lpOutputRoutine;
EvalExpression = lpExtensionApis->lpGetExpressionRoutine;
GetSymbol = lpExtensionApis->lpGetSymbolRoutine;
chVerbose = ' ';
do {
/*
* Skip white space
*/
while (*lpArgString && *lpArgString == ' ')
lpArgString++;
switch (*lpArgString) {
case 'v':
chVerbose = 'v';
break;
case '\0':
/*
* If no console is specified, loop through all of them
*/
moveExpressionValue(NumberOfConsoleHandles,
"winsrv!NumberOfConsoleHandles");
moveExpressionValuePtr(ConsoleHandles,
"winsrv!ConsoleHandles");
for (i = 0; i < NumberOfConsoleHandles; i++) {
move(pConsole, ConsoleHandles);
if (pConsole != NULL) {
sprintf(ach, "%c %p", chVerbose, pConsole);
cbTotal += dmem(hCurrentProcess, hCurrentThread, dwCurrentPc, lpExtensionApis, ach);
Print("==========================================\n");
}
ConsoleHandles++;
}
Print("Total Size for all consoles = %d bytes\n", cbTotal);
return cbTotal;
default:
pConsole = (PCONSOLE_INFORMATION)EvalExpression(lpArgString);
break;
}
lpArgString++;
} while (pConsole == NULL);
move(Console, pConsole);
DebugConvertToAnsi(hCurrentProcess,
lpExtensionApis,
Console.Title,
Console.TitleLength,
ach,
sizeof(ach));
Print("PCONSOLE @ 0x%lX \"%s\"\n", pConsole, ach);
cbConsole = HEAP_SIZE(sizeof(Console)) +
HEAP_SIZE(Console.TitleLength) +
HEAP_SIZE(Console.OriginalTitleLength);
cbInput = HEAP_SIZE(Console.InputBuffer.AllocatedBufferSize);
pScreen = Console.ScreenBuffers;
while (pScreen != NULL) {
move(Screen, pScreen);
cbOutput += HEAP_SIZE(sizeof(Screen));
if (Screen.Flags & CONSOLE_TEXTMODE_BUFFER) {
cbOutput += HEAP_SIZE(Screen.ScreenBufferSize.Y * sizeof(ROW)) +
HEAP_SIZE(Screen.ScreenBufferSize.X * Screen.ScreenBufferSize.Y * sizeof(WCHAR));
if (Screen.BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferCharacter) {
cbFE += HEAP_SIZE(Screen.ScreenBufferSize.X * Screen.ScreenBufferSize.Y * sizeof(WCHAR));
}
if (Screen.BufferInfo.TextInfo.DbcsScreenBuffer.TransBufferAttribute) {
cbFE += HEAP_SIZE(Screen.ScreenBufferSize.X * Screen.ScreenBufferSize.Y * sizeof(BYTE));
}
if (Screen.BufferInfo.TextInfo.DbcsScreenBuffer.TransWriteConsole) {
cbFE += HEAP_SIZE(Screen.ScreenBufferSize.X * Screen.ScreenBufferSize.Y * sizeof(WCHAR));
}
if (Screen.BufferInfo.TextInfo.DbcsScreenBuffer.KAttrRows) {
cbFE += HEAP_SIZE(Screen.ScreenBufferSize.X * Screen.ScreenBufferSize.Y * sizeof(BYTE));
}
}
pScreen = Screen.Next;
}
cbTotal = cbConsole + cbInput + cbOutput + cbFE;
if (chVerbose == 'v') {
Print(" Console Size = %7d\n", cbConsole);
Print(" Input Size = %7d\n", cbInput);
Print(" Output Size = %7d\n", cbOutput);
Print(" FE Size = %7d\n", cbFE);
}
Print("Total Size = %7d\n", cbTotal);
return cbTotal;
}