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