ReactOS 0.4.16-dev-974-g5022a45
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
33#include "kdb.h"
34#include "../kd/kdterminal.h"
35
36#define NDEBUG
37#include "debug.h"
38
39/* DEFINES *******************************************************************/
40
41#define KDB_ENTER_CONDITION_TO_STRING(cond) \
42 ((cond) == KdbDoNotEnter ? "never" : \
43 ((cond) == KdbEnterAlways ? "always" : \
44 ((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
45
46#define KDB_ACCESS_TYPE_TO_STRING(type) \
47 ((type) == KdbAccessRead ? "read" : \
48 ((type) == KdbAccessWrite ? "write" : \
49 ((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
50
51#define NPX_STATE_TO_STRING(state) \
52 ((state) == NPX_STATE_LOADED ? "Loaded" : \
53 ((state) == NPX_STATE_NOT_LOADED ? "Not loaded" : "Unknown"))
54
55/* PROTOTYPES ****************************************************************/
56
57static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]);
58static BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]);
59static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]);
60static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]);
61
62static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]);
63static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]);
64static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]);
66static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]);
67
68static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]);
69static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
70
71static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
72static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
73static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
74#ifdef _M_IX86
75static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
76#endif
77
78static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
79static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
80static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[]);
81static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
82static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
83static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
84
92
93extern char __ImageBase;
94
95#ifdef __ROS_DWARF__
96static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
97#endif
98
99/* Be more descriptive than intrinsics */
100#ifndef Ke386GetGlobalDescriptorTable
101# define Ke386GetGlobalDescriptorTable __sgdt
102#endif
103#ifndef Ke386GetLocalDescriptorTable
104# define Ke386GetLocalDescriptorTable __sldt
105#endif
106
107/* Portability */
110strtoulptr(const char* nptr, char** endptr, int base)
111{
112#ifdef _M_IX86
113 return strtoul(nptr, endptr, base);
114#else
115 return strtoull(nptr, endptr, base);
116#endif
117}
118
119/* GLOBALS *******************************************************************/
120
121typedef
125 IN ULONG Argc,
126 IN PCH Argv[]);
127
129static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
130static BOOLEAN KdbBreakOnModuleLoad = FALSE; /* Set to TRUE to break into KDB when a module is loaded */
131
136
137volatile PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
139
140/* Variables for Dmesg */
141static const ULONG KdpDmesgBufferSize = 128 * 1024; // 512*1024;
143static volatile ULONG KdpDmesgCurrentPosition = 0;
144static volatile ULONG KdpDmesgFreeBytes = 0;
145static volatile ULONG KdbDmesgTotalWritten = 0;
148
150
151//
152// Debug Filter Component Table
153//
154#define KD_DEBUG_PRINT_FILTER(Name) \
155 { #Name, DPFLTR_##Name##_ID }
156
157static struct
158{
161}
163{
164//
165// Default components
166//
167 { "WIN2000", MAXULONG },
169//
170// Standard components
171//
177 KD_DEBUG_PRINT_FILTER(CRASHDUMP),
178 KD_DEBUG_PRINT_FILTER(CDAUDIO),
180 KD_DEBUG_PRINT_FILTER(CLASSPNP),
182 KD_DEBUG_PRINT_FILTER(REDBOOK),
183 KD_DEBUG_PRINT_FILTER(STORPROP),
184 KD_DEBUG_PRINT_FILTER(SCSIPORT),
185 KD_DEBUG_PRINT_FILTER(SCSIMINIPORT),
186 KD_DEBUG_PRINT_FILTER(CONFIG),
187 KD_DEBUG_PRINT_FILTER(I8042PRT),
188 KD_DEBUG_PRINT_FILTER(SERMOUSE),
189 KD_DEBUG_PRINT_FILTER(LSERMOUS),
190 KD_DEBUG_PRINT_FILTER(KBDHID),
191 KD_DEBUG_PRINT_FILTER(MOUHID),
192 KD_DEBUG_PRINT_FILTER(KBDCLASS),
193 KD_DEBUG_PRINT_FILTER(MOUCLASS),
194 KD_DEBUG_PRINT_FILTER(TWOTRACK),
195 KD_DEBUG_PRINT_FILTER(WMILIB),
198 KD_DEBUG_PRINT_FILTER(HALIA64),
200 KD_DEBUG_PRINT_FILTER(SVCHOST),
201 KD_DEBUG_PRINT_FILTER(VIDEOPRT),
203 KD_DEBUG_PRINT_FILTER(DMSYNTH),
204 KD_DEBUG_PRINT_FILTER(NTOSPNP),
205 KD_DEBUG_PRINT_FILTER(FASTFAT),
207 KD_DEBUG_PRINT_FILTER(PNPMGR),
208 KD_DEBUG_PRINT_FILTER(NETAPI),
209 KD_DEBUG_PRINT_FILTER(SCSERVER),
210 KD_DEBUG_PRINT_FILTER(SCCLIENT),
211 KD_DEBUG_PRINT_FILTER(SERIAL),
212 KD_DEBUG_PRINT_FILTER(SERENUM),
214 KD_DEBUG_PRINT_FILTER(RPCPROXY),
215 KD_DEBUG_PRINT_FILTER(AUTOCHK),
216 KD_DEBUG_PRINT_FILTER(DCOMSS),
217 KD_DEBUG_PRINT_FILTER(UNIMODEM),
219 KD_DEBUG_PRINT_FILTER(FLTMGR),
220 KD_DEBUG_PRINT_FILTER(WMICORE),
221 KD_DEBUG_PRINT_FILTER(BURNENG),
224 KD_DEBUG_PRINT_FILTER(FUSION),
225 KD_DEBUG_PRINT_FILTER(IDLETASK),
226 KD_DEBUG_PRINT_FILTER(SOFTPCI),
230 KD_DEBUG_PRINT_FILTER(PCIIDE),
231 KD_DEBUG_PRINT_FILTER(FLOPPY),
233 KD_DEBUG_PRINT_FILTER(TERMSRV),
234 KD_DEBUG_PRINT_FILTER(W32TIME),
235 KD_DEBUG_PRINT_FILTER(PREFETCHER),
236 KD_DEBUG_PRINT_FILTER(RSFILTER),
237 KD_DEBUG_PRINT_FILTER(FCPORT),
240 KD_DEBUG_PRINT_FILTER(DMCONFIG),
241 KD_DEBUG_PRINT_FILTER(DMADMIN),
242 KD_DEBUG_PRINT_FILTER(WSOCKTRANSPORT),
244 KD_DEBUG_PRINT_FILTER(PNPMEM),
245 KD_DEBUG_PRINT_FILTER(PROCESSOR),
246 KD_DEBUG_PRINT_FILTER(DMSERVER),
248 KD_DEBUG_PRINT_FILTER(INFINIBAND),
249 KD_DEBUG_PRINT_FILTER(IHVDRIVER),
250 KD_DEBUG_PRINT_FILTER(IHVVIDEO),
251 KD_DEBUG_PRINT_FILTER(IHVAUDIO),
252 KD_DEBUG_PRINT_FILTER(IHVNETWORK),
253 KD_DEBUG_PRINT_FILTER(IHVSTREAMING),
254 KD_DEBUG_PRINT_FILTER(IHVBUS),
256 KD_DEBUG_PRINT_FILTER(RTLTHREADPOOL),
258 KD_DEBUG_PRINT_FILTER(TCPIP6),
259 KD_DEBUG_PRINT_FILTER(ISAPNP),
261 KD_DEBUG_PRINT_FILTER(STORPORT),
262 KD_DEBUG_PRINT_FILTER(STORMINIPORT),
263 KD_DEBUG_PRINT_FILTER(PRINTSPOOLER),
264 KD_DEBUG_PRINT_FILTER(VSSDYNDISK),
265 KD_DEBUG_PRINT_FILTER(VERIFIER),
267 KD_DEBUG_PRINT_FILTER(VDSBAS),
268 KD_DEBUG_PRINT_FILTER(VDSDYN), // Specified in Vista+
269 KD_DEBUG_PRINT_FILTER(VDSDYNDR),
270 KD_DEBUG_PRINT_FILTER(VDSLDR), // Specified in Vista+
271 KD_DEBUG_PRINT_FILTER(VDSUTIL),
272 KD_DEBUG_PRINT_FILTER(DFRGIFC),
276//
277// Components specified in Vista+, some of which we also use in ReactOS
278//
281 KD_DEBUG_PRINT_FILTER(PERFLIB),
283 KD_DEBUG_PRINT_FILTER(IOSTRESS),
286 KD_DEBUG_PRINT_FILTER(USERGDI),
289 KD_DEBUG_PRINT_FILTER(THREADORDER),
290 KD_DEBUG_PRINT_FILTER(ENVIRON),
293 KD_DEBUG_PRINT_FILTER(FVEVOL),
295 KD_DEBUG_PRINT_FILTER(NVCTRACE),
297 KD_DEBUG_PRINT_FILTER(APPCOMPAT),
298 KD_DEBUG_PRINT_FILTER(USBSTOR),
299 KD_DEBUG_PRINT_FILTER(SBP2PORT),
301 KD_DEBUG_PRINT_FILTER(CACHEMGR),
302 KD_DEBUG_PRINT_FILTER(MOUNTMGR),
305 KD_DEBUG_PRINT_FILTER(KSECDD),
306 KD_DEBUG_PRINT_FILTER(FLTREGRESS),
311 KD_DEBUG_PRINT_FILTER(STORVSP),
313 KD_DEBUG_PRINT_FILTER(SSPICLI),
316 KD_DEBUG_PRINT_FILTER(FILETRACE),
319 KD_DEBUG_PRINT_FILTER(DRIVEEXTENDER),
320//
321// Components specified in Windows 8
322//
324 KD_DEBUG_PRINT_FILTER(CRASHDUMPXHCI),
328//
329// Components specified in Windows 10
330//
331 KD_DEBUG_PRINT_FILTER(CAPIMG),
333 KD_DEBUG_PRINT_FILTER(STORAGECLASSMEMORY),
336#undef KD_DEBUG_PRINT_FILTER
337
338//
339// Command Table
340//
341static const struct
342{
343 PCHAR Name;
346 BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
348 /* Data */
349 { NULL, NULL, "Data", NULL },
350 { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
351#ifdef _M_IX86 // FIXME: this is broken on x64
352 { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
353#endif // _M_IX86
354 { "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX },
355 { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
356 { "cregs", "cregs", "Display control, descriptor table and task segment registers.", KdbpCmdRegs },
357 { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
358 { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
359 { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame address.", KdbpCmdBackTrace },
360#ifdef __ROS_DWARF__
361 { "dt", "dt [mod] [type] [addr]", "Print a struct. The address is optional.", KdbpCmdPrintStruct },
362#endif
363 /* Flow control */
364 { NULL, NULL, "Flow control", NULL },
365 { "cont", "cont", "Continue execution (leave debugger).", KdbpCmdContinue },
366 { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
367 { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
368 { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
369 { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
370 { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
371 { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
372 { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
373 { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
374
375 /* Process/Thread */
376 { NULL, NULL, "Process/Thread", NULL },
377 { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
378 { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
379
380 /* System information */
381 { NULL, NULL, "System info", NULL },
382 { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
383 { "gdt", "gdt", "Display the global descriptor table.", KdbpCmdGdtLdtIdt },
384 { "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
385 { "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
386 { "pcr", "pcr", "Display the processor control region.", KdbpCmdPcr },
387#ifdef _M_IX86
388 { "tss", "tss [selector|*descaddr]", "Display the current task state segment, or the one specified by its selector number or descriptor address.", KdbpCmdTss },
389#endif
390
391 /* Others */
392 { NULL, NULL, "Others", NULL },
393 { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
394 { "reboot", "reboot", "Reboots the system.", KdbpCmdReboot},
395 { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels.", KdbpCmdFilter },
396 { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
397 { "dmesg", "dmesg", "Display debug messages on screen, with navigation on pages.", KdbpCmdDmesg },
398 { "kmsg", "kmsg", "Kernel dmesg. Alias for dmesg.", KdbpCmdDmesg },
399 { "help", "help", "Display help screen.", KdbpCmdHelp },
400 { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool },
401 { "!poolused", "!poolused [Flags [Tag]]", "Display pool usage.", ExpKdbgExtPoolUsed },
402 { "!poolfind", "!poolfind Tag [Pool]", "Search for pool tag allocations.", ExpKdbgExtPoolFind },
403 { "!filecache", "!filecache", "Display cache usage.", ExpKdbgExtFileCache },
404 { "!defwrites", "!defwrites", "Display cache write values.", ExpKdbgExtDefWrites },
405 { "!irpfind", "!irpfind [Pool [startaddress [criteria data]]]", "Lists IRPs potentially matching criteria.", ExpKdbgExtIrpFind },
406 { "!handle", "!handle [Handle]", "Displays info about handles.", ExpKdbgExtHandle },
408
409/* FUNCTIONS *****************************************************************/
410
423static BOOLEAN
426 IN LONG ErrOffset,
428{
429 static CHAR ErrMsgBuffer[130] = "^ ";
430 LONG ExpressionErrOffset = -1;
431 PCHAR ErrMsg = ErrMsgBuffer;
432 BOOLEAN Ok;
433
435 &ExpressionErrOffset, ErrMsgBuffer + 2);
436 if (!Ok)
437 {
438 if (ExpressionErrOffset >= 0)
439 ExpressionErrOffset += ErrOffset;
440 else
441 ErrMsg += 2;
442
443 KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
444 }
445
446 return Ok;
447}
448
450NTAPI
452 IN PCHAR pszNum,
453 OUT ULONG_PTR *pulValue)
454{
455 char *endptr;
456
457 /* Skip optional '0x' prefix */
458 if ((pszNum[0] == '0') && ((pszNum[1] == 'x') || (pszNum[1] == 'X')))
459 pszNum += 2;
460
461 /* Make a number from the string (hex) */
462 *pulValue = strtoul(pszNum, &endptr, 16);
463
464 return (*endptr == '\0');
465}
466
469static BOOLEAN
471 ULONG Argc,
472 PCHAR Argv[])
473{
474 ULONG i;
475 SIZE_T len;
476 ULONGLONG Result = 0;
477 ULONG ul;
478 LONG l = 0;
479 BOOLEAN Ok;
480
481 if (Argc < 2)
482 {
483 KdbpPrint("?: Argument required\n");
484 return TRUE;
485 }
486
487 /* Put the arguments back together */
488 Argc--;
489 for (i = 1; i < Argc; i++)
490 {
491 len = strlen(Argv[i]);
492 Argv[i][len] = ' ';
493 }
494
495 /* Evaluate the expression */
496 Ok = KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result);
497 if (Ok)
498 {
499 if (Result > 0x00000000ffffffffLL)
500 {
501 if (Result & 0x8000000000000000LL)
502 KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
503 else
504 KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
505 }
506 else
507 {
508 ul = (ULONG)Result;
509
510 if (ul <= 0xff && ul >= 0x80)
511 l = (LONG)((CHAR)ul);
512 else if (ul <= 0xffff && ul >= 0x8000)
513 l = (LONG)((SHORT)ul);
514 else
515 l = (LONG)ul;
516
517 if (l < 0)
518 KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
519 else
520 KdbpPrint("0x%08lx %10lu\n", ul, ul);
521 }
522 }
523
524 return TRUE;
525}
526
527#ifdef __ROS_DWARF__
528
531static VOID
532KdbpPrintStructInternal
534 PCHAR Indent,
535 BOOLEAN DoRead,
537 PROSSYM_AGGREGATE Aggregate)
538{
539 ULONG i;
542 ULONG IndentLen = strlen(Indent);
543 ROSSYM_AGGREGATE MemberAggregate = {0 };
544
545 for (i = 0; i < Aggregate->NumElements; i++) {
546 Member = &Aggregate->Elements[i];
547 KdbpPrint("%s%p+%x: %s", Indent, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size, Member->Name ? Member->Name : "<anoymous>");
548 if (DoRead) {
549 if (!strcmp(Member->Type, "_UNICODE_STRING")) {
550 KdbpPrint("\"");
552 KdbpPrint("\"\n");
553 continue;
554 } else if (!strcmp(Member->Type, "PUNICODE_STRING")) {
555 KdbpPrint("\"");
557 KdbpPrint("\"\n");
558 continue;
559 }
560 switch (Member->Size) {
561 case 1:
562 case 2:
563 case 4:
564 case 8: {
565 Result = 0;
566 if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
567 if (Member->Bits) {
568 Result >>= Member->FirstBit;
569 Result &= ((1 << Member->Bits) - 1);
570 }
571 KdbpPrint(" %lx\n", Result);
572 }
573 else goto readfail;
574 break;
575 }
576 default: {
577 if (Member->Size < 8) {
578 if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
579 ULONG j;
580 for (j = 0; j < Member->Size; j++) {
581 KdbpPrint(" %02x", (int)(Result & 0xff));
582 Result >>= 8;
583 }
584 } else goto readfail;
585 } else {
586 KdbpPrint(" %s @ %p {\n", Member->Type, ((PCHAR)BaseAddress) + Member->BaseOffset);
587 Indent[IndentLen] = ' ';
588 if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
589 KdbpPrintStructInternal(Info, Indent, DoRead, ((PCHAR)BaseAddress) + Member->BaseOffset, &MemberAggregate);
590 RosSymFreeAggregate(&MemberAggregate);
591 }
592 Indent[IndentLen] = 0;
593 KdbpPrint("%s}\n", Indent);
594 } break;
595 }
596 }
597 } else {
598 readfail:
599 if (Member->Size <= 8) {
600 KdbpPrint(" ??\n");
601 } else {
602 KdbpPrint(" %s @ %x {\n", Member->Type, Member->BaseOffset);
603 Indent[IndentLen] = ' ';
604 if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
605 KdbpPrintStructInternal(Info, Indent, DoRead, BaseAddress, &MemberAggregate);
606 RosSymFreeAggregate(&MemberAggregate);
607 }
608 Indent[IndentLen] = 0;
609 KdbpPrint("%s}\n", Indent);
610 }
611 }
612 }
613}
614
615PROSSYM_INFO KdbpSymFindCachedFile(PUNICODE_STRING ModName);
616
617static BOOLEAN
618KdbpCmdPrintStruct(
619 ULONG Argc,
620 PCHAR Argv[])
621{
622 ULONG i;
623 ULONGLONG Result = 0;
625 ROSSYM_AGGREGATE Aggregate = {0};
626 UNICODE_STRING ModName = {0};
627 ANSI_STRING AnsiName = {0};
628 CHAR Indent[100] = {0};
630
631 if (Argc < 3) goto end;
632 AnsiName.Length = AnsiName.MaximumLength = strlen(Argv[1]);
633 AnsiName.Buffer = Argv[1];
634 RtlAnsiStringToUnicodeString(&ModName, &AnsiName, TRUE);
635 Info = KdbpSymFindCachedFile(&ModName);
636
637 if (!Info || !RosSymAggregate(Info, Argv[2], &Aggregate)) {
638 DPRINT1("Could not get aggregate\n");
639 goto end;
640 }
641
642 // Get an argument for location if it was given
643 if (Argc > 3) {
644 ULONG len;
645 PCHAR ArgStart = Argv[3];
646 DPRINT("Trying to get expression\n");
647 for (i = 3; i < Argc - 1; i++)
648 {
649 len = strlen(Argv[i]);
650 Argv[i][len] = ' ';
651 }
652
653 /* Evaluate the expression */
654 DPRINT("Arg: %s\n", ArgStart);
655 if (KdbpEvaluateExpression(ArgStart, strlen(ArgStart), &Result))
657 }
658 DPRINT("BaseAddress: %p\n", BaseAddress);
659 KdbpPrintStructInternal(Info, Indent, !!BaseAddress, BaseAddress, &Aggregate);
660end:
661 RosSymFreeAggregate(&Aggregate);
662 RtlFreeUnicodeString(&ModName);
663 return TRUE;
664}
665#endif // __ROS_DWARF__
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] == 'c') /* cregs */
989 {
990 ULONG Cr0, Cr2, Cr3, Cr4;
991 KDESCRIPTOR Gdtr = {0, 0, 0}, Idtr = {0, 0, 0};
992 USHORT Ldtr, Tr;
993 static const PCHAR Cr0Bits[32] = { " PE", " MP", " EM", " TS", " ET", " NE", NULL, NULL,
995 " WP", NULL, " AM", NULL, NULL, NULL, NULL, NULL,
996 NULL, NULL, NULL, NULL, NULL, " NW", " CD", " PG" };
997 static const PCHAR Cr4Bits[32] = { " VME", " PVI", " TSD", " DE", " PSE", " PAE", " MCE", " PGE",
998 " PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
1000 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
1002 KSPECIAL_REGISTERS SpecialRegisters;
1004
1005 /* Retrieve the control registers */
1006 RtlZeroMemory(&Input, sizeof(Input));
1007 Input.Buffer = &SpecialRegisters;
1008 Input.Request = sizeof(SpecialRegisters);
1009#ifdef _M_IX86
1010 Input.Address = sizeof(CONTEXT);
1011#else
1013#endif
1015 &Input, sizeof(Input),
1016 NULL, 0,
1017 NULL, KernelMode);
1018 if (!NT_SUCCESS(Status))
1019 {
1020 KdbpPrint("Failed to get registers: status 0x%08x\n", Status);
1021 return TRUE;
1022 }
1023 Cr0 = SpecialRegisters.Cr0;
1024 Cr2 = SpecialRegisters.Cr2;
1025 Cr3 = SpecialRegisters.Cr3;
1026 Cr4 = SpecialRegisters.Cr4;
1027
1028 /* Retrieve the descriptor table and task segment registers */
1029 Gdtr = SpecialRegisters.Gdtr;
1030 Ldtr = SpecialRegisters.Ldtr;
1031 Idtr = SpecialRegisters.Idtr;
1032 Tr = SpecialRegisters.Tr;
1033
1034 /* Display the control registers */
1035 KdbpPrint("CR0 0x%08x ", Cr0);
1036 for (i = 0; i < 32; i++)
1037 {
1038 if (!Cr0Bits[i])
1039 continue;
1040
1041 if ((Cr0 & (1 << i)) != 0)
1042 KdbpPrint(Cr0Bits[i]);
1043 }
1044 KdbpPrint("\n");
1045
1046 KdbpPrint("CR2 0x%08x\n", Cr2);
1047 KdbpPrint("CR3 0x%08x Pagedir-Base 0x%08x %s%s\n", Cr3, (Cr3 & 0xfffff000),
1048 (Cr3 & (1 << 3)) ? " PWT" : "", (Cr3 & (1 << 4)) ? " PCD" : "" );
1049 KdbpPrint("CR4 0x%08x ", Cr4);
1050 for (i = 0; i < 32; i++)
1051 {
1052 if (!Cr4Bits[i])
1053 continue;
1054
1055 if ((Cr4 & (1 << i)) != 0)
1056 KdbpPrint(Cr4Bits[i]);
1057 }
1058 KdbpPrint("\n");
1059
1060 /* Display the descriptor table and task segment registers */
1061 KdbpPrint("GDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
1062 KdbpPrint("LDTR 0x%04x\n", Ldtr);
1063 KdbpPrint("IDTR Base 0x%08x Size 0x%04x\n", Idtr.Base, Idtr.Limit);
1064 KdbpPrint("TR 0x%04x\n", Tr);
1065 }
1066 else if (Argv[0][0] == 's') /* sregs */
1067 {
1068 KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
1069 Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
1070 (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
1071 KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
1072 Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
1073 KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
1074 Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
1075 KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
1076 Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
1077 KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
1078 Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1079 KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1080 Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1081 }
1082 else /* dregs */
1083 {
1084 ASSERT(Argv[0][0] == 'd');
1085 KdbpPrint("DR0 0x%08x\n"
1086 "DR1 0x%08x\n"
1087 "DR2 0x%08x\n"
1088 "DR3 0x%08x\n"
1089 "DR6 0x%08x\n"
1090 "DR7 0x%08x\n",
1091 Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1092 Context->Dr6, Context->Dr7);
1093 }
1094
1095 return TRUE;
1096}
1097
1098#ifdef _M_IX86
1099static PKTSS
1100KdbpRetrieveTss(
1101 IN USHORT TssSelector,
1102 OUT PULONG pType OPTIONAL,
1103 IN PKDESCRIPTOR pGdtr OPTIONAL)
1104{
1105 KDESCRIPTOR Gdtr;
1106 KGDTENTRY Desc;
1107 PKTSS Tss;
1108
1109 /* Retrieve the Global Descriptor Table (user-provided or system) */
1110 if (pGdtr)
1111 Gdtr = *pGdtr;
1112 else
1114
1115 /* Check limits */
1116 if ((TssSelector & (sizeof(KGDTENTRY) - 1)) ||
1117 (TssSelector < sizeof(KGDTENTRY)) ||
1118 (TssSelector + sizeof(KGDTENTRY) - 1 > Gdtr.Limit))
1119 {
1120 return NULL;
1121 }
1122
1123 /* Retrieve the descriptor */
1124 if (!NT_SUCCESS(KdbpSafeReadMemory(&Desc,
1125 (PVOID)(Gdtr.Base + TssSelector),
1126 sizeof(KGDTENTRY))))
1127 {
1128 return NULL;
1129 }
1130
1131 /* Check for TSS32(Avl) or TSS32(Busy) */
1132 if (Desc.HighWord.Bits.Type != 9 && Desc.HighWord.Bits.Type != 11)
1133 {
1134 return NULL;
1135 }
1136 if (pType) *pType = Desc.HighWord.Bits.Type;
1137
1138 Tss = (PKTSS)(ULONG_PTR)(Desc.BaseLow |
1139 Desc.HighWord.Bytes.BaseMid << 16 |
1140 Desc.HighWord.Bytes.BaseHi << 24);
1141
1142 return Tss;
1143}
1144
1146KdbpIsNestedTss(
1147 IN USHORT TssSelector,
1148 IN PKTSS Tss)
1149{
1150 USHORT Backlink;
1151
1152 if (!Tss)
1153 return FALSE;
1154
1155#ifdef _M_AMD64
1156 // HACK
1157 return FALSE;
1158#else
1159 /* Retrieve the TSS Backlink */
1160 if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1161 (PVOID)&Tss->Backlink,
1162 sizeof(USHORT))))
1163 {
1164 return FALSE;
1165 }
1166#endif
1167
1168 return (Backlink != 0 && Backlink != TssSelector);
1169}
1170
1171static BOOLEAN
1172KdbpContextFromPrevTss(
1174 OUT PUSHORT TssSelector,
1175 IN OUT PKTSS* pTss,
1176 IN PKDESCRIPTOR pGdtr)
1177{
1178 ULONG_PTR Eip, Ebp;
1179 USHORT Backlink;
1180 PKTSS Tss = *pTss;
1181
1182#ifdef _M_AMD64
1183 // HACK
1184 return FALSE;
1185#else
1186 /* Retrieve the TSS Backlink */
1187 if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1188 (PVOID)&Tss->Backlink,
1189 sizeof(USHORT))))
1190 {
1191 return FALSE;
1192 }
1193
1194 /* Retrieve the parent TSS */
1195 Tss = KdbpRetrieveTss(Backlink, NULL, pGdtr);
1196 if (!Tss)
1197 return FALSE;
1198
1200 (PVOID)&Tss->Eip,
1201 sizeof(ULONG_PTR))))
1202 {
1203 return FALSE;
1204 }
1205
1207 (PVOID)&Tss->Ebp,
1208 sizeof(ULONG_PTR))))
1209 {
1210 return FALSE;
1211 }
1212
1213 /* Return the parent TSS and its trap frame */
1214 *TssSelector = Backlink;
1215 *pTss = Tss;
1216 Context->Eip = Eip;
1217 Context->Ebp = Ebp;
1218#endif
1219 return TRUE;
1220}
1221#endif // _M_IX86
1222
1223#ifdef _M_AMD64
1224
1225static
1226BOOLEAN
1227GetNextFrame(
1229{
1230 PRUNTIME_FUNCTION FunctionEntry;
1231 ULONG64 ImageBase, EstablisherFrame;
1232 PVOID HandlerData;
1233
1234 _SEH2_TRY
1235 {
1236 /* Lookup the FunctionEntry for the current RIP */
1237 FunctionEntry = RtlLookupFunctionEntry(Context->Rip, &ImageBase, NULL);
1238 if (FunctionEntry == NULL)
1239 {
1240 /* No function entry, so this must be a leaf function. Pop the return address from the stack.
1241 Note: this can happen after the first frame as the result of an exception */
1242 Context->Rip = *(DWORD64*)Context->Rsp;
1243 Context->Rsp += sizeof(DWORD64);
1244 return TRUE;
1245 }
1246 else
1247 {
1249 ImageBase,
1250 Context->Rip,
1251 FunctionEntry,
1252 Context,
1253 &HandlerData,
1255 NULL);
1256 }
1257 }
1258 _SEH2_EXCEPT(1)
1259 {
1260 return FALSE;
1261 }
1262 _SEH2_END
1263
1264 return TRUE;
1265}
1266
1267static BOOLEAN
1269 ULONG Argc,
1270 PCHAR Argv[])
1271{
1273
1274 /* Walk through the frames */
1275 KdbpPrint("Frames:\n");
1276 do
1277 {
1278 BOOLEAN GotNextFrame;
1279
1280 KdbpPrint("[%p] ", (PVOID)Context.Rsp);
1281
1282 /* Print the location after the call instruction */
1284 KdbpPrint("<%p>", (PVOID)Context.Rip);
1285 KdbpPrint("\n");
1286
1287 if (KdbOutputAborted)
1288 break;
1289
1290 GotNextFrame = GetNextFrame(&Context);
1291 if (!GotNextFrame)
1292 {
1293 KdbpPrint("Couldn't get next frame\n");
1294 break;
1295 }
1296 } while ((Context.Rip != 0) && (Context.Rsp != 0));
1297
1298 return TRUE;
1299}
1300#else
1303static BOOLEAN
1305 ULONG Argc,
1306 PCHAR Argv[])
1307{
1308 ULONG ul;
1309 ULONGLONG Result = 0;
1313
1314 if (Argc >= 2)
1315 {
1316 /* Check for [L count] part */
1317 ul = 0;
1318 if (strcmp(Argv[Argc-2], "L") == 0)
1319 {
1320 ul = strtoul(Argv[Argc-1], NULL, 0);
1321 if (ul > 0)
1322 {
1323 Argc -= 2;
1324 }
1325 }
1326 else if (Argv[Argc-1][0] == 'L')
1327 {
1328 ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1329 if (ul > 0)
1330 {
1331 Argc--;
1332 }
1333 }
1334
1335 /* Put the remaining arguments back together */
1336 Argc--;
1337 for (ul = 1; ul < Argc; ul++)
1338 {
1339 Argv[ul][strlen(Argv[ul])] = ' ';
1340 }
1341 Argc++;
1342 }
1343
1344 /* Check if a Frame Address or Thread ID is given */
1345 if (Argc > 1)
1346 {
1347 if (Argv[1][0] == '*')
1348 {
1349 Argv[1]++;
1350
1351 /* Evaluate the expression */
1352 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
1353 return TRUE;
1354
1355 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1356 KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1357
1358 Frame = (ULONG_PTR)Result;
1359 }
1360 else
1361 {
1362 KdbpPrint("Thread backtrace not supported yet!\n");
1363 return TRUE;
1364 }
1365 }
1366
1367#ifdef _M_IX86
1368 KDESCRIPTOR Gdtr;
1369 USHORT TssSelector;
1370 PKTSS Tss;
1371
1372 /* Retrieve the Global Descriptor Table */
1374
1375 /* Retrieve the current (active) TSS */
1376 TssSelector = Ke386GetTr();
1377 Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1378 if (KdbpIsNestedTss(TssSelector, Tss))
1379 {
1380 /* Display the active TSS if it is nested */
1381 KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1382 }
1383#endif
1384
1385 /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1386 if (Argc <= 1)
1387 {
1388 KdbpPrint("Eip:\n");
1390 KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1391 else
1392 KdbpPrint("\n");
1393 }
1394
1395 /* Walk through the frames */
1396 KdbpPrint("Frames:\n");
1397 for (;;)
1398 {
1399 BOOLEAN GotNextFrame;
1400
1401 if (Frame == 0)
1402 goto CheckForParentTSS;
1403
1404 Address = 0;
1405 if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1406 {
1407 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1408 goto CheckForParentTSS;
1409 }
1410
1411 if (Address == 0)
1412 goto CheckForParentTSS;
1413
1414 GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1415 if (GotNextFrame)
1416 {
1418 }
1419 // else
1420 // Frame = 0;
1421
1422 /* Print the location of the call instruction (assumed 5 bytes length) */
1423 if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1424 KdbpPrint("<%08x>\n", Address);
1425 else
1426 KdbpPrint("\n");
1427
1428 if (KdbOutputAborted)
1429 break;
1430
1431 if (!GotNextFrame)
1432 {
1433 KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1434 goto CheckForParentTSS; // break;
1435 }
1436
1437 continue;
1438
1439CheckForParentTSS:
1440#ifndef _M_IX86
1441 break;
1442#else
1443 /*
1444 * We have ended the stack walking for the current (active) TSS.
1445 * Check whether this TSS was nested, and if so switch to its parent
1446 * and walk its stack.
1447 */
1448 if (!KdbpIsNestedTss(TssSelector, Tss))
1449 break; // The TSS is not nested, we stop there.
1450
1451 GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1452 if (!GotNextFrame)
1453 {
1454 KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1455 break; // Cannot retrieve the parent TSS, we stop there.
1456 }
1457
1458
1459 Address = Context.Eip;
1460 Frame = Context.Ebp;
1461
1462 KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1463
1465 KdbpPrint("<%08x>\n", Address);
1466 else
1467 KdbpPrint("\n");
1468#endif
1469 }
1470
1471 return TRUE;
1472}
1473
1474#endif // M_AMD64
1475
1478static BOOLEAN
1480 ULONG Argc,
1481 PCHAR Argv[])
1482{
1483 /* Exit the main loop */
1484 return FALSE;
1485}
1486
1489static BOOLEAN
1491 ULONG Argc,
1492 PCHAR Argv[])
1493{
1494 ULONG Count = 1;
1495
1496 if (Argc > 1)
1497 {
1498 Count = strtoul(Argv[1], NULL, 0);
1499 if (Count == 0)
1500 {
1501 KdbpPrint("%s: Integer argument required\n", Argv[0]);
1502 return TRUE;
1503 }
1504 }
1505
1506 if (Argv[0][0] == 'n')
1508 else
1510
1511 /* Set the number of single steps and return to the interrupted code. */
1513
1514 return FALSE;
1515}
1516
1519static BOOLEAN
1521 ULONG Argc,
1522 PCHAR Argv[])
1523{
1524 LONG l;
1525 ULONG_PTR Address = 0;
1527 KDB_ACCESS_TYPE AccessType = 0;
1528 UCHAR Size = 0;
1529 UCHAR DebugReg = 0;
1533 PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
1534 CHAR Buffer[20];
1535
1537 if (l < 0)
1538 {
1539 KdbpPrint("No breakpoints.\n");
1540 return TRUE;
1541 }
1542
1543 KdbpPrint("Breakpoints:\n");
1544 do
1545 {
1546 if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
1547 &Enabled, &Global, &Process, &ConditionExpr))
1548 {
1549 continue;
1550 }
1551
1552 if (l == KdbLastBreakPointNr)
1553 {
1554 str1 = "\x1b[1m*";
1555 str2 = "\x1b[0m";
1556 }
1557 else
1558 {
1559 str1 = " ";
1560 str2 = "";
1561 }
1562
1563 if (Global)
1564 {
1565 GlobalOrLocal = " global";
1566 }
1567 else
1568 {
1569 GlobalOrLocal = Buffer;
1570 sprintf(Buffer, " PID 0x%Ix",
1571 (ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
1572 }
1573
1575 {
1576 KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
1577 str1, l, Address,
1578 Enabled ? "" : " disabled",
1579 GlobalOrLocal,
1580 ConditionExpr ? " IF " : "",
1581 ConditionExpr ? ConditionExpr : "",
1582 str2);
1583 }
1584 else if (Type == KdbBreakPointHardware)
1585 {
1586 if (!Enabled)
1587 {
1588 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
1589 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1590 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1591 GlobalOrLocal,
1592 ConditionExpr ? " IF " : "",
1593 ConditionExpr ? ConditionExpr : "",
1594 str2);
1595 }
1596 else
1597 {
1598 KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
1599 KDB_ACCESS_TYPE_TO_STRING(AccessType),
1600 Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1601 DebugReg,
1602 GlobalOrLocal,
1603 ConditionExpr ? " IF " : "",
1604 ConditionExpr ? ConditionExpr : "",
1605 str2);
1606 }
1607 }
1608 }
1609 while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
1610
1611 return TRUE;
1612}
1613
1616static BOOLEAN
1618 ULONG Argc,
1619 PCHAR Argv[])
1620{
1621 PCHAR pend;
1622 ULONG BreakPointNr;
1623
1624 if (Argc < 2)
1625 {
1626 KdbpPrint("%s: argument required\n", Argv[0]);
1627 return TRUE;
1628 }
1629
1630 pend = Argv[1];
1631 BreakPointNr = strtoul(Argv[1], &pend, 0);
1632 if (pend == Argv[1] || *pend != '\0')
1633 {
1634 KdbpPrint("%s: integer argument required\n", Argv[0]);
1635 return TRUE;
1636 }
1637
1638 if (Argv[0][1] == 'e') /* enable */
1639 {
1640 KdbpEnableBreakPoint(BreakPointNr, NULL);
1641 }
1642 else if (Argv [0][1] == 'd') /* disable */
1643 {
1644 KdbpDisableBreakPoint(BreakPointNr, NULL);
1645 }
1646 else /* clear */
1647 {
1648 ASSERT(Argv[0][1] == 'c');
1649 KdbpDeleteBreakPoint(BreakPointNr, NULL);
1650 }
1651
1652 return TRUE;
1653}
1654
1657static BOOLEAN
1659{
1660 ULONGLONG Result = 0;
1663 UCHAR Size = 0;
1664 KDB_ACCESS_TYPE AccessType = 0;
1665 ULONG AddressArgIndex, i;
1666 LONG ConditionArgIndex;
1668
1669 if (Argv[0][2] == 'x') /* software breakpoint */
1670 {
1671 if (Argc < 2)
1672 {
1673 KdbpPrint("bpx: Address argument required.\n");
1674 return TRUE;
1675 }
1676
1677 AddressArgIndex = 1;
1679 }
1680 else /* memory breakpoint */
1681 {
1682 ASSERT(Argv[0][2] == 'm');
1683
1684 if (Argc < 2)
1685 {
1686 KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
1687 return TRUE;
1688 }
1689
1690 if (_stricmp(Argv[1], "x") == 0)
1691 AccessType = KdbAccessExec;
1692 else if (_stricmp(Argv[1], "r") == 0)
1693 AccessType = KdbAccessRead;
1694 else if (_stricmp(Argv[1], "w") == 0)
1695 AccessType = KdbAccessWrite;
1696 else if (_stricmp(Argv[1], "rw") == 0)
1697 AccessType = KdbAccessReadWrite;
1698 else
1699 {
1700 KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
1701 return TRUE;
1702 }
1703
1704 if (Argc < 3)
1705 {
1706 KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
1707 return TRUE;
1708 }
1709
1710 AddressArgIndex = 3;
1711 if (_stricmp(Argv[2], "byte") == 0)
1712 Size = 1;
1713 else if (_stricmp(Argv[2], "word") == 0)
1714 Size = 2;
1715 else if (_stricmp(Argv[2], "dword") == 0)
1716 Size = 4;
1717 else if (AccessType == KdbAccessExec)
1718 {
1719 Size = 1;
1720 AddressArgIndex--;
1721 }
1722 else
1723 {
1724 KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
1725 return TRUE;
1726 }
1727
1728 if (Argc <= AddressArgIndex)
1729 {
1730 KdbpPrint("bpm: Address argument required.\n");
1731 return TRUE;
1732 }
1733
1735 }
1736
1737 /* Put the arguments back together */
1738 ConditionArgIndex = -1;
1739 for (i = AddressArgIndex; i < (Argc-1); i++)
1740 {
1741 if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
1742 {
1743 ConditionArgIndex = i + 2;
1744 if ((ULONG)ConditionArgIndex >= Argc)
1745 {
1746 KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
1747 return TRUE;
1748 }
1749
1750 for (i = ConditionArgIndex; i < (Argc-1); i++)
1751 Argv[i][strlen(Argv[i])] = ' ';
1752
1753 break;
1754 }
1755
1756 Argv[i][strlen(Argv[i])] = ' ';
1757 }
1758
1759 /* Evaluate the address expression */
1760 if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
1761 KdbPromptStr.Length + (Argv[AddressArgIndex]-Argv[0]),
1762 &Result))
1763 {
1764 return TRUE;
1765 }
1766
1767 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1768 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
1769
1771
1772 KdbpInsertBreakPoint(Address, Type, Size, AccessType,
1773 (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
1774 Global, NULL);
1775
1776 return TRUE;
1777}
1778
1781static BOOLEAN
1783 ULONG Argc,
1784 PCHAR Argv[])
1785{
1789 BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1791 PULONG_PTR Frame;
1792 ULONG_PTR Pc;
1793 ULONG_PTR ul = 0;
1794 PCHAR State, pend, str1, str2;
1795 static const PCHAR ThreadStateToString[DeferredReady+1] =
1796 {
1797 "Initialized", "Ready", "Running",
1798 "Standby", "Terminated", "Waiting",
1799 "Transition", "DeferredReady"
1800 };
1801
1803
1804 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1805 {
1807
1808 if (Argc >= 3)
1809 {
1810 ul = strtoulptr(Argv[2], &pend, 0);
1811 if (Argv[2] == pend)
1812 {
1813 KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1814 return TRUE;
1815 }
1816
1818 {
1819 KdbpPrint("thread: Invalid process id!\n");
1820 return TRUE;
1821 }
1822
1823 /* Remember our reference */
1824 ReferencedProcess = TRUE;
1825 }
1826
1827 Entry = Process->ThreadListHead.Flink;
1828 if (Entry == &Process->ThreadListHead)
1829 {
1830 if (Argc >= 3)
1831 KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1832 else
1833 KdbpPrint("No threads in current process!\n");
1834
1835 if (ReferencedProcess)
1837
1838 return TRUE;
1839 }
1840
1841 KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1842 do
1843 {
1844 Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1845
1846 if (Thread == KdbCurrentThread)
1847 {
1848 str1 = "\x1b[1m*";
1849 str2 = "\x1b[0m";
1850 }
1851 else
1852 {
1853 str1 = " ";
1854 str2 = "";
1855 }
1856
1857 if (!Thread->Tcb.InitialStack)
1858 {
1859 /* Thread has no kernel stack (probably terminated) */
1860 Stack = Frame = NULL;
1861 Pc = 0;
1862 }
1863 else if (Thread->Tcb.TrapFrame)
1864 {
1868 }
1869 else
1870 {
1872 Frame = (PULONG_PTR)Stack[4];
1873 Pc = 0;
1874
1875 if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1876 KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1877 }
1878
1879 if (Thread->Tcb.State < (DeferredReady + 1))
1880 State = ThreadStateToString[Thread->Tcb.State];
1881 else
1882 State = "Unknown";
1883
1884 KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1885 str1,
1887 State,
1890 Frame,
1891 Pc,
1892 str2);
1893
1894 Entry = Entry->Flink;
1895 }
1896 while (Entry != &Process->ThreadListHead);
1897
1898 /* Release our reference, if any */
1899 if (ReferencedProcess)
1901 }
1902 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1903 {
1904 if (Argc < 3)
1905 {
1906 KdbpPrint("thread attach: thread id argument required!\n");
1907 return TRUE;
1908 }
1909
1910 ul = strtoulptr(Argv[2], &pend, 0);
1911 if (Argv[2] == pend)
1912 {
1913 KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1914 return TRUE;
1915 }
1916
1917 if (!KdbpAttachToThread((PVOID)ul))
1918 {
1919 return TRUE;
1920 }
1921
1922 KdbpPrint("Attached to thread 0x%08x.\n", ul);
1923 }
1924 else
1925 {
1927
1928 if (Argc >= 2)
1929 {
1930 ul = strtoulptr(Argv[1], &pend, 0);
1931 if (Argv[1] == pend)
1932 {
1933 KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1934 return TRUE;
1935 }
1936
1938 {
1939 KdbpPrint("thread: Invalid thread id!\n");
1940 return TRUE;
1941 }
1942
1943 /* Remember our reference */
1944 ReferencedThread = TRUE;
1945 }
1946
1947 if (Thread->Tcb.State < (DeferredReady + 1))
1948 State = ThreadStateToString[Thread->Tcb.State];
1949 else
1950 State = "Unknown";
1951
1952 KdbpPrint("%s"
1953 " TID: 0x%08x\n"
1954 " State: %s (0x%x)\n"
1955 " Priority: %d\n"
1956 " Affinity: 0x%08x\n"
1957 " Initial Stack: 0x%08x\n"
1958 " Stack Limit: 0x%08x\n"
1959 " Stack Base: 0x%08x\n"
1960 " Kernel Stack: 0x%08x\n"
1961 " Trap Frame: 0x%08x\n"
1962#ifndef _M_AMD64
1963 " NPX State: %s (0x%x)\n"
1964#endif
1965 , (Argc < 2) ? "Current Thread:\n" : ""
1967 , State, Thread->Tcb.State
1975#ifndef _M_AMD64
1977#endif
1978 );
1979
1980 /* Release our reference if we had one */
1981 if (ReferencedThread)
1983 }
1984
1985 return TRUE;
1986}
1987
1990static BOOLEAN
1992 ULONG Argc,
1993 PCHAR Argv[])
1994{
1997 BOOLEAN ReferencedProcess = FALSE;
1998 PCHAR State, pend, str1, str2;
1999 ULONG_PTR ul;
2001
2002 if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
2003 {
2005 if (!Entry || Entry == &PsActiveProcessHead)
2006 {
2007 KdbpPrint("No processes in the system!\n");
2008 return TRUE;
2009 }
2010
2011 KdbpPrint(" PID State Filename\n");
2012 do
2013 {
2014 Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
2015
2017 {
2018 str1 = "\x1b[1m*";
2019 str2 = "\x1b[0m";
2020 }
2021 else
2022 {
2023 str1 = " ";
2024 str2 = "";
2025 }
2026
2027 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2028 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2029
2030 KdbpPrint(" %s0x%08x %-10s %s%s\n",
2031 str1,
2032 Process->UniqueProcessId,
2033 State,
2034 Process->ImageFileName,
2035 str2);
2036
2037 Entry = Entry->Flink;
2038 }
2039 while(Entry != &PsActiveProcessHead);
2040 }
2041 else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
2042 {
2043 if (Argc < 3)
2044 {
2045 KdbpPrint("process attach: process id argument required!\n");
2046 return TRUE;
2047 }
2048
2049 ul = strtoulptr(Argv[2], &pend, 0);
2050 if (Argv[2] == pend)
2051 {
2052 KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
2053 return TRUE;
2054 }
2055
2056 if (!KdbpAttachToProcess((PVOID)ul))
2057 {
2058 return TRUE;
2059 }
2060
2061 KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
2063 }
2064 else
2065 {
2067
2068 if (Argc >= 2)
2069 {
2070 ul = strtoulptr(Argv[1], &pend, 0);
2071 if (Argv[1] == pend)
2072 {
2073 KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
2074 return TRUE;
2075 }
2076
2078 {
2079 KdbpPrint("proc: Invalid process id!\n");
2080 return TRUE;
2081 }
2082
2083 /* Remember our reference */
2084 ReferencedProcess = TRUE;
2085 }
2086
2087 State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2088 ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2089 KdbpPrint("%s"
2090 " PID: 0x%08x\n"
2091 " State: %s (0x%x)\n"
2092 " Image Filename: %s\n",
2093 (Argc < 2) ? "Current process:\n" : "",
2094 Process->UniqueProcessId,
2095 State, Process->Pcb.State,
2096 Process->ImageFileName);
2097
2098 /* Release our reference, if any */
2099 if (ReferencedProcess)
2101 }
2102
2103 return TRUE;
2104}
2105
2108static BOOLEAN
2110 ULONG Argc,
2111 PCHAR Argv[])
2112{
2113 ULONGLONG Result = 0;
2115 PLDR_DATA_TABLE_ENTRY LdrEntry;
2116 BOOLEAN DisplayOnlyOneModule = FALSE;
2117 INT i = 0;
2118
2119 if (Argc >= 2)
2120 {
2121 /* Put the arguments back together */
2122 Argc--;
2123 while (--Argc >= 1)
2124 Argv[Argc][strlen(Argv[Argc])] = ' ';
2125
2126 /* Evaluate the expression */
2127 if (!KdbpEvaluateExpression(Argv[1], KdbPromptStr.Length + (Argv[1]-Argv[0]), &Result))
2128 {
2129 return TRUE;
2130 }
2131
2132 if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2133 KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2134
2136
2137 if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2138 {
2139 KdbpPrint("No module containing address 0x%p found!\n", Address);
2140 return TRUE;
2141 }
2142
2143 DisplayOnlyOneModule = TRUE;
2144 }
2145 else
2146 {
2147 if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2148 {
2149 ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2150 KdbpPrint(" Base Size Name\n");
2151 KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2152 return TRUE;
2153 }
2154
2155 i = 1;
2156 }
2157
2158 KdbpPrint(" Base Size Name\n");
2159 for (;;)
2160 {
2161 KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2163 KdbpPrint("\n");
2164
2165 if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2166 break;
2167 }
2168
2169 return TRUE;
2170}
2171
2174static BOOLEAN
2176 ULONG Argc,
2177 PCHAR Argv[])
2178{
2179 KDESCRIPTOR Reg;
2180 ULONG SegDesc[2];
2181 ULONG SegBase;
2182 ULONG SegLimit;
2183 PCHAR SegType;
2184 USHORT SegSel;
2185 UCHAR Type, Dpl;
2186 INT i;
2187 ULONG ul;
2188
2189 if (Argv[0][0] == 'i')
2190 {
2191 /* Read IDTR */
2192 __sidt(&Reg.Limit);
2193
2194 if (Reg.Limit < 7)
2195 {
2196 KdbpPrint("Interrupt descriptor table is empty.\n");
2197 return TRUE;
2198 }
2199
2200 KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
2201 KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
2202
2203 for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2204 {
2205 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2206 {
2207 KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
2208 return TRUE;
2209 }
2210
2211 Dpl = ((SegDesc[1] >> 13) & 3);
2212 if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2213 SegType = "TASKGATE";
2214 else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
2215 SegType = "INTGATE32";
2216 else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
2217 SegType = "INTGATE16";
2218 else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
2219 SegType = "TRAPGATE32";
2220 else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
2221 SegType = "TRAPGATE16";
2222 else
2223 SegType = "UNKNOWN";
2224
2225 if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
2226 {
2227 KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
2228 i / 8, SegType, Dpl);
2229 }
2230 else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2231 {
2232 SegSel = SegDesc[0] >> 16;
2233 KdbpPrint(" %03d %-10s 0x%04x %02d\n",
2234 i / 8, SegType, SegSel, Dpl);
2235 }
2236 else
2237 {
2238 SegSel = SegDesc[0] >> 16;
2239 SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
2240 KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
2241 i / 8, SegType, SegSel, SegBase, Dpl);
2242 }
2243 }
2244 }
2245 else
2246 {
2247 ul = 0;
2248
2249 if (Argv[0][0] == 'g')
2250 {
2251 /* Read GDTR */
2253 i = 8;
2254 }
2255 else
2256 {
2257 ASSERT(Argv[0][0] == 'l');
2258
2259 /* Read LDTR */
2261 Reg.Base = 0;
2262 i = 0;
2263 ul = 1 << 2;
2264 }
2265
2266 if (Reg.Limit < 7)
2267 {
2268 KdbpPrint("%s descriptor table is empty.\n",
2269 Argv[0][0] == 'g' ? "Global" : "Local");
2270 return TRUE;
2271 }
2272
2273 KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
2274 Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
2275 KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
2276
2277 for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2278 {
2279 if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2280 {
2281 KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
2282 return TRUE;
2283 }
2284
2285 Dpl = ((SegDesc[1] >> 13) & 3);
2286 Type = ((SegDesc[1] >> 8) & 0xf);
2287
2288 SegBase = SegDesc[0] >> 16;
2289 SegBase |= (SegDesc[1] & 0xff) << 16;
2290 SegBase |= SegDesc[1] & 0xff000000;
2291 SegLimit = SegDesc[0] & 0x0000ffff;
2292 SegLimit |= (SegDesc[1] >> 16) & 0xf;
2293
2294 if ((SegDesc[1] & (1 << 23)) != 0)
2295 {
2296 SegLimit *= 4096;
2297 SegLimit += 4095;
2298 }
2299 else
2300 {
2301 SegLimit++;
2302 }
2303
2304 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2305 {
2306 switch (Type)
2307 {
2308 case 1: SegType = "TSS16(Avl)"; break;
2309 case 2: SegType = "LDT"; break;
2310 case 3: SegType = "TSS16(Busy)"; break;
2311 case 4: SegType = "CALLGATE16"; break;
2312 case 5: SegType = "TASKGATE"; break;
2313 case 6: SegType = "INTGATE16"; break;
2314 case 7: SegType = "TRAPGATE16"; break;
2315 case 9: SegType = "TSS32(Avl)"; break;
2316 case 11: SegType = "TSS32(Busy)"; break;
2317 case 12: SegType = "CALLGATE32"; break;
2318 case 14: SegType = "INTGATE32"; break;
2319 case 15: SegType = "TRAPGATE32"; break;
2320 default: SegType = "UNKNOWN"; break;
2321 }
2322
2323 if (!(Type >= 1 && Type <= 3) &&
2324 Type != 9 && Type != 11)
2325 {
2326 SegBase = 0;
2327 SegLimit = 0;
2328 }
2329 }
2330 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2331 {
2332 if ((SegDesc[1] & (1 << 22)) != 0)
2333 SegType = "DATA32";
2334 else
2335 SegType = "DATA16";
2336 }
2337 else /* Code segment */
2338 {
2339 if ((SegDesc[1] & (1 << 22)) != 0)
2340 SegType = "CODE32";
2341 else
2342 SegType = "CODE16";
2343 }
2344
2345 if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
2346 {
2347 KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
2348 i / 8, i | Dpl | ul, SegType, Dpl);
2349 }
2350 else
2351 {
2352 KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
2353 i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
2354
2355 if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2356 {
2357 /* FIXME: Display system segment */
2358 }
2359 else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2360 {
2361 if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
2362 KdbpPrint(" E");
2363
2364 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
2365
2366 if ((SegDesc[1] & (1 << 8)) != 0)
2367 KdbpPrint(" A");
2368 }
2369 else /* Code segment */
2370 {
2371 if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
2372 KdbpPrint(" C");
2373
2374 KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
2375
2376 if ((SegDesc[1] & (1 << 8)) != 0)
2377 KdbpPrint(" A");
2378 }
2379
2380 if ((SegDesc[1] & (1 << 20)) != 0)
2381 KdbpPrint(" AVL");
2382
2383 KdbpPrint("\n");
2384 }
2385 }
2386 }
2387
2388 return TRUE;
2389}
2390
2393static BOOLEAN
2395 ULONG Argc,
2396 PCHAR Argv[])
2397{
2398 PKIPCR Pcr = (PKIPCR)KeGetPcr();
2399
2400 KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2401#ifdef _M_IX86
2402 KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2403 " Tib.StackBase: 0x%08x\n"
2404 " Tib.StackLimit: 0x%08x\n"
2405 " Tib.SubSystemTib: 0x%08x\n"
2406 " Tib.FiberData/Version: 0x%08x\n"
2407 " Tib.ArbitraryUserPointer: 0x%08x\n"
2408 " Tib.Self: 0x%08x\n"
2409 " SelfPcr: 0x%08x\n"
2410 " PCRCB: 0x%08x\n"
2411 " Irql: 0x%02x\n"
2412 " IRR: 0x%08x\n"
2413 " IrrActive: 0x%08x\n"
2414 " IDR: 0x%08x\n"
2415 " KdVersionBlock: 0x%08x\n"
2416 " IDT: 0x%08x\n"
2417 " GDT: 0x%08x\n"
2418 " TSS: 0x%08x\n"
2419 " MajorVersion: 0x%04x\n"
2420 " MinorVersion: 0x%04x\n"
2421 " SetMember: 0x%08x\n"
2422 " StallScaleFactor: 0x%08x\n"
2423 " Number: 0x%02x\n"
2424 " L2CacheAssociativity: 0x%02x\n"
2425 " VdmAlert: 0x%08x\n"
2426 " L2CacheSize: 0x%08x\n"
2427 " InterruptMode: 0x%08x\n"
2430 Pcr->NtTib.Self
2431 , Pcr->SelfPcr
2432 , Pcr->Prcb, Pcr->Irql
2433 , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2434 , Pcr->KdVersionBlock
2435 , Pcr->IDT, Pcr->GDT, Pcr->TSS
2436 , Pcr->MajorVersion, Pcr->MinorVersion
2437 , Pcr->SetMember
2438 , Pcr->StallScaleFactor
2439 , Pcr->Number
2441 , Pcr->VdmAlert
2443 , Pcr->InterruptMode);
2444#else
2445 KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2446 KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2447 KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2448 KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2449 KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2450 KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2451 KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2452 KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2453 KdbpPrint(" Irql: %u\n", Pcr->Irql);
2454 KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2455 KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2456 KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2457 KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2458 KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2459 KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2460 KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2461#endif
2462
2463 return TRUE;
2464}
2465
2466#ifdef _M_IX86
2469static BOOLEAN
2470KdbpCmdTss(
2471 ULONG Argc,
2472 PCHAR Argv[])
2473{
2474 USHORT TssSelector;
2475 PKTSS Tss = NULL;
2476
2477 if (Argc >= 2)
2478 {
2479 /*
2480 * Specified TSS via its selector [selector] or descriptor address [*descaddr].
2481 * Note that we ignore any other argument values.
2482 */
2483 PCHAR Param, pszNext;
2484 ULONG ulValue;
2485
2486 Param = Argv[1];
2487 if (Argv[1][0] == '*')
2488 ++Param;
2489
2490 ulValue = strtoul(Param, &pszNext, 0);
2491 if (pszNext && *pszNext)
2492 {
2493 KdbpPrint("Invalid TSS specification.\n");
2494 return TRUE;
2495 }
2496
2497 if (Argv[1][0] == '*')
2498 {
2499 /* Descriptor specified */
2500 TssSelector = 0; // Unknown selector!
2501 // TODO: Room for improvement: Find the TSS descriptor
2502 // in the GDT so as to validate it.
2503 Tss = (PKTSS)(ULONG_PTR)ulValue;
2504 if (!Tss)
2505 {
2506 KdbpPrint("Invalid 32-bit TSS descriptor.\n");
2507 return TRUE;
2508 }
2509 }
2510 else
2511 {
2512 /* Selector specified, retrive the corresponding TSS */
2513 TssSelector = (USHORT)ulValue;
2514 Tss = KdbpRetrieveTss(TssSelector, NULL, NULL);
2515 if (!Tss)
2516 {
2517 KdbpPrint("Invalid 32-bit TSS selector.\n");
2518 return TRUE;
2519 }
2520 }
2521 }
2522
2523 if (!Tss)
2524 {
2525 /* If no TSS was specified, use the current TSS descriptor */
2526 TssSelector = Ke386GetTr();
2527 Tss = KeGetPcr()->TSS;
2528 // NOTE: If everything works OK, Tss is the current TSS corresponding to the TR selector.
2529 }
2530
2531 KdbpPrint("%s TSS 0x%04x is at 0x%p.\n",
2532 (Tss == KeGetPcr()->TSS) ? "Current" : "Specified", TssSelector, Tss);
2533 KdbpPrint(" Backlink: 0x%04x\n"
2534 " Ss0:Esp0: 0x%04x:0x%08x\n"
2535 // NOTE: Ss1:Esp1 and Ss2:Esp2: are in the NotUsed1 field.
2536 " CR3: 0x%08x\n"
2537 " EFlags: 0x%08x\n"
2538 " Eax: 0x%08x\n"
2539 " Ebx: 0x%08x\n"
2540 " Ecx: 0x%08x\n"
2541 " Edx: 0x%08x\n"
2542 " Esi: 0x%08x\n"
2543 " Edi: 0x%08x\n"
2544 " Eip: 0x%08x\n"
2545 " Esp: 0x%08x\n"
2546 " Ebp: 0x%08x\n"
2547 " Cs: 0x%04x\n"
2548 " Ss: 0x%04x\n"
2549 " Ds: 0x%04x\n"
2550 " Es: 0x%04x\n"
2551 " Fs: 0x%04x\n"
2552 " Gs: 0x%04x\n"
2553 " LDT: 0x%04x\n"
2554 " Flags: 0x%04x\n"
2555 " IoMapBase: 0x%04x\n",
2556 Tss->Backlink, Tss->Ss0, Tss->Esp0, Tss->CR3, Tss->EFlags,
2557 Tss->Eax, Tss->Ebx, Tss->Ecx, Tss->Edx, Tss->Esi, Tss->Edi,
2558 Tss->Eip, Tss->Esp, Tss->Ebp,
2559 Tss->Cs, Tss->Ss, Tss->Ds, Tss->Es, Tss->Fs, Tss->Gs,
2560 Tss->LDT, Tss->Flags, Tss->IoMapBase);
2561
2562 return TRUE;
2563}
2564#endif // _M_IX86
2565
2568static BOOLEAN
2570 ULONG Argc,
2571 PCHAR Argv[])
2572{
2573 /* Set the flag and quit looping */
2575 return FALSE;
2576}
2577
2578static BOOLEAN
2580 ULONG Argc,
2581 PCHAR Argv[])
2582{
2583 /* Reboot immediately (we do not return) */
2585 return FALSE;
2586}
2587
2593static BOOLEAN
2595 ULONG Argc,
2596 PCHAR Argv[])
2597{
2598 ULONG beg, end;
2599
2600 KdbpIsInDmesgMode = TRUE; /* Toggle logging flag */
2601 if (!KdpDmesgBuffer)
2602 {
2603 KdbpPrint("Dmesg: error, buffer is not allocated! /DEBUGPORT=SCREEN kernel param required for dmesg.\n");
2604 return TRUE;
2605 }
2606
2607 KdbpPrint("*** Dmesg *** TotalWritten=%lu, BufferSize=%lu, CurrentPosition=%lu\n",
2609
2610 /* Pass data to the pager */
2613
2614 /* No roll-overs, and overwritten=lost bytes */
2616 {
2617 /* Show buffer (KdpDmesgBuffer + beg, num) */
2619 }
2620 else
2621 {
2622 /* Show 2 buffers: (KdpDmesgBuffer + beg, KdpDmesgBufferSize - beg)
2623 * and: (KdpDmesgBuffer, end) */
2625 KdbpPrint("*** Dmesg: buffer rollup ***\n");
2627 }
2628 KdbpPrint("*** Dmesg: end of output ***\n");
2629
2630 KdbpIsInDmesgMode = FALSE; /* Toggle logging flag */
2631
2632 return TRUE;
2633}
2634
2637static BOOLEAN
2639 ULONG Argc,
2640 PCHAR Argv[])
2641{
2642 LONG l;
2643 BOOLEAN First;
2644 PCHAR pend = 0;
2645 KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
2646 KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
2647
2648 static const PCHAR ExceptionNames[21] =
2649 {
2650 "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
2651 "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
2652 "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
2653 "MACHINECHECK", "SIMDFAULT", "OTHERS"
2654 };
2655
2656 if (Argc == 1)
2657 {
2658 KdbpPrint("Available settings:\n");
2659 KdbpPrint(" syntax [intel|at&t]\n");
2660 KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
2661 KdbpPrint(" break_on_module_load [true|false]\n");
2662 }
2663 else if (strcmp(Argv[1], "syntax") == 0)
2664 {
2665 if (Argc == 2)
2666 {
2667 KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
2668 }
2669 else if (Argc >= 3)
2670 {
2671 if (_stricmp(Argv[2], "intel") == 0)
2673 else if (_stricmp(Argv[2], "at&t") == 0)
2675 else
2676 KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
2677 }
2678 }
2679 else if (strcmp(Argv[1], "condition") == 0)
2680 {
2681 if (Argc == 2)
2682 {
2683 KdbpPrint("Conditions: (First) (Last)\n");
2684 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
2685 {
2686 if (!ExceptionNames[l])
2687 continue;
2688
2689 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2690 ASSERT(FALSE);
2691
2692 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2693 ASSERT(FALSE);
2694
2695 KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
2696 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2697 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2698 }
2699
2700 ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
2701 KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
2702 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2703 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2704 }
2705 else
2706 {
2707 if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
2708 {
2709 l = -1;
2710 }
2711 else
2712 {
2713 l = strtoul(Argv[2], &pend, 0);
2714
2715 if (Argv[2] == pend)
2716 {
2717 for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
2718 {
2719 if (!ExceptionNames[l])
2720 continue;
2721
2722 if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
2723 break;
2724 }
2725 }
2726
2727 if (l >= RTL_NUMBER_OF(ExceptionNames))
2728 {
2729 KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
2730 return TRUE;
2731 }
2732 }
2733
2734 if (Argc > 4)
2735 {
2736 if (_stricmp(Argv[3], "first") == 0)
2737 First = TRUE;
2738 else if (_stricmp(Argv[3], "last") == 0)
2739 First = FALSE;
2740 else
2741 {
2742 KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
2743 return TRUE;
2744 }
2745
2746 if (_stricmp(Argv[4], "never") == 0)
2747 ConditionFirst = KdbDoNotEnter;
2748 else if (_stricmp(Argv[4], "always") == 0)
2749 ConditionFirst = KdbEnterAlways;
2750 else if (_stricmp(Argv[4], "umode") == 0)
2751 ConditionFirst = KdbEnterFromUmode;
2752 else if (_stricmp(Argv[4], "kmode") == 0)
2753 ConditionFirst = KdbEnterFromKmode;
2754 else
2755 {
2756 KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
2757 return TRUE;
2758 }
2759
2760 if (!KdbpSetEnterCondition(l, First, ConditionFirst))
2761 {
2762 if (l >= 0)
2763 KdbpPrint("Couldn't change condition for exception #%02d\n", l);
2764 else
2765 KdbpPrint("Couldn't change condition for all exceptions\n", l);
2766 }
2767 }
2768 else /* Argc >= 3 */
2769 {
2770 if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2771 ASSERT(FALSE);
2772
2773 if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2774 ASSERT(FALSE);
2775
2776 if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
2777 {
2778 KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
2779 l, ExceptionNames[l],
2780 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2781 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2782 }
2783 else
2784 {
2785 KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
2786 KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2787 KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2788 }
2789 }
2790 }
2791 }
2792 else if (strcmp(Argv[1], "break_on_module_load") == 0)
2793 {
2794 if (Argc == 2)
2795 KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
2796 else if (Argc >= 3)
2797 {
2798 if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
2800 else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
2802 else
2803 KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
2804 }
2805 }
2806 else
2807 {
2808 KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
2809 }
2810
2811 return TRUE;
2812}
2813
2816static BOOLEAN
2818 ULONG Argc,
2819 PCHAR Argv[])
2820{
2821 ULONG i;
2822
2823 KdbpPrint("Kernel debugger commands:\n");
2824 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
2825 {
2826 if (!KdbDebuggerCommands[i].Syntax) /* Command group */
2827 {
2828 if (i > 0)
2829 KdbpPrint("\n");
2830
2831 KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
2832 continue;
2833 }
2834
2835 KdbpPrint(" %-20s - %s\n",
2838 }
2839
2840 return TRUE;
2841}
2842
2843
2844/*
2845 * memrchr(), explicitly defined, since absent in the CRT.
2846 * Reverse memchr()
2847 * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
2848 */
2849void *
2850memrchr(const void *s, int c, size_t n)
2851{
2852 const unsigned char *cp;
2853
2854 if (n != 0)
2855 {
2856 cp = (unsigned char *)s + n;
2857 do
2858 {
2859 if (*(--cp) == (unsigned char)c)
2860 return (void *)cp;
2861 } while (--n != 0);
2862 }
2863 return NULL;
2864}
2865
2885static PCHAR
2888 _In_ ULONG BufLength,
2889 _In_ PCCH pCurPos,
2890 _In_ const SIZE* TermSize)
2891{
2892 PCCH p;
2893 // p0 is initial guess of Page Start
2894 ULONG p0len = TermSize->cx * TermSize->cy;
2895 PCCH p0 = pCurPos - p0len;
2896 PCCH prev_p = p0, p1;
2897 ULONG j;
2898
2899 if (pCurPos < Buffer)
2900 pCurPos = Buffer;
2901 ASSERT(pCurPos <= Buffer + BufLength);
2902
2903 p = memrchr(p0, '\n', p0len);
2904 if (!p)
2905 p = p0;
2906 for (j = TermSize->cy; j--; )
2907 {
2908 int linesCnt;
2909 p1 = memrchr(p0, '\n', p-p0);
2910 prev_p = p;
2911 p = p1;
2912 if (!p)
2913 {
2914 p = prev_p;
2915 if (!p)
2916 p = p0;
2917 break;
2918 }
2919 linesCnt = (TermSize->cx+prev_p-p-2) / TermSize->cx;
2920 if (linesCnt > 1)
2921 j -= linesCnt-1;
2922 }
2923
2924 ASSERT(p != NULL);
2925 ++p;
2926 return (PCHAR)p;
2927}
2928
2929static VOID
2932{
2933 PCHAR p;
2934 SIZE_T i;
2935 size_t len;
2936
2937 while ((p = strrchr(String, '\x1b'))) /* Look for escape character */
2938 {
2939 len = strlen(p);
2940 if (p[1] == '[')
2941 {
2942 i = 2;
2943 while (!isalpha(p[i++]));
2944 memmove(p, p + i, len + 1 - i);
2945 }
2946 else
2947 {
2948 memmove(p, p + 1, len);
2949 }
2950 }
2951}
2952
2965static VOID
2968 _In_ ULONG BufLength,
2969 _In_ BOOLEAN DoPage)
2970{
2971 static BOOLEAN TerminalInitialized = FALSE;
2972 CHAR c;
2974 PCHAR p;
2975 SIZE_T i;
2976 LONG RowsPrintedByTerminal;
2977
2978 if (BufLength == 0)
2979 return;
2980
2981 /* Check if the user has aborted output of the current command */
2982 if (KdbOutputAborted)
2983 return;
2984
2985 /* Initialize the terminal */
2986 if (!TerminalInitialized)
2987 {
2988 TerminalInitialized = TRUE;
2990 }
2991
2992 /* Refresh terminal size each time when number of printed rows is 0 */
2993 if (KdbNumberOfRowsPrinted == 0)
2994 {
2996 }
2997
2998 /* Loop through the strings */
2999 p = Buffer;
3000 while (p[0] != '\0')
3001 {
3002 if (DoPage)
3003 {
3004 if (p > Buffer + BufLength)
3005 {
3006 KdbPrintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer + BufLength));
3007 return;
3008 }
3009 }
3010 i = strcspn(p, "\n");
3011
3012 if (DoPage)
3013 {
3014 /* Are we out of buffer? */
3015 if (p + i > Buffer + BufLength)
3016 break; // Leaving pager function
3017 }
3018
3019 /* Calculate the number of lines which will be printed in
3020 * the terminal when outputting the current line. */
3021 if (i > 0)
3022 RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdTermSize.cx;
3023 else
3024 RowsPrintedByTerminal = 0;
3025
3026 if (p[i] == '\n')
3027 RowsPrintedByTerminal++;
3028
3029 //KdbPrintf("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);
3030
3031 /* Display a prompt if we printed one screen full of text */
3032 if (KdTermSize.cy > 0 &&
3033 (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdTermSize.cy)
3034 {
3035 PCSTR Prompt;
3036
3037 /* Disable the repetition of previous command with long many-page output */
3039
3040 if (KdbNumberOfColsPrinted > 0)
3041 KdbPuts("\n");
3042
3043 if (DoPage)
3044 Prompt = "--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---";
3045 else
3046 Prompt = "--- Press q to abort, any other key to continue ---";
3047
3048 KdbPuts(Prompt);
3050 if (DoPage) // Show pressed key
3051 KdbPrintf(" '%c'/scan=%04x\n", c, ScanCode);
3052 else
3053 KdbPuts("\n");
3054
3055 RowsPrintedByTerminal++;
3056
3057 if (c == 'q')
3058 {
3060 return;
3061 }
3062
3063 if (DoPage)
3064 {
3065 if (ScanCode == KEYSC_END || c == 'e')
3066 {
3067 PCHAR pBufEnd = Buffer + BufLength;
3068 p = CountOnePageUp(Buffer, BufLength, pBufEnd, &KdTermSize);
3069 i = strcspn(p, "\n");
3070 }
3071 else if (ScanCode == KEYSC_PAGEUP ||
3072 ScanCode == KEYSC_ARROWUP || c == 'u')
3073 {
3074 p = CountOnePageUp(Buffer, BufLength, p, &KdTermSize);
3075 i = strcspn(p, "\n");
3076 }
3077 else if (ScanCode == KEYSC_HOME || c == 'h')
3078 {
3079 p = Buffer;
3080 i = strcspn(p, "\n");
3081 }
3082 }
3083
3086 }
3087
3088 /* Insert a NUL after the line and print only the current line */
3089 if (p[i] == '\n' && p[i + 1] != '\0')
3090 {
3091 c = p[i + 1];
3092 p[i + 1] = '\0';
3093 }
3094 else
3095 {
3096 c = '\0';
3097 }
3098
3099 /* Remove escape sequences from the line if there is no terminal connected */
3100 // FIXME: Dangerous operation since we modify the source string!!
3101 if (!KdTermConnected)
3103
3104 /* Print the current line */
3105 KdbPuts(p);
3106
3107 /* Restore not null char with saved */
3108 if (c != '\0')
3109 p[i + 1] = c;
3110
3111 /* Set p to the start of the next line and
3112 * remember the number of printed rows/cols */
3113 p += i;
3114 if (p[0] == '\n')
3115 {
3116 p++;
3118 }
3119 else
3120 {
3121 ASSERT(p[0] == '\0');
3123 }
3124
3125 KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3126 }
3127}
3128
3141VOID
3144 _In_ ULONG BufLength)
3145{
3146 /* Call the internal function */
3147 KdbpPagerInternal(Buffer, BufLength, TRUE);
3148}
3149
3159VOID
3162 _In_ ...)
3163{
3164 static CHAR Buffer[4096];
3165 ULONG Length;
3166 va_list ap;
3167
3168 /* Check if the user has aborted output of the current command */
3169 if (KdbOutputAborted)
3170 return;
3171
3172 /* Build the string */
3173 va_start(ap, Format);
3174 Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
3175 Buffer[Length] = '\0';
3176 va_end(ap);
3177
3178 /* Actually print it */
3180}
3181
3182VOID
3185{
3186 ULONG i;
3187
3188 if ((String == NULL) || (String->Buffer == NULL))
3189 {
3190 KdbpPrint("<NULL>");
3191 return;
3192 }
3193
3194 for (i = 0; i < String->Length / sizeof(WCHAR); i++)
3195 {
3196 KdbpPrint("%c", (CHAR)String->Buffer[i]);
3197 }
3198}
3199
3200
3201BOOLEAN
3202NTAPI
3205 BOOLEAN Deregister)
3206{
3207 ULONG i;
3208
3209 /* Loop all entries */
3210 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3211 {
3212 /* Check if deregistering was requested */
3213 if (Deregister)
3214 {
3215 /* Check if this entry is the one that was registered */
3216 if (KdbCliCallbacks[i] == Callback)
3217 {
3218 /* Delete it and report success */
3220 return TRUE;
3221 }
3222 }
3223 else
3224 {
3225 /* Check if this entry is free */
3226 if (KdbCliCallbacks[i] == NULL)
3227 {
3228 /* Set it and and report success */
3230 return TRUE;
3231 }
3232 }
3233 }
3234
3235 /* Unsuccessful */
3236 return FALSE;
3237}
3238
3248static
3249BOOLEAN
3252 IN ULONG Argc,
3253 IN PCHAR Argv[])
3254{
3255 ULONG i;
3256
3257 /* Loop all entries */
3258 for (i = 0; i < _countof(KdbCliCallbacks); i++)
3259 {
3260 /* Check if this entry is registered */
3261 if (KdbCliCallbacks[i])
3262 {
3263 /* Invoke the callback and check if it handled the command */
3264 if (KdbCliCallbacks[i](Command, Argc, Argv))
3265 {
3266 return TRUE;
3267 }
3268 }
3269 }
3270
3271 /* None of the callbacks handled the command */
3272 return FALSE;
3273}
3274
3275
3283static BOOLEAN
3286{
3287 BOOLEAN Continue = TRUE;
3288 SIZE_T i;
3289 PCHAR p;
3290 ULONG Argc;
3291 // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3292 static PCHAR Argv[256];
3293 static CHAR OrigCommand[1024];
3294
3295 RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3296
3297 Argc = 0;
3298 p = Command;
3299
3300 for (;;)
3301 {
3302 while (*p == '\t' || *p == ' ')
3303 p++;
3304
3305 if (*p == '\0')
3306 break;
3307
3308 i = strcspn(p, "\t ");
3309 Argv[Argc++] = p;
3310 p += i;
3311 if (*p == '\0')
3312 break;
3313
3314 *p = '\0';
3315 p++;
3316 }
3317
3318 if (Argc < 1)
3319 return TRUE;
3320
3321 /* Reset the pager state: number of printed rows/cols and aborted output flag */
3324
3325 for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3326 {
3328 continue;
3329
3330 if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3331 {
3332 Continue = KdbDebuggerCommands[i].Fn(Argc, Argv);
3333 goto Done;
3334 }
3335 }
3336
3337 /* Now invoke the registered callbacks */
3338 if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3339 goto Done;
3340
3341 KdbPrintf("Command '%s' is unknown.\n", OrigCommand);
3342
3343Done:
3345 return Continue;
3346}
3347
3352VOID
3354 IN BOOLEAN EnteredOnSingleStep)
3355{
3356 BOOLEAN Continue = TRUE;
3357 static CHAR Command[1024];
3358 static CHAR LastCommand[1024] = "";
3359
3360// FIXME HACK: SYSREG SUPPORT CORE-19807 -- Emit a backtrace.
3361// TODO: Remove once SYSREG "bt" command emission is fixed!
3362#if 1
3363 KdbpDoCommand("bt");
3364#endif
3365
3366 if (EnteredOnSingleStep)
3367 {
3370
3371 KdbPuts(": ");
3373 KdbPuts("<INVALID>");
3374 KdbPuts("\n");
3375 }
3376 else
3377 {
3378 /* Preceding this message is one of the "Entered debugger..." banners */
3379 // KdbPuts("\nEntered debugger\n");
3380 KdbPuts("\nType \"help\" for a list of commands.\n");
3381 }
3382
3383 /* Main loop */
3384 while (Continue)
3385 {
3386 /*
3387 * Print the prompt and read a command.
3388 * Repeat the last one if the user pressed Enter.
3389 * This reduces the risk of RSI when single-stepping!
3390 */
3391 // TEMP HACK! Issue an empty string instead of duplicating "kdb:>"
3392 SIZE_T CmdLen = KdbPrompt(/*KdbPromptStr.Buffer*/"", Command, sizeof(Command));
3393 if (CmdLen == 0)
3394 {
3395 /* Nothing received but the user didn't press Enter, retry */
3396 continue;
3397 }
3398 else if (CmdLen > 1) // i.e. (*Command != ANSI_NULL)
3399 {
3400 /* Save this new last command */
3402 RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Command);
3403
3404 /* Remember it */
3406 }
3407 else if (KdbRepeatLastCommand)
3408 {
3409 /* The user directly pressed Enter */
3410 RtlStringCbCopyA(Command, sizeof(Command), LastCommand);
3411 }
3412
3413 /* Invoke the command */
3414 Continue = KdbpDoCommand(Command);
3415 }
3416}
3417
3429VOID
3431{
3432 PCHAR p1, p2;
3433
3435 if (!p1)
3436 return;
3437
3438 /* Execute the commands in the init file */
3439 KdbPuts("KDB: Executing KDBinit file...\n");
3440 while (p1[0] != '\0')
3441 {
3442 size_t i = strcspn(p1, "\r\n");
3443 if (i > 0)
3444 {
3445 CHAR c = p1[i];
3446 p1[i] = '\0';
3447
3448 /* Look for "break" command and comments */
3449 p2 = p1;
3450 while (isspace(p2[0]))
3451 p2++;
3452
3453 if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3454 (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3455 {
3456 /* Run the interactive debugger loop */
3458 }
3459 else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3460 {
3461 /* Invoke the command */
3462 KdbpDoCommand(p1);
3463 }
3464
3465 p1[i] = c;
3466 }
3467
3468 p1 += i;
3469 while (p1[0] == '\r' || p1[0] == '\n')
3470 p1++;
3471 }
3472 KdbPuts("KDB: KDBinit executed\n");
3473}
3474
3483{
3488 FILE_STANDARD_INFORMATION FileStdInfo;
3489 HANDLE hFile = NULL;
3491 PCHAR FileBuffer;
3492
3493 /* Don't load the KDBinit file if its buffer is already lying around */
3495 return STATUS_SUCCESS;
3496
3497 /* Initialize the object attributes */
3498 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3500 &FileName,
3502 NULL,
3503 NULL);
3504
3505 /* Open the file */
3507 &ObjectAttributes, &Iosb, 0,
3510 if (!NT_SUCCESS(Status))
3511 {
3512 DPRINT("Could not open %wZ (Status 0x%lx)\n", &FileName, Status);
3513 return Status;
3514 }
3515
3516 /* Get the size of the file */
3517 Status = ZwQueryInformationFile(hFile, &Iosb,
3518 &FileStdInfo, sizeof(FileStdInfo),
3520 if (!NT_SUCCESS(Status))
3521 {
3522 ZwClose(hFile);
3523 DPRINT1("Could not query size of %wZ (Status 0x%lx)\n", &FileName, Status);
3524 return Status;
3525 }
3526 FileSize = FileStdInfo.EndOfFile.u.LowPart;
3527
3528 /* Allocate memory for the file (add 1 byte for terminating NUL) */
3529 FileBuffer = ExAllocatePool(NonPagedPool, FileSize + 1);
3530 if (!FileBuffer)
3531 {
3532 ZwClose(hFile);
3533 DPRINT1("Could not allocate %lu bytes for KDBinit file\n", FileSize);
3534 return Status;
3535 }
3536
3537 /* Load file into memory */
3538 Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb,
3539 FileBuffer, FileSize, NULL, NULL);
3540 ZwClose(hFile);
3541
3543 {
3544 ExFreePool(FileBuffer);
3545 DPRINT1("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3546 return Status;
3547 }
3548
3549 FileSize = min(FileSize, (ULONG)Iosb.Information);
3550 FileBuffer[FileSize] = ANSI_NULL;
3551
3552 /* Interpret the KDBinit file by calling back into the debugger */
3556
3557 ExFreePool(FileBuffer);
3558
3559 return STATUS_SUCCESS;
3560}
3561
3562
3571static VOID
3572NTAPI
3576{
3577 KIRQL OldIrql;
3578 ULONG beg, end, num;
3579
3580 /* Avoid recursive calling if we already are in Dmesg mode */
3582 return;
3583
3584 if (KdpDmesgBuffer == NULL)
3585 return;
3586
3587 /* Acquire the printing spinlock without waiting at raised IRQL */
3589
3591 /* Invariant: always_true(KdpDmesgFreeBytes == KdpDmesgBufferSize); */
3593 if (num != 0)
3594 {
3595 end = (beg + num) % KdpDmesgBufferSize;
3596 if (end > beg)
3597 {
3599 }
3600 else
3601 {
3604 }
3606
3607 /* Counting the total bytes written */
3609 }
3610
3611 /* Release the spinlock */
3613
3614 /* Optional step(?): find out a way to notify about buffer exhaustion,
3615 * and possibly fall into kbd to use dmesg command: user will read
3616 * debug strings before they will be wiped over by next writes. */
3617}
3618
3632NTAPI
3635 _In_ ULONG BootPhase)
3636{
3637 /* Saves the different symbol-loading status across boot phases */
3638 static ULONG LoadSymbols = 0;
3639
3640 if (BootPhase == 0)
3641 {
3642 /* Write out the functions that we support for now */
3643 DispatchTable->KdpPrintRoutine = KdbDebugPrint;
3644
3645 /* Check if we have a command line */
3647 {
3648 /* Get the KDBG Settings */
3650 }
3651
3652 /* Register for BootPhase 1 initialization and as a Provider */
3653 DispatchTable->KdpInitRoutine = KdbInitialize;
3654 InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
3655 }
3656 else if (BootPhase == 1)
3657 {
3658 /* Register for later BootPhase 2 reinitialization */
3659 DispatchTable->KdpInitRoutine = KdbInitialize;
3660
3661 /* Initialize Dmesg support */
3662
3663 /* Allocate a buffer for Dmesg log buffer. +1 for terminating null,
3664 * see kdbp_cli.c:KdbpCmdDmesg()/2 */
3667 TAG_KDBG);
3668 /* Ignore failure if KdpDmesgBuffer is NULL */
3671
3672 /* Initialize spinlock */
3674 }
3675
3676 /* Initialize symbols support in BootPhase 0 and 1 */
3677 if (BootPhase <= 1)
3678 {
3679 LoadSymbols <<= 1;
3680 LoadSymbols |= KdbSymInit(BootPhase);
3681 }
3682
3683 if (BootPhase == 1)
3684 {
3685 /* Announce ourselves */
3686 CHAR buffer[60];
3688 " KDBG debugger enabled - %s\r\n",
3689 !(LoadSymbols & 0x2) ? "No symbols loaded" :
3690 !(LoadSymbols & 0x1) ? "Kernel symbols loaded"
3691 : "Loading symbols");
3693 }
3694
3695 if (BootPhase >= 2)
3696 {
3697 /* I/O is now set up for disk access: load the KDBinit file */
3699
3700 /* Schedule an I/O reinitialization if needed */
3703 {
3704 DispatchTable->KdpInitRoutine = KdbInitialize;
3705 }
3706 }
3707
3708 return STATUS_SUCCESS;
3709}
3710
3711/* 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:405
#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 STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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:33
#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:4403
#define ULONG_PTR
Definition: config.h:101
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#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 SYSTEM
Definition: fatfs.h:185
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
struct _FileName FileName
Definition: fatprocs.h:897
_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
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2046
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:2766
NTSTATUS NTAPI KdSystemDebugControl(_In_ SYSDBG_COMMAND Command, _In_reads_bytes_(InputBufferLength) PVOID InputBuffer, _In_ ULONG InputBufferLength, _Out_writes_bytes_(OutputBufferLength) PVOID OutputBuffer, _In_ ULONG OutputBufferLength, _Out_opt_ PULONG ReturnLength, _In_ KPROCESSOR_MODE PreviousMode)
Perform various queries to the kernel debugger.
Definition: kdapi.c:2217
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:1657
VOID KdbpGetCommandLineSettings(_In_ PCSTR p1)
Definition: kdb.c:1635
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:160
VOID KdbpPager(_In_ PCHAR Buffer, _In_ ULONG BufLength)
Prints the given string with, page by page.
Definition: kdb_cli.c:3142
static BOOLEAN KdbRepeatLastCommand
Definition: kdb_cli.c:135
static struct @1855 ComponentTable[]
char __ImageBase
static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
Lists breakpoints.
Definition: kdb_cli.c:1520
#define KDB_ACCESS_TYPE_TO_STRING(type)
Definition: kdb_cli.c:46
static ULONG KdbNumberOfRowsPrinted
Definition: kdb_cli.c:132
static BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
Enables, disables or clears a breakpoint.
Definition: kdb_cli.c:1617
#define KDB_ENTER_CONDITION_TO_STRING(cond)
Definition: kdb_cli.c:41
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:2850
static BOOLEAN KdbUseIntelSyntax
Definition: kdb_cli.c:129
static PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
Definition: kdb_cli.c:128
static KSPIN_LOCK KdpDmesgLogSpinLock
Definition: kdb_cli.c:147
static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1479
VOID KdbpCliInterpretInitFile(VOID)
Interprets the KDBinit file from the \SystemRoot\System32\drivers\etc directory, that has been loaded...
Definition: kdb_cli.c:3430
static BOOLEAN KdbBreakOnModuleLoad
Definition: kdb_cli.c:130
static VOID KdpFilterEscapes(_Inout_ PSTR String)
Definition: kdb_cli.c:2930
BOOLEAN NTAPI KdbRegisterCliCallback(PVOID Callback, BOOLEAN Deregister)
Definition: kdb_cli.c:3203
static VOID KdbpPagerInternal(_In_ PCHAR Buffer, _In_ ULONG BufLength, _In_ BOOLEAN DoPage)
Prints the given string with, page by page.
Definition: kdb_cli.c:2966
BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[])
static VOID NTAPI KdbDebugPrint(_In_ PCCH String, _In_ ULONG Length)
Debug logger function.
Definition: kdb_cli.c:3573
static BOOLEAN KdbpEvaluateExpression(IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
Evaluates an expression...
Definition: kdb_cli.c:424
static const ULONG KdpDmesgBufferSize
Definition: kdb_cli.c:141
PCSTR Name
Definition: kdb_cli.c:159
#define NPX_STATE_TO_STRING(state)
Definition: kdb_cli.c:51
BOOLEAN ExpKdbgExtPoolFind(ULONG Argc, PCHAR Argv[])
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:138
static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[])
Lists processes or switches to another process context.
Definition: kdb_cli.c:1991
#define Ke386GetGlobalDescriptorTable
Definition: kdb_cli.c:101
static volatile ULONG KdpDmesgCurrentPosition
Definition: kdb_cli.c:143
static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1490
static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
Displays a backtrace.
Definition: kdb_cli.c:1304
static volatile ULONG KdpDmesgFreeBytes
Definition: kdb_cli.c:144
NTSTATUS NTAPI KdbInitialize(_In_ PKD_DISPATCH_TABLE DispatchTable, _In_ ULONG BootPhase)
Initializes the KDBG debugger.
Definition: kdb_cli.c:3633
VOID KdbpPrintUnicodeString(_In_ PCUNICODE_STRING String)
Definition: kdb_cli.c:3183
static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
Sets a software or hardware (memory) breakpoint at the given address.
Definition: kdb_cli.c:1658
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[])
Display debug messages on screen, with paging.
Definition: kdb_cli.c:2594
BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[])
volatile PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:137
#define Ke386GetLocalDescriptorTable
Definition: kdb_cli.c:104
BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[])
static BOOLEAN KdbpDoCommand(IN PCHAR Command)
Parses command line and executes command if found.
Definition: kdb_cli.c:3284
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:346
static const struct @1856 KdbDebuggerCommands[]
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:2394
static PCHAR KdpDmesgBuffer
Definition: kdb_cli.c:142
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:134
VOID KdbpPrint(_In_ PSTR Format, _In_ ...)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:3160
static volatile ULONG KdbDmesgTotalWritten
Definition: kdb_cli.c:145
BOOLEAN ExpKdbgExtPoolUsed(ULONG Argc, PCHAR Argv[])
PCHAR Help
Definition: kdb_cli.c:345
BOOLEAN(NTAPI * PKDBG_CLI_ROUTINE)(IN PCHAR Command, IN ULONG Argc, IN PCH Argv[])
Definition: kdb_cli.c:123
static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[])
Displays help screen.
Definition: kdb_cli.c:2817
static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
Evaluates an expression and displays the result.
Definition: kdb_cli.c:470
BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[])
static volatile BOOLEAN KdbpIsInDmesgMode
Definition: kdb_cli.c:146
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[])
Lists loaded modules or the one containing the specified address.
Definition: kdb_cli.c:2109
const CSTRING KdbPromptStr
Definition: kdb_cli.c:149
PCHAR Syntax
Definition: kdb_cli.c:344
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:2886
BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[])
Bugchecks the system.
Definition: kdb_cli.c:2569
static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[])
Sets or displays a config variables value.
Definition: kdb_cli.c:2638
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:3250
static ULONG KdbNumberOfColsPrinted
Definition: kdb_cli.c:133
#define KD_DEBUG_PRINT_FILTER(Name)
Definition: kdb_cli.c:154
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[])
Displays GDT, LDT or IDT.
Definition: kdb_cli.c:2175
static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[])
Lists threads or switches to another thread context.
Definition: kdb_cli.c:1782
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3353
BOOLEAN NTAPI KdbpGetHexNumber(IN PCHAR pszNum, OUT ULONG_PTR *pulValue)
Definition: kdb_cli.c:451
NTSTATUS KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3482
static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[])
Definition: kdb_cli.c:2579
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:28
if(dx< 0)
Definition: linetemp.h:194
static int ErrMsg(int Error)
Definition: lnktool.cpp:123
POINT cp
Definition: magnifier.c:59
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
UNICODE_STRING Global
Definition: symlink.c:46
#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
FORCEINLINE PVOID ExAllocatePoolZero(ULONG PoolType, SIZE_T NumberOfBytes, ULONG Tag)
Definition: precomp.h:45
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define min(a, b)
Definition: monoChain.cc:55
@ Enabled
Definition: mountmgr.h:179
_In_ HANDLE hFile
Definition: mswsock.h:90
#define PKTSS
Definition: ketypes.h:1019
struct _KIPCR * PKIPCR
@ HalRebootRoutine
Definition: haltypes.h:37
#define KernelMode
Definition: asm.h:38
#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
@ SysDbgReadControlSpace
Definition: kdtypes.h:74
#define DPFLTR_MASK
Definition: kdtypes.h:34
#define DBG_STATUS_CONTROL_C
Definition: kdtypes.h:39
#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)
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
int Count
Definition: noreturn.cpp:7
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_DATA
Definition: nt_native.h:628
struct _CONTEXT CONTEXT
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:661
CHAR * PCH
Definition: ntbasedef.h:399
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:391
#define ANSI_NULL
CONST CHAR * PCCH
Definition: ntbasedef.h:400
_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
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
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
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
@ Input
Definition: arc.h:84
static const char *const debug_classes[]
Definition: debug.c:51
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
#define _countof(array)
Definition: sndvol32.h:70
#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:1104
CLIENT_ID Cid
Definition: pstypes.h:1129
Definition: heap.c:52
PVOID Base
Definition: ketypes.h:580
USHORT Limit
Definition: ketypes.h:579
union _KGDTENTRY::@2531 HighWord
USHORT BaseLow
Definition: ketypes.h:390
struct _KGDTENTRY::@2531::@2533 Bits
struct _KGDTENTRY::@2531::@2532 Bytes
KPRCB Prcb
Definition: ketypes.h:988
USHORT MinorVersion
Definition: ketypes.h:976
ULONG SecondLevelCacheSize
Definition: ketypes.h:980
PKIDTENTRY IDT
Definition: ketypes.h:818
USHORT MajorVersion
Definition: ketypes.h:975
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:971
ULONG IrrActive
Definition: ketypes.h:815
KIRQL Irql
Definition: ketypes.h:970
UCHAR Number
Definition: ketypes.h:826
KAFFINITY SetMember
Definition: ketypes.h:823
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:963
ULONG IRR
Definition: ketypes.h:814
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:959
ULONG InterruptMode
Definition: ketypes.h:833
PKGDTENTRY GDT
Definition: ketypes.h:819
struct _KPCR * SelfPcr
Definition: ketypes.h:811
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:964
struct _KTSS64 * TssBase
Definition: ketypes.h:960
struct _KTSS * TSS
Definition: ketypes.h:820
UCHAR ObsoleteNumber
Definition: ketypes.h:972
NT_TIB NtTib
Definition: ketypes.h:956
ULONG IDR
Definition: ketypes.h:816
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:968
struct _KPCR * Self
Definition: ketypes.h:962
ULONG StallScaleFactor
Definition: ketypes.h:977
ULONG VdmAlert
Definition: ketypes.h:829
ULONG64 UserRsp
Definition: ketypes.h:961
PVOID KdVersionBlock
Definition: ketypes.h:984
PVOID Used_Self
Definition: ketypes.h:965
KDESCRIPTOR Gdtr
Definition: ketypes.h:600
KDESCRIPTOR Idtr
Definition: ketypes.h:601
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:850
USHORT Fs
Definition: ketypes.h:876
USHORT LDT
Definition: ketypes.h:880
USHORT Backlink
Definition: ketypes.h:851
USHORT Flags
Definition: ketypes.h:882
USHORT Ds
Definition: ketypes.h:874
ULONG Eax
Definition: ketypes.h:860
ULONG Ecx
Definition: ketypes.h:861
ULONG Esi
Definition: ketypes.h:866
ULONG Ebp
Definition: ketypes.h:865
ULONG Esp
Definition: ketypes.h:864
ULONG Edx
Definition: ketypes.h:862
USHORT Gs
Definition: ketypes.h:878
USHORT Ss
Definition: ketypes.h:872
ULONG Eip
Definition: ketypes.h:858
USHORT Cs
Definition: ketypes.h:870
ULONG Ebx
Definition: ketypes.h:863
USHORT IoMapBase
Definition: ketypes.h:883
ULONG Edi
Definition: ketypes.h:867
ULONG Esp0
Definition: ketypes.h:853
ULONG CR3
Definition: ketypes.h:857
USHORT Ss0
Definition: ketypes.h:854
USHORT Es
Definition: ketypes.h:868
ULONG EFlags
Definition: ketypes.h:859
Definition: btrfs_drv.h:1876
ULONG SizeOfImage
Definition: ldrtypes.h:147
PVOID DllBase
Definition: btrfs_drv.h:1880
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:149
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
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
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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
__analysis_noreturn NTSYSAPI VOID NTAPI DbgBreakPointWithStatus(_In_ ULONG Status)
struct _LARGE_INTEGER::@2379 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:478
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. https://learn....
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
#define AMD64_DEBUG_CONTROL_SPACE_KSPECIAL
Definition: windbgkd.h:205
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