/***************************** Module Header ******************************\ * Module Name: conexts.c * * Copyright (c) 1985-93, Microsoft Corporation * * This module contains random debugging related functions. * \***************************************************************************/ #include "precomp.h" #pragma hdrstop #define NOEXTAPI #include /***************************************************************************\ * Global variables \***************************************************************************/ PSTR pszAccessViolation = "USEREXTS: Access violation on \"%s\", switch to server context\n"; PSTR pszMoveException = "exception in move()\n"; PSTR pszReadFailure = "lpReadProcessMemoryRoutine 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) (src), &(dst), (size), NULL)) { \ (*lpExtensionApis->lpOutputRoutine)(pszReadFailure); \ return FALSE; \ } \ } else { \ NtReadVirtualMemory(hCurrentProcess, \ (LPVOID)(src), &(dst), (size), NULL); \ } \ } except (EXCEPTION_EXECUTE_HANDLER) { \ (*lpExtensionApis->lpOutputRoutine)(pszMoveException); \ return FALSE; \ } #define moveExpressionValue(dst, src) \ try { \ DWORD dwGlobal = 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 moveExpressionAddress(dst, src) \ try { \ if (lpExtensionApis->nSize >= sizeof(WINDBG_EXTENSION_APIS)) { \ (DWORD)dst = lpExtensionApis->lpGetExpressionRoutine("&"src); \ } else { \ (DWORD)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, LPSTR pdst) { WCHAR awch[80]; ULONG cchText; move(awch, psrc); cchText = wcslen(awch) + 1; if (cchText == 0) { strcpy(pdst, ""); } else { awch[sizeof(awch) / sizeof(WCHAR) - 1] = L'\0'; RtlUnicodeToMultiByteN(pdst, cchText, NULL, awch, cchText * sizeof(WCHAR)); } } 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 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

- Dump Command History\n"); Print("!dcpt [address] - Dump CPTABLEINFO (default: GlyphCP)\n"); Print("!df - Dump font cache\n"); Print("!di

- Dump input buffer info\n"); Print("!dir

- Dump input record ???\n"); Print("!ds - Dump SCREEN_INFORMATION struct\n"); Print("!dt [f] [v[n]] - 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 [f] [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(" 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"); } } 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_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"); moveExpressionValue(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 %lx", chVerbose, chShowFlags, chHistory, pConsole); if (!dc(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); DebugConvertToAnsi(hCurrentProcess,lpExtensionApis,Console.Title, 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, "%lx", 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%08lX\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, &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, 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 ); } 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_GET_SYMBOL GetSymbol; char ach[120]; BOOL fPrintLine; ULONG i, nLines; ULONG NumberOfConsoleHandles; PCONSOLE_INFORMATION *ConsoleHandles; CONSOLE_INFORMATION Console; SCREEN_INFORMATION Screen; PCONSOLE_INFORMATION pConsole; DWORD FrameBufPtr; char chVerbose = ' '; char chShowFlags = ' '; 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 '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"); moveExpressionValue(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 %lx", 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, 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); } 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, 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_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; Print = lpExtensionApis->lpOutputRoutine; EvalExpression = lpExtensionApis->lpGetExpressionRoutine; GetSymbol = lpExtensionApis->lpGetSymbolRoutine; /* * Skip space */ while (*lpArgumentString == ' ') lpArgumentString++; Print("Faces:\n"); moveExpressionValue(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"); moveExpressionValue(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); } 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_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"); moveExpressionValue(ConsoleHandles, "winsrv!ConsoleHandles"); fPrintLine = FALSE; for (i = 0; i < NumberOfConsoleHandles; i++) { move(pConsole, ConsoleHandles); if (pConsole != NULL) { if (fPrintLine) Print("---\n"); pInput = &pConsole->InputBuffer; _itoa((ULONG)pInput, ach, 16); 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_GET_SYMBOL GetSymbol; INPUT_RECORD InputRecord; PINPUT_RECORD pInputRecord; char ach[80]; int cch; LPSTR lpAddress; DWORD NumRecords,i; Print = lpExtensionApis->lpOutputRoutine; EvalExpression = lpExtensionApis->lpGetExpressionRoutine; GetSymbol = lpExtensionApis->lpGetSymbolRoutine; /* * Skip with space */ while (*lpArgumentString == ' ') lpArgumentString++; lpAddress = lpArgumentString; while (*lpArgumentString != ' ' && *lpArgumentString != 0) lpArgumentString++; cch = 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;ilpOutputRoutine; 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 MaxWindowSize.X Y 0x%08X 0x%08X\n" "\t Window.L T R B 0x%08X 0x%08X 0x%08X 0x%08X\n" "\t MaxWindow.X Y 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.MaximumWindowSize.X, (DWORD)Screen.MaximumWindowSize.Y, (DWORD)Screen.Window.Left, (DWORD)Screen.Window.Top, (DWORD)Screen.Window.Right, (DWORD)Screen.Window.Bottom, (DWORD)Screen.MaxWindow.X, (DWORD)Screen.MaxWindow.Y, Screen.ResizingWindow ); Print("\t Attributes 0x%08X\n" "\t PopupAttributes 0x%08X\n" "\t MinX 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 hBackground 0x%08X\n" "\t dwUsage 0x%08X\n" "\t CursorDisplayCount 0x%08X\n" "\t WheelDelta 0x%08X\n", Screen.Attributes, Screen.PopupAttributes, Screen.MinX, Screen.WindowMaximizedX, Screen.WindowMaximizedY, Screen.WindowMaximized, Screen.CommandIdLow, Screen.CommandIdHigh, Screen.CursorHandle, Screen.hPalette, Screen.hBackground, 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" "\t TextInfo.FontSize 0x%04X,0x%04X\n" "\t TextInfo.FontNumber 0x%08X\n", Screen.BufferInfo.TextInfo.Rows, Screen.BufferInfo.TextInfo.TextRows, Screen.BufferInfo.TextInfo.FirstRow, Screen.BufferInfo.TextInfo.FontSize.X, Screen.BufferInfo.TextInfo.FontSize.Y, Screen.BufferInfo.TextInfo.FontNumber); Print("\t TextInfo.Family, Weight 0x%08X, 0x%08X\n" "\t TextInfo.FaceName %ls\n", Screen.BufferInfo.TextInfo.Family, Screen.BufferInfo.TextInfo.Weight, Screen.BufferInfo.TextInfo.FaceName); 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_GET_SYMBOL GetSymbol; PCPTABLEINFO pcpt; CPTABLEINFO cpt; 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) { PNTSD_OUTPUT_ROUTINE Print; PNTSD_GET_EXPRESSION EvalExpression; PNTSD_GET_SYMBOL GetSymbol; PCOMMAND_HISTORY pCmdHist; COMMAND_HISTORY CmdHist; PCOMMAND pCmd; union { COMMAND Cmd; WCHAR awch[80]; } DbgCmd; int i; char ach[120]; 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, 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; }