ReactOS 0.4.15-dev-7788-g1ad9096
kdb_cli.c
Go to the documentation of this file.
1/*
2 * ReactOS kernel
3 * Copyright (C) 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19/*
20 * PROJECT: ReactOS kernel
21 * FILE: ntoskrnl/kdbg/kdb_cli.c
22 * PURPOSE: Kernel debugger command line interface
23 * PROGRAMMER: Gregor Anich (blight@blight.eu.org)
24 * Hervé Poussineau
25 * UPDATE HISTORY:
26 * Created 16/01/2005
27 */
28
29/* INCLUDES ******************************************************************/
30
31#include <ntoskrnl.h>
32#include "kdb.h"
33#include "../kd/kdterminal.h"
34
35#define NDEBUG
36#include "debug.h"
37
38/* DEFINES *******************************************************************/
39
40#define KDB_ENTER_CONDITION_TO_STRING(cond) \
41 ((cond) == KdbDoNotEnter ? "never" : \
42 ((cond) == KdbEnterAlways ? "always" : \
43 ((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
44
45#define KDB_ACCESS_TYPE_TO_STRING(type) \
46 ((type) == KdbAccessRead ? "read" : \
47 ((type) == KdbAccessWrite ? "write" : \
48 ((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
49
50#define NPX_STATE_TO_STRING(state) \
51 ((state) == NPX_STATE_LOADED ? "Loaded" : \
52 ((state) == NPX_STATE_NOT_LOADED ? "Not loaded" : "Unknown"))
53
54/* PROTOTYPES ****************************************************************/
55
56static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]);
57static BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]);
58static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]);
59static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]);
60
61static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]);
62static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]);
63static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]);
65static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]);
66
67static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]);
68static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
69
70static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
71static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
72static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
73#ifdef _M_IX86
74static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
75#endif
76
77static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
78static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
79static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[]);
80static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
81static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
82static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
83
91
92extern char __ImageBase;
93
94#ifdef __ROS_DWARF__
95static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
96#endif
97
98/* Be more descriptive than intrinsics */
99#ifndef Ke386GetGlobalDescriptorTable
100# define Ke386GetGlobalDescriptorTable __sgdt
101#endif
102#ifndef Ke386GetLocalDescriptorTable
103# define Ke386GetLocalDescriptorTable __sldt
104#endif
105
106/* Portability */
109strtoulptr(const char* nptr, char** endptr, int base)
110{
111#ifdef _M_IX86
112 return strtoul(nptr, endptr, base);
113#else
114 return strtoull(nptr, endptr, base);
115#endif
116}
117
118/* GLOBALS *******************************************************************/
119
120typedef
124 IN ULONG Argc,
125 IN PCH Argv[]);
126
128static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
129static BOOLEAN KdbBreakOnModuleLoad = FALSE; /* Set to TRUE to break into KDB when a module is loaded */
130
135
136PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
138
139/* Variables for Dmesg */
140static const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
142static volatile ULONG KdpDmesgCurrentPosition = 0;
143static volatile ULONG KdpDmesgFreeBytes = 0;
144static volatile ULONG KdbDmesgTotalWritten = 0;
147
149
150//
151// Debug Filter Component Table
152//
153#define KD_DEBUG_PRINT_FILTER(Name) \
154 { #Name, DPFLTR_##Name##_ID }
155
156static struct
157{
160}
162{
163//
164// Default components
165//
166 { "WIN2000", MAXULONG },
168//
169// Standard components
170//
176 KD_DEBUG_PRINT_FILTER(CRASHDUMP),
177 KD_DEBUG_PRINT_FILTER(CDAUDIO),
179 KD_DEBUG_PRINT_FILTER(CLASSPNP),
181 KD_DEBUG_PRINT_FILTER(REDBOOK),
182 KD_DEBUG_PRINT_FILTER(STORPROP),
183 KD_DEBUG_PRINT_FILTER(SCSIPORT),
184 KD_DEBUG_PRINT_FILTER(SCSIMINIPORT),
185 KD_DEBUG_PRINT_FILTER(CONFIG),
186 KD_DEBUG_PRINT_FILTER(I8042PRT),
187 KD_DEBUG_PRINT_FILTER(SERMOUSE),
188 KD_DEBUG_PRINT_FILTER(LSERMOUS),
189 KD_DEBUG_PRINT_FILTER(KBDHID),
190 KD_DEBUG_PRINT_FILTER(MOUHID),
191 KD_DEBUG_PRINT_FILTER(KBDCLASS),
192 KD_DEBUG_PRINT_FILTER(MOUCLASS),
193 KD_DEBUG_PRINT_FILTER(TWOTRACK),
194 KD_DEBUG_PRINT_FILTER(WMILIB),
197 KD_DEBUG_PRINT_FILTER(HALIA64),
199 KD_DEBUG_PRINT_FILTER(SVCHOST),
200 KD_DEBUG_PRINT_FILTER(VIDEOPRT),
202 KD_DEBUG_PRINT_FILTER(DMSYNTH),
203 KD_DEBUG_PRINT_FILTER(NTOSPNP),
204 KD_DEBUG_PRINT_FILTER(FASTFAT),
206 KD_DEBUG_PRINT_FILTER(PNPMGR),
207 KD_DEBUG_PRINT_FILTER(NETAPI),
208 KD_DEBUG_PRINT_FILTER(SCSERVER),
209 KD_DEBUG_PRINT_FILTER(SCCLIENT),
210 KD_DEBUG_PRINT_FILTER(SERIAL),
211 KD_DEBUG_PRINT_FILTER(SERENUM),
213 KD_DEBUG_PRINT_FILTER(RPCPROXY),
214 KD_DEBUG_PRINT_FILTER(AUTOCHK),
215 KD_DEBUG_PRINT_FILTER(DCOMSS),
216 KD_DEBUG_PRINT_FILTER(UNIMODEM),
218 KD_DEBUG_PRINT_FILTER(FLTMGR),
219 KD_DEBUG_PRINT_FILTER(WMICORE),
220 KD_DEBUG_PRINT_FILTER(BURNENG),
223 KD_DEBUG_PRINT_FILTER(FUSION),
224 KD_DEBUG_PRINT_FILTER(IDLETASK),
225 KD_DEBUG_PRINT_FILTER(SOFTPCI),
229 KD_DEBUG_PRINT_FILTER(PCIIDE),
230 KD_DEBUG_PRINT_FILTER(FLOPPY),
232 KD_DEBUG_PRINT_FILTER(TERMSRV),
233 KD_DEBUG_PRINT_FILTER(W32TIME),
234 KD_DEBUG_PRINT_FILTER(PREFETCHER),
235 KD_DEBUG_PRINT_FILTER(RSFILTER),
236 KD_DEBUG_PRINT_FILTER(FCPORT),
239 KD_DEBUG_PRINT_FILTER(DMCONFIG),
240 KD_DEBUG_PRINT_FILTER(DMADMIN),
241 KD_DEBUG_PRINT_FILTER(WSOCKTRANSPORT),
243 KD_DEBUG_PRINT_FILTER(PNPMEM),
244 KD_DEBUG_PRINT_FILTER(PROCESSOR),
245 KD_DEBUG_PRINT_FILTER(DMSERVER),
247 KD_DEBUG_PRINT_FILTER(INFINIBAND),
248 KD_DEBUG_PRINT_FILTER(IHVDRIVER),
249 KD_DEBUG_PRINT_FILTER(IHVVIDEO),
250 KD_DEBUG_PRINT_FILTER(IHVAUDIO),
251 KD_DEBUG_PRINT_FILTER(IHVNETWORK),
252 KD_DEBUG_PRINT_FILTER(IHVSTREAMING),
253 KD_DEBUG_PRINT_FILTER(IHVBUS),
255 KD_DEBUG_PRINT_FILTER(RTLTHREADPOOL),
257 KD_DEBUG_PRINT_FILTER(TCPIP6),
258 KD_DEBUG_PRINT_FILTER(ISAPNP),
260 KD_DEBUG_PRINT_FILTER(STORPORT),
261 KD_DEBUG_PRINT_FILTER(STORMINIPORT),
262 KD_DEBUG_PRINT_FILTER(PRINTSPOOLER),
263 KD_DEBUG_PRINT_FILTER(VSSDYNDISK),
264 KD_DEBUG_PRINT_FILTER(VERIFIER),
266 KD_DEBUG_PRINT_FILTER(VDSBAS),
267 KD_DEBUG_PRINT_FILTER(VDSDYN), // Specified in Vista+
268 KD_DEBUG_PRINT_FILTER(VDSDYNDR),
269 KD_DEBUG_PRINT_FILTER(VDSLDR), // Specified in Vista+
270 KD_DEBUG_PRINT_FILTER(VDSUTIL),
271 KD_DEBUG_PRINT_FILTER(DFRGIFC),
275//
276// Components specified in Vista+, some of which we also use in ReactOS
277//
280 KD_DEBUG_PRINT_FILTER(PERFLIB),
282 KD_DEBUG_PRINT_FILTER(IOSTRESS),
285 KD_DEBUG_PRINT_FILTER(USERGDI),
288 KD_DEBUG_PRINT_FILTER(THREADORDER),
289 KD_DEBUG_PRINT_FILTER(ENVIRON),
292 KD_DEBUG_PRINT_FILTER(FVEVOL),
294 KD_DEBUG_PRINT_FILTER(NVCTRACE),
296 KD_DEBUG_PRINT_FILTER(APPCOMPAT),
297 KD_DEBUG_PRINT_FILTER(USBSTOR),
298 KD_DEBUG_PRINT_FILTER(SBP2PORT),
300 KD_DEBUG_PRINT_FILTER(CACHEMGR),
301 KD_DEBUG_PRINT_FILTER(MOUNTMGR),
304 KD_DEBUG_PRINT_FILTER(KSECDD),
305 KD_DEBUG_PRINT_FILTER(FLTREGRESS),
310 KD_DEBUG_PRINT_FILTER(STORVSP),
312 KD_DEBUG_PRINT_FILTER(SSPICLI),
315 KD_DEBUG_PRINT_FILTER(FILETRACE),
318 KD_DEBUG_PRINT_FILTER(DRIVEEXTENDER),
319//
320// Components specified in Windows 8
321//
323 KD_DEBUG_PRINT_FILTER(CRASHDUMPXHCI),
327//
328// Components specified in Windows 10
329//
330 KD_DEBUG_PRINT_FILTER(CAPIMG),
332 KD_DEBUG_PRINT_FILTER(STORAGECLASSMEMORY),
335#undef KD_DEBUG_PRINT_FILTER
336
337//
338// Command Table
339//
340static const struct
341{
342 PCHAR Name;
345 BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
347 /* Data */
348 { NULL, NULL, "Data", NULL },
349 { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
350#ifdef _M_IX86 // FIXME: this is broken on x64
351 { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
352#endif // _M_IX86
353 { "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX },
354 { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
355 { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
356 { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
357 { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame address.", KdbpCmdBackTrace },
358#ifdef __ROS_DWARF__
359 { "dt", "dt [mod] [type] [addr]", "Print a struct. The address is optional.", KdbpCmdPrintStruct },
360#endif
361 /* Flow control */
362 { NULL, NULL, "Flow control", NULL },
363 { "cont", "cont", "Continue execution (leave debugger).", KdbpCmdContinue },
364 { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
365 { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
366 { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
367 { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
368 { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
369 { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
370 { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
371 { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
372
373 /* Process/Thread */
374 { NULL, NULL, "Process/Thread", NULL },
375 { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
376 { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
377
378 /* System information */
379 { NULL, NULL, "System info", NULL },
380 { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
381 { "gdt", "gdt", "Display the global descriptor table.", KdbpCmdGdtLdtIdt },
382 { "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
383 { "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
384 { "pcr", "pcr", "Display the processor control region.", KdbpCmdPcr },
385#ifdef _M_IX86
386 { "tss", "tss [selector|*descaddr]", "Display the current task state segment, or the one specified by its selector number or descriptor address.", KdbpCmdTss },
387#endif
388
389 /* Others */
390 { NULL, NULL, "Others", NULL },
391 { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
392 { "reboot", "reboot", "Reboots the system.", KdbpCmdReboot},
393 { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels.", KdbpCmdFilter },
394 { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
395 { "dmesg", "dmesg", "Display debug messages on screen, with navigation on pages.", KdbpCmdDmesg },
396 { "kmsg", "kmsg", "Kernel dmesg. Alias for dmesg.", KdbpCmdDmesg },
397 { "help", "help", "Display help screen.", KdbpCmdHelp },
398 { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool },
399 { "!poolused", "!poolused [Flags [Tag]]", "Display pool usage.", ExpKdbgExtPoolUsed },
400 { "!poolfind", "!poolfind Tag [Pool]", "Search for pool tag allocations.", ExpKdbgExtPoolFind },
401 { "!filecache", "!filecache", "Display cache usage.", ExpKdbgExtFileCache },
402 { "!defwrites", "!defwrites", "Display cache write values.", ExpKdbgExtDefWrites },
403 { "!irpfind", "!irpfind [Pool [startaddress [criteria data]]]", "Lists IRPs potentially matching criteria.", ExpKdbgExtIrpFind },
404 { "!handle", "!handle [Handle]", "Displays info about handles.", ExpKdbgExtHandle },
406
407/* FUNCTIONS *****************************************************************/
408
421static BOOLEAN
424 IN LONG ErrOffset,
426{
427 static CHAR ErrMsgBuffer[130] = "^ ";
428 LONG ExpressionErrOffset = -1;
429 PCHAR ErrMsg = ErrMsgBuffer;
430 BOOLEAN Ok;
431
433 &ExpressionErrOffset, ErrMsgBuffer + 2);
434 if (!Ok)
435 {
436 if (ExpressionErrOffset >= 0)
437 ExpressionErrOffset += ErrOffset;
438 else
439 ErrMsg += 2;
440
441 KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
442 }
443
444 return Ok;
445}
446
448NTAPI
450 IN PCHAR pszNum,
451 OUT ULONG_PTR *pulValue)
452{
453 char *endptr;
454
455 /* Skip optional '0x' prefix */
456 if ((pszNum[0] == '0') && ((pszNum[1] == 'x') || (pszNum[1] == 'X')))
457 pszNum += 2;
458
459 /* Make a number from the string (hex) */
460 *pulValue = strtoul(pszNum, &endptr, 16);
461
462 return (*endptr == '\0');
463}
464
467static BOOLEAN
469 ULONG Argc,
470 PCHAR Argv[])
471{
472 ULONG i;
473 SIZE_T len;
474 ULONGLONG Result = 0;
475 ULONG ul;
476 LONG l = 0;
477 BOOLEAN Ok;
478
479 if (Argc < 2)
480 {
481 KdbpPrint("?: Argument required\n");
482 return TRUE;
483 }
484
485 /* Put the arguments back together */
486 Argc--;
487 for (i = 1; i < Argc; i++)
488 {
489 len = strlen(Argv[i]);
490 Argv[i][len] = ' ';
491 }
492
493 /* Evaluate the expression */
494 Ok = KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result);
495 if (Ok)
496 {
497 if (Result > 0x00000000ffffffffLL)
498 {
499 if (Result & 0x8000000000000000LL)
500 KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
501 else
502 KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
503 }
504 else
505 {
506 ul = (ULONG)Result;
507
508 if (ul <= 0xff && ul >= 0x80)
509 l = (LONG)((CHAR)ul);
510 else if (ul <= 0xffff && ul >= 0x8000)
511 l = (LONG)((SHORT)ul);
512 else
513 l = (LONG)ul;
514
515 if (l < 0)
516 KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
517 else
518 KdbpPrint("0x%08lx %10lu\n", ul, ul);
519 }
520 }
521
522 return TRUE;
523}
524
525#ifdef __ROS_DWARF__
526
529static VOID
530KdbpPrintStructInternal
532 PCHAR Indent,
533 BOOLEAN DoRead,
535 PROSSYM_AGGREGATE Aggregate)
536{
537 ULONG i;
540 ULONG IndentLen = strlen(Indent);
541 ROSSYM_AGGREGATE MemberAggregate = {0 };
542
543 for (i = 0; i < Aggregate->NumElements; i++) {
544 Member = &Aggregate->Elements[i];
545 KdbpPrint("%s%p+%x: %s", Indent, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size, Member->Name ? Member->Name : "<anoymous>");
546 if (DoRead) {
547 if (!strcmp(Member->Type, "_UNICODE_STRING")) {
548 KdbpPrint("\"");
550 KdbpPrint("\"\n");
551 continue;
552 } else if (!strcmp(Member->Type, "PUNICODE_STRING")) {
553 KdbpPrint("\"");
555 KdbpPrint("\"\n");
556 continue;
557 }
558 switch (Member->Size) {
559 case 1:
560 case 2:
561 case 4:
562 case 8: {
563 Result = 0;
564 if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
565 if (Member->Bits) {
566 Result >>= Member->FirstBit;
567 Result &= ((1 << Member->Bits) - 1);
568 }
569 KdbpPrint(" %lx\n", Result);
570 }
571 else goto readfail;
572 break;
573 }
574 default: {
575 if (Member->Size < 8) {
576 if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
577 ULONG j;
578 for (j = 0; j < Member->Size; j++) {
579 KdbpPrint(" %02x", (int)(Result & 0xff));
580 Result >>= 8;
581 }
582 } else goto readfail;
583 } else {
584 KdbpPrint(" %s @ %p {\n", Member->Type, ((PCHAR)BaseAddress) + Member->BaseOffset);
585 Indent[IndentLen] = ' ';
586 if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
587 KdbpPrintStructInternal(Info, Indent, DoRead, ((PCHAR)BaseAddress) + Member->BaseOffset, &MemberAggregate);
588 RosSymFreeAggregate(&MemberAggregate);
589 }
590 Indent[IndentLen] = 0;
591 KdbpPrint("%s}\n", Indent);
592 } break;
593 }
594 }
595 } else {
596 readfail:
597 if (Member->Size <= 8) {
598 KdbpPrint(" ??\n");
599 } else {
600 KdbpPrint(" %s @ %x {\n", Member->Type, Member->BaseOffset);
601 Indent[IndentLen] = ' ';
602 if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
603 KdbpPrintStructInternal(Info, Indent, DoRead, BaseAddress, &MemberAggregate);
604 RosSymFreeAggregate(&MemberAggregate);
605 }
606 Indent[IndentLen] = 0;
607 KdbpPrint("%s}\n", Indent);
608 }
609 }
610 }
611}
612
613PROSSYM_INFO KdbpSymFindCachedFile(PUNICODE_STRING ModName);
614
615static BOOLEAN
616KdbpCmdPrintStruct(
617 ULONG Argc,
618 PCHAR Argv[])
619{
620 ULONG i;
621 ULONGLONG Result = 0;
622 PVOID BaseAddress = 0;
623 ROSSYM_AGGREGATE Aggregate = {0};
624 UNICODE_STRING ModName = {0};
625 ANSI_STRING AnsiName = {0};
626 CHAR Indent[100] = {0};
628
629 if (Argc < 3) goto end;
630 AnsiName.Length = AnsiName.MaximumLength = strlen(Argv[1]);
631 AnsiName.Buffer = Argv[1];
632 RtlAnsiStringToUnicodeString(&ModName, &AnsiName, TRUE);
633 Info = KdbpSymFindCachedFile(&ModName);
634
635 if (!Info || !RosSymAggregate(Info, Argv[2], &Aggregate)) {
636 DPRINT1("Could not get aggregate\n");
637 goto end;
638 }
639
640 // Get an argument for location if it was given
641 if (Argc > 3) {
642 ULONG len;
643 PCHAR ArgStart = Argv[3];
644 DPRINT1("Trying to get expression\n");
645 for (i = 3; i < Argc - 1; i++)
646 {
647 len = strlen(Argv[i]);
648 Argv[i][len] = ' ';
649 }
650
651 /* Evaluate the expression */
652 DPRINT1("Arg: %s\n", ArgStart);
653 if (KdbpEvaluateExpression(ArgStart, strlen(ArgStart), &Result)) {
655 DPRINT1("BaseAddress: %p\n", BaseAddress);
656 }
657 }
658 DPRINT1("BaseAddress: %p\n", BaseAddress);
659 KdbpPrintStructInternal(Info, Indent, !!BaseAddress, BaseAddress, &Aggregate);
660end:
661 RosSymFreeAggregate(&Aggregate);
662 RtlFreeUnicodeString(&ModName);
663 return TRUE;
664}
665#endif
666
675static BOOLEAN
677 IN PCSTR ComponentName,
679{
680 ULONG i;
681
682 for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
683 {
684 if (_stricmp(ComponentName, ComponentTable[i].Name) == 0)
685 {
687 return TRUE;
688 }
689 }
690
691 return FALSE;
692}
693
696static BOOLEAN
698 ULONG Argc,
699 PCHAR Argv[])
700{
702 ULONG set = DPFLTR_MASK, clear = DPFLTR_MASK;
703 PCHAR pend;
704 PCSTR opt, p;
705
706 static struct
707 {
708 PCSTR Name;
709 ULONG Level;
710 }
711 debug_classes[] =
712 {
713 { "error", 1 << DPFLTR_ERROR_LEVEL },
714 { "warning", 1 << DPFLTR_WARNING_LEVEL },
715 { "trace", 1 << DPFLTR_TRACE_LEVEL },
716 { "info", 1 << DPFLTR_INFO_LEVEL },
717 };
718
719 if (Argc <= 1)
720 {
721 /* Display the list of available debug filter components */
722 KdbpPrint("REMARKS:\n"
723 "- The 'WIN2000' system-wide debug filter component is used for DbgPrint()\n"
724 " messages without Component ID and Level.\n"
725 "- The 'DEFAULT' debug filter component is used for DbgPrint() messages with\n"
726 " an unknown Component ID.\n\n");
727 KdbpPrint("The list of debug filter components currently available on your system is:\n\n");
728 KdbpPrint(" Component Name Component ID\n"
729 " ================== ================\n");
730 for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
731 {
732 KdbpPrint("%20s 0x%08lx\n", ComponentTable[i].Name, ComponentTable[i].Id);
733 }
734 return TRUE;
735 }
736
737 for (i = 1; i < Argc; i++)
738 {
739 opt = Argv[i];
740 p = opt + strcspn(opt, "+-");
741 if (!p[0]) p = opt; /* Assume it's a debug channel name */
742
743 if (p > opt)
744 {
745 for (j = 0; j < RTL_NUMBER_OF(debug_classes); j++)
746 {
748 if (len != (p - opt))
749 continue;
750 if (_strnicmp(opt, debug_classes[j].Name, len) == 0) /* Found it */
751 {
752 if (*p == '+')
753 set |= debug_classes[j].Level;
754 else
755 clear |= debug_classes[j].Level;
756 break;
757 }
758 }
760 {
761 Level = strtoul(opt, &pend, 0);
762 if (pend != p)
763 {
764 KdbpPrint("filter: bad class name '%.*s'\n", p - opt, opt);
765 continue;
766 }
767 if (*p == '+')
768 set |= Level;
769 else
770 clear |= Level;
771 }
772 }
773 else
774 {
775 if (*p == '-')
776 clear = MAXULONG;
777 else
778 set = MAXULONG;
779 }
780 if (*p == '+' || *p == '-')
781 p++;
782
784 {
785 KdbpPrint("filter: '%s' is not a valid component name!\n", p);
786 return TRUE;
787 }
788
789 /* Get current mask value */
792 }
793
794 return TRUE;
795}
796
800static BOOLEAN
802 ULONG Argc,
803 PCHAR Argv[])
804{
805 ULONG Count;
806 ULONG ul;
807 INT i;
808 ULONGLONG Result = 0;
810 LONG InstLen;
811
812 if (Argv[0][0] == 'x') /* display memory */
813 Count = 16;
814 else /* disassemble */
815 Count = 10;
816
817 if (Argc >= 2)
818 {
819 /* Check for [L count] part */
820 ul = 0;
821 if (strcmp(Argv[Argc-2], "L") == 0)
822 {
823 ul = strtoul(Argv[Argc-1], NULL, 0);
824 if (ul > 0)
825 {
826 Count = ul;
827 Argc -= 2;
828 }
829 }
830 else if (Argv[Argc-1][0] == 'L')
831 {
832 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
833 if (ul > 0)
834 {
835 Count = ul;
836 Argc--;
837 }
838 }
839
840 /* Put the remaining arguments back together */
841 Argc--;
842 for (ul = 1; ul < Argc; ul++)
843 {
844 Argv[ul][strlen(Argv[ul])] = ' ';
845 }
846 Argc++;
847 }
848
849 /* Evaluate the expression */
850 if (Argc > 1)
851 {
852 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
853 return TRUE;
854
855 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
856 KdbpPrint("Warning: Address %I64x is beeing truncated\n",Result);
857
859 }
860 else if (Argv[0][0] == 'x')
861 {
862 KdbpPrint("x: Address argument required.\n");
863 return TRUE;
864 }
865
866 if (Argv[0][0] == 'x')
867 {
868 /* Display dwords */
869 ul = 0;
870
871 while (Count > 0)
872 {
874 KdbpPrint("<%p>:", (PVOID)Address);
875 else
876 KdbpPrint(":");
877
878 i = min(4, Count);
879 Count -= i;
880
881 while (--i >= 0)
882 {
883 if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
884 KdbpPrint(" ????????");
885 else
886 KdbpPrint(" %08x", ul);
887
888 Address += sizeof(ul);
889 }
890
891 KdbpPrint("\n");
892 }
893 }
894 else
895 {
896 /* Disassemble */
897 while (Count-- > 0)
898 {
900 KdbpPrint("<%08x>: ", Address);
901 else
902 KdbpPrint(": ");
903
905 if (InstLen < 0)
906 {
907 KdbpPrint("<INVALID>\n");
908 return TRUE;
909 }
910
911 KdbpPrint("\n");
912 Address += InstLen;
913 }
914 }
915
916 return TRUE;
917}
918
921static BOOLEAN
923 ULONG Argc,
924 PCHAR Argv[])
925{
927 INT i;
928 static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
929 " ZF", " SF", " TF", " IF", " DF", " OF",
930 NULL, NULL, " NT", " BIT15", " RF", " VF",
931 " AC", " VIF", " VIP", " ID", " BIT22",
932 " BIT23", " BIT24", " BIT25", " BIT26",
933 " BIT27", " BIT28", " BIT29", " BIT30",
934 " BIT31" };
935
936 if (Argv[0][0] == 'r') /* regs */
937 {
938#ifdef _M_IX86
939 KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
940 "SS:ESP 0x%04x:0x%08x\n"
941 " EAX 0x%08x EBX 0x%08x\n"
942 " ECX 0x%08x EDX 0x%08x\n"
943 " ESI 0x%08x EDI 0x%08x\n"
944 " EBP 0x%08x\n",
945 Context->SegCs & 0xFFFF, Context->Eip,
946 Context->SegSs, Context->Esp,
947 Context->Eax, Context->Ebx,
948 Context->Ecx, Context->Edx,
949 Context->Esi, Context->Edi,
950 Context->Ebp);
951#else
952 KdbpPrint("CS:RIP 0x%04x:0x%p\n"
953 "SS:RSP 0x%04x:0x%p\n"
954 " RAX 0x%p RBX 0x%p\n"
955 " RCX 0x%p RDX 0x%p\n"
956 " RSI 0x%p RDI 0x%p\n"
957 " RBP 0x%p\n",
958 Context->SegCs & 0xFFFF, Context->Rip,
959 Context->SegSs, Context->Rsp,
960 Context->Rax, Context->Rbx,
961 Context->Rcx, Context->Rdx,
962 Context->Rsi, Context->Rdi,
963 Context->Rbp);
964#endif
965 /* Display the EFlags */
966 KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
967 for (i = 0; i < 32; i++)
968 {
969 if (i == 1)
970 {
971 if ((Context->EFlags & (1 << 1)) == 0)
972 KdbpPrint(" !BIT1");
973 }
974 else if (i == 12)
975 {
976 KdbpPrint(" IOPL%d", (Context->EFlags >> 12) & 3);
977 }
978 else if (i == 13)
979 {
980 }
981 else if ((Context->EFlags & (1 << i)) != 0)
982 {
983 KdbpPrint(EflagsBits[i]);
984 }
985 }
986 KdbpPrint("\n");
987 }
988 else if (Argv[0][0] == 's') /* sregs */
989 {
990 KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
991 Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
992 (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
993 KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
994 Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
995 KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
996 Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
997 KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
998 Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
999 KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
1000 Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1001 KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1002 Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1003 }
1004 else /* dregs */
1005 {
1006 ASSERT(Argv[0][0] == 'd');
1007 KdbpPrint("DR0 0x%08x\n"
1008 "DR1 0x%08x\n"
1009 "DR2 0x%08x\n"
1010 "DR3 0x%08x\n"
1011 "DR6 0x%08x\n"
1012 "DR7 0x%08x\n",
1013 Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1014 Context->Dr6, Context->Dr7);
1015 }
1016
1017 return TRUE;
1018}
1019
1020#ifdef _M_IX86
1021static PKTSS
1022KdbpRetrieveTss(
1023 IN USHORT TssSelector,
1024 OUT PULONG pType OPTIONAL,
1025 IN PKDESCRIPTOR pGdtr OPTIONAL)
1026{
1027 KDESCRIPTOR Gdtr;
1028 KGDTENTRY Desc;
1029 PKTSS Tss;
1030
1031 /* Retrieve the Global Descriptor Table (user-provided or system) */
1032 if (pGdtr)
1033 Gdtr = *pGdtr;
1034 else
1036
1037 /* Check limits */
1038 if ((TssSelector & (sizeof(KGDTENTRY) - 1)) ||
1039 (TssSelector < sizeof(KGDTENTRY)) ||
1040 (TssSelector + sizeof(KGDTENTRY) - 1 > Gdtr.Limit))
1041 {
1042 return NULL;
1043 }
1044
1045 /* Retrieve the descriptor */
1046 if (!NT_SUCCESS(KdbpSafeReadMemory(&Desc,
1047 (PVOID)(Gdtr.Base + TssSelector),
1048 sizeof(KGDTENTRY))))
1049 {
1050 return NULL;
1051 }
1052
1053 /* Check for TSS32(Avl) or TSS32(Busy) */
1054 if (Desc.HighWord.Bits.Type != 9 && Desc.HighWord.Bits.Type != 11)
1055 {
1056 return NULL;
1057 }
1058 if (pType) *pType = Desc.HighWord.Bits.Type;
1059
1060 Tss = (PKTSS)(ULONG_PTR)(Desc.BaseLow |
1061 Desc.HighWord.Bytes.BaseMid << 16 |
1062 Desc.HighWord.Bytes.BaseHi << 24);
1063
1064 return Tss;
1065}
1066
1068KdbpIsNestedTss(
1069 IN USHORT TssSelector,
1070 IN PKTSS Tss)
1071{
1072 USHORT Backlink;
1073
1074 if (!Tss)
1075 return FALSE;
1076
1077#ifdef _M_AMD64
1078 // HACK
1079 return FALSE;
1080#else
1081 /* Retrieve the TSS Backlink */
1082 if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1083 (PVOID)&Tss->Backlink,
1084 sizeof(USHORT))))
1085 {
1086 return FALSE;
1087 }
1088#endif
1089
1090 return (Backlink != 0 && Backlink != TssSelector);
1091}
1092
1093static BOOLEAN
1094KdbpContextFromPrevTss(
1096 OUT PUSHORT TssSelector,
1097 IN OUT PKTSS* pTss,
1098 IN PKDESCRIPTOR pGdtr)
1099{
1100 ULONG_PTR Eip, Ebp;
1101 USHORT Backlink;
1102 PKTSS Tss = *pTss;
1103
1104#ifdef _M_AMD64
1105 // HACK
1106 return FALSE;
1107#else
1108 /* Retrieve the TSS Backlink */
1109 if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1110 (PVOID)&Tss->Backlink,
1111 sizeof(USHORT))))
1112 {
1113 return FALSE;
1114 }
1115
1116 /* Retrieve the parent TSS */
1117 Tss = KdbpRetrieveTss(Backlink, NULL, pGdtr);
1118 if (!Tss)
1119 return FALSE;
1120
1122 (PVOID)&Tss->Eip,
1123 sizeof(ULONG_PTR))))
1124 {
1125 return FALSE;
1126 }
1127
1129 (PVOID)&Tss->Ebp,
1130 sizeof(ULONG_PTR))))
1131 {
1132 return FALSE;
1133 }
1134
1135 /* Return the parent TSS and its trap frame */
1136 *TssSelector = Backlink;
1137 *pTss = Tss;
1138 Context->Eip = Eip;
1139 Context->Ebp = Ebp;
1140#endif
1141 return TRUE;
1142}
1143#endif
1144
1145#ifdef _M_AMD64
1146
1147static
1148BOOLEAN
1149GetNextFrame(
1151{
1152 PRUNTIME_FUNCTION FunctionEntry;
1153 ULONG64 ImageBase, EstablisherFrame;
1154 PVOID HandlerData;
1155
1156 _SEH2_TRY
1157 {
1158 /* Lookup the FunctionEntry for the current RIP */
1159 FunctionEntry = RtlLookupFunctionEntry(Context->Rip, &ImageBase, NULL);
1160 if (FunctionEntry == NULL)
1161 {
1162 /* No function entry, so this must be a leaf function. Pop the return address from the stack.
1163 Note: this can happen after the first frame as the result of an exception */
1164 Context->Rip = *(DWORD64*)Context->Rsp;
1165 Context->Rsp += sizeof(DWORD64);
1166 return TRUE;
1167 }
1168 else
1169 {
1171 ImageBase,
1172 Context->Rip,
1173 FunctionEntry,
1174 Context,
1175 &HandlerData,
1177 NULL);
1178 }
1179 }
1180 _SEH2_EXCEPT(1)
1181 {
1182 return FALSE;
1183 }
1184 _SEH2_END
1185
1186 return TRUE;
1187}
1188
1189static BOOLEAN
1191 ULONG Argc,
1192 PCHAR Argv[])
1193{
1195
1196 /* Walk through the frames */
1197 KdbpPrint("Frames:\n");
1198 do
1199 {
1200 BOOLEAN GotNextFrame;
1201
1202 KdbpPrint("[%p] ", (PVOID)Context.Rsp);
1203
1204 /* Print the location after the call instruction */
1206 KdbpPrint("<%p>", (PVOID)Context.Rip);
1207 KdbpPrint("\n");
1208
1209 if (KdbOutputAborted)
1210 break;
1211
1212 GotNextFrame = GetNextFrame(&Context);
1213 if (!GotNextFrame)
1214 {
1215 KdbpPrint("Couldn't get next frame\n");
1216 break;
1217 }
1218 } while ((Context.Rip != 0) && (Context.Rsp != 0));
1219
1220 return TRUE;
1221}
1222#else
1225static BOOLEAN
1227 ULONG Argc,
1228 PCHAR Argv[])
1229{
1230 ULONG ul;
1231 ULONGLONG Result = 0;
1235
1236 if (Argc >= 2)
1237 {
1238 /* Check for [L count] part */
1239 ul = 0;
1240 if (strcmp(Argv[Argc-2], "L") == 0)
1241 {
1242 ul = strtoul(Argv[Argc-1], NULL, 0);
1243 if (ul > 0)
1244 {
1245 Argc -= 2;
1246 }
1247 }
1248 else if (Argv[Argc-1][0] == 'L')
1249 {
1250 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1251 if (ul > 0)
1252 {
1253 Argc--;
1254 }
1255 }
1256
1257 /* Put the remaining arguments back together */
1258 Argc--;
1259 for (ul = 1; ul < Argc; ul++)
1260 {
1261 Argv[ul][strlen(Argv[ul])] = ' ';
1262 }
1263 Argc++;
1264 }
1265
1266 /* Check if a Frame Address or Thread ID is given */
1267 if (Argc > 1)
1268 {
1269 if (Argv[1][0] == '*')
1270 {
1271 Argv[1]++;
1272
1273 /* Evaluate the expression */
1274 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
1275 return TRUE;
1276
1277 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1278 KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1279
1280 Frame = (ULONG_PTR)Result;
1281 }
1282 else
1283 {
1284 KdbpPrint("Thread backtrace not supported yet!\n");
1285 return TRUE;
1286 }
1287 }
1288
1289#ifdef _M_IX86
1290 KDESCRIPTOR Gdtr;
1291 USHORT TssSelector;
1292 PKTSS Tss;
1293
1294 /* Retrieve the Global Descriptor Table */
1296
1297 /* Retrieve the current (active) TSS */
1298 TssSelector = Ke386GetTr();
1299 Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1300 if (KdbpIsNestedTss(TssSelector, Tss))
1301 {
1302 /* Display the active TSS if it is nested */
1303 KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1304 }
1305#endif
1306
1307 /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1308 if (Argc <= 1)
1309 {
1310 KdbpPrint("Eip:\n");
1312 KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1313 else
1314 KdbpPrint("\n");
1315 }
1316
1317 /* Walk through the frames */
1318 KdbpPrint("Frames:\n");
1319 for (;;)
1320 {
1321 BOOLEAN GotNextFrame;
1322
1323 if (Frame == 0)
1324 goto CheckForParentTSS;
1325
1326 Address = 0;
1327 if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1328 {
1329 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1330 goto CheckForParentTSS;
1331 }
1332
1333 if (Address == 0)
1334 goto CheckForParentTSS;
1335
1336 GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1337 if (GotNextFrame)
1338 {
1340 }
1341 // else
1342 // Frame = 0;
1343
1344 /* Print the location of the call instruction (assumed 5 bytes length) */
1345 if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1346 KdbpPrint("<%08x>\n", Address);
1347 else
1348 KdbpPrint("\n");
1349
1350 if (KdbOutputAborted)
1351 break;
1352
1353 if (!GotNextFrame)
1354 {
1355 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1356 goto CheckForParentTSS; // break;
1357 }
1358
1359 continue;
1360
1361CheckForParentTSS:
1362#ifndef _M_IX86
1363 break;
1364#else
1365 /*
1366 * We have ended the stack walking for the current (active) TSS.
1367 * Check whether this TSS was nested, and if so switch to its parent
1368 * and walk its stack.
1369 */
1370 if (!KdbpIsNestedTss(TssSelector, Tss))
1371 break; // The TSS is not nested, we stop there.
1372
1373 GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1374 if (!GotNextFrame)
1375 {
1376 KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1377 break; // Cannot retrieve the parent TSS, we stop there.
1378 }
1379
1380
1381 Address = Context.Eip;
1382 Frame = Context.Ebp;
1383
1384 KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1385
1387 KdbpPrint("<%08x>\n", Address);
1388 else
1389 KdbpPrint("\n");
1390#endif
1391 }
1392
1393 return TRUE;
1394}
1395
1396#endif // M_AMD64
1397
1400static BOOLEAN
1402 ULONG Argc,
1403 PCHAR Argv[])
1404{
1405 /* Exit the main loop */
1406 return FALSE;
1407}
1408
1411static BOOLEAN
1413 ULONG Argc,
1414 PCHAR Argv[])
1415{
1416 ULONG Count = 1;
1417
1418 if (Argc > 1)
1419 {
1420 Count = strtoul(Argv[1], NULL, 0);
1421 if (Count == 0)
1422 {
1423 KdbpPrint("%s: Integer argument required\n", Argv[0]);
1424 return TRUE;
1425 }
1426 }
1427
1428 if (Argv[0][0] == 'n')
1430 else
1432
1433 /* Set the number of single steps and return to the interrupted code. */
1435
1436 return FALSE;
1437}
1438
1441static BOOLEAN
1443 ULONG Argc,
1444 PCHAR Argv[])
1445{
1446 LONG l;
1447 ULONG_PTR Address = 0;
1449 KDB_ACCESS_TYPE AccessType = 0;
1450 UCHAR Size = 0;
1451 UCHAR DebugReg = 0;
1455 PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
1456 CHAR Buffer[20];
1457
1459 if (l < 0)
1460 {
1461 KdbpPrint("No breakpoints.\n");
1462 return TRUE;
1463 }
1464
1465 KdbpPrint("Breakpoints:\n");
1466 do
1467 {
1468 if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
1469 &Enabled, &Global, &Process, &ConditionExpr))
1470 {
1471 continue;
1472 }
1473
1474 if (l == KdbLastBreakPointNr)
1475 {
1476 str1 = "\x1b[1m*";
1477 str2 = "\x1b[0m";
1478 }
1479 else
1480 {
1481 str1 = " ";
1482 str2 = "";
1483 }
1484
1485 if (Global)
1486 {
1487 GlobalOrLocal = " global";
1488 }
1489 else
1490 {
1491 GlobalOrLocal = Buffer;
1492 sprintf(Buffer, " PID 0x%Ix",
1493 (ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
1494 }
1495
1497 {
1498 KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
1499 str1, l, Address,
1500 Enabled ? "" : " disabled",
1501 GlobalOrLocal,
1502 ConditionExpr ? " IF " : "",
1503 ConditionExpr ? ConditionExpr : "",
1504 str2);
1505 }
1506 else if (Type == KdbBreakPointHardware)
1507 {
1508 if (!Enabled)
1509 {
1510 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
1511 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1512 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1513 GlobalOrLocal,
1514 ConditionExpr ? " IF " : "",
1515 ConditionExpr ? ConditionExpr : "",
1516 str2);
1517 }
1518 else
1519 {
1520 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
1521 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1522 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1523 DebugReg,
1524 GlobalOrLocal,
1525 ConditionExpr ? " IF " : "",
1526 ConditionExpr ? ConditionExpr : "",
1527 str2);
1528 }
1529 }
1530 }
1531 while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
1532
1533 return TRUE;
1534}
1535
1538static BOOLEAN
1540 ULONG Argc,
1541 PCHAR Argv[])
1542{
1543 PCHAR pend;
1544 ULONG BreakPointNr;
1545
1546 if (Argc < 2)
1547 {
1548 KdbpPrint("%s: argument required\n", Argv[0]);
1549 return TRUE;
1550 }
1551
1552 pend = Argv[1];
1553 BreakPointNr = strtoul(Argv[1], &pend, 0);
1554 if (pend == Argv[1] || *pend != '\0')
1555 {
1556 KdbpPrint("%s: integer argument required\n", Argv[0]);
1557 return TRUE;
1558 }
1559
1560 if (Argv[0][1] == 'e') /* enable */
1561 {
1562 KdbpEnableBreakPoint(BreakPointNr, NULL);
1563 }
1564 else if (Argv [0][1] == 'd') /* disable */
1565 {
1566 KdbpDisableBreakPoint(BreakPointNr, NULL);
1567 }
1568 else /* clear */
1569 {
1570 ASSERT(Argv[0][1] == 'c');
1571 KdbpDeleteBreakPoint(BreakPointNr, NULL);
1572 }
1573
1574 return TRUE;
1575}
1576
1579static BOOLEAN
1581{
1582 ULONGLONG Result = 0;
1585 UCHAR Size = 0;
1586 KDB_ACCESS_TYPE AccessType = 0;
1587 ULONG AddressArgIndex, i;
1588 LONG ConditionArgIndex;
1590
1591 if (Argv[0][2] == 'x') /* software breakpoint */
1592 {
1593 if (Argc < 2)
1594 {
1595 KdbpPrint("bpx: Address argument required.\n");
1596 return TRUE;
1597 }
1598
1599 AddressArgIndex = 1;
1601 }
1602 else /* memory breakpoint */
1603 {
1604 ASSERT(Argv[0][2] == 'm');
1605
1606 if (Argc < 2)
1607 {
1608 KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
1609 return TRUE;
1610 }
1611
1612 if (_stricmp(Argv[1], "x") == 0)
1613 AccessType = KdbAccessExec;
1614 else if (_stricmp(Argv[1], "r") == 0)
1615 AccessType = KdbAccessRead;
1616 else if (_stricmp(Argv[1], "w") == 0)
1617 AccessType = KdbAccessWrite;
1618 else if (_stricmp(Argv[1], "rw") == 0)
1619 AccessType = KdbAccessReadWrite;
1620 else
1621 {
1622 KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
1623 return TRUE;
1624 }
1625
1626 if (Argc < 3)
1627 {
1628 KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
1629 return TRUE;
1630 }
1631
1632 AddressArgIndex = 3;
1633 if (_stricmp(Argv[2], "byte") == 0)
1634 Size = 1;
1635 else if (_stricmp(Argv[2], "word") == 0)
1636 Size = 2;
1637 else if (_stricmp(Argv[2], "dword") == 0)
1638 Size = 4;
1639 else if (AccessType == KdbAccessExec)
1640 {
1641 Size = 1;
1642 AddressArgIndex--;
1643 }
1644 else
1645 {
1646 KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
1647 return TRUE;
1648 }
1649
1650 if (Argc <= AddressArgIndex)
1651 {
1652 KdbpPrint("bpm: Address argument required.\n");
1653 return TRUE;
1654 }
1655
1657 }
1658
1659 /* Put the arguments back together */
1660 ConditionArgIndex = -1;
1661 for (i = AddressArgIndex; i < (Argc-1); i++)
1662 {
1663 if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
1664 {
1665 ConditionArgIndex = i + 2;
1666 if ((ULONG)ConditionArgIndex >= Argc)
1667 {
1668 KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
1669 return TRUE;
1670 }
1671
1672 for (i = ConditionArgIndex; i < (Argc-1); i++)
1673 Argv[i][strlen(Argv[i])] = ' ';
1674
1675 break;
1676 }
1677
1678 Argv[i][strlen(Argv[i])] = ' ';
1679 }
1680
1681 /* Evaluate the address expression */
1682 if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
1683 KdbPromptStr.Length + (Argv[AddressArgIndex]-Argv[0]),
1684 &Result))
1685 {
1686 return TRUE;
1687 }
1688
1689 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1690 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
1691
1693
1694 KdbpInsertBreakPoint(Address, Type, Size, AccessType,
1695 (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
1696 Global, NULL);
1697
1698 return TRUE;
1699}
1700
1703static BOOLEAN
1705 ULONG Argc,
1706 PCHAR Argv[])
1707{
1711 BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1713 PULONG_PTR Frame;
1714 ULONG_PTR Pc;
1715 ULONG_PTR ul = 0;
1716 PCHAR State, pend, str1, str2;
1717 static const PCHAR ThreadStateToString[DeferredReady+1] =
1718 {
1719 "Initialized", "Ready", "Running",
1720 "Standby", "Terminated", "Waiting",
1721 "Transition", "DeferredReady"
1722 };
1723
1725
1726 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1727 {
1729
1730 if (Argc >= 3)
1731 {
1732 ul = strtoulptr(Argv[2], &pend, 0);
1733 if (Argv[2] == pend)
1734 {
1735 KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1736 return TRUE;
1737 }
1738
1740 {
1741 KdbpPrint("thread: Invalid process id!\n");
1742 return TRUE;
1743 }
1744
1745 /* Remember our reference */
1746 ReferencedProcess = TRUE;
1747 }
1748
1749 Entry = Process->ThreadListHead.Flink;
1750 if (Entry == &Process->ThreadListHead)
1751 {
1752 if (Argc >= 3)
1753 KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1754 else
1755 KdbpPrint("No threads in current process!\n");
1756
1757 if (ReferencedProcess)
1759
1760 return TRUE;
1761 }
1762
1763 KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1764 do
1765 {
1766 Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1767
1768 if (Thread == KdbCurrentThread)
1769 {
1770 str1 = "\x1b[1m*";
1771 str2 = "\x1b[0m";
1772 }
1773 else
1774 {
1775 str1 = " ";
1776 str2 = "";
1777 }
1778
1779 if (!Thread->Tcb.InitialStack)
1780 {
1781 /* Thread has no kernel stack (probably terminated) */
1782 Stack = Frame = NULL;
1783 Pc = 0;
1784 }
1785 else if (Thread->Tcb.TrapFrame)
1786 {
1790 }
1791 else
1792 {
1794 Frame = (PULONG_PTR)Stack[4];
1795 Pc = 0;
1796
1797 if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1798 KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1799 }
1800
1801 if (Thread->Tcb.State < (DeferredReady + 1))
1802 State = ThreadStateToString[Thread->Tcb.State];
1803 else
1804 State = "Unknown";
1805
1806 KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1807 str1,
1809 State,
1812 Frame,
1813 Pc,
1814 str2);
1815
1816 Entry = Entry->Flink;
1817 }
1818 while (Entry != &Process->ThreadListHead);
1819
1820 /* Release our reference, if any */
1821 if (ReferencedProcess)
1823 }
1824 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1825 {
1826 if (Argc < 3)
1827 {
1828 KdbpPrint("thread attach: thread id argument required!\n");
1829 return TRUE;
1830 }
1831
1832 ul = strtoulptr(Argv[2], &pend, 0);
1833 if (Argv[2] == pend)
1834 {
1835 KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1836 return TRUE;
1837 }
1838
1839 if (!KdbpAttachToThread((PVOID)ul))
1840 {
1841 return TRUE;
1842 }
1843
1844 KdbpPrint("Attached to thread 0x%08x.\n", ul);
1845 }
1846 else
1847 {
1849
1850 if (Argc >= 2)
1851 {
1852 ul = strtoulptr(Argv[1], &pend, 0);
1853 if (Argv[1] == pend)
1854 {
1855 KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1856 return TRUE;
1857 }
1858
1860 {
1861 KdbpPrint("thread: Invalid thread id!\n");
1862 return TRUE;
1863 }
1864
1865 /* Remember our reference */
1866 ReferencedThread = TRUE;
1867 }
1868
1869 if (Thread->Tcb.State < (DeferredReady + 1))
1870 State = ThreadStateToString[Thread->Tcb.State];
1871 else
1872 State = "Unknown";
1873
1874 KdbpPrint("%s"
1875 " TID: 0x%08x\n"
1876 " State: %s (0x%x)\n"
1877 " Priority: %d\n"
1878 " Affinity: 0x%08x\n"
1879 " Initial Stack: 0x%08x\n"
1880 " Stack Limit: 0x%08x\n"
1881 " Stack Base: 0x%08x\n"
1882 " Kernel Stack: 0x%08x\n"
1883 " Trap Frame: 0x%08x\n"
1884#ifndef _M_AMD64
1885 " NPX State: %s (0x%x)\n"
1886#endif
1887 , (Argc < 2) ? "Current Thread:\n" : ""
1889 , State, Thread->Tcb.State
1897#ifndef _M_AMD64
1899#endif
1900 );
1901
1902 /* Release our reference if we had one */
1903 if (ReferencedThread)
1905 }
1906
1907 return TRUE;
1908}
1909
1912static BOOLEAN
1914 ULONG Argc,
1915 PCHAR Argv[])
1916{
1919 BOOLEAN ReferencedProcess = FALSE;
1920 PCHAR State, pend, str1, str2;
1921 ULONG_PTR ul;
1923
1924 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1925 {
1927 if (!Entry || Entry == &PsActiveProcessHead)
1928 {
1929 KdbpPrint("No processes in the system!\n");
1930 return TRUE;
1931 }
1932
1933 KdbpPrint(" PID State Filename\n");
1934 do
1935 {
1936 Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
1937
1939 {
1940 str1 = "\x1b[1m*";
1941 str2 = "\x1b[0m";
1942 }
1943 else
1944 {
1945 str1 = " ";
1946 str2 = "";
1947 }
1948
1949 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
1950 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
1951
1952 KdbpPrint(" %s0x%08x %-10s %s%s\n",
1953 str1,
1954 Process->UniqueProcessId,
1955 State,
1956 Process->ImageFileName,
1957 str2);
1958
1959 Entry = Entry->Flink;
1960 }
1961 while(Entry != &PsActiveProcessHead);
1962 }
1963 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1964 {
1965 if (Argc < 3)
1966 {
1967 KdbpPrint("process attach: process id argument required!\n");
1968 return TRUE;
1969 }
1970
1971 ul = strtoulptr(Argv[2], &pend, 0);
1972 if (Argv[2] == pend)
1973 {
1974 KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
1975 return TRUE;
1976 }
1977
1978 if (!KdbpAttachToProcess((PVOID)ul))
1979 {
1980 return TRUE;
1981 }
1982
1983 KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
1985 }
1986 else
1987 {
1989
1990 if (Argc >= 2)
1991 {
1992 ul = strtoulptr(Argv[1], &pend, 0);
1993 if (Argv[1] == pend)
1994 {
1995 KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
1996 return TRUE;
1997 }
1998
2000 {
2001 KdbpPrint("proc: Invalid process id!\n");
2002 return TRUE;
2003 }
2004
2005 /* Remember our reference */
2006 ReferencedProcess = TRUE;
2007 }
2008
2009 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2010 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2011 KdbpPrint("%s"
2012 " PID: 0x%08x\n"
2013 " State: %s (0x%x)\n"
2014 " Image Filename: %s\n",
2015 (Argc < 2) ? "Current process:\n" : "",
2016 Process->UniqueProcessId,
2017 State, Process->Pcb.State,
2018 Process->ImageFileName);
2019
2020 /* Release our reference, if any */
2021 if (ReferencedProcess)
2023 }
2024
2025 return TRUE;
2026}
2027
2030static BOOLEAN
2032 ULONG Argc,
2033 PCHAR Argv[])
2034{
2035 ULONGLONG Result = 0;
2037 PLDR_DATA_TABLE_ENTRY LdrEntry;
2038 BOOLEAN DisplayOnlyOneModule = FALSE;
2039 INT i = 0;
2040
2041 if (Argc >= 2)
2042 {
2043 /* Put the arguments back together */
2044 Argc--;
2045 while (--Argc >= 1)
2046 Argv[Argc][strlen(Argv[Argc])] = ' ';
2047
2048 /* Evaluate the expression */
2049 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
2050 {
2051 return TRUE;
2052 }
2053
2054 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2055 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2056
2058
2059 if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2060 {
2061 KdbpPrint("No module containing address 0x%p found!\n", Address);
2062 return TRUE;
2063 }
2064
2065 DisplayOnlyOneModule = TRUE;
2066 }
2067 else
2068 {
2069 if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2070 {
2071 ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2072 KdbpPrint(" Base Size Name\n");
2073 KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2074 return TRUE;
2075 }
2076
2077 i = 1;
2078 }
2079
2080 KdbpPrint(" Base Size Name\n");
2081 for (;;)
2082 {
2083 KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2085 KdbpPrint("\n");
2086
2087 if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2088 break;
2089 }
2090
2091 return TRUE;
2092}
2093
2096static BOOLEAN
2098 ULONG Argc,
2099 PCHAR Argv[])
2100{
2101 KDESCRIPTOR Reg;
2102 ULONG SegDesc[2];
2103 ULONG SegBase;
2104 ULONG SegLimit;
2105 PCHAR SegType;
2106 USHORT SegSel;
2107 UCHAR Type, Dpl;
2108 INT i;
2109 ULONG ul;
2110
2111 if (Argv[0][0] == 'i')
2112 {
2113 /* Read IDTR */
2114 __sidt(&Reg.Limit);
2115
2116 if (Reg.Limit < 7)
2117 {
2118 KdbpPrint("Interrupt descriptor table is empty.\n");
2119 return TRUE;
2120 }
2121
2122 KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
2123 KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
2124
2125 for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2126 {
2127 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2128 {
2129 KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
2130 return TRUE;
2131 }
2132
2133 Dpl = ((SegDesc[1] >> 13) & 3);
2134 if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2135 SegType = "TASKGATE";
2136 else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
2137 SegType = "INTGATE32";
2138 else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
2139 SegType = "INTGATE16";
2140 else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
2141 SegType = "TRAPGATE32";
2142 else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
2143 SegType = "TRAPGATE16";
2144 else
2145 SegType = "UNKNOWN";
2146
2147 if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
2148 {
2149 KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
2150 i / 8, SegType, Dpl);
2151 }
2152 else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2153 {
2154 SegSel = SegDesc[0] >> 16;
2155 KdbpPrint(" %03d %-10s 0x%04x %02d\n",
2156 i / 8, SegType, SegSel, Dpl);
2157 }
2158 else
2159 {
2160 SegSel = SegDesc[0] >> 16;
2161 SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
2162 KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
2163 i / 8, SegType, SegSel, SegBase, Dpl);
2164 }
2165 }
2166 }
2167 else
2168 {
2169 ul = 0;
2170
2171 if (Argv[0][0] == 'g')
2172 {
2173 /* Read GDTR */
2175 i = 8;
2176 }
2177 else
2178 {
2179 ASSERT(Argv[0][0] == 'l');
2180
2181 /* Read LDTR */
2183 Reg.Base = 0;
2184 i = 0;
2185 ul = 1 << 2;
2186 }
2187
2188 if (Reg.Limit < 7)
2189 {
2190 KdbpPrint("%s descriptor table is empty.\n",
2191 Argv[0][0] == 'g' ? "Global" : "Local");
2192 return TRUE;
2193 }
2194
2195 KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
2196 Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
2197 KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
2198
2199 for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2200 {
2201 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2202 {
2203 KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
2204 return TRUE;
2205 }
2206
2207 Dpl = ((SegDesc[1] >> 13) & 3);
2208 Type = ((SegDesc[1] >> 8) & 0xf);
2209
2210 SegBase = SegDesc[0] >> 16;
2211 SegBase |= (SegDesc[1] & 0xff) << 16;
2212 SegBase |= SegDesc[1] & 0xff000000;
2213 SegLimit = SegDesc[0] & 0x0000ffff;
2214 SegLimit |= (SegDesc[1] >> 16) & 0xf;
2215
2216 if ((SegDesc[1] & (1 << 23)) != 0)
2217 {
2218 SegLimit *= 4096;
2219 SegLimit += 4095;
2220 }
2221 else
2222 {
2223 SegLimit++;
2224 }
2225
2226 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2227 {
2228 switch (Type)
2229 {
2230 case 1: SegType = "TSS16(Avl)"; break;
2231 case 2: SegType = "LDT"; break;
2232 case 3: SegType = "TSS16(Busy)"; break;
2233 case 4: SegType = "CALLGATE16"; break;
2234 case 5: SegType = "TASKGATE"; break;
2235 case 6: SegType = "INTGATE16"; break;
2236 case 7: SegType = "TRAPGATE16"; break;
2237 case 9: SegType = "TSS32(Avl)"; break;
2238 case 11: SegType = "TSS32(Busy)"; break;
2239 case 12: SegType = "CALLGATE32"; break;
2240 case 14: SegType = "INTGATE32"; break;
2241 case 15: SegType = "TRAPGATE32"; break;
2242 default: SegType = "UNKNOWN"; break;
2243 }
2244
2245 if (!(Type >= 1 && Type <= 3) &&
2246 Type != 9 && Type != 11)
2247 {
2248 SegBase = 0;
2249 SegLimit = 0;
2250 }
2251 }
2252 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2253 {
2254 if ((SegDesc[1] & (1 << 22)) != 0)
2255 SegType = "DATA32";
2256 else
2257 SegType = "DATA16";
2258 }
2259 else /* Code segment */
2260 {
2261 if ((SegDesc[1] & (1 << 22)) != 0)
2262 SegType = "CODE32";
2263 else
2264 SegType = "CODE16";
2265 }
2266
2267 if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
2268 {
2269 KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
2270 i / 8, i | Dpl | ul, SegType, Dpl);
2271 }
2272 else
2273 {
2274 KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
2275 i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
2276
2277 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2278 {
2279 /* FIXME: Display system segment */
2280 }
2281 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2282 {
2283 if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
2284 KdbpPrint(" E");
2285
2286 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
2287
2288 if ((SegDesc[1] & (1 << 8)) != 0)
2289 KdbpPrint(" A");
2290 }
2291 else /* Code segment */
2292 {
2293 if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
2294 KdbpPrint(" C");
2295
2296 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
2297
2298 if ((SegDesc[1] & (1 << 8)) != 0)
2299 KdbpPrint(" A");
2300 }
2301
2302 if ((SegDesc[1] & (1 << 20)) != 0)
2303 KdbpPrint(" AVL");
2304
2305 KdbpPrint("\n");
2306 }
2307 }
2308 }
2309
2310 return TRUE;
2311}
2312
2315static BOOLEAN
2317 ULONG Argc,
2318 PCHAR Argv[])
2319{
2320 PKIPCR Pcr = (PKIPCR)KeGetPcr();
2321
2322 KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2323#ifdef _M_IX86
2324 KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2325 " Tib.StackBase: 0x%08x\n"
2326 " Tib.StackLimit: 0x%08x\n"
2327 " Tib.SubSystemTib: 0x%08x\n"
2328 " Tib.FiberData/Version: 0x%08x\n"
2329 " Tib.ArbitraryUserPointer: 0x%08x\n"
2330 " Tib.Self: 0x%08x\n"
2331 " SelfPcr: 0x%08x\n"
2332 " PCRCB: 0x%08x\n"
2333 " Irql: 0x%02x\n"
2334 " IRR: 0x%08x\n"
2335 " IrrActive: 0x%08x\n"
2336 " IDR: 0x%08x\n"
2337 " KdVersionBlock: 0x%08x\n"
2338 " IDT: 0x%08x\n"
2339 " GDT: 0x%08x\n"
2340 " TSS: 0x%08x\n"
2341 " MajorVersion: 0x%04x\n"
2342 " MinorVersion: 0x%04x\n"
2343 " SetMember: 0x%08x\n"
2344 " StallScaleFactor: 0x%08x\n"
2345 " Number: 0x%02x\n"
2346 " L2CacheAssociativity: 0x%02x\n"
2347 " VdmAlert: 0x%08x\n"
2348 " L2CacheSize: 0x%08x\n"
2349 " InterruptMode: 0x%08x\n"
2352 Pcr->NtTib.Self
2353 , Pcr->SelfPcr
2354 , Pcr->Prcb, Pcr->Irql
2355 , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2356 , Pcr->KdVersionBlock
2357 , Pcr->IDT, Pcr->GDT, Pcr->TSS
2358 , Pcr->MajorVersion, Pcr->MinorVersion
2359 , Pcr->SetMember
2360 , Pcr->StallScaleFactor
2361 , Pcr->Number
2363 , Pcr->VdmAlert
2365 , Pcr->InterruptMode);
2366#else
2367 KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2368 KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2369 KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2370 KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2371 KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2372 KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2373 KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2374 KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2375 KdbpPrint(" Irql: %u\n", Pcr->Irql);
2376 KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2377 KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2378 KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2379 KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2380 KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2381 KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2382 KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2383#endif
2384
2385 return TRUE;
2386}
2387
2388#ifdef _M_IX86
2391static BOOLEAN
2392KdbpCmdTss(
2393 ULONG Argc,
2394 PCHAR Argv[])
2395{
2396 USHORT TssSelector;
2397 PKTSS Tss = NULL;
2398
2399 if (Argc >= 2)
2400 {
2401 /*
2402 * Specified TSS via its selector [selector] or descriptor address [*descaddr].
2403 * Note that we ignore any other argument values.
2404 */
2405 PCHAR Param, pszNext;
2406 ULONG ulValue;
2407
2408 Param = Argv[1];
2409 if (Argv[1][0] == '*')
2410 ++Param;
2411
2412 ulValue = strtoul(Param, &pszNext, 0);
2413 if (pszNext && *pszNext)
2414 {
2415 KdbpPrint("Invalid TSS specification.\n");
2416 return TRUE;
2417 }
2418
2419 if (Argv[1][0] == '*')
2420 {
2421 /* Descriptor specified */
2422 TssSelector = 0; // Unknown selector!
2423 // TODO: Room for improvement: Find the TSS descriptor
2424 // in the GDT so as to validate it.
2425 Tss = (PKTSS)(ULONG_PTR)ulValue;
2426 if (!Tss)
2427 {
2428 KdbpPrint("Invalid 32-bit TSS descriptor.\n");
2429 return TRUE;
2430 }
2431 }
2432 else
2433 {
2434 /* Selector specified, retrive the corresponding TSS */
2435 TssSelector = (USHORT)ulValue;
2436 Tss = KdbpRetrieveTss(TssSelector, NULL, NULL);
2437 if (!Tss)
2438 {
2439 KdbpPrint("Invalid 32-bit TSS selector.\n");
2440 return TRUE;
2441 }
2442 }
2443 }
2444
2445 if (!Tss)
2446 {
2447 /* If no TSS was specified, use the current TSS descriptor */
2448 TssSelector = Ke386GetTr();
2449 Tss = KeGetPcr()->TSS;
2450 // NOTE: If everything works OK, Tss is the current TSS corresponding to the TR selector.
2451 }
2452
2453 KdbpPrint("%s TSS 0x%04x is at 0x%p.\n",
2454 (Tss == KeGetPcr()->TSS) ? "Current" : "Specified", TssSelector, Tss);
2455 KdbpPrint(" Backlink: 0x%04x\n"
2456 " Ss0:Esp0: 0x%04x:0x%08x\n"
2457 // NOTE: Ss1:Esp1 and Ss2:Esp2: are in the NotUsed1 field.
2458 " CR3: 0x%08x\n"
2459 " EFlags: 0x%08x\n"
2460 " Eax: 0x%08x\n"
2461 " Ebx: 0x%08x\n"
2462 " Ecx: 0x%08x\n"
2463 " Edx: 0x%08x\n"
2464 " Esi: 0x%08x\n"
2465 " Edi: 0x%08x\n"
2466 " Eip: 0x%08x\n"
2467 " Esp: 0x%08x\n"
2468 " Ebp: 0x%08x\n"
2469 " Cs: 0x%04x\n"
2470 " Ss: 0x%04x\n"
2471 " Ds: 0x%04x\n"
2472 " Es: 0x%04x\n"
2473 " Fs: 0x%04x\n"
2474 " Gs: 0x%04x\n"
2475 " LDT: 0x%04x\n"
2476 " Flags: 0x%04x\n"
2477 " IoMapBase: 0x%04x\n",
2478 Tss->Backlink, Tss->Ss0, Tss->Esp0, Tss->CR3, Tss->EFlags,
2479 Tss->Eax, Tss->Ebx, Tss->Ecx, Tss->Edx, Tss->Esi, Tss->Edi,
2480 Tss->Eip, Tss->Esp, Tss->Ebp,
2481 Tss->Cs, Tss->Ss, Tss->Ds, Tss->Es, Tss->Fs, Tss->Gs,
2482 Tss->LDT, Tss->Flags, Tss->IoMapBase);
2483
2484 return TRUE;
2485}
2486#endif // _M_IX86
2487
2490static BOOLEAN
2492 ULONG Argc,
2493 PCHAR Argv[])
2494{
2495 /* Set the flag and quit looping */
2497 return FALSE;
2498}
2499
2500static BOOLEAN
2502 ULONG Argc,
2503 PCHAR Argv[])
2504{
2505 /* Reboot immediately (we do not return) */
2507 return FALSE;
2508}
2509
2515static BOOLEAN
2517 ULONG Argc,
2518 PCHAR Argv[])
2519{
2520 ULONG beg, end;
2521
2522 KdbpIsInDmesgMode = TRUE; /* Toggle logging flag */
2523 if (!KdpDmesgBuffer)
2524 {
2525 KdbpPrint("Dmesg: error, buffer is not allocated! /DEBUGPORT=SCREEN kernel param required for dmesg.\n");
2526 return TRUE;
2527 }
2528
2529 KdbpPrint("*** Dmesg *** TotalWritten=%lu, BufferSize=%lu, CurrentPosition=%lu\n",
2531
2532 /* Pass data to the pager */
2535
2536 /* No roll-overs, and overwritten=lost bytes */
2538 {
2539 /* Show buffer (KdpDmesgBuffer + beg, num) */
2541 }
2542 else
2543 {
2544 /* Show 2 buffers: (KdpDmesgBuffer + beg, KdpDmesgBufferSize - beg)
2545 * and: (KdpDmesgBuffer, end) */
2547 KdbpPrint("*** Dmesg: buffer rollup ***\n");
2549 }
2550 KdbpPrint("*** Dmesg: end of output ***\n");
2551
2552 KdbpIsInDmesgMode = FALSE; /* Toggle logging flag */
2553
2554 return TRUE;
2555}
2556
2559static BOOLEAN
2561 ULONG Argc,
2562 PCHAR Argv[])
2563{
2564 LONG l;
2565 BOOLEAN First;
2566 PCHAR pend = 0;
2567 KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
2568 KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
2569
2570 static const PCHAR ExceptionNames[21] =
2571 {
2572 "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
2573 "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
2574 "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
2575 "MACHINECHECK", "SIMDFAULT", "OTHERS"
2576 };
2577
2578 if (Argc == 1)
2579 {
2580 KdbpPrint("Available settings:\n");
2581 KdbpPrint(" syntax [intel|at&t]\n");
2582 KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
2583 KdbpPrint(" break_on_module_load [true|false]\n");
2584 }
2585 else if (strcmp(Argv[1], "syntax") == 0)
2586 {
2587 if (Argc == 2)
2588 {
2589 KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
2590 }
2591 else if (Argc >= 3)
2592 {
2593 if (_stricmp(Argv[2], "intel") == 0)
2595 else if (_stricmp(Argv[2], "at&t") == 0)
2597 else
2598 KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
2599 }
2600 }
2601 else if (strcmp(Argv[1], "condition") == 0)
2602 {
2603 if (Argc == 2)
2604 {
2605 KdbpPrint("Conditions: (First) (Last)\n");
2606 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
2607 {
2608 if (!ExceptionNames[l])
2609 continue;
2610
2611 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2612 ASSERT(FALSE);
2613
2614 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2615 ASSERT(FALSE);
2616
2617 KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
2618 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2619 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2620 }
2621
2622 ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
2623 KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
2624 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2625 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2626 }
2627 else
2628 {
2629 if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
2630 {
2631 l = -1;
2632 }
2633 else
2634 {
2635 l = strtoul(Argv[2], &pend, 0);
2636
2637 if (Argv[2] == pend)
2638 {
2639 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
2640 {
2641 if (!ExceptionNames[l])
2642 continue;
2643
2644 if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
2645 break;
2646 }
2647 }
2648
2649 if (l >= RTL_NUMBER_OF(ExceptionNames))
2650 {
2651 KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
2652 return TRUE;
2653 }
2654 }
2655
2656 if (Argc > 4)
2657 {
2658 if (_stricmp(Argv[3], "first") == 0)
2659 First = TRUE;
2660 else if (_stricmp(Argv[3], "last") == 0)
2661 First = FALSE;
2662 else
2663 {
2664 KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
2665 return TRUE;
2666 }
2667
2668 if (_stricmp(Argv[4], "never") == 0)
2669 ConditionFirst = KdbDoNotEnter;
2670 else if (_stricmp(Argv[4], "always") == 0)
2671 ConditionFirst = KdbEnterAlways;
2672 else if (_stricmp(Argv[4], "umode") == 0)
2673 ConditionFirst = KdbEnterFromUmode;
2674 else if (_stricmp(Argv[4], "kmode") == 0)
2675 ConditionFirst = KdbEnterFromKmode;
2676 else
2677 {
2678 KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
2679 return TRUE;
2680 }
2681
2682 if (!KdbpSetEnterCondition(l, First, ConditionFirst))
2683 {
2684 if (l >= 0)
2685 KdbpPrint("Couldn't change condition for exception #%02d\n", l);
2686 else
2687 KdbpPrint("Couldn't change condition for all exceptions\n", l);
2688 }
2689 }
2690 else /* Argc >= 3 */
2691 {
2692 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2693 ASSERT(FALSE);
2694
2695 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2696 ASSERT(FALSE);
2697
2698 if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
2699 {
2700 KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
2701 l, ExceptionNames[l],
2702 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2703 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2704 }
2705 else
2706 {
2707 KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
2708 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2709 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2710 }
2711 }
2712 }
2713 }
2714 else if (strcmp(Argv[1], "break_on_module_load") == 0)
2715 {
2716 if (Argc == 2)
2717 KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
2718 else if (Argc >= 3)
2719 {
2720 if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
2722 else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
2724 else
2725 KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
2726 }
2727 }
2728 else
2729 {
2730 KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
2731 }
2732
2733 return TRUE;
2734}
2735
2738static BOOLEAN
2740 ULONG Argc,
2741 PCHAR Argv[])
2742{
2743 ULONG i;
2744
2745 KdbpPrint("Kernel debugger commands:\n");
2746 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
2747 {
2748 if (!KdbDebuggerCommands[i].Syntax) /* Command group */
2749 {
2750 if (i > 0)
2751 KdbpPrint("\n");
2752
2753 KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
2754 continue;
2755 }
2756
2757 KdbpPrint(" %-20s - %s\n",
2760 }
2761
2762 return TRUE;
2763}
2764
2765
2766/*
2767 * memrchr(), explicitly defined, since absent in the CRT.
2768 * Reverse memchr()
2769 * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
2770 */
2771void *
2772memrchr(const void *s, int c, size_t n)
2773{
2774 const unsigned char *cp;
2775
2776 if (n != 0)
2777 {
2778 cp = (unsigned char *)s + n;
2779 do
2780 {
2781 if (*(--cp) == (unsigned char)c)
2782 return (void *)cp;
2783 } while (--n != 0);
2784 }
2785 return NULL;
2786}
2787
2807static PCHAR
2810 _In_ ULONG BufLength,
2811 _In_ PCCH pCurPos,
2812 _In_ const SIZE* TermSize)
2813{
2814 PCCH p;
2815 // p0 is initial guess of Page Start
2816 ULONG p0len = TermSize->cx * TermSize->cy;
2817 PCCH p0 = pCurPos - p0len;
2818 PCCH prev_p = p0, p1;
2819 ULONG j;
2820
2821 if (pCurPos < Buffer)
2822 pCurPos = Buffer;
2823 ASSERT(pCurPos <= Buffer + BufLength);
2824
2825 p = memrchr(p0, '\n', p0len);
2826 if (!p)
2827 p = p0;
2828 for (j = TermSize->cy; j--; )
2829 {
2830 int linesCnt;
2831 p1 = memrchr(p0, '\n', p-p0);
2832 prev_p = p;
2833 p = p1;
2834 if (!p)
2835 {
2836 p = prev_p;
2837 if (!p)
2838 p = p0;
2839 break;
2840 }
2841 linesCnt = (TermSize->cx+prev_p-p-2) / TermSize->cx;
2842 if (linesCnt > 1)
2843 j -= linesCnt-1;
2844 }
2845
2846 ASSERT(p != NULL);
2847 ++p;
2848 return (PCHAR)p;
2849}
2850
2851static VOID
2854{
2855 PCHAR p;
2856 SIZE_T i;
2857 size_t len;
2858
2859 while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
2860 {
2861 len = strlen(p);
2862 if (p[1] == '[')
2863 {
2864 i = 2;
2865 while (!isalpha(p[i++]));
2866 memmove(p, p + i, len + 1 - i);
2867 }
2868 else
2869 {
2870 memmove(p, p + 1, len);
2871 }
2872 }
2873}
2874
2887static VOID
2890 _In_ ULONG BufLength,
2891 _In_ BOOLEAN DoPage)
2892{
2893 static BOOLEAN TerminalInitialized = FALSE;
2894 CHAR c;
2896 PCHAR p;
2897 SIZE_T i;
2898 LONG RowsPrintedByTerminal;
2899
2900 if (BufLength == 0)
2901 return;
2902
2903 /* Check if the user has aborted output of the current command */
2904 if (KdbOutputAborted)
2905 return;
2906
2907 /* Initialize the terminal */
2908 if (!TerminalInitialized)
2909 {
2910 TerminalInitialized = TRUE;
2912 }
2913
2914 /* Refresh terminal size each time when number of rows printed is 0 */
2915 if (KdbNumberOfRowsPrinted == 0)
2916 {
2918 }
2919
2920 /* Loop through the strings */
2921 p = Buffer;
2922 while (p[0] != '\0')
2923 {
2924 if (DoPage)
2925 {
2926 if (p > Buffer + BufLength)
2927 {
2928 KdbPrintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer + BufLength));
2929 return;
2930 }
2931 }
2932 i = strcspn(p, "\n");
2933
2934 if (DoPage)
2935 {
2936 /* Are we out of buffer? */
2937 if (p + i > Buffer + BufLength)
2938 break; // Leaving pager function
2939 }
2940
2941 /* Calculate the number of lines which will be printed in
2942 * the terminal when outputting the current line. */
2943 if (i > 0)
2944 RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdTermSize.cx;
2945 else
2946 RowsPrintedByTerminal = 0;
2947
2948 if (p[i] == '\n')
2949 RowsPrintedByTerminal++;
2950
2951 //KdbPrintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
2952
2953 /* Display a prompt if we printed one screen full of text */
2954 if (KdTermSize.cy > 0 &&
2955 (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdTermSize.cy)
2956 {
2957 PCSTR Prompt;
2958
2959 /* Disable the repetition of previous command with long many-page output */
2961
2962 if (KdbNumberOfColsPrinted > 0)
2963 KdbPuts("\n");
2964
2965 if (DoPage)
2966 Prompt = "--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---";
2967 else
2968 Prompt = "--- Press q to abort, any other key to continue ---";
2969
2970 KdbPuts(Prompt);
2972 if (DoPage) // Show pressed key
2973 KdbPrintf(" '%c'/scan=%04x\n", c, ScanCode);
2974 else
2975 KdbPuts("\n");
2976
2977 RowsPrintedByTerminal++;
2978
2979 if (c == 'q')
2980 {
2982 return;
2983 }
2984
2985 if (DoPage)
2986 {
2987 if (ScanCode == KEYSC_END || c == 'e')
2988 {
2989 PCHAR pBufEnd = Buffer + BufLength;
2990 p = CountOnePageUp(Buffer, BufLength, pBufEnd, &KdTermSize);
2991 i = strcspn(p, "\n");
2992 }
2993 else if (ScanCode == KEYSC_PAGEUP ||
2994 ScanCode == KEYSC_ARROWUP || c == 'u')
2995 {
2996 p = CountOnePageUp(Buffer, BufLength, p, &KdTermSize);
2997 i = strcspn(p, "\n");
2998 }
2999 else if (ScanCode == KEYSC_HOME || c == 'h')
3000 {
3001 p = Buffer;
3002 i = strcspn(p, "\n");
3003 }
3004 }
3005
3008 }
3009
3010 /* Insert a NUL after the line and print only the current line */
3011 if (p[i] == '\n' && p[i + 1] != '\0')
3012 {
3013 c = p[i + 1];
3014 p[i + 1] = '\0';
3015 }
3016 else
3017 {
3018 c = '\0';
3019 }
3020
3021 /* Remove escape sequences from the line if there is no terminal connected */
3022 // FIXME: Dangerous operation since we modify the source string!!
3023 if (!KdTermConnected)
3025
3026 /* Print the current line */
3027 KdbPuts(p);
3028
3029 /* Restore not null char with saved */
3030 if (c != '\0')
3031 p[i + 1] = c;
3032
3033 /* Set p to the start of the next line and
3034 * remember the number of rows/cols printed */
3035 p += i;
3036 if (p[0] == '\n')
3037 {
3038 p++;
3040 }
3041 else
3042 {
3043 ASSERT(p[0] == '\0');
3045 }
3046
3047 KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3048 }
3049}
3050
3063VOID
3066 _In_ ULONG BufLength)
3067{
3068 /* Call the internal function */
3069 KdbpPagerInternal(Buffer, BufLength, TRUE);
3070}
3071
3081VOID
3084 _In_ ...)
3085{
3086 static CHAR Buffer[4096];
3087 ULONG Length;
3088 va_list ap;
3089
3090 /* Check if the user has aborted output of the current command */
3091 if (KdbOutputAborted)
3092 return;
3093
3094 /* Build the string */
3095 va_start(ap, Format);
3096 Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
3097 Buffer[Length] = '\0';
3098 va_end(ap);
3099
3100 /* Actually print it */
3102}
3103
3104VOID
3107{
3108 ULONG i;
3109
3110 if ((String == NULL) || (String->Buffer == NULL))
3111 {
3112 KdbpPrint("<NULL>");
3113 return;
3114 }
3115
3116 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
3117 {
3118 KdbpPrint("%c", (CHAR)String->Buffer[i]);
3119 }
3120}
3121
3122
3123BOOLEAN
3124NTAPI
3127 BOOLEAN Deregister)
3128{
3129 ULONG i;
3130
3131 /* Loop all entries */
3132 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3133 {
3134 /* Check if deregistering was requested */
3135 if (Deregister)
3136 {
3137 /* Check if this entry is the one that was registered */
3138 if (KdbCliCallbacks[i] == Callback)
3139 {
3140 /* Delete it and report success */
3142 return TRUE;
3143 }
3144 }
3145 else
3146 {
3147 /* Check if this entry is free */
3148 if (KdbCliCallbacks[i] == NULL)
3149 {
3150 /* Set it and and report success */
3152 return TRUE;
3153 }
3154 }
3155 }
3156
3157 /* Unsuccessful */
3158 return FALSE;
3159}
3160
3170static
3171BOOLEAN
3174 IN ULONG Argc,
3175 IN PCHAR Argv[])
3176{
3177 ULONG i;
3178
3179 /* Loop all entries */
3180 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3181 {
3182 /* Check if this entry is registered */
3183 if (KdbCliCallbacks[i])
3184 {
3185 /* Invoke the callback and check if it handled the command */
3186 if (KdbCliCallbacks[i](Command, Argc, Argv))
3187 {
3188 return TRUE;
3189 }
3190 }
3191 }
3192
3193 /* None of the callbacks handled the command */
3194 return FALSE;
3195}
3196
3197
3205static BOOLEAN
3208{
3209 SIZE_T i;
3210 PCHAR p;
3211 ULONG Argc;
3212 // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3213 static PCHAR Argv[256];
3214 static CHAR OrigCommand[1024];
3215
3216 RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3217
3218 Argc = 0;
3219 p = Command;
3220
3221 for (;;)
3222 {
3223 while (*p == '\t' || *p == ' ')
3224 p++;
3225
3226 if (*p == '\0')
3227 break;
3228
3229 i = strcspn(p, "\t ");
3230 Argv[Argc++] = p;
3231 p += i;
3232 if (*p == '\0')
3233 break;
3234
3235 *p = '\0';
3236 p++;
3237 }
3238
3239 if (Argc < 1)
3240 return TRUE;
3241
3242 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3243 {
3245 continue;
3246
3247 if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3248 {
3249 return KdbDebuggerCommands[i].Fn(Argc, Argv);
3250 }
3251 }
3252
3253 /* Now invoke the registered callbacks */
3254 if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3255 {
3256 return TRUE;
3257 }
3258
3259 KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
3260 return TRUE;
3261}
3262
3267VOID
3269 IN BOOLEAN EnteredOnSingleStep)
3270{
3271 BOOLEAN Continue;
3272 SIZE_T CmdLen;
3273 static CHAR Command[1024];
3274 static CHAR LastCommand[1024] = "";
3275
3276 if (EnteredOnSingleStep)
3277 {
3279 {
3281 }
3282
3283 KdbpPrint(": ");
3285 {
3286 KdbpPrint("<INVALID>");
3287 }
3288 KdbpPrint("\n");
3289 }
3290
3291 /* Main loop */
3292 do
3293 {
3294 /* Reset the number of rows/cols printed */
3296
3297 /*
3298 * Print the prompt and read a command.
3299 * Repeat the last one if the user pressed Enter.
3300 * This reduces the risk of RSI when single-stepping!
3301 */
3302 // TEMP HACK! Issue an empty string instead of duplicating "kdb:>"
3303 CmdLen = KdbPrompt(/*KdbPromptStr.Buffer*/"", Command, sizeof(Command));
3304 if (CmdLen == 0)
3305 {
3306 /* Nothing received but the user didn't press Enter, retry */
3307 continue;
3308 }
3309 else if (CmdLen > 1) // i.e. (*Command != ANSI_NULL)
3310 {
3311 /* Save this new last command */
3313 RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Command);
3314
3315 /* Remember it */
3317 }
3318 else if (KdbRepeatLastCommand)
3319 {
3320 /* The user directly pressed Enter */
3321 RtlStringCbCopyA(Command, sizeof(Command), LastCommand);
3322 }
3323
3324 /* Reset the number of rows/cols printed and output aborted state */
3327
3328 /* Call the command */
3329 Continue = KdbpDoCommand(Command);
3331 }
3332 while (Continue);
3333}
3334
3341VOID
3343{
3344 PCHAR p1, p2;
3345 INT_PTR i;
3346 CHAR c;
3347
3348 /* Execute the commands in the init file */
3349 DPRINT("KDB: Executing KDBinit file...\n");
3350 p1 = KdbInitFileBuffer;
3351 while (p1[0] != '\0')
3352 {
3353 i = strcspn(p1, "\r\n");
3354 if (i > 0)
3355 {
3356 c = p1[i];
3357 p1[i] = '\0';
3358
3359 /* Look for "break" command and comments */
3360 p2 = p1;
3361
3362 while (isspace(p2[0]))
3363 p2++;
3364
3365 if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3366 (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3367 {
3368 /* break into the debugger */
3370 }
3371 else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3372 {
3373 KdbpDoCommand(p1);
3374 }
3375
3376 p1[i] = c;
3377 }
3378
3379 p1 += i;
3380 while (p1[0] == '\r' || p1[0] == '\n')
3381 p1++;
3382 }
3383 DPRINT("KDB: KDBinit executed\n");
3384}
3385
3394{
3399 FILE_STANDARD_INFORMATION FileStdInfo;
3400 HANDLE hFile = NULL;
3401 INT FileSize;
3402 PCHAR FileBuffer;
3403 ULONG OldEflags;
3404
3405 /* Don't load the KDBinit file if its buffer is already lying around */
3407 return STATUS_SUCCESS;
3408
3409 /* Initialize the object attributes */
3410 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3412 &FileName,
3414 NULL,
3415 NULL);
3416
3417 /* Open the file */
3419 &ObjectAttributes, &Iosb, 0,
3422 if (!NT_SUCCESS(Status))
3423 {
3424 DPRINT("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3425 return Status;
3426 }
3427
3428 /* Get the size of the file */
3429 Status = ZwQueryInformationFile(hFile, &Iosb,
3430 &FileStdInfo, sizeof(FileStdInfo),
3432 if (!NT_SUCCESS(Status))
3433 {
3434 ZwClose(hFile);
3435 DPRINT("Could not query size of \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3436 return Status;
3437 }
3438 FileSize = FileStdInfo.EndOfFile.u.LowPart;
3439
3440 /* Allocate memory for the file */
3441 FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
3442 if (!FileBuffer)
3443 {
3444 ZwClose(hFile);
3445 DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
3446 return Status;
3447 }
3448
3449 /* Load file into memory */
3450 Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb, FileBuffer, FileSize, NULL, NULL);
3451 ZwClose(hFile);
3452
3454 {
3455 ExFreePool(FileBuffer);
3456 DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3457 return Status;
3458 }
3459
3460 FileSize = min(FileSize, (INT)Iosb.Information);
3461 FileBuffer[FileSize] = '\0';
3462
3463 /* Enter critical section */
3464 OldEflags = __readeflags();
3465 _disable();
3466
3467 /* Interpret the init file... */
3468 KdbInitFileBuffer = FileBuffer;
3469 //KdbEnter(); // FIXME, see commit baa47fa5e
3471
3472 /* Leave critical section */
3473 __writeeflags(OldEflags);
3474
3475 ExFreePool(FileBuffer);
3476
3477 return STATUS_SUCCESS;
3478}
3479
3480
3489static VOID
3490NTAPI
3494{
3495 KIRQL OldIrql;
3496 ULONG beg, end, num;
3497
3498 /* Avoid recursive calling if we already are in Dmesg mode */
3500 return;
3501
3502 if (KdpDmesgBuffer == NULL)
3503 return;
3504
3505 /* Acquire the printing spinlock without waiting at raised IRQL */
3507
3509 /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
3511 if (num != 0)
3512 {
3513 end = (beg + num) % KdpDmesgBufferSize;
3514 if (end > beg)
3515 {
3517 }
3518 else
3519 {
3522 }
3524
3525 /* Counting the total bytes written */
3527 }
3528
3529 /* Release the spinlock */
3531
3532 /* Optional step(?): find out a way to notify about buffer exhaustion,
3533 * and possibly fall into kbd to use dmesg command: user will read
3534 * debug strings before they will be wiped over by next writes. */
3535}
3536
3550NTAPI
3553 _In_ ULONG BootPhase)
3554{
3555 /* Saves the different symbol-loading status across boot phases */
3556 static ULONG LoadSymbols = 0;
3557
3558 if (BootPhase == 0)
3559 {
3560 /* Write out the functions that we support for now */
3561 DispatchTable->KdpPrintRoutine = KdbDebugPrint;
3562
3563 /* Check if we have a command line */
3565 {
3566 /* Get the KDBG Settings */
3568 }
3569
3570 /* Register for BootPhase 1 initialization and as a Provider */
3571 DispatchTable->KdpInitRoutine = KdbInitialize;
3572 InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
3573 }
3574 else if (BootPhase == 1)
3575 {
3576 /* Register for later BootPhase 2 reinitialization */
3577 DispatchTable->KdpInitRoutine = KdbInitialize;
3578
3579 /* Initialize Dmesg support */
3580
3581 /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
3582 * see kdbp_cli.c:KdbpCmdDmesg()/2 */
3583 KdpDmesgBuffer = ExAllocatePoolZero(NonPagedPool,
3585 TAG_KDBG);
3586 /* Ignore failure if KdpDmesgBuffer is NULL */
3589
3590 /* Initialize spinlock */
3592 }
3593
3594 /* Initialize symbols support in BootPhase 0 and 1 */
3595 if (BootPhase <= 1)
3596 {
3597 LoadSymbols <<= 1;
3598 LoadSymbols |= KdbSymInit(BootPhase);
3599 }
3600
3601 if (BootPhase == 1)
3602 {
3603 /* Announce ourselves */
3604 CHAR buffer[60];
3606 " KDBG debugger enabled - %s\r\n",
3607 !(LoadSymbols & 0x2) ? "No symbols loaded" :
3608 !(LoadSymbols & 0x1) ? "Kernel symbols loaded"
3609 : "Loading symbols");
3611 }
3612
3613 if (BootPhase >= 2)
3614 {
3615 /* I/O is now set up for disk access: Read KDB Data */
3617
3618 /* Schedule an I/O reinitialization if needed */
3621 {
3622 DispatchTable->KdpInitRoutine = KdbInitialize;
3623 }
3624 }
3625
3626 return STATUS_SUCCESS;
3627}
3628
3629/* EOF */
WCHAR First[]
Definition: FormatMessage.c:11
PCWSTR Expression
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Type
Definition: Type.h:7
UINT ScanCode
Definition: VirtualKey.c:24
#define isspace(c)
Definition: acclib.h:69
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isalpha(c)
Definition: acclib.h:74
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char UINT32 ACPI_STATUS const char UINT32 const char const char UINT32 ComponentId
Definition: acpixf.h:1281
#define COVERAGE(name, NAME, description, tag1, tag2, tag3, tag4)
Definition: aftypes.h:403
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
r l[0]
Definition: byte_order.h:168
#define _stricmp
Definition: cat.c:22
Definition: bufpool.h:45
Definition: _set.h:50
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
unsigned char
Definition: typeof.h:29
return Iosb
Definition: create.c:4402
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
#define PagedPool
Definition: env_spec_w32.h:308
#define SYSTEM
Definition: fatfs.h:185
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _FileName FileName
Definition: fatprocs.h:896
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
#define SE
Definition: ftp_var.h:28
Status
Definition: gdiplustypes.h:25
@ Ok
Definition: gdiplustypes.h:26
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define UNW_FLAG_NHANDLER
Definition: gs_support.c:32
VOID NTAPI HalReturnToFirmware(_In_ FIRMWARE_REENTRY Action)
Definition: reboot.c:21
LONG KdbpDisassemble(IN ULONG_PTR Address, IN ULONG IntelSyntax)
Definition: i386-dis.c:124
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
void __cdecl _disable(void)
Definition: intrin_arm.h:365
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1669
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1674
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2023
VOID NTAPI KdbpReleaseLock(_In_ PKSPIN_LOCK SpinLock, _In_ KIRQL OldIrql)
Definition: kdio.c:91
LIST_ENTRY KdProviders
Definition: kdio.c:47
KIRQL NTAPI KdbpAcquireLock(_In_ PKSPIN_LOCK SpinLock)
Definition: kdio.c:64
NTSTATUS NTAPI NtSetDebugFilterState(_In_ ULONG ComponentId, _In_ ULONG Level, _In_ BOOLEAN State)
Definition: kdapi.c:2411
PEPROCESS KdbCurrentProcess
Definition: kdb.c:52
LONG KdbpGetNextBreakPointNr(IN ULONG Start OPTIONAL)
Gets the number of the next breakpoint >= Start.
Definition: kdb.c:382
PETHREAD KdbCurrentThread
Definition: kdb.c:54
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:56
BOOLEAN KdbpSetEnterCondition(IN LONG ExceptionNr, IN BOOLEAN FirstChance, IN KDB_ENTER_CONDITION Condition)
Sets the first or last chance enter-condition for exception nr. ExceptionNr.
Definition: kdb.c:995
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
Definition: kdb.c:868
BOOLEAN KdbpGetEnterCondition(IN LONG ExceptionNr, IN BOOLEAN FirstChance, OUT KDB_ENTER_CONDITION *Condition)
Gets the first or last chance enter-condition for exception nr. ExceptionNr.
Definition: kdb.c:973
BOOLEAN KdbpAttachToProcess(PVOID ProcessId)
Switches to another process/thread context.
Definition: kdb.c:1117
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
Definition: kdb.c:1036
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
Definition: kdb.c:702
LONG KdbLastBreakPointNr
Definition: kdb.c:48
BOOLEAN KdbSingleStepOver
Definition: kdb.c:50
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
Definition: kdb.c:599
ULONG KdbNumSingleSteps
Definition: kdb.c:49
NTSTATUS KdbpInsertBreakPoint(IN ULONG_PTR Address, IN KDB_BREAKPOINT_TYPE Type, IN UCHAR Size OPTIONAL, IN KDB_ACCESS_TYPE AccessType OPTIONAL, IN PCHAR ConditionExpression OPTIONAL, IN BOOLEAN Global, OUT PLONG BreakPointNr OPTIONAL)
Inserts a breakpoint into the breakpoint array.
Definition: kdb.c:478
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1643
VOID KdbpGetCommandLineSettings(_In_ PCSTR p1)
Definition: kdb.c:1621
BOOLEAN KdbpGetBreakPointInfo(IN ULONG BreakPointNr, OUT ULONG_PTR *Address OPTIONAL, OUT KDB_BREAKPOINT_TYPE *Type OPTIONAL, OUT UCHAR *Size OPTIONAL, OUT KDB_ACCESS_TYPE *AccessType OPTIONAL, OUT UCHAR *DebugReg OPTIONAL, OUT BOOLEAN *Enabled OPTIONAL, OUT BOOLEAN *Global OPTIONAL, OUT PEPROCESS *Process OPTIONAL, OUT PCHAR *ConditionExpression OPTIONAL)
Returns information of the specified breakpoint.
Definition: kdb.c:409
BOOLEAN KdbSymPrintAddress(IN PVOID Address, IN PCONTEXT Context)
Print address...
Definition: kdb_symbols.c:149
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
@ KdbBreakPointSoftware
Definition: kdb.h:12
@ KdbBreakPointTemporary
Definition: kdb.h:14
@ KdbBreakPointHardware
Definition: kdb.h:13
BOOLEAN KdbpRpnEvaluateExpression(IN PCHAR Expression, IN PKDB_KTRAP_FRAME TrapFrame, OUT PULONGLONG Result, OUT PLONG ErrOffset OPTIONAL, OUT PCHAR ErrMsg OPTIONAL)
Evaluates the given expression.
Definition: kdb_expr.c:1106
VOID KdbpCommandHistoryAppend(_In_ PCSTR Command)
Appends a command to the command history.
Definition: kdb_cmdhist.c:37
VOID KdbPuts(_In_ PCSTR String)
Definition: kdb_print.c:152
@ KdbAccessExec
Definition: kdb.h:22
@ KdbAccessRead
Definition: kdb.h:19
@ KdbAccessReadWrite
Definition: kdb.h:21
@ KdbAccessWrite
Definition: kdb.h:20
BOOLEAN KdbpSymFindModule(IN PVOID Address OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY *pLdrEntry)
Find a module...
Definition: kdb_symbols.c:76
BOOLEAN KdbSymInit(_In_ ULONG BootPhase)
Initializes the KDB symbols implementation.
Definition: kdb_symbols.c:343
@ KdbDoNotEnter
Definition: kdb.h:48
@ KdbEnterFromUmode
Definition: kdb.h:51
@ KdbEnterAlways
Definition: kdb.h:49
@ KdbEnterFromKmode
Definition: kdb.h:50
VOID __cdecl KdbPrintf(_In_ PCSTR Format,...)
Definition: kdb_print.c:160
SIZE_T KdbPrompt(_In_ PCSTR Prompt, _Out_ PCHAR Buffer, _In_ SIZE_T Size)
Definition: kdb_print.c:182
enum _KDB_ACCESS_TYPE KDB_ACCESS_TYPE
enum _KDB_BREAKPOINT_TYPE KDB_BREAKPOINT_TYPE
ULONG Id
Definition: kdb_cli.c:159
VOID KdbpPager(_In_ PCHAR Buffer, _In_ ULONG BufLength)
Prints the given string with, page by page.
Definition: kdb_cli.c:3064
static BOOLEAN KdbRepeatLastCommand
Definition: kdb_cli.c:134
char __ImageBase
static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
Lists breakpoints.
Definition: kdb_cli.c:1442
#define KDB_ACCESS_TYPE_TO_STRING(type)
Definition: kdb_cli.c:45
static ULONG KdbNumberOfRowsPrinted
Definition: kdb_cli.c:131
static BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
Enables, disables or clears a breakpoint.
Definition: kdb_cli.c:1539
#define KDB_ENTER_CONDITION_TO_STRING(cond)
Definition: kdb_cli.c:40
static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[])
Displays CPU registers.
Definition: kdb_cli.c:922
void * memrchr(const void *s, int c, size_t n)
Definition: kdb_cli.c:2772
static BOOLEAN KdbUseIntelSyntax
Definition: kdb_cli.c:128
static PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
Definition: kdb_cli.c:127
static KSPIN_LOCK KdpDmesgLogSpinLock
Definition: kdb_cli.c:146
static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1401
VOID KdbpCliInterpretInitFile(VOID)
This function is called by KdbEnterDebuggerException...
Definition: kdb_cli.c:3342
static BOOLEAN KdbBreakOnModuleLoad
Definition: kdb_cli.c:129
static VOID KdpFilterEscapes(_Inout_ PSTR String)
Definition: kdb_cli.c:2852
BOOLEAN NTAPI KdbRegisterCliCallback(PVOID Callback, BOOLEAN Deregister)
Definition: kdb_cli.c:3125
static VOID KdbpPagerInternal(_In_ PCHAR Buffer, _In_ ULONG BufLength, _In_ BOOLEAN DoPage)
Prints the given string with, page by page.
Definition: kdb_cli.c:2888
BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[])
static VOID NTAPI KdbDebugPrint(_In_ PCCH String, _In_ ULONG Length)
Debug logger function.
Definition: kdb_cli.c:3491
static BOOLEAN KdbpEvaluateExpression(IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
Evaluates an expression...
Definition: kdb_cli.c:422
static const ULONG KdpDmesgBufferSize
Definition: kdb_cli.c:140
PCSTR Name
Definition: kdb_cli.c:158
#define NPX_STATE_TO_STRING(state)
Definition: kdb_cli.c:50
BOOLEAN ExpKdbgExtPoolFind(ULONG Argc, PCHAR Argv[])
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:137
static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[])
Lists processes or switches to another process context.
Definition: kdb_cli.c:1913
#define Ke386GetGlobalDescriptorTable
Definition: kdb_cli.c:100
static volatile ULONG KdpDmesgCurrentPosition
Definition: kdb_cli.c:142
static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1412
static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
Displays a backtrace.
Definition: kdb_cli.c:1226
static volatile ULONG KdpDmesgFreeBytes
Definition: kdb_cli.c:143
NTSTATUS NTAPI KdbInitialize(_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
Initializes the KDBG debugger.
Definition: kdb_cli.c:3551
VOID KdbpPrintUnicodeString(_In_ PCUNICODE_STRING String)
Definition: kdb_cli.c:3105
static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
Sets a software or hardware (memory) breakpoint at the given address.
Definition: kdb_cli.c:1580
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[])
Display debug messages on screen, with paging.
Definition: kdb_cli.c:2516
BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[])
#define Ke386GetLocalDescriptorTable
Definition: kdb_cli.c:103
BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[])
static const struct @1811 KdbDebuggerCommands[]
static BOOLEAN KdbpDoCommand(IN PCHAR Command)
Parses command line and executes command if found.
Definition: kdb_cli.c:3206
static BOOLEAN KdbpGetComponentId(IN PCSTR ComponentName, OUT PULONG ComponentId)
Retrieves the component ID corresponding to a given component name.
Definition: kdb_cli.c:676
BOOLEAN(* Fn)(ULONG Argc, PCHAR Argv[])
Definition: kdb_cli.c:345
static BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[])
Disassembles 10 instructions at eip or given address or displays 16 dwords from memory at given addre...
Definition: kdb_cli.c:801
static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[])
Displays the KPCR.
Definition: kdb_cli.c:2316
static PCHAR KdpDmesgBuffer
Definition: kdb_cli.c:141
static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[])
Displays the list of active debug channels, or enable/disable debug channels.
Definition: kdb_cli.c:697
static BOOLEAN KdbOutputAborted
Definition: kdb_cli.c:133
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3082
static volatile ULONG KdbDmesgTotalWritten
Definition: kdb_cli.c:144
BOOLEAN ExpKdbgExtPoolUsed(ULONG Argc, PCHAR Argv[])
PCHAR Help
Definition: kdb_cli.c:344
BOOLEAN(NTAPI * PKDBG_CLI_ROUTINE)(IN PCHAR Command, IN ULONG Argc, IN PCH Argv[])
Definition: kdb_cli.c:122
static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[])
Displays help screen.
Definition: kdb_cli.c:2739
static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
Evaluates an expression and displays the result.
Definition: kdb_cli.c:468
BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[])
static struct @1810 ComponentTable[]
static volatile BOOLEAN KdbpIsInDmesgMode
Definition: kdb_cli.c:145
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[])
Lists loaded modules or the one containing the specified address.
Definition: kdb_cli.c:2031
const CSTRING KdbPromptStr
Definition: kdb_cli.c:148
PCHAR Syntax
Definition: kdb_cli.c:343
static PCHAR CountOnePageUp(_In_ PCCH Buffer, _In_ ULONG BufLength, _In_ PCCH pCurPos, _In_ const SIZE *TermSize)
Calculate pointer position for N lines above the current position.
Definition: kdb_cli.c:2808
BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:136
static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[])
Bugchecks the system.
Definition: kdb_cli.c:2491
static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[])
Sets or displays a config variables value.
Definition: kdb_cli.c:2560
static BOOLEAN KdbpInvokeCliCallbacks(IN PCHAR Command, IN ULONG Argc, IN PCHAR Argv[])
Invokes registered CLI callbacks until one of them handled the Command.
Definition: kdb_cli.c:3172
static ULONG KdbNumberOfColsPrinted
Definition: kdb_cli.c:132
#define KD_DEBUG_PRINT_FILTER(Name)
Definition: kdb_cli.c:153
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[])
Displays GDT, LDT or IDT.
Definition: kdb_cli.c:2097
static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[])
Lists threads or switches to another thread context.
Definition: kdb_cli.c:1704
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3268
BOOLEAN NTAPI KdbpGetHexNumber(IN PCHAR pszNum, OUT ULONG_PTR *pulValue)
Definition: kdb_cli.c:449
NTSTATUS KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3393
static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[])
Definition: kdb_cli.c:2501
static BOOLEAN LoadSymbols
Definition: kdb_symbols.c:30
BOOLEAN KdTermConnected
Definition: kdterminal.c:34
BOOLEAN KdpUpdateTerminalSize(_Out_ PSIZE TermSize)
Definition: kdterminal.c:108
SIZE KdTermSize
Definition: kdterminal.c:33
BOOLEAN KdpInitTerminal(VOID)
Initializes the controlling terminal.
Definition: kdterminal.c:51
CHAR KdpReadTermKey(_Out_ PULONG ScanCode)
Reads one character from the terminal. This function returns a scan code even when reading is done fr...
Definition: kdterminal.c:217
#define KEYSC_END
Definition: kdterminal.h:18
#define KEYSC_ARROWUP
Definition: kdterminal.h:22
#define KEYSC_HOME
Definition: kdterminal.h:21
#define KEYSC_PAGEUP
Definition: kdterminal.h:19
#define c
Definition: ke_i.h:80
PLOADER_PARAMETER_BLOCK KeLoaderBlock
Definition: krnlinit.c:29
if(dx< 0)
Definition: linetemp.h:194
POINT cp
Definition: magnifier.c:59
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
UNICODE_STRING Global
Definition: symlink.c:37
#define ASSERT(a)
Definition: mode.c:44
static const struct op_mask SETUP
Definition: startup.c:427
unsigned __int64 ULONG64
Definition: imports.h:198
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define min(a, b)
Definition: monoChain.cc:55
@ Enabled
Definition: mountmgr.h:159
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
_In_ HANDLE hFile
Definition: mswsock.h:90
#define PKTSS
Definition: ketypes.h:994
struct _KIPCR * PKIPCR
@ HalRebootRoutine
Definition: haltypes.h:37
#define KeGetPcr()
Definition: ketypes.h:81
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
#define DPFLTR_MASK
Definition: kdtypes.h:34
#define DPFLTR_TRACE_LEVEL
Definition: kdtypes.h:32
@ ProcessOutOfMemory
Definition: ketypes.h:461
@ ProcessInMemory
Definition: ketypes.h:460
@ DeferredReady
Definition: ketypes.h:395
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
int Count
Definition: noreturn.cpp:7
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:653
CHAR * PCH
Definition: ntbasedef.h:391
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
CONST CHAR * PCCH
Definition: ntbasedef.h:392
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define strtoulptr
Definition: handle.c:28
FORCEINLINE ULONG_PTR KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:200
FORCEINLINE ULONG_PTR KeGetContextFrameRegister(PCONTEXT Context)
Definition: ke.h:165
FORCEINLINE VOID KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
Definition: ke.h:172
FORCEINLINE ULONG_PTR KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:193
#define KeGetContextPc(Context)
Definition: ke.h:31
#define KeGetTrapFramePc(TrapFrame)
Definition: ke.h:37
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
#define L(x)
Definition: ntvdm.h:50
#define BOOLEAN
Definition: pedump.c:73
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define FileStandardInformation
Definition: propsheet.cpp:61
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
VOID RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate)
Definition: find.c:126
BOOLEAN RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate)
Definition: find.c:137
#define DEFAULT
Definition: ruserpass.c:31
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
static const char *const debug_classes[]
Definition: debug.c:51
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define _countof(array)
Definition: sndvol32.h:68
#define strtoull
Definition: stabs.c:58
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: shell.h:41
base of all file and directory entries
Definition: entries.h:83
USHORT MaximumLength
Definition: env_spec_w32.h:377
HANDLE UniqueThread
Definition: compat.h:826
USHORT Length
Definition: umtypes.h:157
KTHREAD Tcb
Definition: pstypes.h:1103
CLIENT_ID Cid
Definition: pstypes.h:1128
Definition: heap.c:52
PVOID Base
Definition: ketypes.h:556
USHORT Limit
Definition: ketypes.h:555
struct _KGDTENTRY::@2442::@2444 Bits
USHORT BaseLow
Definition: ketypes.h:390
struct _KGDTENTRY::@2442::@2443 Bytes
union _KGDTENTRY::@2442 HighWord
KPRCB Prcb
Definition: ketypes.h:962
USHORT MinorVersion
Definition: ketypes.h:950
ULONG SecondLevelCacheSize
Definition: ketypes.h:954
PKIDTENTRY IDT
Definition: ketypes.h:812
USHORT MajorVersion
Definition: ketypes.h:949
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:945
ULONG IrrActive
Definition: ketypes.h:809
KIRQL Irql
Definition: ketypes.h:944
UCHAR Number
Definition: ketypes.h:820
KAFFINITY SetMember
Definition: ketypes.h:817
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:937
ULONG IRR
Definition: ketypes.h:808
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:933
ULONG InterruptMode
Definition: ketypes.h:827
PKGDTENTRY GDT
Definition: ketypes.h:813
struct _KPCR * SelfPcr
Definition: ketypes.h:805
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:938
struct _KTSS64 * TssBase
Definition: ketypes.h:934
struct _KTSS * TSS
Definition: ketypes.h:814
UCHAR ObsoleteNumber
Definition: ketypes.h:946
NT_TIB NtTib
Definition: ketypes.h:930
ULONG IDR
Definition: ketypes.h:810
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:942
struct _KPCR * Self
Definition: ketypes.h:936
ULONG StallScaleFactor
Definition: ketypes.h:951
ULONG VdmAlert
Definition: ketypes.h:823
ULONG64 UserRsp
Definition: ketypes.h:935
PVOID KdVersionBlock
Definition: ketypes.h:958
PVOID Used_Self
Definition: ketypes.h:939
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1774
PVOID InitialStack
Definition: ketypes.h:1664
GROUP_AFFINITY Affinity
Definition: ketypes.h:1938
SCHAR Priority
Definition: ketypes.h:1782
ULONG64 NpxState
Definition: ketypes.h:2068
PVOID KernelStack
Definition: ketypes.h:1675
PVOID StackBase
Definition: ketypes.h:1666
volatile VOID * StackLimit
Definition: ketypes.h:1665
volatile UCHAR State
Definition: ketypes.h:1789
Definition: ketypes.h:844
USHORT Fs
Definition: ketypes.h:870
USHORT LDT
Definition: ketypes.h:874
USHORT Backlink
Definition: ketypes.h:845
USHORT Flags
Definition: ketypes.h:876
USHORT Ds
Definition: ketypes.h:868
ULONG Eax
Definition: ketypes.h:854
ULONG Ecx
Definition: ketypes.h:855
ULONG Esi
Definition: ketypes.h:860
ULONG Ebp
Definition: ketypes.h:859
ULONG Esp
Definition: ketypes.h:858
ULONG Edx
Definition: ketypes.h:856
USHORT Gs
Definition: ketypes.h:872
USHORT Ss
Definition: ketypes.h:866
ULONG Eip
Definition: ketypes.h:852
USHORT Cs
Definition: ketypes.h:864
ULONG Ebx
Definition: ketypes.h:857
USHORT IoMapBase
Definition: ketypes.h:877
ULONG Edi
Definition: ketypes.h:861
ULONG Esp0
Definition: ketypes.h:847
ULONG CR3
Definition: ketypes.h:851
USHORT Ss0
Definition: ketypes.h:848
USHORT Es
Definition: ketypes.h:862
ULONG EFlags
Definition: ketypes.h:853
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:143
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID ArbitraryUserPointer
Definition: compat.h:719
struct _NT_TIB * Self
Definition: compat.h:720
PVOID FiberData
Definition: compat.h:716
PVOID StackLimit
Definition: compat.h:713
PVOID StackBase
Definition: compat.h:712
PVOID SubSystemTib
Definition: compat.h:714
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
ULONG NumElements
Definition: rossym.h:101
PROSSYM_AGGREGATE_MEMBER Elements
Definition: rossym.h:102
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
#define TAG_KDBG
Definition: tag.h:38
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define MAXULONG
Definition: typedefs.h:251
uint32_t * PULONG_PTR
Definition: typedefs.h:65
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t * PULONG
Definition: typedefs.h:59
char * PSTR
Definition: typedefs.h:51
uint64_t DWORD64
Definition: typedefs.h:67
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint16_t * PUSHORT
Definition: typedefs.h:56
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _LARGE_INTEGER::@2290 u
PEXCEPTION_ROUTINE NTAPI RtlVirtualUnwind(_In_ ULONG HandlerType, _In_ ULONG64 ImageBase, _In_ ULONG64 ControlPc, _In_ PRUNTIME_FUNCTION FunctionEntry, _Inout_ PCONTEXT Context, _Outptr_ PVOID *HandlerData, _Out_ PULONG64 EstablisherFrame, _Inout_opt_ PKNONVOLATILE_CONTEXT_POINTERS ContextPointers)
Definition: unwind.c:479
PRUNTIME_FUNCTION NTAPI RtlLookupFunctionEntry(IN DWORD64 ControlPc, OUT PDWORD64 ImageBase, OUT PUNWIND_HISTORY_TABLE HistoryTable)
Locates the RUNTIME_FUNCTION entry corresponding to a code address. http://msdn.microsoft....
Definition: unwind.c:124
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:458
_In_ PWDFDEVICE_INIT _In_ PWDF_PDO_EVENT_CALLBACKS DispatchTable
Definition: wdfpdo.h:248
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define FORCEINLINE
Definition: wdftypes.h:67
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define ObDereferenceObject
Definition: obfuncs.h:203
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175