ReactOS  0.4.15-dev-5112-g22d8c0f
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 #define NDEBUG
34 #include <debug.h>
35 
36 /* DEFINES *******************************************************************/
37 
38 #define KEY_BS 8
39 #define KEY_ESC 27
40 #define KEY_DEL 127
41 
42 #define KEY_SCAN_UP 72
43 #define KEY_SCAN_DOWN 80
44 
45 /* Scan codes of keyboard keys: */
46 #define KEYSC_END 0x004f
47 #define KEYSC_PAGEUP 0x0049
48 #define KEYSC_PAGEDOWN 0x0051
49 #define KEYSC_HOME 0x0047
50 #define KEYSC_ARROWUP 0x0048
51 
52 #define KDB_ENTER_CONDITION_TO_STRING(cond) \
53  ((cond) == KdbDoNotEnter ? "never" : \
54  ((cond) == KdbEnterAlways ? "always" : \
55  ((cond) == KdbEnterFromKmode ? "kmode" : "umode")))
56 
57 #define KDB_ACCESS_TYPE_TO_STRING(type) \
58  ((type) == KdbAccessRead ? "read" : \
59  ((type) == KdbAccessWrite ? "write" : \
60  ((type) == KdbAccessReadWrite ? "rdwr" : "exec")))
61 
62 #define NPX_STATE_TO_STRING(state) \
63  ((state) == NPX_STATE_LOADED ? "Loaded" : \
64  ((state) == NPX_STATE_NOT_LOADED ? "Not loaded" : "Unknown"))
65 
66 /* PROTOTYPES ****************************************************************/
67 
68 static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]);
69 static BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]);
70 static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]);
71 static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]);
72 
73 static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[]);
74 static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[]);
75 static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[]);
77 static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[]);
78 
79 static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[]);
80 static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[]);
81 
82 static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[]);
83 static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[]);
84 static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[]);
85 #ifdef _M_IX86
86 static BOOLEAN KdbpCmdTss(ULONG Argc, PCHAR Argv[]);
87 #endif
88 
89 static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[]);
90 static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[]);
91 static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[]);
92 static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[]);
93 static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[]);
94 static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[]);
95 
96 BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[]);
100 BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[]);
101 BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[]);
102 BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[]);
103 
104 extern char __ImageBase;
105 
106 #ifdef __ROS_DWARF__
107 static BOOLEAN KdbpCmdPrintStruct(ULONG Argc, PCHAR Argv[]);
108 #endif
109 
110 /* Be more descriptive than intrinsics */
111 #ifndef Ke386GetGlobalDescriptorTable
112 # define Ke386GetGlobalDescriptorTable __sgdt
113 #endif
114 #ifndef Ke386GetLocalDescriptorTable
115 # define Ke386GetLocalDescriptorTable __sldt
116 #endif
117 
118 /* Portability */
120 ULONG_PTR
121 strtoulptr(const char* nptr, char** endptr, int base)
122 {
123 #ifdef _M_IX86
124  return strtoul(nptr, endptr, base);
125 #else
126  return strtoull(nptr, endptr, base);
127 #endif
128 }
129 
130 /* GLOBALS *******************************************************************/
131 
132 typedef
133 BOOLEAN
135  IN PCHAR Command,
136  IN ULONG Argc,
137  IN PCH Argv[]);
138 
140 static BOOLEAN KdbUseIntelSyntax = FALSE; /* Set to TRUE for intel syntax */
141 static BOOLEAN KdbBreakOnModuleLoad = FALSE; /* Set to TRUE to break into KDB when a module is loaded */
142 
143 static CHAR KdbCommandHistoryBuffer[2048]; /* Command history string ringbuffer */
144 static PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer) / 8] = { NULL }; /* Command history ringbuffer */
147 
154 
155 PCHAR KdbInitFileBuffer = NULL; /* Buffer where KDBinit file is loaded into during initialization */
157 
158 /* Vars for dmesg */
159 /* defined in ../kd/kdio.c, declare here: */
160 extern volatile BOOLEAN KdbpIsInDmesgMode;
161 extern const ULONG KdpDmesgBufferSize;
162 extern PCHAR KdpDmesgBuffer;
163 extern volatile ULONG KdpDmesgCurrentPosition;
164 extern volatile ULONG KdpDmesgFreeBytes;
165 extern volatile ULONG KdbDmesgTotalWritten;
166 
168 
169 //
170 // Debug Filter Component Table
171 //
172 #define KD_DEBUG_PRINT_FILTER(Name) \
173  { #Name, DPFLTR_##Name##_ID }
174 
175 static struct
176 {
179 }
180 ComponentTable[] =
181 {
182 //
183 // Default components
184 //
185  { "WIN2000", MAXULONG },
187 //
188 // Standard components
189 //
191  KD_DEBUG_PRINT_FILTER(SMSS),
193  KD_DEBUG_PRINT_FILTER(NTFS),
194  KD_DEBUG_PRINT_FILTER(FSTUB),
195  KD_DEBUG_PRINT_FILTER(CRASHDUMP),
196  KD_DEBUG_PRINT_FILTER(CDAUDIO),
197  KD_DEBUG_PRINT_FILTER(CDROM),
198  KD_DEBUG_PRINT_FILTER(CLASSPNP),
199  KD_DEBUG_PRINT_FILTER(DISK),
200  KD_DEBUG_PRINT_FILTER(REDBOOK),
201  KD_DEBUG_PRINT_FILTER(STORPROP),
202  KD_DEBUG_PRINT_FILTER(SCSIPORT),
203  KD_DEBUG_PRINT_FILTER(SCSIMINIPORT),
204  KD_DEBUG_PRINT_FILTER(CONFIG),
205  KD_DEBUG_PRINT_FILTER(I8042PRT),
206  KD_DEBUG_PRINT_FILTER(SERMOUSE),
207  KD_DEBUG_PRINT_FILTER(LSERMOUS),
208  KD_DEBUG_PRINT_FILTER(KBDHID),
209  KD_DEBUG_PRINT_FILTER(MOUHID),
210  KD_DEBUG_PRINT_FILTER(KBDCLASS),
211  KD_DEBUG_PRINT_FILTER(MOUCLASS),
212  KD_DEBUG_PRINT_FILTER(TWOTRACK),
213  KD_DEBUG_PRINT_FILTER(WMILIB),
214  KD_DEBUG_PRINT_FILTER(ACPI),
215  KD_DEBUG_PRINT_FILTER(AMLI),
216  KD_DEBUG_PRINT_FILTER(HALIA64),
217  KD_DEBUG_PRINT_FILTER(VIDEO),
218  KD_DEBUG_PRINT_FILTER(SVCHOST),
219  KD_DEBUG_PRINT_FILTER(VIDEOPRT),
220  KD_DEBUG_PRINT_FILTER(TCPIP),
221  KD_DEBUG_PRINT_FILTER(DMSYNTH),
222  KD_DEBUG_PRINT_FILTER(NTOSPNP),
223  KD_DEBUG_PRINT_FILTER(FASTFAT),
224  KD_DEBUG_PRINT_FILTER(SAMSS),
225  KD_DEBUG_PRINT_FILTER(PNPMGR),
226  KD_DEBUG_PRINT_FILTER(NETAPI),
227  KD_DEBUG_PRINT_FILTER(SCSERVER),
228  KD_DEBUG_PRINT_FILTER(SCCLIENT),
229  KD_DEBUG_PRINT_FILTER(SERIAL),
230  KD_DEBUG_PRINT_FILTER(SERENUM),
231  KD_DEBUG_PRINT_FILTER(UHCD),
232  KD_DEBUG_PRINT_FILTER(RPCPROXY),
233  KD_DEBUG_PRINT_FILTER(AUTOCHK),
234  KD_DEBUG_PRINT_FILTER(DCOMSS),
235  KD_DEBUG_PRINT_FILTER(UNIMODEM),
237  KD_DEBUG_PRINT_FILTER(FLTMGR),
238  KD_DEBUG_PRINT_FILTER(WMICORE),
239  KD_DEBUG_PRINT_FILTER(BURNENG),
240  KD_DEBUG_PRINT_FILTER(IMAPI),
242  KD_DEBUG_PRINT_FILTER(FUSION),
243  KD_DEBUG_PRINT_FILTER(IDLETASK),
244  KD_DEBUG_PRINT_FILTER(SOFTPCI),
245  KD_DEBUG_PRINT_FILTER(TAPE),
246  KD_DEBUG_PRINT_FILTER(MCHGR),
247  KD_DEBUG_PRINT_FILTER(IDEP),
248  KD_DEBUG_PRINT_FILTER(PCIIDE),
249  KD_DEBUG_PRINT_FILTER(FLOPPY),
251  KD_DEBUG_PRINT_FILTER(TERMSRV),
252  KD_DEBUG_PRINT_FILTER(W32TIME),
253  KD_DEBUG_PRINT_FILTER(PREFETCHER),
254  KD_DEBUG_PRINT_FILTER(RSFILTER),
255  KD_DEBUG_PRINT_FILTER(FCPORT),
257  KD_DEBUG_PRINT_FILTER(DMIO),
258  KD_DEBUG_PRINT_FILTER(DMCONFIG),
259  KD_DEBUG_PRINT_FILTER(DMADMIN),
260  KD_DEBUG_PRINT_FILTER(WSOCKTRANSPORT),
262  KD_DEBUG_PRINT_FILTER(PNPMEM),
263  KD_DEBUG_PRINT_FILTER(PROCESSOR),
264  KD_DEBUG_PRINT_FILTER(DMSERVER),
266  KD_DEBUG_PRINT_FILTER(INFINIBAND),
267  KD_DEBUG_PRINT_FILTER(IHVDRIVER),
268  KD_DEBUG_PRINT_FILTER(IHVVIDEO),
269  KD_DEBUG_PRINT_FILTER(IHVAUDIO),
270  KD_DEBUG_PRINT_FILTER(IHVNETWORK),
271  KD_DEBUG_PRINT_FILTER(IHVSTREAMING),
272  KD_DEBUG_PRINT_FILTER(IHVBUS),
274  KD_DEBUG_PRINT_FILTER(RTLTHREADPOOL),
276  KD_DEBUG_PRINT_FILTER(TCPIP6),
277  KD_DEBUG_PRINT_FILTER(ISAPNP),
278  KD_DEBUG_PRINT_FILTER(SHPC),
279  KD_DEBUG_PRINT_FILTER(STORPORT),
280  KD_DEBUG_PRINT_FILTER(STORMINIPORT),
281  KD_DEBUG_PRINT_FILTER(PRINTSPOOLER),
282  KD_DEBUG_PRINT_FILTER(VSSDYNDISK),
283  KD_DEBUG_PRINT_FILTER(VERIFIER),
285  KD_DEBUG_PRINT_FILTER(VDSBAS),
286  KD_DEBUG_PRINT_FILTER(VDSDYN), // Specified in Vista+
287  KD_DEBUG_PRINT_FILTER(VDSDYNDR),
288  KD_DEBUG_PRINT_FILTER(VDSLDR), // Specified in Vista+
289  KD_DEBUG_PRINT_FILTER(VDSUTIL),
290  KD_DEBUG_PRINT_FILTER(DFRGIFC),
292  KD_DEBUG_PRINT_FILTER(DFSC),
293  KD_DEBUG_PRINT_FILTER(WOW64),
294 //
295 // Components specified in Vista+, some of which we also use in ReactOS
296 //
297  KD_DEBUG_PRINT_FILTER(ALPC),
299  KD_DEBUG_PRINT_FILTER(PERFLIB),
301  KD_DEBUG_PRINT_FILTER(IOSTRESS),
303  KD_DEBUG_PRINT_FILTER(WHEA),
304  KD_DEBUG_PRINT_FILTER(USERGDI),
305  KD_DEBUG_PRINT_FILTER(MMCSS),
307  KD_DEBUG_PRINT_FILTER(THREADORDER),
308  KD_DEBUG_PRINT_FILTER(ENVIRON),
311  KD_DEBUG_PRINT_FILTER(FVEVOL),
312  KD_DEBUG_PRINT_FILTER(NDIS),
313  KD_DEBUG_PRINT_FILTER(NVCTRACE),
314  KD_DEBUG_PRINT_FILTER(LUAFV),
315  KD_DEBUG_PRINT_FILTER(APPCOMPAT),
316  KD_DEBUG_PRINT_FILTER(USBSTOR),
317  KD_DEBUG_PRINT_FILTER(SBP2PORT),
319  KD_DEBUG_PRINT_FILTER(CACHEMGR),
320  KD_DEBUG_PRINT_FILTER(MOUNTMGR),
323  KD_DEBUG_PRINT_FILTER(KSECDD),
324  KD_DEBUG_PRINT_FILTER(FLTREGRESS),
325  KD_DEBUG_PRINT_FILTER(MPIO),
326  KD_DEBUG_PRINT_FILTER(MSDSM),
327  KD_DEBUG_PRINT_FILTER(UDFS),
328  KD_DEBUG_PRINT_FILTER(PSHED),
329  KD_DEBUG_PRINT_FILTER(STORVSP),
330  KD_DEBUG_PRINT_FILTER(LSASS),
331  KD_DEBUG_PRINT_FILTER(SSPICLI),
333  KD_DEBUG_PRINT_FILTER(EXFAT),
334  KD_DEBUG_PRINT_FILTER(FILETRACE),
335  KD_DEBUG_PRINT_FILTER(XSAVE),
337  KD_DEBUG_PRINT_FILTER(DRIVEEXTENDER),
338 //
339 // Components specified in Windows 8
340 //
341  KD_DEBUG_PRINT_FILTER(POWER),
342  KD_DEBUG_PRINT_FILTER(CRASHDUMPXHCI),
343  KD_DEBUG_PRINT_FILTER(GPIO),
344  KD_DEBUG_PRINT_FILTER(REFS),
346 //
347 // Components specified in Windows 10
348 //
349  KD_DEBUG_PRINT_FILTER(CAPIMG),
350  KD_DEBUG_PRINT_FILTER(VPCI),
351  KD_DEBUG_PRINT_FILTER(STORAGECLASSMEMORY),
352  KD_DEBUG_PRINT_FILTER(FSLIB),
353 };
354 #undef KD_DEBUG_PRINT_FILTER
355 
356 //
357 // Command Table
358 //
359 static const struct
360 {
361  PCHAR Name;
364  BOOLEAN (*Fn)(ULONG Argc, PCHAR Argv[]);
365 } KdbDebuggerCommands[] = {
366  /* Data */
367  { NULL, NULL, "Data", NULL },
368  { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression },
369 #ifdef _M_IX86 // FIXME: this is broken on x64
370  { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX },
371 #endif // _M_IX86
372  { "x", "x [address] [L count]", "Display count dwords, starting at address.", KdbpCmdDisassembleX },
373  { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs },
374  { "sregs", "sregs", "Display status registers.", KdbpCmdRegs },
375  { "dregs", "dregs", "Display debug registers.", KdbpCmdRegs },
376  { "bt", "bt [*frameaddr|thread id]", "Prints current backtrace or from given frame address.", KdbpCmdBackTrace },
377 #ifdef __ROS_DWARF__
378  { "dt", "dt [mod] [type] [addr]", "Print a struct. The address is optional.", KdbpCmdPrintStruct },
379 #endif
380  /* Flow control */
381  { NULL, NULL, "Flow control", NULL },
382  { "cont", "cont", "Continue execution (leave debugger).", KdbpCmdContinue },
383  { "step", "step [count]", "Execute single instructions, stepping into interrupts.", KdbpCmdStep },
384  { "next", "next [count]", "Execute single instructions, skipping calls and reps.", KdbpCmdStep },
385  { "bl", "bl", "List breakpoints.", KdbpCmdBreakPointList },
386  { "be", "be [breakpoint]", "Enable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
387  { "bd", "bd [breakpoint]", "Disable breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
388  { "bc", "bc [breakpoint]", "Clear breakpoint.", KdbpCmdEnableDisableClearBreakPoint },
389  { "bpx", "bpx [address] [IF condition]", "Set software execution breakpoint at address.", KdbpCmdBreakPoint },
390  { "bpm", "bpm [r|w|rw|x] [byte|word|dword] [address] [IF condition]", "Set memory breakpoint at address.", KdbpCmdBreakPoint },
391 
392  /* Process/Thread */
393  { NULL, NULL, "Process/Thread", NULL },
394  { "thread", "thread [list[ pid]|[attach ]tid]", "List threads in current or specified process, display thread with given id or attach to thread.", KdbpCmdThread },
395  { "proc", "proc [list|[attach ]pid]", "List processes, display process with given id or attach to process.", KdbpCmdProc },
396 
397  /* System information */
398  { NULL, NULL, "System info", NULL },
399  { "mod", "mod [address]", "List all modules or the one containing address.", KdbpCmdMod },
400  { "gdt", "gdt", "Display the global descriptor table.", KdbpCmdGdtLdtIdt },
401  { "ldt", "ldt", "Display the local descriptor table.", KdbpCmdGdtLdtIdt },
402  { "idt", "idt", "Display the interrupt descriptor table.", KdbpCmdGdtLdtIdt },
403  { "pcr", "pcr", "Display the processor control region.", KdbpCmdPcr },
404 #ifdef _M_IX86
405  { "tss", "tss [selector|*descaddr]", "Display the current task state segment, or the one specified by its selector number or descriptor address.", KdbpCmdTss },
406 #endif
407 
408  /* Others */
409  { NULL, NULL, "Others", NULL },
410  { "bugcheck", "bugcheck", "Bugchecks the system.", KdbpCmdBugCheck },
411  { "reboot", "reboot", "Reboots the system.", KdbpCmdReboot},
412  { "filter", "filter [error|warning|trace|info|level]+|-[componentname|default]", "Enable/disable debug channels.", KdbpCmdFilter },
413  { "set", "set [var] [value]", "Sets var to value or displays value of var.", KdbpCmdSet },
414  { "dmesg", "dmesg", "Display debug messages on screen, with navigation on pages.", KdbpCmdDmesg },
415  { "kmsg", "kmsg", "Kernel dmesg. Alias for dmesg.", KdbpCmdDmesg },
416  { "help", "help", "Display help screen.", KdbpCmdHelp },
417  { "!pool", "!pool [Address [Flags]]", "Display information about pool allocations.", ExpKdbgExtPool },
418  { "!poolused", "!poolused [Flags [Tag]]", "Display pool usage.", ExpKdbgExtPoolUsed },
419  { "!poolfind", "!poolfind Tag [Pool]", "Search for pool tag allocations.", ExpKdbgExtPoolFind },
420  { "!filecache", "!filecache", "Display cache usage.", ExpKdbgExtFileCache },
421  { "!defwrites", "!defwrites", "Display cache write values.", ExpKdbgExtDefWrites },
422  { "!irpfind", "!irpfind [Pool [startaddress [criteria data]]]", "Lists IRPs potentially matching criteria.", ExpKdbgExtIrpFind },
423  { "!handle", "!handle [Handle]", "Displays info about handles.", ExpKdbgExtHandle },
424 };
425 
426 /* FUNCTIONS *****************************************************************/
427 
440 static BOOLEAN
443  IN LONG ErrOffset,
445 {
446  static CHAR ErrMsgBuffer[130] = "^ ";
447  LONG ExpressionErrOffset = -1;
448  PCHAR ErrMsg = ErrMsgBuffer;
449  BOOLEAN Ok;
450 
452  &ExpressionErrOffset, ErrMsgBuffer + 2);
453  if (!Ok)
454  {
455  if (ExpressionErrOffset >= 0)
456  ExpressionErrOffset += ErrOffset;
457  else
458  ErrMsg += 2;
459 
460  KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
461  }
462 
463  return Ok;
464 }
465 
466 BOOLEAN
467 NTAPI
469  IN PCHAR pszNum,
470  OUT ULONG_PTR *pulValue)
471 {
472  char *endptr;
473 
474  /* Skip optional '0x' prefix */
475  if ((pszNum[0] == '0') && ((pszNum[1] == 'x') || (pszNum[1] == 'X')))
476  pszNum += 2;
477 
478  /* Make a number from the string (hex) */
479  *pulValue = strtoul(pszNum, &endptr, 16);
480 
481  return (*endptr == '\0');
482 }
483 
486 static BOOLEAN
488  ULONG Argc,
489  PCHAR Argv[])
490 {
491  ULONG i;
492  SIZE_T len;
493  ULONGLONG Result = 0;
494  ULONG ul;
495  LONG l = 0;
496  BOOLEAN Ok;
497 
498  if (Argc < 2)
499  {
500  KdbpPrint("?: Argument required\n");
501  return TRUE;
502  }
503 
504  /* Put the arguments back together */
505  Argc--;
506  for (i = 1; i < Argc; i++)
507  {
508  len = strlen(Argv[i]);
509  Argv[i][len] = ' ';
510  }
511 
512  /* Evaluate the expression */
513  Ok = KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result);
514  if (Ok)
515  {
516  if (Result > 0x00000000ffffffffLL)
517  {
518  if (Result & 0x8000000000000000LL)
519  KdbpPrint("0x%016I64x %20I64u %20I64d\n", Result, Result, Result);
520  else
521  KdbpPrint("0x%016I64x %20I64u\n", Result, Result);
522  }
523  else
524  {
525  ul = (ULONG)Result;
526 
527  if (ul <= 0xff && ul >= 0x80)
528  l = (LONG)((CHAR)ul);
529  else if (ul <= 0xffff && ul >= 0x8000)
530  l = (LONG)((SHORT)ul);
531  else
532  l = (LONG)ul;
533 
534  if (l < 0)
535  KdbpPrint("0x%08lx %10lu %10ld\n", ul, ul, l);
536  else
537  KdbpPrint("0x%08lx %10lu\n", ul, ul);
538  }
539  }
540 
541  return TRUE;
542 }
543 
544 #ifdef __ROS_DWARF__
545 
548 static VOID
549 KdbpPrintStructInternal
551  PCHAR Indent,
552  BOOLEAN DoRead,
554  PROSSYM_AGGREGATE Aggregate)
555 {
556  ULONG i;
559  ULONG IndentLen = strlen(Indent);
560  ROSSYM_AGGREGATE MemberAggregate = {0 };
561 
562  for (i = 0; i < Aggregate->NumElements; i++) {
563  Member = &Aggregate->Elements[i];
564  KdbpPrint("%s%p+%x: %s", Indent, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size, Member->Name ? Member->Name : "<anoymous>");
565  if (DoRead) {
566  if (!strcmp(Member->Type, "_UNICODE_STRING")) {
567  KdbpPrint("\"");
569  KdbpPrint("\"\n");
570  continue;
571  } else if (!strcmp(Member->Type, "PUNICODE_STRING")) {
572  KdbpPrint("\"");
574  KdbpPrint("\"\n");
575  continue;
576  }
577  switch (Member->Size) {
578  case 1:
579  case 2:
580  case 4:
581  case 8: {
582  Result = 0;
583  if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
584  if (Member->Bits) {
585  Result >>= Member->FirstBit;
586  Result &= ((1 << Member->Bits) - 1);
587  }
588  KdbpPrint(" %lx\n", Result);
589  }
590  else goto readfail;
591  break;
592  }
593  default: {
594  if (Member->Size < 8) {
595  if (NT_SUCCESS(KdbpSafeReadMemory(&Result, ((PCHAR)BaseAddress) + Member->BaseOffset, Member->Size))) {
596  ULONG j;
597  for (j = 0; j < Member->Size; j++) {
598  KdbpPrint(" %02x", (int)(Result & 0xff));
599  Result >>= 8;
600  }
601  } else goto readfail;
602  } else {
603  KdbpPrint(" %s @ %p {\n", Member->Type, ((PCHAR)BaseAddress) + Member->BaseOffset);
604  Indent[IndentLen] = ' ';
605  if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
606  KdbpPrintStructInternal(Info, Indent, DoRead, ((PCHAR)BaseAddress) + Member->BaseOffset, &MemberAggregate);
607  RosSymFreeAggregate(&MemberAggregate);
608  }
609  Indent[IndentLen] = 0;
610  KdbpPrint("%s}\n", Indent);
611  } break;
612  }
613  }
614  } else {
615  readfail:
616  if (Member->Size <= 8) {
617  KdbpPrint(" ??\n");
618  } else {
619  KdbpPrint(" %s @ %x {\n", Member->Type, Member->BaseOffset);
620  Indent[IndentLen] = ' ';
621  if (RosSymAggregate(Info, Member->Type, &MemberAggregate)) {
622  KdbpPrintStructInternal(Info, Indent, DoRead, BaseAddress, &MemberAggregate);
623  RosSymFreeAggregate(&MemberAggregate);
624  }
625  Indent[IndentLen] = 0;
626  KdbpPrint("%s}\n", Indent);
627  }
628  }
629  }
630 }
631 
632 PROSSYM_INFO KdbpSymFindCachedFile(PUNICODE_STRING ModName);
633 
634 static BOOLEAN
635 KdbpCmdPrintStruct(
636  ULONG Argc,
637  PCHAR Argv[])
638 {
639  ULONG i;
640  ULONGLONG Result = 0;
641  PVOID BaseAddress = 0;
642  ROSSYM_AGGREGATE Aggregate = {0};
643  UNICODE_STRING ModName = {0};
644  ANSI_STRING AnsiName = {0};
645  CHAR Indent[100] = {0};
647 
648  if (Argc < 3) goto end;
649  AnsiName.Length = AnsiName.MaximumLength = strlen(Argv[1]);
650  AnsiName.Buffer = Argv[1];
651  RtlAnsiStringToUnicodeString(&ModName, &AnsiName, TRUE);
652  Info = KdbpSymFindCachedFile(&ModName);
653 
654  if (!Info || !RosSymAggregate(Info, Argv[2], &Aggregate)) {
655  DPRINT1("Could not get aggregate\n");
656  goto end;
657  }
658 
659  // Get an argument for location if it was given
660  if (Argc > 3) {
661  ULONG len;
662  PCHAR ArgStart = Argv[3];
663  DPRINT1("Trying to get expression\n");
664  for (i = 3; i < Argc - 1; i++)
665  {
666  len = strlen(Argv[i]);
667  Argv[i][len] = ' ';
668  }
669 
670  /* Evaluate the expression */
671  DPRINT1("Arg: %s\n", ArgStart);
672  if (KdbpEvaluateExpression(ArgStart, strlen(ArgStart), &Result)) {
674  DPRINT1("BaseAddress: %p\n", BaseAddress);
675  }
676  }
677  DPRINT1("BaseAddress %p\n", BaseAddress);
678  KdbpPrintStructInternal(Info, Indent, !!BaseAddress, BaseAddress, &Aggregate);
679 end:
680  RosSymFreeAggregate(&Aggregate);
681  RtlFreeUnicodeString(&ModName);
682  return TRUE;
683 }
684 #endif
685 
694 static BOOLEAN
696  IN PCSTR ComponentName,
698 {
699  ULONG i;
700 
701  for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
702  {
703  if (_stricmp(ComponentName, ComponentTable[i].Name) == 0)
704  {
706  return TRUE;
707  }
708  }
709 
710  return FALSE;
711 }
712 
715 static BOOLEAN
717  ULONG Argc,
718  PCHAR Argv[])
719 {
721  ULONG set = DPFLTR_MASK, clear = DPFLTR_MASK;
722  PCHAR pend;
723  PCSTR opt, p;
724 
725  static struct
726  {
727  PCSTR Name;
728  ULONG Level;
729  }
730  debug_classes[] =
731  {
732  { "error", 1 << DPFLTR_ERROR_LEVEL },
733  { "warning", 1 << DPFLTR_WARNING_LEVEL },
734  { "trace", 1 << DPFLTR_TRACE_LEVEL },
735  { "info", 1 << DPFLTR_INFO_LEVEL },
736  };
737 
738  if (Argc <= 1)
739  {
740  /* Display the list of available debug filter components */
741  KdbpPrint("REMARKS:\n"
742  "- The 'WIN2000' system-wide debug filter component is used for DbgPrint()\n"
743  " messages without Component ID and Level.\n"
744  "- The 'DEFAULT' debug filter component is used for DbgPrint() messages with\n"
745  " an unknown Component ID.\n\n");
746  KdbpPrint("The list of debug filter components currently available on your system is:\n\n");
747  KdbpPrint(" Component Name Component ID\n"
748  " ================== ================\n");
749  for (i = 0; i < RTL_NUMBER_OF(ComponentTable); i++)
750  {
751  KdbpPrint("%20s 0x%08lx\n", ComponentTable[i].Name, ComponentTable[i].Id);
752  }
753  return TRUE;
754  }
755 
756  for (i = 1; i < Argc; i++)
757  {
758  opt = Argv[i];
759  p = opt + strcspn(opt, "+-");
760  if (!p[0]) p = opt; /* Assume it's a debug channel name */
761 
762  if (p > opt)
763  {
764  for (j = 0; j < RTL_NUMBER_OF(debug_classes); j++)
765  {
767  if (len != (p - opt))
768  continue;
769  if (_strnicmp(opt, debug_classes[j].Name, len) == 0) /* Found it */
770  {
771  if (*p == '+')
772  set |= debug_classes[j].Level;
773  else
774  clear |= debug_classes[j].Level;
775  break;
776  }
777  }
778  if (j == RTL_NUMBER_OF(debug_classes))
779  {
780  Level = strtoul(opt, &pend, 0);
781  if (pend != p)
782  {
783  KdbpPrint("filter: bad class name '%.*s'\n", p - opt, opt);
784  continue;
785  }
786  if (*p == '+')
787  set |= Level;
788  else
789  clear |= Level;
790  }
791  }
792  else
793  {
794  if (*p == '-')
795  clear = MAXULONG;
796  else
797  set = MAXULONG;
798  }
799  if (*p == '+' || *p == '-')
800  p++;
801 
803  {
804  KdbpPrint("filter: '%s' is not a valid component name!\n", p);
805  return TRUE;
806  }
807 
808  /* Get current mask value */
811  }
812 
813  return TRUE;
814 }
815 
819 static BOOLEAN
821  ULONG Argc,
822  PCHAR Argv[])
823 {
824  ULONG Count;
825  ULONG ul;
826  INT i;
827  ULONGLONG Result = 0;
829  LONG InstLen;
830 
831  if (Argv[0][0] == 'x') /* display memory */
832  Count = 16;
833  else /* disassemble */
834  Count = 10;
835 
836  if (Argc >= 2)
837  {
838  /* Check for [L count] part */
839  ul = 0;
840  if (strcmp(Argv[Argc-2], "L") == 0)
841  {
842  ul = strtoul(Argv[Argc-1], NULL, 0);
843  if (ul > 0)
844  {
845  Count = ul;
846  Argc -= 2;
847  }
848  }
849  else if (Argv[Argc-1][0] == 'L')
850  {
851  ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
852  if (ul > 0)
853  {
854  Count = ul;
855  Argc--;
856  }
857  }
858 
859  /* Put the remaining arguments back together */
860  Argc--;
861  for (ul = 1; ul < Argc; ul++)
862  {
863  Argv[ul][strlen(Argv[ul])] = ' ';
864  }
865  Argc++;
866  }
867 
868  /* Evaluate the expression */
869  if (Argc > 1)
870  {
871  if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
872  return TRUE;
873 
874  if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
875  KdbpPrint("Warning: Address %I64x is beeing truncated\n",Result);
876 
878  }
879  else if (Argv[0][0] == 'x')
880  {
881  KdbpPrint("x: Address argument required.\n");
882  return TRUE;
883  }
884 
885  if (Argv[0][0] == 'x')
886  {
887  /* Display dwords */
888  ul = 0;
889 
890  while (Count > 0)
891  {
893  KdbpPrint("<%p>:", (PVOID)Address);
894  else
895  KdbpPrint(":");
896 
897  i = min(4, Count);
898  Count -= i;
899 
900  while (--i >= 0)
901  {
902  if (!NT_SUCCESS(KdbpSafeReadMemory(&ul, (PVOID)Address, sizeof(ul))))
903  KdbpPrint(" ????????");
904  else
905  KdbpPrint(" %08x", ul);
906 
907  Address += sizeof(ul);
908  }
909 
910  KdbpPrint("\n");
911  }
912  }
913  else
914  {
915  /* Disassemble */
916  while (Count-- > 0)
917  {
919  KdbpPrint("<%08x>: ", Address);
920  else
921  KdbpPrint(": ");
922 
924  if (InstLen < 0)
925  {
926  KdbpPrint("<INVALID>\n");
927  return TRUE;
928  }
929 
930  KdbpPrint("\n");
931  Address += InstLen;
932  }
933  }
934 
935  return TRUE;
936 }
937 
940 static BOOLEAN
942  ULONG Argc,
943  PCHAR Argv[])
944 {
946  INT i;
947  static const PCHAR EflagsBits[32] = { " CF", NULL, " PF", " BIT3", " AF", " BIT5",
948  " ZF", " SF", " TF", " IF", " DF", " OF",
949  NULL, NULL, " NT", " BIT15", " RF", " VF",
950  " AC", " VIF", " VIP", " ID", " BIT22",
951  " BIT23", " BIT24", " BIT25", " BIT26",
952  " BIT27", " BIT28", " BIT29", " BIT30",
953  " BIT31" };
954 
955  if (Argv[0][0] == 'r') /* regs */
956  {
957 #ifdef _M_IX86
958  KdbpPrint("CS:EIP 0x%04x:0x%08x\n"
959  "SS:ESP 0x%04x:0x%08x\n"
960  " EAX 0x%08x EBX 0x%08x\n"
961  " ECX 0x%08x EDX 0x%08x\n"
962  " ESI 0x%08x EDI 0x%08x\n"
963  " EBP 0x%08x\n",
964  Context->SegCs & 0xFFFF, Context->Eip,
965  Context->SegSs, Context->Esp,
966  Context->Eax, Context->Ebx,
967  Context->Ecx, Context->Edx,
968  Context->Esi, Context->Edi,
969  Context->Ebp);
970 #else
971  KdbpPrint("CS:RIP 0x%04x:0x%p\n"
972  "SS:RSP 0x%04x:0x%p\n"
973  " RAX 0x%p RBX 0x%p\n"
974  " RCX 0x%p RDX 0x%p\n"
975  " RSI 0x%p RDI 0x%p\n"
976  " RBP 0x%p\n",
977  Context->SegCs & 0xFFFF, Context->Rip,
978  Context->SegSs, Context->Rsp,
979  Context->Rax, Context->Rbx,
980  Context->Rcx, Context->Rdx,
981  Context->Rsi, Context->Rdi,
982  Context->Rbp);
983 #endif
984  /* Display the EFlags */
985  KdbpPrint("EFLAGS 0x%08x ", Context->EFlags);
986  for (i = 0; i < 32; i++)
987  {
988  if (i == 1)
989  {
990  if ((Context->EFlags & (1 << 1)) == 0)
991  KdbpPrint(" !BIT1");
992  }
993  else if (i == 12)
994  {
995  KdbpPrint(" IOPL%d", (Context->EFlags >> 12) & 3);
996  }
997  else if (i == 13)
998  {
999  }
1000  else if ((Context->EFlags & (1 << i)) != 0)
1001  {
1002  KdbpPrint(EflagsBits[i]);
1003  }
1004  }
1005  KdbpPrint("\n");
1006  }
1007  else if (Argv[0][0] == 's') /* sregs */
1008  {
1009  KdbpPrint("CS 0x%04x Index 0x%04x %cDT RPL%d\n",
1010  Context->SegCs & 0xffff, (Context->SegCs & 0xffff) >> 3,
1011  (Context->SegCs & (1 << 2)) ? 'L' : 'G', Context->SegCs & 3);
1012  KdbpPrint("DS 0x%04x Index 0x%04x %cDT RPL%d\n",
1013  Context->SegDs, Context->SegDs >> 3, (Context->SegDs & (1 << 2)) ? 'L' : 'G', Context->SegDs & 3);
1014  KdbpPrint("ES 0x%04x Index 0x%04x %cDT RPL%d\n",
1015  Context->SegEs, Context->SegEs >> 3, (Context->SegEs & (1 << 2)) ? 'L' : 'G', Context->SegEs & 3);
1016  KdbpPrint("FS 0x%04x Index 0x%04x %cDT RPL%d\n",
1017  Context->SegFs, Context->SegFs >> 3, (Context->SegFs & (1 << 2)) ? 'L' : 'G', Context->SegFs & 3);
1018  KdbpPrint("GS 0x%04x Index 0x%04x %cDT RPL%d\n",
1019  Context->SegGs, Context->SegGs >> 3, (Context->SegGs & (1 << 2)) ? 'L' : 'G', Context->SegGs & 3);
1020  KdbpPrint("SS 0x%04x Index 0x%04x %cDT RPL%d\n",
1021  Context->SegSs, Context->SegSs >> 3, (Context->SegSs & (1 << 2)) ? 'L' : 'G', Context->SegSs & 3);
1022  }
1023  else /* dregs */
1024  {
1025  ASSERT(Argv[0][0] == 'd');
1026  KdbpPrint("DR0 0x%08x\n"
1027  "DR1 0x%08x\n"
1028  "DR2 0x%08x\n"
1029  "DR3 0x%08x\n"
1030  "DR6 0x%08x\n"
1031  "DR7 0x%08x\n",
1032  Context->Dr0, Context->Dr1, Context->Dr2, Context->Dr3,
1033  Context->Dr6, Context->Dr7);
1034  }
1035 
1036  return TRUE;
1037 }
1038 
1039 #ifdef _M_IX86
1040 static PKTSS
1041 KdbpRetrieveTss(
1042  IN USHORT TssSelector,
1043  OUT PULONG pType OPTIONAL,
1044  IN PKDESCRIPTOR pGdtr OPTIONAL)
1045 {
1046  KDESCRIPTOR Gdtr;
1047  KGDTENTRY Desc;
1048  PKTSS Tss;
1049 
1050  /* Retrieve the Global Descriptor Table (user-provided or system) */
1051  if (pGdtr)
1052  Gdtr = *pGdtr;
1053  else
1055 
1056  /* Check limits */
1057  if ((TssSelector & (sizeof(KGDTENTRY) - 1)) ||
1058  (TssSelector < sizeof(KGDTENTRY)) ||
1059  (TssSelector + sizeof(KGDTENTRY) - 1 > Gdtr.Limit))
1060  {
1061  return NULL;
1062  }
1063 
1064  /* Retrieve the descriptor */
1065  if (!NT_SUCCESS(KdbpSafeReadMemory(&Desc,
1066  (PVOID)(Gdtr.Base + TssSelector),
1067  sizeof(KGDTENTRY))))
1068  {
1069  return NULL;
1070  }
1071 
1072  /* Check for TSS32(Avl) or TSS32(Busy) */
1073  if (Desc.HighWord.Bits.Type != 9 && Desc.HighWord.Bits.Type != 11)
1074  {
1075  return NULL;
1076  }
1077  if (pType) *pType = Desc.HighWord.Bits.Type;
1078 
1079  Tss = (PKTSS)(ULONG_PTR)(Desc.BaseLow |
1080  Desc.HighWord.Bytes.BaseMid << 16 |
1081  Desc.HighWord.Bytes.BaseHi << 24);
1082 
1083  return Tss;
1084 }
1085 
1087 KdbpIsNestedTss(
1088  IN USHORT TssSelector,
1089  IN PKTSS Tss)
1090 {
1091  USHORT Backlink;
1092 
1093  if (!Tss)
1094  return FALSE;
1095 
1096 #ifdef _M_AMD64
1097  // HACK
1098  return FALSE;
1099 #else
1100  /* Retrieve the TSS Backlink */
1101  if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1102  (PVOID)&Tss->Backlink,
1103  sizeof(USHORT))))
1104  {
1105  return FALSE;
1106  }
1107 #endif
1108 
1109  return (Backlink != 0 && Backlink != TssSelector);
1110 }
1111 
1112 static BOOLEAN
1113 KdbpContextFromPrevTss(
1115  OUT PUSHORT TssSelector,
1116  IN OUT PKTSS* pTss,
1117  IN PKDESCRIPTOR pGdtr)
1118 {
1119  ULONG_PTR Eip, Ebp;
1120  USHORT Backlink;
1121  PKTSS Tss = *pTss;
1122 
1123 #ifdef _M_AMD64
1124  // HACK
1125  return FALSE;
1126 #else
1127  /* Retrieve the TSS Backlink */
1128  if (!NT_SUCCESS(KdbpSafeReadMemory(&Backlink,
1129  (PVOID)&Tss->Backlink,
1130  sizeof(USHORT))))
1131  {
1132  return FALSE;
1133  }
1134 
1135  /* Retrieve the parent TSS */
1136  Tss = KdbpRetrieveTss(Backlink, NULL, pGdtr);
1137  if (!Tss)
1138  return FALSE;
1139 
1140  if (!NT_SUCCESS(KdbpSafeReadMemory(&Eip,
1141  (PVOID)&Tss->Eip,
1142  sizeof(ULONG_PTR))))
1143  {
1144  return FALSE;
1145  }
1146 
1147  if (!NT_SUCCESS(KdbpSafeReadMemory(&Ebp,
1148  (PVOID)&Tss->Ebp,
1149  sizeof(ULONG_PTR))))
1150  {
1151  return FALSE;
1152  }
1153 
1154  /* Return the parent TSS and its trap frame */
1155  *TssSelector = Backlink;
1156  *pTss = Tss;
1157  Context->Eip = Eip;
1158  Context->Ebp = Ebp;
1159 #endif
1160  return TRUE;
1161 }
1162 #endif
1163 
1164 #ifdef _M_AMD64
1165 
1166 static
1167 BOOLEAN
1168 GetNextFrame(
1170 {
1171  PRUNTIME_FUNCTION FunctionEntry;
1172  ULONG64 ImageBase, EstablisherFrame;
1173  PVOID HandlerData;
1174 
1175  _SEH2_TRY
1176  {
1177  /* Lookup the FunctionEntry for the current RIP */
1178  FunctionEntry = RtlLookupFunctionEntry(Context->Rip, &ImageBase, NULL);
1179  if (FunctionEntry == NULL)
1180  {
1181  /* No function entry, so this must be a leaf function. Pop the return address from the stack.
1182  Note: this can happen after the first frame as the result of an exception */
1183  Context->Rip = *(DWORD64*)Context->Rsp;
1184  Context->Rsp += sizeof(DWORD64);
1185  return TRUE;
1186  }
1187  else
1188  {
1190  ImageBase,
1191  Context->Rip,
1192  FunctionEntry,
1193  Context,
1194  &HandlerData,
1196  NULL);
1197  }
1198  }
1199  _SEH2_EXCEPT(1)
1200  {
1201  return FALSE;
1202  }
1203  _SEH2_END
1204 
1205  return TRUE;
1206 }
1207 
1208 static BOOLEAN
1210  ULONG Argc,
1211  PCHAR Argv[])
1212 {
1214 
1215  /* Walk through the frames */
1216  KdbpPrint("Frames:\n");
1217  do
1218  {
1219  BOOLEAN GotNextFrame;
1220 
1221  KdbpPrint("[%p] ", (PVOID)Context.Rsp);
1222 
1223  /* Print the location after the call instruction */
1224  if (!KdbSymPrintAddress((PVOID)Context.Rip, &Context))
1225  KdbpPrint("<%p>", (PVOID)Context.Rip);
1226  KdbpPrint("\n");
1227 
1228  if (KdbOutputAborted)
1229  break;
1230 
1231  GotNextFrame = GetNextFrame(&Context);
1232  if (!GotNextFrame)
1233  {
1234  KdbpPrint("Couldn't get next frame\n");
1235  break;
1236  }
1237  } while ((Context.Rip != 0) && (Context.Rsp != 0));
1238 
1239  return TRUE;
1240 }
1241 #else
1242 
1244 static BOOLEAN
1246  ULONG Argc,
1247  PCHAR Argv[])
1248 {
1249  ULONG ul;
1250  ULONGLONG Result = 0;
1254 
1255  if (Argc >= 2)
1256  {
1257  /* Check for [L count] part */
1258  ul = 0;
1259  if (strcmp(Argv[Argc-2], "L") == 0)
1260  {
1261  ul = strtoul(Argv[Argc-1], NULL, 0);
1262  if (ul > 0)
1263  {
1264  Argc -= 2;
1265  }
1266  }
1267  else if (Argv[Argc-1][0] == 'L')
1268  {
1269  ul = strtoul(Argv[Argc-1] + 1, NULL, 0);
1270  if (ul > 0)
1271  {
1272  Argc--;
1273  }
1274  }
1275 
1276  /* Put the remaining arguments back together */
1277  Argc--;
1278  for (ul = 1; ul < Argc; ul++)
1279  {
1280  Argv[ul][strlen(Argv[ul])] = ' ';
1281  }
1282  Argc++;
1283  }
1284 
1285  /* Check if a Frame Address or Thread ID is given */
1286  if (Argc > 1)
1287  {
1288  if (Argv[1][0] == '*')
1289  {
1290  Argv[1]++;
1291 
1292  /* Evaluate the expression */
1293  if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
1294  return TRUE;
1295 
1296  if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1297  KdbpPrint("Warning: Address %I64x is beeing truncated\n", Result);
1298 
1299  Frame = (ULONG_PTR)Result;
1300  }
1301  else
1302  {
1303  KdbpPrint("Thread backtrace not supported yet!\n");
1304  return TRUE;
1305  }
1306  }
1307 
1308 #ifdef _M_IX86
1309  KDESCRIPTOR Gdtr;
1310  USHORT TssSelector;
1311  PKTSS Tss;
1312 
1313  /* Retrieve the Global Descriptor Table */
1315 
1316  /* Retrieve the current (active) TSS */
1317  TssSelector = Ke386GetTr();
1318  Tss = KdbpRetrieveTss(TssSelector, NULL, &Gdtr);
1319  if (KdbpIsNestedTss(TssSelector, Tss))
1320  {
1321  /* Display the active TSS if it is nested */
1322  KdbpPrint("[Active TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1323  }
1324 #endif
1325 
1326  /* If no Frame Address or Thread ID was given, try printing the function at EIP */
1327  if (Argc <= 1)
1328  {
1329  KdbpPrint("Eip:\n");
1331  KdbpPrint("<%p>\n", KeGetContextPc(&Context));
1332  else
1333  KdbpPrint("\n");
1334  }
1335 
1336  /* Walk through the frames */
1337  KdbpPrint("Frames:\n");
1338  for (;;)
1339  {
1340  BOOLEAN GotNextFrame;
1341 
1342  if (Frame == 0)
1343  goto CheckForParentTSS;
1344 
1345  Address = 0;
1346  if (!NT_SUCCESS(KdbpSafeReadMemory(&Address, (PVOID)(Frame + sizeof(ULONG_PTR)), sizeof(ULONG_PTR))))
1347  {
1348  KdbpPrint("Couldn't access memory at 0x%p!\n", Frame + sizeof(ULONG_PTR));
1349  goto CheckForParentTSS;
1350  }
1351 
1352  if (Address == 0)
1353  goto CheckForParentTSS;
1354 
1355  GotNextFrame = NT_SUCCESS(KdbpSafeReadMemory(&Frame, (PVOID)Frame, sizeof(ULONG_PTR)));
1356  if (GotNextFrame)
1357  {
1359  }
1360  // else
1361  // Frame = 0;
1362 
1363  /* Print the location of the call instruction (assumed 5 bytes length) */
1364  if (!KdbSymPrintAddress((PVOID)(Address - 5), &Context))
1365  KdbpPrint("<%08x>\n", Address);
1366  else
1367  KdbpPrint("\n");
1368 
1369  if (KdbOutputAborted)
1370  break;
1371 
1372  if (!GotNextFrame)
1373  {
1374  KdbpPrint("Couldn't access memory at 0x%p!\n", Frame);
1375  goto CheckForParentTSS; // break;
1376  }
1377 
1378  continue;
1379 
1380 CheckForParentTSS:
1381 #ifndef _M_IX86
1382  break;
1383 #else
1384  /*
1385  * We have ended the stack walking for the current (active) TSS.
1386  * Check whether this TSS was nested, and if so switch to its parent
1387  * and walk its stack.
1388  */
1389  if (!KdbpIsNestedTss(TssSelector, Tss))
1390  break; // The TSS is not nested, we stop there.
1391 
1392  GotNextFrame = KdbpContextFromPrevTss(&Context, &TssSelector, &Tss, &Gdtr);
1393  if (!GotNextFrame)
1394  {
1395  KdbpPrint("Couldn't access parent TSS 0x%04x\n", Tss->Backlink);
1396  break; // Cannot retrieve the parent TSS, we stop there.
1397  }
1398 
1399 
1400  Address = Context.Eip;
1401  Frame = Context.Ebp;
1402 
1403  KdbpPrint("[Parent TSS 0x%04x @ 0x%p]\n", TssSelector, Tss);
1404 
1406  KdbpPrint("<%08x>\n", Address);
1407  else
1408  KdbpPrint("\n");
1409 #endif
1410  }
1411 
1412  return TRUE;
1413 }
1414 
1415 #endif // M_AMD64
1416 
1419 static BOOLEAN
1421  ULONG Argc,
1422  PCHAR Argv[])
1423 {
1424  /* Exit the main loop */
1425  return FALSE;
1426 }
1427 
1430 static BOOLEAN
1432  ULONG Argc,
1433  PCHAR Argv[])
1434 {
1435  ULONG Count = 1;
1436 
1437  if (Argc > 1)
1438  {
1439  Count = strtoul(Argv[1], NULL, 0);
1440  if (Count == 0)
1441  {
1442  KdbpPrint("%s: Integer argument required\n", Argv[0]);
1443  return TRUE;
1444  }
1445  }
1446 
1447  if (Argv[0][0] == 'n')
1449  else
1451 
1452  /* Set the number of single steps and return to the interrupted code. */
1454 
1455  return FALSE;
1456 }
1457 
1460 static BOOLEAN
1462  ULONG Argc,
1463  PCHAR Argv[])
1464 {
1465  LONG l;
1466  ULONG_PTR Address = 0;
1468  KDB_ACCESS_TYPE AccessType = 0;
1469  UCHAR Size = 0;
1470  UCHAR DebugReg = 0;
1471  BOOLEAN Enabled = FALSE;
1472  BOOLEAN Global = FALSE;
1474  PCHAR str1, str2, ConditionExpr, GlobalOrLocal;
1475  CHAR Buffer[20];
1476 
1478  if (l < 0)
1479  {
1480  KdbpPrint("No breakpoints.\n");
1481  return TRUE;
1482  }
1483 
1484  KdbpPrint("Breakpoints:\n");
1485  do
1486  {
1487  if (!KdbpGetBreakPointInfo(l, &Address, &Type, &Size, &AccessType, &DebugReg,
1488  &Enabled, &Global, &Process, &ConditionExpr))
1489  {
1490  continue;
1491  }
1492 
1493  if (l == KdbLastBreakPointNr)
1494  {
1495  str1 = "\x1b[1m*";
1496  str2 = "\x1b[0m";
1497  }
1498  else
1499  {
1500  str1 = " ";
1501  str2 = "";
1502  }
1503 
1504  if (Global)
1505  {
1506  GlobalOrLocal = " global";
1507  }
1508  else
1509  {
1510  GlobalOrLocal = Buffer;
1511  sprintf(Buffer, " PID 0x%Ix",
1512  (ULONG_PTR)(Process ? Process->UniqueProcessId : INVALID_HANDLE_VALUE));
1513  }
1514 
1516  {
1517  KdbpPrint(" %s%03d BPX 0x%08x%s%s%s%s%s\n",
1518  str1, l, Address,
1519  Enabled ? "" : " disabled",
1520  GlobalOrLocal,
1521  ConditionExpr ? " IF " : "",
1522  ConditionExpr ? ConditionExpr : "",
1523  str2);
1524  }
1525  else if (Type == KdbBreakPointHardware)
1526  {
1527  if (!Enabled)
1528  {
1529  KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s disabled%s%s%s%s\n", str1, l, Address,
1530  KDB_ACCESS_TYPE_TO_STRING(AccessType),
1531  Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1532  GlobalOrLocal,
1533  ConditionExpr ? " IF " : "",
1534  ConditionExpr ? ConditionExpr : "",
1535  str2);
1536  }
1537  else
1538  {
1539  KdbpPrint(" %s%03d BPM 0x%08x %-5s %-5s DR%d%s%s%s%s\n", str1, l, Address,
1540  KDB_ACCESS_TYPE_TO_STRING(AccessType),
1541  Size == 1 ? "byte" : (Size == 2 ? "word" : "dword"),
1542  DebugReg,
1543  GlobalOrLocal,
1544  ConditionExpr ? " IF " : "",
1545  ConditionExpr ? ConditionExpr : "",
1546  str2);
1547  }
1548  }
1549  }
1550  while ((l = KdbpGetNextBreakPointNr(l+1)) >= 0);
1551 
1552  return TRUE;
1553 }
1554 
1557 static BOOLEAN
1559  ULONG Argc,
1560  PCHAR Argv[])
1561 {
1562  PCHAR pend;
1563  ULONG BreakPointNr;
1564 
1565  if (Argc < 2)
1566  {
1567  KdbpPrint("%s: argument required\n", Argv[0]);
1568  return TRUE;
1569  }
1570 
1571  pend = Argv[1];
1572  BreakPointNr = strtoul(Argv[1], &pend, 0);
1573  if (pend == Argv[1] || *pend != '\0')
1574  {
1575  KdbpPrint("%s: integer argument required\n", Argv[0]);
1576  return TRUE;
1577  }
1578 
1579  if (Argv[0][1] == 'e') /* enable */
1580  {
1581  KdbpEnableBreakPoint(BreakPointNr, NULL);
1582  }
1583  else if (Argv [0][1] == 'd') /* disable */
1584  {
1585  KdbpDisableBreakPoint(BreakPointNr, NULL);
1586  }
1587  else /* clear */
1588  {
1589  ASSERT(Argv[0][1] == 'c');
1590  KdbpDeleteBreakPoint(BreakPointNr, NULL);
1591  }
1592 
1593  return TRUE;
1594 }
1595 
1598 static BOOLEAN
1600 {
1601  ULONGLONG Result = 0;
1604  UCHAR Size = 0;
1605  KDB_ACCESS_TYPE AccessType = 0;
1606  ULONG AddressArgIndex, i;
1607  LONG ConditionArgIndex;
1608  BOOLEAN Global = TRUE;
1609 
1610  if (Argv[0][2] == 'x') /* software breakpoint */
1611  {
1612  if (Argc < 2)
1613  {
1614  KdbpPrint("bpx: Address argument required.\n");
1615  return TRUE;
1616  }
1617 
1618  AddressArgIndex = 1;
1620  }
1621  else /* memory breakpoint */
1622  {
1623  ASSERT(Argv[0][2] == 'm');
1624 
1625  if (Argc < 2)
1626  {
1627  KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
1628  return TRUE;
1629  }
1630 
1631  if (_stricmp(Argv[1], "x") == 0)
1632  AccessType = KdbAccessExec;
1633  else if (_stricmp(Argv[1], "r") == 0)
1634  AccessType = KdbAccessRead;
1635  else if (_stricmp(Argv[1], "w") == 0)
1636  AccessType = KdbAccessWrite;
1637  else if (_stricmp(Argv[1], "rw") == 0)
1638  AccessType = KdbAccessReadWrite;
1639  else
1640  {
1641  KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
1642  return TRUE;
1643  }
1644 
1645  if (Argc < 3)
1646  {
1647  KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
1648  return TRUE;
1649  }
1650 
1651  AddressArgIndex = 3;
1652  if (_stricmp(Argv[2], "byte") == 0)
1653  Size = 1;
1654  else if (_stricmp(Argv[2], "word") == 0)
1655  Size = 2;
1656  else if (_stricmp(Argv[2], "dword") == 0)
1657  Size = 4;
1658  else if (AccessType == KdbAccessExec)
1659  {
1660  Size = 1;
1661  AddressArgIndex--;
1662  }
1663  else
1664  {
1665  KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
1666  return TRUE;
1667  }
1668 
1669  if (Argc <= AddressArgIndex)
1670  {
1671  KdbpPrint("bpm: Address argument required.\n");
1672  return TRUE;
1673  }
1674 
1676  }
1677 
1678  /* Put the arguments back together */
1679  ConditionArgIndex = -1;
1680  for (i = AddressArgIndex; i < (Argc-1); i++)
1681  {
1682  if (strcmp(Argv[i+1], "IF") == 0) /* IF found */
1683  {
1684  ConditionArgIndex = i + 2;
1685  if ((ULONG)ConditionArgIndex >= Argc)
1686  {
1687  KdbpPrint("%s: IF requires condition expression.\n", Argv[0]);
1688  return TRUE;
1689  }
1690 
1691  for (i = ConditionArgIndex; i < (Argc-1); i++)
1692  Argv[i][strlen(Argv[i])] = ' ';
1693 
1694  break;
1695  }
1696 
1697  Argv[i][strlen(Argv[i])] = ' ';
1698  }
1699 
1700  /* Evaluate the address expression */
1701  if (!KdbpEvaluateExpression(Argv[AddressArgIndex],
1702  KdbPromptString.Length + (Argv[AddressArgIndex]-Argv[0]),
1703  &Result))
1704  {
1705  return TRUE;
1706  }
1707 
1708  if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
1709  KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
1710 
1712 
1713  KdbpInsertBreakPoint(Address, Type, Size, AccessType,
1714  (ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
1715  Global, NULL);
1716 
1717  return TRUE;
1718 }
1719 
1722 static BOOLEAN
1724  ULONG Argc,
1725  PCHAR Argv[])
1726 {
1728  PETHREAD Thread = NULL;
1730  BOOLEAN ReferencedThread = FALSE, ReferencedProcess = FALSE;
1731  PULONG_PTR Stack;
1732  PULONG_PTR Frame;
1733  ULONG_PTR Pc;
1734  ULONG_PTR ul = 0;
1735  PCHAR State, pend, str1, str2;
1736  static const PCHAR ThreadStateToString[DeferredReady+1] =
1737  {
1738  "Initialized", "Ready", "Running",
1739  "Standby", "Terminated", "Waiting",
1740  "Transition", "DeferredReady"
1741  };
1742 
1744 
1745  if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1746  {
1748 
1749  if (Argc >= 3)
1750  {
1751  ul = strtoulptr(Argv[2], &pend, 0);
1752  if (Argv[2] == pend)
1753  {
1754  KdbpPrint("thread: '%s' is not a valid process id!\n", Argv[2]);
1755  return TRUE;
1756  }
1757 
1759  {
1760  KdbpPrint("thread: Invalid process id!\n");
1761  return TRUE;
1762  }
1763 
1764  /* Remember our reference */
1765  ReferencedProcess = TRUE;
1766  }
1767 
1768  Entry = Process->ThreadListHead.Flink;
1769  if (Entry == &Process->ThreadListHead)
1770  {
1771  if (Argc >= 3)
1772  KdbpPrint("No threads in process 0x%px!\n", (PVOID)ul);
1773  else
1774  KdbpPrint("No threads in current process!\n");
1775 
1776  if (ReferencedProcess)
1778 
1779  return TRUE;
1780  }
1781 
1782  KdbpPrint(" TID State Prior. Affinity EBP EIP\n");
1783  do
1784  {
1785  Thread = CONTAINING_RECORD(Entry, ETHREAD, ThreadListEntry);
1786 
1787  if (Thread == KdbCurrentThread)
1788  {
1789  str1 = "\x1b[1m*";
1790  str2 = "\x1b[0m";
1791  }
1792  else
1793  {
1794  str1 = " ";
1795  str2 = "";
1796  }
1797 
1798  if (!Thread->Tcb.InitialStack)
1799  {
1800  /* Thread has no kernel stack (probably terminated) */
1801  Stack = Frame = NULL;
1802  Pc = 0;
1803  }
1804  else if (Thread->Tcb.TrapFrame)
1805  {
1809  }
1810  else
1811  {
1813  Frame = (PULONG_PTR)Stack[4];
1814  Pc = 0;
1815 
1816  if (Frame) /* FIXME: Should we attach to the process to read Ebp[1]? */
1817  KdbpSafeReadMemory(&Pc, Frame + 1, sizeof(Pc));
1818  }
1819 
1820  if (Thread->Tcb.State < (DeferredReady + 1))
1821  State = ThreadStateToString[Thread->Tcb.State];
1822  else
1823  State = "Unknown";
1824 
1825  KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
1826  str1,
1828  State,
1829  Thread->Tcb.Priority,
1830  Thread->Tcb.Affinity,
1831  Frame,
1832  Pc,
1833  str2);
1834 
1835  Entry = Entry->Flink;
1836  }
1837  while (Entry != &Process->ThreadListHead);
1838 
1839  /* Release our reference, if any */
1840  if (ReferencedProcess)
1842  }
1843  else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1844  {
1845  if (Argc < 3)
1846  {
1847  KdbpPrint("thread attach: thread id argument required!\n");
1848  return TRUE;
1849  }
1850 
1851  ul = strtoulptr(Argv[2], &pend, 0);
1852  if (Argv[2] == pend)
1853  {
1854  KdbpPrint("thread attach: '%s' is not a valid thread id!\n", Argv[2]);
1855  return TRUE;
1856  }
1857 
1858  if (!KdbpAttachToThread((PVOID)ul))
1859  {
1860  return TRUE;
1861  }
1862 
1863  KdbpPrint("Attached to thread 0x%08x.\n", ul);
1864  }
1865  else
1866  {
1868 
1869  if (Argc >= 2)
1870  {
1871  ul = strtoulptr(Argv[1], &pend, 0);
1872  if (Argv[1] == pend)
1873  {
1874  KdbpPrint("thread: '%s' is not a valid thread id!\n", Argv[1]);
1875  return TRUE;
1876  }
1877 
1879  {
1880  KdbpPrint("thread: Invalid thread id!\n");
1881  return TRUE;
1882  }
1883 
1884  /* Remember our reference */
1885  ReferencedThread = TRUE;
1886  }
1887 
1888  if (Thread->Tcb.State < (DeferredReady + 1))
1889  State = ThreadStateToString[Thread->Tcb.State];
1890  else
1891  State = "Unknown";
1892 
1893  KdbpPrint("%s"
1894  " TID: 0x%08x\n"
1895  " State: %s (0x%x)\n"
1896  " Priority: %d\n"
1897  " Affinity: 0x%08x\n"
1898  " Initial Stack: 0x%08x\n"
1899  " Stack Limit: 0x%08x\n"
1900  " Stack Base: 0x%08x\n"
1901  " Kernel Stack: 0x%08x\n"
1902  " Trap Frame: 0x%08x\n"
1903 #ifndef _M_AMD64
1904  " NPX State: %s (0x%x)\n"
1905 #endif
1906  , (Argc < 2) ? "Current Thread:\n" : ""
1908  , State, Thread->Tcb.State
1909  , Thread->Tcb.Priority
1910  , Thread->Tcb.Affinity
1912  , Thread->Tcb.StackLimit
1913  , Thread->Tcb.StackBase
1915  , Thread->Tcb.TrapFrame
1916 #ifndef _M_AMD64
1918 #endif
1919  );
1920 
1921  /* Release our reference if we had one */
1922  if (ReferencedThread)
1924  }
1925 
1926  return TRUE;
1927 }
1928 
1931 static BOOLEAN
1933  ULONG Argc,
1934  PCHAR Argv[])
1935 {
1938  BOOLEAN ReferencedProcess = FALSE;
1939  PCHAR State, pend, str1, str2;
1940  ULONG_PTR ul;
1942 
1943  if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
1944  {
1946  if (!Entry || Entry == &PsActiveProcessHead)
1947  {
1948  KdbpPrint("No processes in the system!\n");
1949  return TRUE;
1950  }
1951 
1952  KdbpPrint(" PID State Filename\n");
1953  do
1954  {
1955  Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
1956 
1957  if (Process == KdbCurrentProcess)
1958  {
1959  str1 = "\x1b[1m*";
1960  str2 = "\x1b[0m";
1961  }
1962  else
1963  {
1964  str1 = " ";
1965  str2 = "";
1966  }
1967 
1968  State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
1969  ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
1970 
1971  KdbpPrint(" %s0x%08x %-10s %s%s\n",
1972  str1,
1973  Process->UniqueProcessId,
1974  State,
1975  Process->ImageFileName,
1976  str2);
1977 
1978  Entry = Entry->Flink;
1979  }
1980  while(Entry != &PsActiveProcessHead);
1981  }
1982  else if (Argc >= 2 && _stricmp(Argv[1], "attach") == 0)
1983  {
1984  if (Argc < 3)
1985  {
1986  KdbpPrint("process attach: process id argument required!\n");
1987  return TRUE;
1988  }
1989 
1990  ul = strtoulptr(Argv[2], &pend, 0);
1991  if (Argv[2] == pend)
1992  {
1993  KdbpPrint("process attach: '%s' is not a valid process id!\n", Argv[2]);
1994  return TRUE;
1995  }
1996 
1997  if (!KdbpAttachToProcess((PVOID)ul))
1998  {
1999  return TRUE;
2000  }
2001 
2002  KdbpPrint("Attached to process 0x%p, thread 0x%p.\n", (PVOID)ul,
2004  }
2005  else
2006  {
2008 
2009  if (Argc >= 2)
2010  {
2011  ul = strtoulptr(Argv[1], &pend, 0);
2012  if (Argv[1] == pend)
2013  {
2014  KdbpPrint("proc: '%s' is not a valid process id!\n", Argv[1]);
2015  return TRUE;
2016  }
2017 
2019  {
2020  KdbpPrint("proc: Invalid process id!\n");
2021  return TRUE;
2022  }
2023 
2024  /* Remember our reference */
2025  ReferencedProcess = TRUE;
2026  }
2027 
2028  State = ((Process->Pcb.State == ProcessInMemory) ? "In Memory" :
2029  ((Process->Pcb.State == ProcessOutOfMemory) ? "Out of Memory" : "In Transition"));
2030  KdbpPrint("%s"
2031  " PID: 0x%08x\n"
2032  " State: %s (0x%x)\n"
2033  " Image Filename: %s\n",
2034  (Argc < 2) ? "Current process:\n" : "",
2035  Process->UniqueProcessId,
2036  State, Process->Pcb.State,
2037  Process->ImageFileName);
2038 
2039  /* Release our reference, if any */
2040  if (ReferencedProcess)
2042  }
2043 
2044  return TRUE;
2045 }
2046 
2049 static BOOLEAN
2051  ULONG Argc,
2052  PCHAR Argv[])
2053 {
2054  ULONGLONG Result = 0;
2056  PLDR_DATA_TABLE_ENTRY LdrEntry;
2057  BOOLEAN DisplayOnlyOneModule = FALSE;
2058  INT i = 0;
2059 
2060  if (Argc >= 2)
2061  {
2062  /* Put the arguments back together */
2063  Argc--;
2064  while (--Argc >= 1)
2065  Argv[Argc][strlen(Argv[Argc])] = ' ';
2066 
2067  /* Evaluate the expression */
2068  if (!KdbpEvaluateExpression(Argv[1], KdbPromptString.Length + (Argv[1]-Argv[0]), &Result))
2069  {
2070  return TRUE;
2071  }
2072 
2073  if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
2074  KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0],Result);
2075 
2077 
2078  if (!KdbpSymFindModule((PVOID)Address, -1, &LdrEntry))
2079  {
2080  KdbpPrint("No module containing address 0x%p found!\n", Address);
2081  return TRUE;
2082  }
2083 
2084  DisplayOnlyOneModule = TRUE;
2085  }
2086  else
2087  {
2088  if (!KdbpSymFindModule(NULL, 0, &LdrEntry))
2089  {
2090  ULONG_PTR ntoskrnlBase = (ULONG_PTR)__ImageBase;
2091  KdbpPrint(" Base Size Name\n");
2092  KdbpPrint(" %p %08x %s\n", (PVOID)ntoskrnlBase, 0, "ntoskrnl.exe");
2093  return TRUE;
2094  }
2095 
2096  i = 1;
2097  }
2098 
2099  KdbpPrint(" Base Size Name\n");
2100  for (;;)
2101  {
2102  KdbpPrint(" %p %08x ", LdrEntry->DllBase, LdrEntry->SizeOfImage);
2103  KdbpPrintUnicodeString(&LdrEntry->BaseDllName);
2104  KdbpPrint("\n");
2105 
2106  if(DisplayOnlyOneModule || !KdbpSymFindModule(NULL, i++, &LdrEntry))
2107  break;
2108  }
2109 
2110  return TRUE;
2111 }
2112 
2115 static BOOLEAN
2117  ULONG Argc,
2118  PCHAR Argv[])
2119 {
2120  KDESCRIPTOR Reg;
2121  ULONG SegDesc[2];
2122  ULONG SegBase;
2123  ULONG SegLimit;
2124  PCHAR SegType;
2125  USHORT SegSel;
2126  UCHAR Type, Dpl;
2127  INT i;
2128  ULONG ul;
2129 
2130  if (Argv[0][0] == 'i')
2131  {
2132  /* Read IDTR */
2133  __sidt(&Reg.Limit);
2134 
2135  if (Reg.Limit < 7)
2136  {
2137  KdbpPrint("Interrupt descriptor table is empty.\n");
2138  return TRUE;
2139  }
2140 
2141  KdbpPrint("IDT Base: 0x%08x Limit: 0x%04x\n", Reg.Base, Reg.Limit);
2142  KdbpPrint(" Idx Type Seg. Sel. Offset DPL\n");
2143 
2144  for (i = 0; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2145  {
2146  if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2147  {
2148  KdbpPrint("Couldn't access memory at 0x%p!\n", (PVOID)((ULONG_PTR)Reg.Base + i));
2149  return TRUE;
2150  }
2151 
2152  Dpl = ((SegDesc[1] >> 13) & 3);
2153  if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2154  SegType = "TASKGATE";
2155  else if ((SegDesc[1] & 0x1fe0) == 0x0e00) /* 32 bit Interrupt gate */
2156  SegType = "INTGATE32";
2157  else if ((SegDesc[1] & 0x1fe0) == 0x0600) /* 16 bit Interrupt gate */
2158  SegType = "INTGATE16";
2159  else if ((SegDesc[1] & 0x1fe0) == 0x0f00) /* 32 bit Trap gate */
2160  SegType = "TRAPGATE32";
2161  else if ((SegDesc[1] & 0x1fe0) == 0x0700) /* 16 bit Trap gate */
2162  SegType = "TRAPGATE16";
2163  else
2164  SegType = "UNKNOWN";
2165 
2166  if ((SegDesc[1] & (1 << 15)) == 0) /* not present */
2167  {
2168  KdbpPrint(" %03d %-10s [NP] [NP] %02d\n",
2169  i / 8, SegType, Dpl);
2170  }
2171  else if ((SegDesc[1] & 0x1f00) == 0x0500) /* Task gate */
2172  {
2173  SegSel = SegDesc[0] >> 16;
2174  KdbpPrint(" %03d %-10s 0x%04x %02d\n",
2175  i / 8, SegType, SegSel, Dpl);
2176  }
2177  else
2178  {
2179  SegSel = SegDesc[0] >> 16;
2180  SegBase = (SegDesc[1] & 0xffff0000) | (SegDesc[0] & 0x0000ffff);
2181  KdbpPrint(" %03d %-10s 0x%04x 0x%08x %02d\n",
2182  i / 8, SegType, SegSel, SegBase, Dpl);
2183  }
2184  }
2185  }
2186  else
2187  {
2188  ul = 0;
2189 
2190  if (Argv[0][0] == 'g')
2191  {
2192  /* Read GDTR */
2194  i = 8;
2195  }
2196  else
2197  {
2198  ASSERT(Argv[0][0] == 'l');
2199 
2200  /* Read LDTR */
2202  Reg.Base = 0;
2203  i = 0;
2204  ul = 1 << 2;
2205  }
2206 
2207  if (Reg.Limit < 7)
2208  {
2209  KdbpPrint("%s descriptor table is empty.\n",
2210  Argv[0][0] == 'g' ? "Global" : "Local");
2211  return TRUE;
2212  }
2213 
2214  KdbpPrint("%cDT Base: 0x%08x Limit: 0x%04x\n",
2215  Argv[0][0] == 'g' ? 'G' : 'L', Reg.Base, Reg.Limit);
2216  KdbpPrint(" Idx Sel. Type Base Limit DPL Attribs\n");
2217 
2218  for (; (i + sizeof(SegDesc) - 1) <= Reg.Limit; i += 8)
2219  {
2220  if (!NT_SUCCESS(KdbpSafeReadMemory(SegDesc, (PVOID)((ULONG_PTR)Reg.Base + i), sizeof(SegDesc))))
2221  {
2222  KdbpPrint("Couldn't access memory at 0x%p!\n", (ULONG_PTR)Reg.Base + i);
2223  return TRUE;
2224  }
2225 
2226  Dpl = ((SegDesc[1] >> 13) & 3);
2227  Type = ((SegDesc[1] >> 8) & 0xf);
2228 
2229  SegBase = SegDesc[0] >> 16;
2230  SegBase |= (SegDesc[1] & 0xff) << 16;
2231  SegBase |= SegDesc[1] & 0xff000000;
2232  SegLimit = SegDesc[0] & 0x0000ffff;
2233  SegLimit |= (SegDesc[1] >> 16) & 0xf;
2234 
2235  if ((SegDesc[1] & (1 << 23)) != 0)
2236  {
2237  SegLimit *= 4096;
2238  SegLimit += 4095;
2239  }
2240  else
2241  {
2242  SegLimit++;
2243  }
2244 
2245  if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2246  {
2247  switch (Type)
2248  {
2249  case 1: SegType = "TSS16(Avl)"; break;
2250  case 2: SegType = "LDT"; break;
2251  case 3: SegType = "TSS16(Busy)"; break;
2252  case 4: SegType = "CALLGATE16"; break;
2253  case 5: SegType = "TASKGATE"; break;
2254  case 6: SegType = "INTGATE16"; break;
2255  case 7: SegType = "TRAPGATE16"; break;
2256  case 9: SegType = "TSS32(Avl)"; break;
2257  case 11: SegType = "TSS32(Busy)"; break;
2258  case 12: SegType = "CALLGATE32"; break;
2259  case 14: SegType = "INTGATE32"; break;
2260  case 15: SegType = "TRAPGATE32"; break;
2261  default: SegType = "UNKNOWN"; break;
2262  }
2263 
2264  if (!(Type >= 1 && Type <= 3) &&
2265  Type != 9 && Type != 11)
2266  {
2267  SegBase = 0;
2268  SegLimit = 0;
2269  }
2270  }
2271  else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2272  {
2273  if ((SegDesc[1] & (1 << 22)) != 0)
2274  SegType = "DATA32";
2275  else
2276  SegType = "DATA16";
2277  }
2278  else /* Code segment */
2279  {
2280  if ((SegDesc[1] & (1 << 22)) != 0)
2281  SegType = "CODE32";
2282  else
2283  SegType = "CODE16";
2284  }
2285 
2286  if ((SegDesc[1] & (1 << 15)) == 0) /* Not present */
2287  {
2288  KdbpPrint(" %03d 0x%04x %-11s [NP] [NP] %02d NP\n",
2289  i / 8, i | Dpl | ul, SegType, Dpl);
2290  }
2291  else
2292  {
2293  KdbpPrint(" %03d 0x%04x %-11s 0x%08x 0x%08x %02d ",
2294  i / 8, i | Dpl | ul, SegType, SegBase, SegLimit, Dpl);
2295 
2296  if ((SegDesc[1] & (1 << 12)) == 0) /* System segment */
2297  {
2298  /* FIXME: Display system segment */
2299  }
2300  else if ((SegDesc[1] & (1 << 11)) == 0) /* Data segment */
2301  {
2302  if ((SegDesc[1] & (1 << 10)) != 0) /* Expand-down */
2303  KdbpPrint(" E");
2304 
2305  KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/W" : " R");
2306 
2307  if ((SegDesc[1] & (1 << 8)) != 0)
2308  KdbpPrint(" A");
2309  }
2310  else /* Code segment */
2311  {
2312  if ((SegDesc[1] & (1 << 10)) != 0) /* Conforming */
2313  KdbpPrint(" C");
2314 
2315  KdbpPrint((SegDesc[1] & (1 << 9)) ? " R/X" : " X");
2316 
2317  if ((SegDesc[1] & (1 << 8)) != 0)
2318  KdbpPrint(" A");
2319  }
2320 
2321  if ((SegDesc[1] & (1 << 20)) != 0)
2322  KdbpPrint(" AVL");
2323 
2324  KdbpPrint("\n");
2325  }
2326  }
2327  }
2328 
2329  return TRUE;
2330 }
2331 
2334 static BOOLEAN
2336  ULONG Argc,
2337  PCHAR Argv[])
2338 {
2339  PKIPCR Pcr = (PKIPCR)KeGetPcr();
2340 
2341  KdbpPrint("Current PCR is at 0x%p.\n", Pcr);
2342 #ifdef _M_IX86
2343  KdbpPrint(" Tib.ExceptionList: 0x%08x\n"
2344  " Tib.StackBase: 0x%08x\n"
2345  " Tib.StackLimit: 0x%08x\n"
2346  " Tib.SubSystemTib: 0x%08x\n"
2347  " Tib.FiberData/Version: 0x%08x\n"
2348  " Tib.ArbitraryUserPointer: 0x%08x\n"
2349  " Tib.Self: 0x%08x\n"
2350  " SelfPcr: 0x%08x\n"
2351  " PCRCB: 0x%08x\n"
2352  " Irql: 0x%02x\n"
2353  " IRR: 0x%08x\n"
2354  " IrrActive: 0x%08x\n"
2355  " IDR: 0x%08x\n"
2356  " KdVersionBlock: 0x%08x\n"
2357  " IDT: 0x%08x\n"
2358  " GDT: 0x%08x\n"
2359  " TSS: 0x%08x\n"
2360  " MajorVersion: 0x%04x\n"
2361  " MinorVersion: 0x%04x\n"
2362  " SetMember: 0x%08x\n"
2363  " StallScaleFactor: 0x%08x\n"
2364  " Number: 0x%02x\n"
2365  " L2CacheAssociativity: 0x%02x\n"
2366  " VdmAlert: 0x%08x\n"
2367  " L2CacheSize: 0x%08x\n"
2368  " InterruptMode: 0x%08x\n"
2369  , Pcr->NtTib.ExceptionList, Pcr->NtTib.StackBase, Pcr->NtTib.StackLimit,
2371  Pcr->NtTib.Self
2372  , Pcr->SelfPcr
2373  , Pcr->Prcb, Pcr->Irql
2374  , Pcr->IRR, Pcr->IrrActive , Pcr->IDR
2375  , Pcr->KdVersionBlock
2376  , Pcr->IDT, Pcr->GDT, Pcr->TSS
2377  , Pcr->MajorVersion, Pcr->MinorVersion
2378  , Pcr->SetMember
2379  , Pcr->StallScaleFactor
2380  , Pcr->Number
2382  , Pcr->VdmAlert
2383  , Pcr->SecondLevelCacheSize
2384  , Pcr->InterruptMode);
2385 #else
2386  KdbpPrint(" GdtBase: 0x%p\n", Pcr->GdtBase);
2387  KdbpPrint(" TssBase: 0x%p\n", Pcr->TssBase);
2388  KdbpPrint(" UserRsp: 0x%p\n", (PVOID)Pcr->UserRsp);
2389  KdbpPrint(" Self: 0x%p\n", Pcr->Self);
2390  KdbpPrint(" CurrentPrcb: 0x%p\n", Pcr->CurrentPrcb);
2391  KdbpPrint(" LockArray: 0x%p\n", Pcr->LockArray);
2392  KdbpPrint(" Used_Self: 0x%p\n", Pcr->Used_Self);
2393  KdbpPrint(" IdtBase: 0x%p\n", Pcr->IdtBase);
2394  KdbpPrint(" Irql: %u\n", Pcr->Irql);
2395  KdbpPrint(" SecondLevelCacheAssociativity: 0x%u\n", Pcr->SecondLevelCacheAssociativity);
2396  KdbpPrint(" ObsoleteNumber: %u\n", Pcr->ObsoleteNumber);
2397  KdbpPrint(" MajorVersion: 0x%x\n", Pcr->MajorVersion);
2398  KdbpPrint(" MinorVersion: 0x%x\n", Pcr->MinorVersion);
2399  KdbpPrint(" StallScaleFactor: 0x%lx\n", Pcr->StallScaleFactor);
2400  KdbpPrint(" SecondLevelCacheSize: 0x%lx\n", Pcr->SecondLevelCacheSize);
2401  KdbpPrint(" KdVersionBlock: 0x%p\n", Pcr->KdVersionBlock);
2402 #endif
2403 
2404  return TRUE;
2405 }
2406 
2407 #ifdef _M_IX86
2408 
2410 static BOOLEAN
2411 KdbpCmdTss(
2412  ULONG Argc,
2413  PCHAR Argv[])
2414 {
2415  USHORT TssSelector;
2416  PKTSS Tss = NULL;
2417 
2418  if (Argc >= 2)
2419  {
2420  /*
2421  * Specified TSS via its selector [selector] or descriptor address [*descaddr].
2422  * Note that we ignore any other argument values.
2423  */
2424  PCHAR Param, pszNext;
2425  ULONG ulValue;
2426 
2427  Param = Argv[1];
2428  if (Argv[1][0] == '*')
2429  ++Param;
2430 
2431  ulValue = strtoul(Param, &pszNext, 0);
2432  if (pszNext && *pszNext)
2433  {
2434  KdbpPrint("Invalid TSS specification.\n");
2435  return TRUE;
2436  }
2437 
2438  if (Argv[1][0] == '*')
2439  {
2440  /* Descriptor specified */
2441  TssSelector = 0; // Unknown selector!
2442  // TODO: Room for improvement: Find the TSS descriptor
2443  // in the GDT so as to validate it.
2444  Tss = (PKTSS)(ULONG_PTR)ulValue;
2445  if (!Tss)
2446  {
2447  KdbpPrint("Invalid 32-bit TSS descriptor.\n");
2448  return TRUE;
2449  }
2450  }
2451  else
2452  {
2453  /* Selector specified, retrive the corresponding TSS */
2454  TssSelector = (USHORT)ulValue;
2455  Tss = KdbpRetrieveTss(TssSelector, NULL, NULL);
2456  if (!Tss)
2457  {
2458  KdbpPrint("Invalid 32-bit TSS selector.\n");
2459  return TRUE;
2460  }
2461  }
2462  }
2463 
2464  if (!Tss)
2465  {
2466  /* If no TSS was specified, use the current TSS descriptor */
2467  TssSelector = Ke386GetTr();
2468  Tss = KeGetPcr()->TSS;
2469  // NOTE: If everything works OK, Tss is the current TSS corresponding to the TR selector.
2470  }
2471 
2472  KdbpPrint("%s TSS 0x%04x is at 0x%p.\n",
2473  (Tss == KeGetPcr()->TSS) ? "Current" : "Specified", TssSelector, Tss);
2474  KdbpPrint(" Backlink: 0x%04x\n"
2475  " Ss0:Esp0: 0x%04x:0x%08x\n"
2476  // NOTE: Ss1:Esp1 and Ss2:Esp2: are in the NotUsed1 field.
2477  " CR3: 0x%08x\n"
2478  " EFlags: 0x%08x\n"
2479  " Eax: 0x%08x\n"
2480  " Ebx: 0x%08x\n"
2481  " Ecx: 0x%08x\n"
2482  " Edx: 0x%08x\n"
2483  " Esi: 0x%08x\n"
2484  " Edi: 0x%08x\n"
2485  " Eip: 0x%08x\n"
2486  " Esp: 0x%08x\n"
2487  " Ebp: 0x%08x\n"
2488  " Cs: 0x%04x\n"
2489  " Ss: 0x%04x\n"
2490  " Ds: 0x%04x\n"
2491  " Es: 0x%04x\n"
2492  " Fs: 0x%04x\n"
2493  " Gs: 0x%04x\n"
2494  " LDT: 0x%04x\n"
2495  " Flags: 0x%04x\n"
2496  " IoMapBase: 0x%04x\n",
2497  Tss->Backlink, Tss->Ss0, Tss->Esp0, Tss->CR3, Tss->EFlags,
2498  Tss->Eax, Tss->Ebx, Tss->Ecx, Tss->Edx, Tss->Esi, Tss->Edi,
2499  Tss->Eip, Tss->Esp, Tss->Ebp,
2500  Tss->Cs, Tss->Ss, Tss->Ds, Tss->Es, Tss->Fs, Tss->Gs,
2501  Tss->LDT, Tss->Flags, Tss->IoMapBase);
2502 
2503  return TRUE;
2504 }
2505 #endif // _M_IX86
2506 
2509 static BOOLEAN
2511  ULONG Argc,
2512  PCHAR Argv[])
2513 {
2514  /* Set the flag and quit looping */
2516  return FALSE;
2517 }
2518 
2519 static BOOLEAN
2521  ULONG Argc,
2522  PCHAR Argv[])
2523 {
2524  /* Reboot immediately (we do not return) */
2526  return FALSE;
2527 }
2528 
2529 
2530 VOID
2531 KdbpPager(
2532  IN PCHAR Buffer,
2533  IN ULONG BufLength);
2534 
2540 static BOOLEAN
2542  ULONG Argc,
2543  PCHAR Argv[])
2544 {
2545  ULONG beg, end;
2546 
2547  KdbpIsInDmesgMode = TRUE; /* Toggle logging flag */
2548  if (!KdpDmesgBuffer)
2549  {
2550  KdbpPrint("Dmesg: error, buffer is not allocated! /DEBUGPORT=SCREEN kernel param required for dmesg.\n");
2551  return TRUE;
2552  }
2553 
2554  KdbpPrint("*** Dmesg *** TotalWritten=%lu, BufferSize=%lu, CurrentPosition=%lu\n",
2556 
2557  /* Pass data to the pager */
2560 
2561  /* No roll-overs, and overwritten=lost bytes */
2563  {
2564  /* Show buffer (KdpDmesgBuffer + beg, num) */
2566  }
2567  else
2568  {
2569  /* Show 2 buffers: (KdpDmesgBuffer + beg, KdpDmesgBufferSize - beg)
2570  * and: (KdpDmesgBuffer, end) */
2572  KdbpPrint("*** Dmesg: buffer rollup ***\n");
2574  }
2575  KdbpPrint("*** Dmesg: end of output ***\n");
2576 
2577  KdbpIsInDmesgMode = FALSE; /* Toggle logging flag */
2578 
2579  return TRUE;
2580 }
2581 
2584 static BOOLEAN
2586  ULONG Argc,
2587  PCHAR Argv[])
2588 {
2589  LONG l;
2590  BOOLEAN First;
2591  PCHAR pend = 0;
2592  KDB_ENTER_CONDITION ConditionFirst = KdbDoNotEnter;
2593  KDB_ENTER_CONDITION ConditionLast = KdbDoNotEnter;
2594 
2595  static const PCHAR ExceptionNames[21] =
2596  {
2597  "ZERODEVIDE", "DEBUGTRAP", "NMI", "INT3", "OVERFLOW", "BOUND", "INVALIDOP",
2598  "NOMATHCOP", "DOUBLEFAULT", "RESERVED(9)", "INVALIDTSS", "SEGMENTNOTPRESENT",
2599  "STACKFAULT", "GPF", "PAGEFAULT", "RESERVED(15)", "MATHFAULT", "ALIGNMENTCHECK",
2600  "MACHINECHECK", "SIMDFAULT", "OTHERS"
2601  };
2602 
2603  if (Argc == 1)
2604  {
2605  KdbpPrint("Available settings:\n");
2606  KdbpPrint(" syntax [intel|at&t]\n");
2607  KdbpPrint(" condition [exception|*] [first|last] [never|always|kmode|umode]\n");
2608  KdbpPrint(" break_on_module_load [true|false]\n");
2609  }
2610  else if (strcmp(Argv[1], "syntax") == 0)
2611  {
2612  if (Argc == 2)
2613  {
2614  KdbpPrint("syntax = %s\n", KdbUseIntelSyntax ? "intel" : "at&t");
2615  }
2616  else if (Argc >= 3)
2617  {
2618  if (_stricmp(Argv[2], "intel") == 0)
2620  else if (_stricmp(Argv[2], "at&t") == 0)
2622  else
2623  KdbpPrint("Unknown syntax '%s'.\n", Argv[2]);
2624  }
2625  }
2626  else if (strcmp(Argv[1], "condition") == 0)
2627  {
2628  if (Argc == 2)
2629  {
2630  KdbpPrint("Conditions: (First) (Last)\n");
2631  for (l = 0; l < RTL_NUMBER_OF(ExceptionNames) - 1; l++)
2632  {
2633  if (!ExceptionNames[l])
2634  continue;
2635 
2636  if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2637  ASSERT(FALSE);
2638 
2639  if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2640  ASSERT(FALSE);
2641 
2642  KdbpPrint(" #%02d %-20s %-8s %-8s\n", l, ExceptionNames[l],
2643  KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2644  KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2645  }
2646 
2647  ASSERT(l == (RTL_NUMBER_OF(ExceptionNames) - 1));
2648  KdbpPrint(" %-20s %-8s %-8s\n", ExceptionNames[l],
2649  KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2650  KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2651  }
2652  else
2653  {
2654  if (Argc >= 5 && strcmp(Argv[2], "*") == 0) /* Allow * only when setting condition */
2655  {
2656  l = -1;
2657  }
2658  else
2659  {
2660  l = strtoul(Argv[2], &pend, 0);
2661 
2662  if (Argv[2] == pend)
2663  {
2664  for (l = 0; l < RTL_NUMBER_OF(ExceptionNames); l++)
2665  {
2666  if (!ExceptionNames[l])
2667  continue;
2668 
2669  if (_stricmp(ExceptionNames[l], Argv[2]) == 0)
2670  break;
2671  }
2672  }
2673 
2674  if (l >= RTL_NUMBER_OF(ExceptionNames))
2675  {
2676  KdbpPrint("Unknown exception '%s'.\n", Argv[2]);
2677  return TRUE;
2678  }
2679  }
2680 
2681  if (Argc > 4)
2682  {
2683  if (_stricmp(Argv[3], "first") == 0)
2684  First = TRUE;
2685  else if (_stricmp(Argv[3], "last") == 0)
2686  First = FALSE;
2687  else
2688  {
2689  KdbpPrint("set condition: second argument must be 'first' or 'last'\n");
2690  return TRUE;
2691  }
2692 
2693  if (_stricmp(Argv[4], "never") == 0)
2694  ConditionFirst = KdbDoNotEnter;
2695  else if (_stricmp(Argv[4], "always") == 0)
2696  ConditionFirst = KdbEnterAlways;
2697  else if (_stricmp(Argv[4], "umode") == 0)
2698  ConditionFirst = KdbEnterFromUmode;
2699  else if (_stricmp(Argv[4], "kmode") == 0)
2700  ConditionFirst = KdbEnterFromKmode;
2701  else
2702  {
2703  KdbpPrint("set condition: third argument must be 'never', 'always', 'umode' or 'kmode'\n");
2704  return TRUE;
2705  }
2706 
2707  if (!KdbpSetEnterCondition(l, First, ConditionFirst))
2708  {
2709  if (l >= 0)
2710  KdbpPrint("Couldn't change condition for exception #%02d\n", l);
2711  else
2712  KdbpPrint("Couldn't change condition for all exceptions\n", l);
2713  }
2714  }
2715  else /* Argc >= 3 */
2716  {
2717  if (!KdbpGetEnterCondition(l, TRUE, &ConditionFirst))
2718  ASSERT(FALSE);
2719 
2720  if (!KdbpGetEnterCondition(l, FALSE, &ConditionLast))
2721  ASSERT(FALSE);
2722 
2723  if (l < (RTL_NUMBER_OF(ExceptionNames) - 1))
2724  {
2725  KdbpPrint("Condition for exception #%02d (%s): FirstChance %s LastChance %s\n",
2726  l, ExceptionNames[l],
2727  KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2728  KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2729  }
2730  else
2731  {
2732  KdbpPrint("Condition for all other exceptions: FirstChance %s LastChance %s\n",
2733  KDB_ENTER_CONDITION_TO_STRING(ConditionFirst),
2734  KDB_ENTER_CONDITION_TO_STRING(ConditionLast));
2735  }
2736  }
2737  }
2738  }
2739  else if (strcmp(Argv[1], "break_on_module_load") == 0)
2740  {
2741  if (Argc == 2)
2742  KdbpPrint("break_on_module_load = %s\n", KdbBreakOnModuleLoad ? "enabled" : "disabled");
2743  else if (Argc >= 3)
2744  {
2745  if (_stricmp(Argv[2], "enable") == 0 || _stricmp(Argv[2], "enabled") == 0 || _stricmp(Argv[2], "true") == 0)
2747  else if (_stricmp(Argv[2], "disable") == 0 || _stricmp(Argv[2], "disabled") == 0 || _stricmp(Argv[2], "false") == 0)
2749  else
2750  KdbpPrint("Unknown setting '%s'.\n", Argv[2]);
2751  }
2752  }
2753  else
2754  {
2755  KdbpPrint("Unknown setting '%s'.\n", Argv[1]);
2756  }
2757 
2758  return TRUE;
2759 }
2760 
2763 static BOOLEAN
2765  ULONG Argc,
2766  PCHAR Argv[])
2767 {
2768  ULONG i;
2769 
2770  KdbpPrint("Kernel debugger commands:\n");
2771  for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
2772  {
2773  if (!KdbDebuggerCommands[i].Syntax) /* Command group */
2774  {
2775  if (i > 0)
2776  KdbpPrint("\n");
2777 
2778  KdbpPrint("\x1b[7m* %s:\x1b[0m\n", KdbDebuggerCommands[i].Help);
2779  continue;
2780  }
2781 
2782  KdbpPrint(" %-20s - %s\n",
2785  }
2786 
2787  return TRUE;
2788 }
2789 
2800 VOID
2802  IN PCHAR Format,
2803  IN ... OPTIONAL)
2804 {
2805  static CHAR Buffer[4096];
2806  static BOOLEAN TerminalInitialized = FALSE;
2807  static BOOLEAN TerminalConnected = FALSE;
2808  static BOOLEAN TerminalReportsSize = TRUE;
2809  CHAR c = '\0';
2810  PCHAR p, p2;
2811  ULONG Length;
2812  SIZE_T i, j;
2813  LONG RowsPrintedByTerminal;
2814  ULONG ScanCode;
2815  va_list ap;
2816 
2817  /* Check if the user has aborted output of the current command */
2818  if (KdbOutputAborted)
2819  return;
2820 
2821  /* Initialize the terminal */
2822  if (!TerminalInitialized)
2823  {
2824  KdpDprintf("\x1b[7h"); /* Enable linewrap */
2825 
2826  /* Query terminal type */
2827  /*DbgPrint("\x1b[Z");*/
2828  KdpDprintf("\x05");
2829 
2830  TerminalInitialized = TRUE;
2831  Length = 0;
2832  KeStallExecutionProcessor(100000);
2833 
2834  for (;;)
2835  {
2836  c = KdbpTryGetCharSerial(5000);
2837  if (c == -1)
2838  break;
2839 
2840  Buffer[Length++] = c;
2841  if (Length >= (sizeof(Buffer) - 1))
2842  break;
2843  }
2844 
2845  Buffer[Length] = '\0';
2846  if (Length > 0)
2847  TerminalConnected = TRUE;
2848  }
2849 
2850  /* Get number of rows and columns in terminal */
2851  if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
2852  (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
2853  {
2854  if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
2855  {
2856  /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
2857  TerminalReportsSize = FALSE;
2858  KeStallExecutionProcessor(100000);
2859  KdpDprintf("\x1b[18t");
2860  c = KdbpTryGetCharSerial(5000);
2861 
2862  if (c == KEY_ESC)
2863  {
2864  c = KdbpTryGetCharSerial(5000);
2865  if (c == '[')
2866  {
2867  Length = 0;
2868 
2869  for (;;)
2870  {
2871  c = KdbpTryGetCharSerial(5000);
2872  if (c == -1)
2873  break;
2874 
2875  Buffer[Length++] = c;
2876  if (isalpha(c) || Length >= (sizeof(Buffer) - 1))
2877  break;
2878  }
2879 
2880  Buffer[Length] = '\0';
2881  if (Buffer[0] == '8' && Buffer[1] == ';')
2882  {
2883  for (i = 2; (i < Length) && (Buffer[i] != ';'); i++);
2884 
2885  if (Buffer[i] == ';')
2886  {
2887  Buffer[i++] = '\0';
2888 
2889  /* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
2892  TerminalReportsSize = TRUE;
2893  }
2894  }
2895  }
2896  /* Clear further characters */
2897  while ((c = KdbpTryGetCharSerial(5000)) != -1);
2898  }
2899  }
2900 
2901  if (KdbNumberOfRowsTerminal <= 0)
2902  {
2903  /* Set number of rows to the default. */
2904  KdbNumberOfRowsTerminal = 23; //24; //Mna.: 23 for SCREEN debugport
2905  }
2906  else if (KdbNumberOfColsTerminal <= 0)
2907  {
2908  /* Set number of cols to the default. */
2909  KdbNumberOfColsTerminal = 75; //80; //Mna.: 75 for SCREEN debugport
2910  }
2911  }
2912 
2913  /* Get the string */
2914  va_start(ap, Format);
2915  Length = _vsnprintf(Buffer, sizeof(Buffer) - 1, Format, ap);
2916  Buffer[Length] = '\0';
2917  va_end(ap);
2918 
2919  p = Buffer;
2920  while (p[0] != '\0')
2921  {
2922  i = strcspn(p, "\n");
2923 
2924  /* Calculate the number of lines which will be printed in the terminal
2925  * when outputting the current line
2926  */
2927  if (i > 0)
2928  RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
2929  else
2930  RowsPrintedByTerminal = 0;
2931 
2932  if (p[i] == '\n')
2933  RowsPrintedByTerminal++;
2934 
2935  /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
2936 
2937  /* Display a prompt if we printed one screen full of text */
2938  if (KdbNumberOfRowsTerminal > 0 &&
2939  (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
2940  {
2942 
2943  if (KdbNumberOfColsPrinted > 0)
2944  KdpDprintf("\n");
2945 
2946  KdpDprintf("--- Press q to abort, any other key to continue ---");
2947  RowsPrintedByTerminal++; /* added by Mna. */
2948 
2950  c = KdbpGetCharSerial();
2951  else
2953 
2954  if (c == '\r')
2955  {
2956  /* Try to read '\n' which might follow '\r' - if \n is not received here
2957  * it will be interpreted as "return" when the next command should be read.
2958  */
2960  c = KdbpTryGetCharSerial(5);
2961  else
2963  }
2964 
2965  KdpDprintf("\n");
2966  if (c == 'q')
2967  {
2969  return;
2970  }
2971 
2974  }
2975 
2976  /* Insert a NUL after the line and print only the current line. */
2977  if (p[i] == '\n' && p[i + 1] != '\0')
2978  {
2979  c = p[i + 1];
2980  p[i + 1] = '\0';
2981  }
2982  else
2983  {
2984  c = '\0';
2985  }
2986 
2987  /* Remove escape sequences from the line if there's no terminal connected */
2988  if (!TerminalConnected)
2989  {
2990  while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
2991  {
2992  size_t len = strlen(p2);
2993  if (p2[1] == '[')
2994  {
2995  j = 2;
2996  while (!isalpha(p2[j++]));
2997  memmove(p2, p2 + j, len + 1 - j);
2998  }
2999  else
3000  {
3001  memmove(p2, p2 + 1, len);
3002  }
3003  }
3004  }
3005 
3006  KdpDprintf("%s", p);
3007 
3008  if (c != '\0')
3009  p[i + 1] = c;
3010 
3011  /* Set p to the start of the next line and
3012  * remember the number of rows/cols printed
3013  */
3014  p += i;
3015  if (p[0] == '\n')
3016  {
3017  p++;
3019  }
3020  else
3021  {
3022  ASSERT(p[0] == '\0');
3024  }
3025 
3026  KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3027  }
3028 }
3029 
3030 VOID
3033 {
3034  ULONG i;
3035 
3036  if ((String == NULL) || (String->Buffer == NULL))
3037  {
3038  KdbpPrint("<NULL>");
3039  return;
3040  }
3041 
3042  for (i = 0; i < String->Length / sizeof(WCHAR); i++)
3043  {
3044  KdbpPrint("%c", (CHAR)String->Buffer[i]);
3045  }
3046 }
3047 
3049 /*
3050  * Reverse memchr()
3051  * Find the last occurrence of 'c' in the buffer 's' of size 'n'.
3052  */
3053 void *
3054 memrchr(const void *s, int c, size_t n)
3055 {
3056  const unsigned char *cp;
3057 
3058  if (n != 0)
3059  {
3060  cp = (unsigned char *)s + n;
3061  do
3062  {
3063  if (*(--cp) == (unsigned char)c)
3064  return (void *)cp;
3065  } while (--n != 0);
3066  }
3067  return NULL;
3068 }
3069 
3081 PCHAR
3082 CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
3083 {
3084  PCHAR p;
3085  // p0 is initial guess of Page Start
3087  PCHAR p0 = pCurPos - p0len;
3088  PCHAR prev_p = p0, p1;
3089  ULONG j;
3090 
3091  if (pCurPos < Buffer)
3092  pCurPos = Buffer;
3093  ASSERT(pCurPos <= Buffer + BufLength);
3094 
3095  p = memrchr(p0, '\n', p0len);
3096  if (NULL == p)
3097  p = p0;
3098  for (j = KdbNumberOfRowsTerminal; j--; )
3099  {
3100  int linesCnt;
3101  p1 = memrchr(p0, '\n', p-p0);
3102  prev_p = p;
3103  p = p1;
3104  if (NULL == p)
3105  {
3106  p = prev_p;
3107  if (NULL == p)
3108  p = p0;
3109  break;
3110  }
3111  linesCnt = (KdbNumberOfColsTerminal+prev_p-p-2) / KdbNumberOfColsTerminal;
3112  if (linesCnt > 1)
3113  j -= linesCnt-1;
3114  }
3115 
3116  ASSERT(p != 0);
3117  ++p;
3118  return p;
3119 }
3120 
3133 VOID
3135  IN PCHAR Buffer,
3136  IN ULONG BufLength)
3137 {
3138  static CHAR InBuffer[4096];
3139  static BOOLEAN TerminalInitialized = FALSE;
3140  static BOOLEAN TerminalConnected = FALSE;
3141  static BOOLEAN TerminalReportsSize = TRUE;
3142  CHAR c = '\0';
3143  PCHAR p, p2;
3144  ULONG Length;
3145  SIZE_T i, j;
3146  LONG RowsPrintedByTerminal;
3147  ULONG ScanCode;
3148 
3149  if( BufLength == 0)
3150  return;
3151 
3152  /* Check if the user has aborted output of the current command */
3153  if (KdbOutputAborted)
3154  return;
3155 
3156  /* Initialize the terminal */
3157  if (!TerminalInitialized)
3158  {
3159  KdpDprintf("\x1b[7h"); /* Enable linewrap */
3160 
3161  /* Query terminal type */
3162  /*DbgPrint("\x1b[Z");*/
3163  KdpDprintf("\x05");
3164 
3165  TerminalInitialized = TRUE;
3166  Length = 0;
3167  KeStallExecutionProcessor(100000);
3168 
3169  for (;;)
3170  {
3171  c = KdbpTryGetCharSerial(5000);
3172  if (c == -1)
3173  break;
3174 
3175  InBuffer[Length++] = c;
3176  if (Length >= (sizeof(InBuffer) - 1))
3177  break;
3178  }
3179 
3180  InBuffer[Length] = '\0';
3181  if (Length > 0)
3182  TerminalConnected = TRUE;
3183  }
3184 
3185  /* Get number of rows and columns in terminal */
3186  if ((KdbNumberOfRowsTerminal < 0) || (KdbNumberOfColsTerminal < 0) ||
3187  (KdbNumberOfRowsPrinted) == 0) /* Refresh terminal size each time when number of rows printed is 0 */
3188  {
3189  if ((KdbDebugState & KD_DEBUG_KDSERIAL) && TerminalConnected && TerminalReportsSize)
3190  {
3191  /* Try to query number of rows from terminal. A reply looks like "\x1b[8;24;80t" */
3192  TerminalReportsSize = FALSE;
3193  KeStallExecutionProcessor(100000);
3194  KdpDprintf("\x1b[18t");
3195  c = KdbpTryGetCharSerial(5000);
3196 
3197  if (c == KEY_ESC)
3198  {
3199  c = KdbpTryGetCharSerial(5000);
3200  if (c == '[')
3201  {
3202  Length = 0;
3203 
3204  for (;;)
3205  {
3206  c = KdbpTryGetCharSerial(5000);
3207  if (c == -1)
3208  break;
3209 
3210  InBuffer[Length++] = c;
3211  if (isalpha(c) || Length >= (sizeof(InBuffer) - 1))
3212  break;
3213  }
3214 
3215  InBuffer[Length] = '\0';
3216  if (InBuffer[0] == '8' && InBuffer[1] == ';')
3217  {
3218  for (i = 2; (i < Length) && (InBuffer[i] != ';'); i++);
3219 
3220  if (Buffer[i] == ';')
3221  {
3222  Buffer[i++] = '\0';
3223 
3224  /* Number of rows is now at Buffer + 2 and number of cols at Buffer + i */
3225  KdbNumberOfRowsTerminal = strtoul(InBuffer + 2, NULL, 0);
3226  KdbNumberOfColsTerminal = strtoul(InBuffer + i, NULL, 0);
3227  TerminalReportsSize = TRUE;
3228  }
3229  }
3230  }
3231  /* Clear further characters */
3232  while ((c = KdbpTryGetCharSerial(5000)) != -1);
3233  }
3234  }
3235 
3236  if (KdbNumberOfRowsTerminal <= 0)
3237  {
3238  /* Set number of rows to the default. */
3240  }
3241  else if (KdbNumberOfColsTerminal <= 0)
3242  {
3243  /* Set number of cols to the default. */
3245  }
3246  }
3247 
3248  /* Get the string */
3249  p = Buffer;
3250 
3251  while (p[0] != '\0')
3252  {
3253  if ( p > Buffer+BufLength)
3254  {
3255  KdpDprintf("Dmesg: error, p > Buffer+BufLength,d=%d", p - (Buffer+BufLength));
3256  return;
3257  }
3258  i = strcspn(p, "\n");
3259 
3260  // Are we out of buffer?
3261  if (p + i > Buffer + BufLength)
3262  // Leaving pager function:
3263  break;
3264 
3265  /* Calculate the number of lines which will be printed in the terminal
3266  * when outputting the current line.
3267  */
3268  if (i > 0)
3269  RowsPrintedByTerminal = (i + KdbNumberOfColsPrinted - 1) / KdbNumberOfColsTerminal;
3270  else
3271  RowsPrintedByTerminal = 0;
3272 
3273  if (p[i] == '\n')
3274  RowsPrintedByTerminal++;
3275 
3276  /*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
3277 
3278  /* Display a prompt if we printed one screen full of text */
3279  if (KdbNumberOfRowsTerminal > 0 &&
3280  (LONG)(KdbNumberOfRowsPrinted + RowsPrintedByTerminal) >= KdbNumberOfRowsTerminal)
3281  {
3283 
3284  if (KdbNumberOfColsPrinted > 0)
3285  KdpDprintf("\n");
3286 
3287  KdpDprintf("--- Press q to abort, e/End,h/Home,u/PgUp, other key/PgDn ---");
3288  RowsPrintedByTerminal++;
3289 
3291  c = KdbpGetCharSerial();
3292  else
3294 
3295  if (c == '\r')
3296  {
3297  /* Try to read '\n' which might follow '\r' - if \n is not received here
3298  * it will be interpreted as "return" when the next command should be read.
3299  */
3301  c = KdbpTryGetCharSerial(5);
3302  else
3304  }
3305 
3306  //DbgPrint("\n"); //Consize version: don't show pressed key
3307  KdpDprintf(" '%c'/scan=%04x\n", c, ScanCode); // Shows pressed key
3308 
3309  if (c == 'q')
3310  {
3312  return;
3313  }
3314  if ( ScanCode == KEYSC_END || c=='e')
3315  {
3316  PCHAR pBufEnd = Buffer + BufLength;
3317  p = CountOnePageUp(Buffer, BufLength, pBufEnd);
3318  i = strcspn(p, "\n");
3319  }
3320  else if (ScanCode == KEYSC_PAGEUP || c=='u')
3321  {
3322  p = CountOnePageUp(Buffer, BufLength, p);
3323  i = strcspn(p, "\n");
3324  }
3325  else if (ScanCode == KEYSC_HOME || c=='h')
3326  {
3327  p = Buffer;
3328  i = strcspn(p, "\n");
3329  }
3330  else if (ScanCode == KEYSC_ARROWUP)
3331  {
3332  p = CountOnePageUp(Buffer, BufLength, p);
3333  i = strcspn(p, "\n");
3334  }
3335 
3338  }
3339 
3340  /* Insert a NUL after the line and print only the current line. */
3341  if (p[i] == '\n' && p[i + 1] != '\0')
3342  {
3343  c = p[i + 1];
3344  p[i + 1] = '\0';
3345  }
3346  else
3347  {
3348  c = '\0';
3349  }
3350 
3351  /* Remove escape sequences from the line if there's no terminal connected */
3352  if (!TerminalConnected)
3353  {
3354  while ((p2 = strrchr(p, '\x1b'))) /* Look for escape character */
3355  {
3356  size_t len = strlen(p2);
3357  if (p2[1] == '[')
3358  {
3359  j = 2;
3360  while (!isalpha(p2[j++]));
3361  memmove(p2, p2 + j, len + 1 - j);
3362  }
3363  else
3364  {
3365  memmove(p2, p2 + 1, len);
3366  }
3367  }
3368  }
3369 
3370  // The main printing of the current line:
3371  KdpDprintf(p);
3372 
3373  // restore not null char with saved:
3374  if (c != '\0')
3375  p[i + 1] = c;
3376 
3377  /* Set p to the start of the next line and
3378  * remember the number of rows/cols printed
3379  */
3380  p += i;
3381  if (p[0] == '\n')
3382  {
3383  p++;
3385  }
3386  else
3387  {
3388  ASSERT(p[0] == '\0');
3390  }
3391 
3392  KdbNumberOfRowsPrinted += RowsPrintedByTerminal;
3393  }
3394 }
3395 
3400 static VOID
3402  IN PCHAR Command)
3403 {
3404  SIZE_T Length1 = strlen(Command) + 1;
3405  SIZE_T Length2 = 0;
3406  INT i;
3407  PCHAR Buffer;
3408 
3410 
3411  if (Length1 <= 1 ||
3414  {
3415  return;
3416  }
3417 
3418  /* Calculate Length1 and Length2 */
3422  {
3425  Length1 -= Length2;
3426  }
3427 
3428  /* Remove previous commands until there is enough space to append the new command */
3430  {
3431  if ((Length2 > 0 &&
3432  (KdbCommandHistory[i] >= Buffer ||
3434  (Length2 <= 0 &&
3435  (KdbCommandHistory[i] >= Buffer &&
3437  {
3439  }
3440 
3441  i--;
3442  if (i < 0)
3444 
3445  if (i == KdbCommandHistoryIndex)
3446  break;
3447  }
3448 
3449  /* Make sure the new command history entry is free */
3453  {
3455  }
3456 
3457  /* Append command */
3461  if (Length2 > 0)
3462  {
3464  }
3465 }
3466 
3474 static VOID
3476  OUT PCHAR Buffer,
3477  IN ULONG Size)
3478 {
3479  CHAR Key;
3480  PCHAR Orig = Buffer;
3481  ULONG ScanCode = 0;
3482  BOOLEAN EchoOn;
3483  static CHAR LastCommand[1024];
3484  static CHAR NextKey = '\0';
3485  INT CmdHistIndex = -1;
3486  INT_PTR i;
3487 
3488  EchoOn = !((KdbDebugState & KD_DEBUG_KDNOECHO) != 0);
3489 
3490  for (;;)
3491  {
3493  {
3494  Key = (NextKey == '\0') ? KdbpGetCharSerial() : NextKey;
3495  NextKey = '\0';
3496  ScanCode = 0;
3497  if (Key == KEY_ESC) /* ESC */
3498  {
3499  Key = KdbpGetCharSerial();
3500  if (Key == '[')
3501  {
3502  Key = KdbpGetCharSerial();
3503 
3504  switch (Key)
3505  {
3506  case 'A':
3508  break;
3509  case 'B':
3511  break;
3512  case 'C':
3513  break;
3514  case 'D':
3515  break;
3516  }
3517  }
3518  }
3519  }
3520  else
3521  {
3522  ScanCode = 0;
3523  Key = (NextKey == '\0') ? KdbpGetCharKeyboard(&ScanCode) : NextKey;
3524  NextKey = '\0';
3525  }
3526 
3527  if ((ULONG)(Buffer - Orig) >= (Size - 1))
3528  {
3529  /* Buffer is full, accept only newlines */
3530  if (Key != '\n')
3531  continue;
3532  }
3533 
3534  if (Key == '\r')
3535  {
3536  /* Read the next char - this is to throw away a \n which most clients should
3537  * send after \r.
3538  */
3539  KeStallExecutionProcessor(100000);
3540 
3542  NextKey = KdbpTryGetCharSerial(5);
3543  else
3544  NextKey = KdbpTryGetCharKeyboard(&ScanCode, 5);
3545 
3546  if (NextKey == '\n' || NextKey == -1) /* \n or no response at all */
3547  NextKey = '\0';
3548 
3549  KdbpPrint("\n");
3550 
3551  /*
3552  * Repeat the last command if the user presses enter. Reduces the
3553  * risk of RSI when single-stepping.
3554  */
3555  if (Buffer != Orig)
3556  {
3558  *Buffer = '\0';
3559  RtlStringCbCopyA(LastCommand, sizeof(LastCommand), Orig);
3560  }
3561  else if (KdbRepeatLastCommand)
3562  RtlStringCbCopyA(Buffer, Size, LastCommand);
3563  else
3564  *Buffer = '\0';
3565 
3566  return;
3567  }
3568  else if (Key == KEY_BS || Key == KEY_DEL)
3569  {
3570  if (Buffer > Orig)
3571  {
3572  Buffer--;
3573  *Buffer = 0;
3574 
3575  if (EchoOn)
3576  KdbpPrint("%c %c", KEY_BS, KEY_BS);
3577  else
3578  KdbpPrint(" %c", KEY_BS);
3579  }
3580  }
3581  else if (ScanCode == KEY_SCAN_UP)
3582  {
3583  BOOLEAN Print = TRUE;
3584 
3585  if (CmdHistIndex < 0)
3586  {
3587  CmdHistIndex = KdbCommandHistoryIndex;
3588  }
3589  else
3590  {
3591  i = CmdHistIndex - 1;
3592 
3593  if (i < 0)
3594  CmdHistIndex = RTL_NUMBER_OF(KdbCommandHistory) - 1;
3595 
3597  CmdHistIndex = i;
3598  else
3599  Print = FALSE;
3600  }
3601 
3602  if (Print && KdbCommandHistory[CmdHistIndex])
3603  {
3604  while (Buffer > Orig)
3605  {
3606  Buffer--;
3607  *Buffer = 0;
3608 
3609  if (EchoOn)
3610  KdbpPrint("%c %c", KEY_BS, KEY_BS);
3611  else
3612  KdbpPrint(" %c", KEY_BS);
3613  }
3614 
3615  i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
3616  memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
3617  Orig[i] = '\0';
3618  Buffer = Orig + i;
3619  KdbpPrint("%s", Orig);
3620  }
3621  }
3622  else if (ScanCode == KEY_SCAN_DOWN)
3623  {
3624  if (CmdHistIndex > 0 && CmdHistIndex != KdbCommandHistoryIndex)
3625  {
3626  i = CmdHistIndex + 1;
3628  i = 0;
3629 
3630  if (KdbCommandHistory[i])
3631  {
3632  CmdHistIndex = i;
3633  while (Buffer > Orig)
3634  {
3635  Buffer--;
3636  *Buffer = 0;
3637 
3638  if (EchoOn)
3639  KdbpPrint("%c %c", KEY_BS, KEY_BS);
3640  else
3641  KdbpPrint(" %c", KEY_BS);
3642  }
3643 
3644  i = min(strlen(KdbCommandHistory[CmdHistIndex]), Size - 1);
3645  memcpy(Orig, KdbCommandHistory[CmdHistIndex], i);
3646  Orig[i] = '\0';
3647  Buffer = Orig + i;
3648  KdbpPrint("%s", Orig);
3649  }
3650  }
3651  }
3652  else
3653  {
3654  if (EchoOn)
3655  KdbpPrint("%c", Key);
3656 
3657  *Buffer = Key;
3658  Buffer++;
3659  }
3660  }
3661 }
3662 
3663 
3664 BOOLEAN
3665 NTAPI
3667  PVOID Callback,
3668  BOOLEAN Deregister)
3669 {
3670  ULONG i;
3671 
3672  /* Loop all entries */
3673  for (i = 0; i < _countof(KdbCliCallbacks); i++)
3674  {
3675  /* Check if deregistering was requested */
3676  if (Deregister)
3677  {
3678  /* Check if this entry is the one that was registered */
3679  if (KdbCliCallbacks[i] == Callback)
3680  {
3681  /* Delete it and report success */
3682  KdbCliCallbacks[i] = NULL;
3683  return TRUE;
3684  }
3685  }
3686  else
3687  {
3688  /* Check if this entry is free */
3689  if (KdbCliCallbacks[i] == NULL)
3690  {
3691  /* Set it and and report success */
3693  return TRUE;
3694  }
3695  }
3696  }
3697 
3698  /* Unsuccessful */
3699  return FALSE;
3700 }
3701 
3711 static
3712 BOOLEAN
3714  IN PCHAR Command,
3715  IN ULONG Argc,
3716  IN PCHAR Argv[])
3717 {
3718  ULONG i;
3719 
3720  /* Loop all entries */
3721  for (i = 0; i < _countof(KdbCliCallbacks); i++)
3722  {
3723  /* Check if this entry is registered */
3724  if (KdbCliCallbacks[i])
3725  {
3726  /* Invoke the callback and check if it handled the command */
3727  if (KdbCliCallbacks[i](Command, Argc, Argv))
3728  {
3729  return TRUE;
3730  }
3731  }
3732  }
3733 
3734  /* None of the callbacks handled the command */
3735  return FALSE;
3736 }
3737 
3738 
3746 static BOOLEAN
3748  IN PCHAR Command)
3749 {
3750  SIZE_T i;
3751  PCHAR p;
3752  ULONG Argc;
3753  // FIXME: for what do we need a 1024 characters command line and 256 tokens?
3754  static PCHAR Argv[256];
3755  static CHAR OrigCommand[1024];
3756 
3757  RtlStringCbCopyA(OrigCommand, sizeof(OrigCommand), Command);
3758 
3759  Argc = 0;
3760  p = Command;
3761 
3762  for (;;)
3763  {
3764  while (*p == '\t' || *p == ' ')
3765  p++;
3766 
3767  if (*p == '\0')
3768  break;
3769 
3770  i = strcspn(p, "\t ");
3771  Argv[Argc++] = p;
3772  p += i;
3773  if (*p == '\0')
3774  break;
3775 
3776  *p = '\0';
3777  p++;
3778  }
3779 
3780  if (Argc < 1)
3781  return TRUE;
3782 
3783  for (i = 0; i < RTL_NUMBER_OF(KdbDebuggerCommands); i++)
3784  {
3785  if (!KdbDebuggerCommands[i].Name)
3786  continue;
3787 
3788  if (strcmp(KdbDebuggerCommands[i].Name, Argv[0]) == 0)
3789  {
3790  return KdbDebuggerCommands[i].Fn(Argc, Argv);
3791  }
3792  }
3793 
3794  /* Now invoke the registered callbacks */
3795  if (KdbpInvokeCliCallbacks(Command, Argc, Argv))
3796  {
3797  return TRUE;
3798  }
3799 
3800  KdbpPrint("Command '%s' is unknown.\n", OrigCommand);
3801  return TRUE;
3802 }
3803 
3808 VOID
3810  IN BOOLEAN EnteredOnSingleStep)
3811 {
3812  static CHAR Command[1024];
3813  BOOLEAN Continue;
3814 
3815  if (EnteredOnSingleStep)
3816  {
3818  {
3820  }
3821 
3822  KdbpPrint(": ");
3824  {
3825  KdbpPrint("<INVALID>");
3826  }
3827  KdbpPrint("\n");
3828  }
3829 
3830  /* Flush the input buffer */
3832  {
3833  while (KdbpTryGetCharSerial(1) != -1);
3834  }
3835  else
3836  {
3837  ULONG ScanCode;
3838  while (KdbpTryGetCharKeyboard(&ScanCode, 1) != -1);
3839  }
3840 
3841  /* Main loop */
3842  do
3843  {
3844  /* Reset the number of rows/cols printed */
3846 
3847  /* Print the prompt */
3848  KdbpPrint(KdbPromptString.Buffer);
3849 
3850  /* Read a command and remember it */
3851  KdbpReadCommand(Command, sizeof(Command));
3853 
3854  /* Reset the number of rows/cols printed and output aborted state */
3857 
3858  /* Call the command */
3859  Continue = KdbpDoCommand(Command);
3861  }
3862  while (Continue);
3863 }
3864 
3871 VOID
3873 {
3874  PCHAR p1, p2;
3875  INT_PTR i;
3876  CHAR c;
3877 
3878  /* Execute the commands in the init file */
3879  DPRINT("KDB: Executing KDBinit file...\n");
3880  p1 = KdbInitFileBuffer;
3881  while (p1[0] != '\0')
3882  {
3883  i = strcspn(p1, "\r\n");
3884  if (i > 0)
3885  {
3886  c = p1[i];
3887  p1[i] = '\0';
3888 
3889  /* Look for "break" command and comments */
3890  p2 = p1;
3891 
3892  while (isspace(p2[0]))
3893  p2++;
3894 
3895  if (strncmp(p2, "break", sizeof("break")-1) == 0 &&
3896  (p2[sizeof("break")-1] == '\0' || isspace(p2[sizeof("break")-1])))
3897  {
3898  /* break into the debugger */
3900  }
3901  else if (p2[0] != '#' && p2[0] != '\0') /* Ignore empty lines and comments */
3902  {
3903  KdbpDoCommand(p1);
3904  }
3905 
3906  p1[i] = c;
3907  }
3908 
3909  p1 += i;
3910  while (p1[0] == '\r' || p1[0] == '\n')
3911  p1++;
3912  }
3913  DPRINT("KDB: KDBinit executed\n");
3914 }
3915 
3920 VOID
3922 {
3923  NTSTATUS Status;
3927  FILE_STANDARD_INFORMATION FileStdInfo;
3928  HANDLE hFile = NULL;
3929  INT FileSize;
3930  PCHAR FileBuffer;
3931  ULONG OldEflags;
3932 
3933  /* Initialize the object attributes */
3934  RtlInitUnicodeString(&FileName, L"\\SystemRoot\\System32\\drivers\\etc\\KDBinit");
3936  &FileName,
3938  NULL,
3939  NULL);
3940 
3941  /* Open the file */
3943  &ObjectAttributes, &Iosb, 0,
3946  if (!NT_SUCCESS(Status))
3947  {
3948  DPRINT("Could not open \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3949  return;
3950  }
3951 
3952  /* Get the size of the file */
3953  Status = ZwQueryInformationFile(hFile, &Iosb, &FileStdInfo, sizeof(FileStdInfo),
3955  if (!NT_SUCCESS(Status))
3956  {
3957  ZwClose(hFile);
3958  DPRINT("Could not query size of \\SystemRoot\\System32\\drivers\\etc\\KDBinit (Status 0x%x)", Status);
3959  return;
3960  }
3961  FileSize = FileStdInfo.EndOfFile.u.LowPart;
3962 
3963  /* Allocate memory for the file */
3964  FileBuffer = ExAllocatePool(PagedPool, FileSize + 1); /* add 1 byte for terminating '\0' */
3965  if (!FileBuffer)
3966  {
3967  ZwClose(hFile);
3968  DPRINT("Could not allocate %d bytes for KDBinit file\n", FileSize);
3969  return;
3970  }
3971 
3972  /* Load file into memory */
3973  Status = ZwReadFile(hFile, NULL, NULL, NULL, &Iosb, FileBuffer, FileSize, NULL, NULL);
3974  ZwClose(hFile);
3975 
3977  {
3978  ExFreePool(FileBuffer);
3979  DPRINT("Could not read KDBinit file into memory (Status 0x%lx)\n", Status);
3980  return;
3981  }
3982 
3983  FileSize = min(FileSize, (INT)Iosb.Information);
3984  FileBuffer[FileSize] = '\0';
3985 
3986  /* Enter critical section */
3987  OldEflags = __readeflags();
3988  _disable();
3989 
3990  /* Interpret the init file... */
3991  KdbInitFileBuffer = FileBuffer;
3992  //KdbEnter(); // FIXME
3994 
3995  /* Leave critical section */
3996  __writeeflags(OldEflags);
3997 
3998  ExFreePool(FileBuffer);
3999 }
PCHAR KdpDmesgBuffer
Definition: kdio.c:41
BOOLEAN KdbpDeleteBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Deletes a breakpoint.
Definition: kdb.c:601
signed char * PCHAR
Definition: retypes.h:7
struct _NT_TIB * Self
Definition: compat.h:579
#define KeGetTrapFramePc(TrapFrame)
Definition: ke.h:37
#define KEY_ESC
Definition: kdb_cli.c:39
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:39
union _KGDTENTRY::@2401 HighWord
#define isspace(c)
Definition: acclib.h:69
static BOOLEAN KdbpCmdFilter(ULONG Argc, PCHAR Argv[])
Displays the list of active debug channels, or enable/disable debug channels.
Definition: kdb_cli.c:716
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:998
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
PCWSTR Expression
static VOID KdbpReadCommand(OUT PCHAR Buffer, IN ULONG Size)
Reads a line of user-input.
Definition: kdb_cli.c:3475
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
FORCEINLINE VOID KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
Definition: ke.h:168
void * memrchr(const void *s, int c, size_t n)
Definition: kdb_cli.c:3054
static VOID KdbpCommandHistoryAppend(IN PCHAR Command)
Appends a command to the command history.
Definition: kdb_cli.c:3401
volatile BOOLEAN KdbpIsInDmesgMode
Definition: kdio.c:45
static PKDBG_CLI_ROUTINE KdbCliCallbacks[10]
Definition: kdb_cli.c:139
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ULONG ScanCode
Definition: api.c:39
#define NPX_STATE_TO_STRING(state)
Definition: kdb_cli.c:62
BOOLEAN KdbSymPrintAddress(IN PVOID Address, IN PCONTEXT Context)
Print address...
Definition: kdb_symbols.c:148
#define _Inout_
Definition: ms_sal.h:378
static const struct op_mask SETUP
Definition: startup.c:427
#define COVERAGE(name, NAME, description, tag1, tag2, tag3, tag4)
struct _Entry Entry
Definition: kefuncs.h:629
static BOOLEAN KdbpCmdProc(ULONG Argc, PCHAR Argv[])
Lists processes or switches to another process context.
Definition: kdb_cli.c:1932
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_IRQL_requires_same_ _In_ PVOID EstablisherFrame
Definition: ntbasedef.h:653
ULONG KdbDebugState
Definition: kdb.c:52
USHORT Fs
Definition: ketypes.h:817
union _KGDTENTRY64 * GdtBase
Definition: ketypes.h:865
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
NTSTATUS NTAPI NtSetDebugFilterState(_In_ ULONG ComponentId, _In_ ULONG Level, _In_ BOOLEAN State)
Definition: kdapi.c:2406
BOOLEAN NTAPI KdbpGetHexNumber(IN PCHAR pszNum, OUT ULONG_PTR *pulValue)
Definition: kdb_cli.c:468
struct _KGDTENTRY::@2401::@2403 Bits
ULONG IRR
Definition: ketypes.h:755
#define KdbpGetCharKeyboard(ScanCode)
Definition: kdb.h:257
static BOOLEAN KdbpEvaluateExpression(IN PCHAR Expression, IN LONG ErrOffset, OUT PULONGLONG Result)
Evaluates an expression...
Definition: kdb_cli.c:441
#define TRUE
Definition: types.h:120
static BOOLEAN KdbpCmdBreakPointList(ULONG Argc, PCHAR Argv[])
Lists breakpoints.
Definition: kdb_cli.c:1461
#define KDB_ACCESS_TYPE_TO_STRING(type)
Definition: kdb_cli.c:57
BOOLEAN KdbpAttachToThread(PVOID ThreadId)
Switches to another thread context.
Definition: kdb.c:1039
USHORT BaseLow
Definition: ketypes.h:337
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
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:469
ULONG CR3
Definition: ketypes.h:798
PEPROCESS KdbCurrentProcess
Definition: kdb.c:54
UCHAR ObsoleteNumber
Definition: ketypes.h:878
_Check_return_ _CRTIMP size_t __cdecl strcspn(_In_z_ const char *_Str, _In_z_ const char *_Control)
UCHAR SecondLevelCacheAssociativity
Definition: ketypes.h:877
static struct @1769 ComponentTable[]
#define DPFLTR_INFO_LEVEL
Definition: kdtypes.h:33
NTSTATUS NTAPI PsLookupThreadByThreadId(IN HANDLE ThreadId, OUT PETHREAD *Thread)
Definition: thread.c:643
char CHAR
Definition: xmlstorage.h:175
VOID KdbpPrint(IN PCHAR Format, IN ... OPTIONAL)
Prints the given string with printf-like formatting.
Definition: kdb_cli.c:2801
#define KEYSC_PAGEUP
Definition: kdb_cli.c:47
PCSTR Name
Definition: kdb_cli.c:177
USHORT MinorVersion
Definition: ketypes.h:882
#define Ke386GetLocalDescriptorTable
Definition: kdb_cli.c:115
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN RosSymAggregate(PROSSYM_INFO RosSymInfo, PCHAR Type, PROSSYM_AGGREGATE Aggregate)
Definition: find.c:137
#define KeGetContextPc(Context)
Definition: ke.h:31
#define KEYSC_HOME
Definition: kdb_cli.c:49
KTHREAD Tcb
Definition: pstypes.h:1103
struct _KIPCR * PKIPCR
static BOOLEAN KdbpCmdBugCheck(ULONG Argc, PCHAR Argv[])
Bugchecks the system.
Definition: kdb_cli.c:2510
ULONG NumElements
Definition: rossym.h:101
SCHAR Priority
Definition: ketypes.h:1722
GLdouble n
Definition: glext.h:7729
#define DPFLTR_MASK
Definition: kdtypes.h:34
USHORT Cs
Definition: ketypes.h:811
_In_ ULONG _In_ ULONG State
Definition: potypes.h:516
UCHAR Number
Definition: ketypes.h:767
ULONG SizeOfImage
Definition: ldrtypes.h:143
USHORT Es
Definition: ketypes.h:809
INT Length2
Definition: FsRtlDissect.c:16
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
#define KD_DEBUG_PRINT_FILTER(Name)
Definition: kdb_cli.c:172
const ULONG KdpDmesgBufferSize
Definition: kdio.c:40
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define KDB_ENTER_CONDITION_TO_STRING(cond)
Definition: kdb_cli.c:52
BOOLEAN ExpKdbgExtPool(ULONG Argc, PCHAR Argv[])
PKTRAP_FRAME TrapFrame
Definition: ketypes.h:1714
#define isalpha(c)
Definition: acclib.h:74
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
ULONG Id
Definition: kdb_cli.c:178
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:1274
#define KdbpGetCharSerial()
Definition: kdb.h:261
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
Definition: shell.h:41
USHORT Backlink
Definition: ketypes.h:792
LIST_ENTRY PsActiveProcessHead
Definition: process.c:22
int32_t INT_PTR
Definition: typedefs.h:64
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:480
KIRQL Irql
Definition: ketypes.h:876
ULONG64 UserRsp
Definition: ketypes.h:867
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define _stricmp
Definition: cat.c:22
UNICODE_STRING Global
Definition: symlink.c:37
int32_t INT
Definition: typedefs.h:58
PVOID Base
Definition: ketypes.h:491
VOID KdbpPrintUnicodeString(_In_ PCUNICODE_STRING String)
Definition: kdb_cli.c:3031
PVOID ArbitraryUserPointer
Definition: compat.h:578
#define KeGetPcr()
Definition: ke.h:26
#define DPFLTR_WARNING_LEVEL
Definition: kdtypes.h:31
static BOOLEAN KdbpCmdEnableDisableClearBreakPoint(ULONG Argc, PCHAR Argv[])
Enables, disables or clears a breakpoint.
Definition: kdb_cli.c:1558
CHAR KdbpTryGetCharSerial(ULONG Retry)
Definition: kdb_serial.c:19
CHAR KdbpTryGetCharKeyboard(PULONG ScanCode, ULONG Retry)
Definition: kdb_keyboard.c:104
USHORT LDT
Definition: ketypes.h:821
PVOID Used_Self
Definition: ketypes.h:871
#define KEY_SCAN_DOWN
Definition: kdb_cli.c:43
void Print(USHORT Window, LPSTR p)
Definition: hardware.c:776
USHORT Limit
Definition: ketypes.h:490
_SEH2_TRY
Definition: create.c:4226
struct _KTSS64 * TssBase
Definition: ketypes.h:866
volatile ULONG KdbDmesgTotalWritten
Definition: kdio.c:44
static ULONG KdbNumberOfRowsPrinted
Definition: kdb_cli.c:148
#define STATUS_END_OF_FILE
Definition: shellext.h:67
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONG KdbpDisassemble(IN ULONG_PTR Address, IN ULONG IntelSyntax)
Definition: i386-dis.c:125
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
INT Length1
Definition: FsRtlDissect.c:15
BOOLEAN KdbpDisableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Disables a breakpoint.
Definition: kdb.c:871
PVOID DllBase
Definition: btrfs_drv.h:1870
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static BOOLEAN KdbpDoCommand(IN PCHAR Command)
Parses command line and executes command if found.
Definition: kdb_cli.c:3747
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
WCHAR First[]
Definition: FormatMessage.c:11
#define DEFAULT
Definition: ruserpass.c:31
USHORT Ds
Definition: ketypes.h:815
static BOOLEAN KdbpCmdStep(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1431
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
static BOOLEAN KdbpCmdContinue(ULONG Argc, PCHAR Argv[])
Continues execution of the system/leaves KDB.
Definition: kdb_cli.c:1420
#define L(x)
Definition: ntvdm.h:50
ULONG Edx
Definition: ketypes.h:803
static BOOLEAN KdbpCmdMod(ULONG Argc, PCHAR Argv[])
Lists loaded modules or the one containing the specified address.
Definition: kdb_cli.c:2050
__INTRIN_INLINE uintptr_t __readeflags(void)
Definition: intrin_x86.h:1666
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define va_end(ap)
Definition: acmsvcex.h:90
#define FALSE
Definition: types.h:117
static ULONG KdbNumberOfColsPrinted
Definition: kdb_cli.c:149
long LONG
Definition: pedump.c:60
ULONG VdmAlert
Definition: ketypes.h:770
__INTRIN_INLINE void __sidt(void *Destination)
Definition: intrin_x86.h:2015
FORCEINLINE ULONG_PTR strtoulptr(const char *nptr, char **endptr, int base)
Definition: kdb_cli.c:121
short SHORT
Definition: pedump.c:59
#define FILE_READ_DATA
Definition: nt_native.h:628
volatile ULONG KdpDmesgCurrentPosition
Definition: kdio.c:42
struct _KGDTENTRY::@2401::@2402 Bytes
#define Ke386GetGlobalDescriptorTable
Definition: kdb_cli.c:112
CHAR * PCH
Definition: ntbasedef.h:391
BOOLEAN NTAPI KdbRegisterCliCallback(PVOID Callback, BOOLEAN Deregister)
Definition: kdb_cli.c:3666
ULONG StallScaleFactor
Definition: ketypes.h:883
unsigned char BOOLEAN
struct _KPRCB * CurrentPrcb
Definition: ketypes.h:869
ULONG SecondLevelCacheSize
Definition: ketypes.h:886
static BOOLEAN KdbRepeatLastCommand
Definition: kdb_cli.c:151
static WCHAR Address[46]
Definition: ping.c:68
unsigned char
Definition: typeof.h:29
KAFFINITY SetMember
Definition: ketypes.h:764
_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:426
#define _In_
Definition: ms_sal.h:308
Definition: ketypes.h:790
PCHAR CountOnePageUp(PCHAR Buffer, ULONG BufLength, PCHAR pCurPos)
Calculate pointer position for N lines upper of current position.
Definition: kdb_cli.c:3082
char * va_list
Definition: acmsvcex.h:78
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFKEY * Key
Definition: wdfdevice.h:2654
static BOOLEAN KdbpCmdHelp(ULONG Argc, PCHAR Argv[])
Displays help screen.
Definition: kdb_cli.c:2764
Definition: bufpool.h:45
PVOID KernelStack
Definition: ketypes.h:1615
#define KEY_BS
Definition: kdb_cli.c:38
FORCEINLINE ULONG_PTR KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:189
void * PVOID
Definition: retypes.h:9
static BOOLEAN KdbpCmdBreakPoint(ULONG Argc, PCHAR Argv[])
Sets a software or hardware (memory) breakpoint at the given address.
Definition: kdb_cli.c:1599
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
VOID KdbpCliMainLoop(IN BOOLEAN EnteredOnSingleStep)
KDB Main Loop.
Definition: kdb_cli.c:3809
static BOOLEAN KdbpCmdSet(ULONG Argc, PCHAR Argv[])
Sets or displays a config variables value.
Definition: kdb_cli.c:2585
#define KEY_SCAN_UP
Definition: kdb_cli.c:42
BOOLEAN KdbpBugCheckRequested
Definition: kdb_cli.c:156
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 KEYSC_END
Definition: kdb_cli.c:46
PKDB_KTRAP_FRAME KdbCurrentTrapFrame
Definition: kdb.c:58
r l[0]
Definition: byte_order.h:167
Status
Definition: gdiplustypes.h:24
ULONG64 NpxState
Definition: ketypes.h:2008
PROSSYM_AGGREGATE_MEMBER Elements
Definition: rossym.h:102
USHORT MaximumLength
Definition: env_spec_w32.h:377
BOOLEAN KdbpEnableBreakPoint(IN LONG BreakPointNr OPTIONAL, IN OUT PKDB_BREAKPOINT BreakPoint OPTIONAL)
Enables a breakpoint.
Definition: kdb.c:704
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
ULONG Ebx
Definition: ketypes.h:804
struct _KTSS * TSS
Definition: ketypes.h:761
int Count
Definition: noreturn.cpp:7
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
static BOOLEAN KdbOutputAborted
Definition: kdb_cli.c:150
static const char *const debug_classes[]
Definition: debug.c:51
PCHAR Syntax
Definition: kdb_cli.c:362
#define ASSERT(a)
Definition: mode.c:44
#define strtoull
Definition: stabs.c:58
static LONG KdbCommandHistoryBufferIndex
Definition: kdb_cli.c:145
ULONG InterruptMode
Definition: ketypes.h:774
__wchar_t WCHAR
Definition: xmlstorage.h:180
return Iosb
Definition: create.c:4402
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USHORT Ss0
Definition: ketypes.h:795
ULONG Eip
Definition: ketypes.h:799
PVOID FiberData
Definition: compat.h:575
struct Command Command
uint64_t ULONGLONG
Definition: typedefs.h:67
#define _countof(array)
Definition: sndvol32.h:68
static BOOLEAN KdbBreakOnModuleLoad
Definition: kdb_cli.c:141
CLIENT_ID Cid
Definition: pstypes.h:1128
BOOLEAN KdbpSymFindModule(IN PVOID Address OPTIONAL, IN INT Index OPTIONAL, OUT PLDR_DATA_TABLE_ENTRY *pLdrEntry)
Find a module...
Definition: kdb_symbols.c:75
static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[])
Displays CPU registers.
Definition: kdb_cli.c:941
BOOLEAN ExpKdbgExtPoolFind(ULONG Argc, PCHAR Argv[])
LONG KdbpGetNextBreakPointNr(IN ULONG Start OPTIONAL)
Gets the number of the next breakpoint >= Start.
Definition: kdb.c:384
static BOOLEAN KdbpCmdThread(ULONG Argc, PCHAR Argv[])
Lists threads or switches to another thread context.
Definition: kdb_cli.c:1723
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:570
static BOOLEAN KdbUseIntelSyntax
Definition: kdb_cli.c:140
#define ObDereferenceObject
Definition: obfuncs.h:203
ULONG Ecx
Definition: ketypes.h:802
const GLubyte * c
Definition: glext.h:8905
static BOOLEAN KdbpCmdReboot(ULONG Argc, PCHAR Argv[])
Definition: kdb_cli.c:2520
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
volatile VOID * StackLimit
Definition: ketypes.h:1605
Type
Definition: Type.h:6
static LONG KdbNumberOfRowsTerminal
Definition: kdb_cli.c:152
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
va_start(ap, x)
#define _strnicmp(_String1, _String2, _MaxCount)
Definition: compat.h:23
VOID NTAPI HalReturnToFirmware(IN FIRMWARE_REENTRY Action)
Definition: reboot.c:22
USHORT IoMapBase
Definition: ketypes.h:824
ULONG EFlags
Definition: ketypes.h:800
struct _LARGE_INTEGER::@2249 u
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:820
HANDLE UniqueThread
Definition: compat.h:685
GLuint GLuint end
Definition: gl.h:1545
std::wstring STRING
Definition: fontsub.cpp:33
enum _KDB_ACCESS_TYPE KDB_ACCESS_TYPE
#define PKTSS
Definition: ketypes.h:926
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)
unsigned __int64 ULONG64
Definition: imports.h:198
NTSTATUS NTAPI PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process)
Definition: process.c:919
unsigned char UCHAR
Definition: xmlstorage.h:181
static LONG KdbNumberOfColsTerminal
Definition: kdb_cli.c:153
ULONG KdbNumSingleSteps
Definition: kdb.c:50
PVOID SubSystemTib
Definition: compat.h:573
KPRCB Prcb
Definition: ketypes.h:894
enum _KDB_ENTER_CONDITION KDB_ENTER_CONDITION
static BOOLEAN KdbpCmdGdtLdtIdt(ULONG Argc, PCHAR Argv[])
Displays GDT, LDT or IDT.
Definition: kdb_cli.c:2116
VOID RosSymFreeAggregate(PROSSYM_AGGREGATE Aggregate)
Definition: find.c:126
__INTRIN_INLINE void __writeeflags(uintptr_t Value)
Definition: intrin_x86.h:1661
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
Definition: btrfs_drv.h:1866
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
PCHAR Help
Definition: kdb_cli.c:363
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
GLdouble s
Definition: gl.h:2039
VOID KdbpPager(IN PCHAR Buffer, IN ULONG BufLength)
Prints the given string with, page by page.
Definition: kdb_cli.c:3134
BOOLEAN KdbSingleStepOver
Definition: kdb.c:51
Definition: typedefs.h:119
BOOLEAN ExpKdbgExtPoolUsed(ULONG Argc, PCHAR Argv[])
char __ImageBase
Definition: mstscax.cpp:17
STRING KdbPromptString
Definition: kdb_cli.c:167
#define SYNCHRONIZE
Definition: nt_native.h:61
enum _KDB_BREAKPOINT_TYPE KDB_BREAKPOINT_TYPE
_In_ HANDLE hFile
Definition: mswsock.h:90
BOOLEAN KdbpAttachToProcess(PVOID ProcessId)
Switches to another process/thread context.
Definition: kdb.c:1120
ULONG Eax
Definition: ketypes.h:801
static BOOLEAN KdbpCmdPcr(ULONG Argc, PCHAR Argv[])
Displays the KPCR.
Definition: kdb_cli.c:2335
USHORT Ss
Definition: ketypes.h:813
#define SE
Definition: ftp_var.h:28
struct _KPCR * Self
Definition: ketypes.h:868
static BOOLEAN KdbpCmdDmesg(ULONG Argc, PCHAR Argv[])
Display debug messages on screen, with paging.
Definition: kdb_cli.c:2541
_In_ WDFINTERRUPT _In_ PFN_WDF_INTERRUPT_SYNCHRONIZE Callback
Definition: wdfinterrupt.h:456
#define MAXULONG
Definition: typedefs.h:251
union _KIDTENTRY64 * IdtBase
Definition: ketypes.h:874
PVOID StackBase
Definition: ketypes.h:1606
static LONG KdbCommandHistoryIndex
Definition: kdb_cli.c:146
ULONG_PTR SIZE_T
Definition: typedefs.h:80
BOOLEAN ExpKdbgExtIrpFind(ULONG Argc, PCHAR Argv[])
ULONG Esp
Definition: ketypes.h:805
USHORT Flags
Definition: ketypes.h:823
struct _FileName FileName
Definition: fatprocs.h:893
NTSTATUS KdbpSafeReadMemory(OUT PVOID Dest, IN PVOID Src, IN ULONG Bytes)
Definition: kdb.c:1690
BOOLEAN ExpKdbgExtFileCache(ULONG Argc, PCHAR Argv[])
_SEH2_END
Definition: create.c:4400
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:411
static PCHAR KdbCommandHistory[sizeof(KdbCommandHistoryBuffer)/8]
Definition: kdb_cli.c:144
PVOID KdVersionBlock
Definition: ketypes.h:890
uint64_t DWORD64
Definition: typedefs.h:67
ULONG Esp0
Definition: ketypes.h:794
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
static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[])
Evaluates an expression and displays the result.
Definition: kdb_cli.c:487
PVOID StackBase
Definition: compat.h:571
#define DPFLTR_ERROR_LEVEL
Definition: main.cpp:32
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN(* Fn)(ULONG Argc, PCHAR Argv[])
Definition: kdb_cli.c:364
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
ULONG Edi
Definition: ketypes.h:808
ULONG Ebp
Definition: ketypes.h:806
PKGDTENTRY GDT
Definition: ketypes.h:760
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
LONG KdbLastBreakPointNr
Definition: kdb.c:49
FORCEINLINE ULONG_PTR KeGetContextFrameRegister(PCONTEXT Context)
Definition: ke.h:161
#define FORCEINLINE
Definition: wdftypes.h:67
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define KEYSC_ARROWUP
Definition: kdb_cli.c:50
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
USHORT MajorVersion
Definition: ketypes.h:881
static CHAR KdbCommandHistoryBuffer[2048]
Definition: kdb_cli.c:143
#define KEY_DEL
Definition: kdb_cli.c:40
VOID KdbpCliInit(VOID)
Called when KDB is initialized.
Definition: kdb_cli.c:3921
#define _vsnprintf
Definition: xmlstorage.h:202
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define SYSTEM
Definition: fatfs.h:185
BOOLEAN(NTAPI * PKDBG_CLI_ROUTINE)(IN PCHAR Command, IN ULONG Argc, IN PCH Argv[])
Definition: kdb_cli.c:134
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
PETHREAD KdbCurrentThread
Definition: kdb.c:56
POINT cp
Definition: magnifier.c:59
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:40
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
volatile UCHAR State
Definition: ketypes.h:1729
ULONG Esi
Definition: ketypes.h:807
void __cdecl _disable(void)
Definition: intrin_arm.h:365
GROUP_AFFINITY Affinity
Definition: ketypes.h:1878
ULONG IDR
Definition: ketypes.h:757
#define c
Definition: ke_i.h:80
FORCEINLINE ULONG_PTR KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
Definition: ke.h:196
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN ExpKdbgExtDefWrites(ULONG Argc, PCHAR Argv[])
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ULONG IrrActive
Definition: ketypes.h:756
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
PVOID StackLimit
Definition: compat.h:572
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
const char * PCSTR
Definition: typedefs.h:52
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:976
NT_TIB NtTib
Definition: ketypes.h:862
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
static BOOLEAN KdbpGetComponentId(IN PCSTR ComponentName, OUT PULONG ComponentId)
Retrieves the component ID corresponding to a given component name.
Definition: kdb_cli.c:695
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
USHORT Gs
Definition: ketypes.h:819
Definition: _set.h:46
PKIDTENTRY IDT
Definition: ketypes.h:759
#define DPFLTR_TRACE_LEVEL
Definition: kdtypes.h:32
PVOID InitialStack
Definition: ketypes.h:1604
VOID KdbpCliInterpretInitFile(VOID)
This function is called by KdbEnterDebuggerException...
Definition: kdb_cli.c:3872
PCHAR KdbInitFileBuffer
Definition: kdb_cli.c:155
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:3713
unsigned short * PUSHORT
Definition: retypes.h:2
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
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:1102
volatile ULONG KdpDmesgFreeBytes
Definition: kdio.c:43
base of all file and directory entries
Definition: entries.h:82
static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[])
Displays a backtrace.
Definition: kdb_cli.c:1245
#define KdpDprintf(...)
Definition: mmdbg.c:19
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
PKSPIN_LOCK_QUEUE LockArray
Definition: ketypes.h:870
struct _KPCR * SelfPcr
Definition: ketypes.h:752
static const struct @1770 KdbDebuggerCommands[]
Definition: heap.c:51
#define UNW_FLAG_NHANDLER
Definition: gs_support.c:32
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
BOOLEAN ExpKdbgExtHandle(ULONG Argc, PCHAR Argv[])