ReactOS  0.4.14-dev-583-g2a1ba2c
kdprint.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/kd64/kdprint.c
5  * PURPOSE: KD64 Trap Handler Routines
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  * Stefan Ginsberg (stefan.ginsberg@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS *****************************************************************/
17 
18 #ifdef _WINKD_
19 
20 BOOLEAN
21 NTAPI
24 {
26  DBGKD_DEBUG_IO DebugIo;
27  USHORT Length;
28 
29  /* Copy the string */
31  Output->Buffer,
32  Output->Length);
33 
34  /* Make sure we don't exceed the KD Packet size */
35  Length = Output->Length;
36  if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
37  {
38  /* Normalize length */
40  }
41 
42  /* Build the packet header */
45  DebugIo.Processor = KeGetCurrentPrcb()->Number;
47  Header.Length = sizeof(DBGKD_DEBUG_IO);
48  Header.Buffer = (PCHAR)&DebugIo;
49 
50  /* Build the data */
51  Data.Length = Length;
52  Data.Buffer = KdpMessageBuffer;
53 
54  /* Send the packet */
56 
57  /* Check if the user pressed CTRL+C */
59 }
60 
61 BOOLEAN
62 NTAPI
64  _In_ PSTRING PromptString,
65  _In_ PSTRING ResponseString)
66 {
68  DBGKD_DEBUG_IO DebugIo;
69  ULONG Length;
71 
72  /* Copy the string to the message buffer */
74  PromptString->Buffer,
75  PromptString->Length);
76 
77  /* Make sure we don't exceed the KD Packet size */
78  Length = PromptString->Length;
79  if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
80  {
81  /* Normalize length */
83  }
84 
85  /* Build the packet header */
86  DebugIo.ApiNumber = DbgKdGetStringApi;
88  DebugIo.Processor = KeGetCurrentPrcb()->Number;
90  DebugIo.u.GetString.LengthOfStringRead = ResponseString->MaximumLength;
91  Header.Length = sizeof(DBGKD_DEBUG_IO);
92  Header.Buffer = (PCHAR)&DebugIo;
93 
94  /* Build the data */
95  Data.Length = Length;
96  Data.Buffer = KdpMessageBuffer;
97 
98  /* Send the packet */
100 
101  /* Set the maximum lengths for the receive */
102  Header.MaximumLength = sizeof(DBGKD_DEBUG_IO);
103  Data.MaximumLength = sizeof(KdpMessageBuffer);
104 
105  /* Enter receive loop */
106  do
107  {
108  /* Get our reply */
110  &Header,
111  &Data,
112  &Length,
113  &KdpContext);
114 
115  /* Return TRUE if we need to resend */
116  if (Status == KdPacketNeedsResend) return TRUE;
117 
118  /* Loop until we succeed */
119  } while (Status != KdPacketReceived);
120 
121  /* Don't copy back a larger response than there is room for */
122  Length = min(Length,
123  ResponseString->MaximumLength);
124 
125  /* Copy back the string and return the length */
126  KdpMoveMemory(ResponseString->Buffer,
128  Length);
129  ResponseString->Length = (USHORT)Length;
130 
131  /* Success; we don't need to resend */
132  return FALSE;
133 }
134 
135 VOID
136 NTAPI
137 KdpCommandString(IN PSTRING NameString,
138  IN PSTRING CommandString,
141  IN PKTRAP_FRAME TrapFrame,
142  IN PKEXCEPTION_FRAME ExceptionFrame)
143 {
144  BOOLEAN Enable;
145  PKPRCB Prcb = KeGetCurrentPrcb();
146 
147  /* Check if we need to do anything */
148  if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;
149 
150  /* Enter the debugger */
151  Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
152 
153  /* Save the CPU Control State and save the context */
157  sizeof(CONTEXT));
158 
159  /* Send the command string to the debugger */
161  CommandString,
163 
164  /* Restore the processor state */
167  sizeof(CONTEXT));
169 
170  /* Exit the debugger and return */
172 }
173 
174 VOID
175 NTAPI
177  IN PKD_SYMBOLS_INFO SymbolInfo,
178  IN BOOLEAN Unload,
181  IN PKTRAP_FRAME TrapFrame,
182  IN PKEXCEPTION_FRAME ExceptionFrame)
183 {
184  BOOLEAN Enable;
185  PKPRCB Prcb = KeGetCurrentPrcb();
186 
187  /* Check if we need to do anything */
188  if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;
189 
190  /* Enter the debugger */
191  Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
192 
193  /* Save the CPU Control State and save the context */
197  sizeof(CONTEXT));
198 
199  /* Report the new state */
201  SymbolInfo,
202  Unload,
204 
205  /* Restore the processor state */
208  sizeof(CONTEXT));
210 
211  /* Exit the debugger and return */
213 }
214 
215 #else
216 
217 extern
218 BOOLEAN
219 NTAPI
222 
223 extern
224 BOOLEAN
225 NTAPI
227  _In_ PSTRING PromptString,
228  _In_ PSTRING ResponseString);
229 
230 #endif // _WINKD_
231 
232 USHORT
233 NTAPI
235  _In_reads_bytes_(PromptLength) PCHAR PromptString,
236  _In_ USHORT PromptLength,
240  _In_ PKTRAP_FRAME TrapFrame,
241  _In_ PKEXCEPTION_FRAME ExceptionFrame)
242 {
243  STRING PromptBuffer, ResponseBuffer;
244  BOOLEAN Enable, Resend;
245  PCHAR SafeResponseString;
246  CHAR CapturedPrompt[512];
247  CHAR SafeResponseBuffer[512];
248 
249  /* Normalize the lengths */
250  PromptLength = min(PromptLength,
251  sizeof(CapturedPrompt));
253  sizeof(SafeResponseBuffer));
254 
255  /* Check if we need to verify the string */
256  if (PreviousMode != KernelMode)
257  {
258  /* Handle user-mode buffers safely */
259  _SEH2_TRY
260  {
261  /* Probe and capture the prompt */
262  ProbeForRead(PromptString, PromptLength, 1);
263  KdpMoveMemory(CapturedPrompt, PromptString, PromptLength);
264  PromptString = CapturedPrompt;
265 
266  /* Probe and make room for the response */
267  ProbeForWrite(ResponseString, MaximumResponseLength, 1);
268  SafeResponseString = SafeResponseBuffer;
269  }
271  {
272  /* Bad string pointer, bail out */
273  _SEH2_YIELD(return 0);
274  }
275  _SEH2_END;
276  }
277  else
278  {
279  SafeResponseString = ResponseString;
280  }
281 
282  /* Setup the prompt and response buffers */
283  PromptBuffer.Buffer = PromptString;
284  PromptBuffer.Length = PromptBuffer.MaximumLength = PromptLength;
285  ResponseBuffer.Buffer = SafeResponseString;
286  ResponseBuffer.Length = 0;
287  ResponseBuffer.MaximumLength = MaximumResponseLength;
288 
289  /* Log the print */
290  //KdLogDbgPrint(&PromptBuffer);
291 
292  /* Enter the debugger */
293  Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
294 
295  /* Enter prompt loop */
296  do
297  {
298  /* Send the prompt and receive the response */
299  Resend = KdpPromptString(&PromptBuffer, &ResponseBuffer);
300 
301  /* Loop while we need to resend */
302  } while (Resend);
303 
304  /* Exit the debugger */
306 
307  /* Copy back the response if required */
308  if (PreviousMode != KernelMode)
309  {
310  _SEH2_TRY
311  {
312  /* Safely copy back the response to user mode */
313  KdpMoveMemory(ResponseString,
314  ResponseBuffer.Buffer,
315  ResponseBuffer.Length);
316  }
318  {
319  /* String became invalid after we exited, fail */
320  _SEH2_YIELD(return 0);
321  }
322  _SEH2_END;
323  }
324 
325  /* Return the number of characters received */
326  return ResponseBuffer.Length;
327 }
328 
329 NTSTATUS
330 NTAPI
333  _In_ ULONG Level,
337  _In_ PKTRAP_FRAME TrapFrame,
338  _In_ PKEXCEPTION_FRAME ExceptionFrame,
340 {
342  BOOLEAN Enable;
343  STRING OutputString;
344  CHAR CapturedString[512];
345 
346  /* Assume failure */
347  *Handled = FALSE;
348 
349 #if (NTDDI_VERSION >= NTDDI_VISTA)
351  {
352  /* Use the default component ID */
353  Mask = &Kd_DEFAULT_Mask;
354  // Level = DPFLTR_INFO_LEVEL; // Override the Level.
355  }
356 #endif
357  /* Convert Level to bit field if required */
358  if (Level < 32) Level = 1 << Level;
359  Level &= ~DPFLTR_MASK;
360 
361  /* Validate the mask */
362  if (!(Kd_WIN2000_Mask & Level) ||
365  {
366  /* Mask validation failed */
367  *Handled = TRUE;
368  return STATUS_SUCCESS;
369  }
370 
371  /* Normalize the length */
372  Length = min(Length, sizeof(CapturedString));
373 
374  /* Check if we need to verify the string */
375  if (PreviousMode != KernelMode)
376  {
377  /* Capture user-mode buffers */
378  _SEH2_TRY
379  {
380  /* Probe and capture the string */
382  KdpMoveMemory(CapturedString, String, Length);
383  String = CapturedString;
384  }
386  {
387  /* Bad string pointer, bail out */
389  }
390  _SEH2_END;
391  }
392 
393  /* Setup the output string */
394  OutputString.Buffer = String;
395  OutputString.Length = OutputString.MaximumLength = Length;
396 
397  /* Log the print */
398  //KdLogDbgPrint(&OutputString);
399 
400  /* Check for a debugger */
402  {
403  /* Fail */
404  *Handled = TRUE;
406  }
407 
408  /* Enter the debugger */
409  Enable = KdEnterDebugger(TrapFrame, ExceptionFrame);
410 
411  /* Print the string */
412  if (KdpPrintString(&OutputString))
413  {
414  /* User pressed CTRL-C, breakpoint on return */
416  }
417  else
418  {
419  /* String was printed */
421  }
422 
423  /* Exit the debugger and return */
425  *Handled = TRUE;
426  return Status;
427 }
428 
429 VOID
430 __cdecl
432  _In_ PCHAR Format,
433  ...)
434 {
435  STRING String;
436  USHORT Length;
437  va_list ap;
438  CHAR Buffer[100];
439 
440  /* Format the string */
441  va_start(ap, Format);
443  sizeof(Buffer),
444  Format,
445  ap);
446  va_end(ap);
447 
448  /* Set it up */
449  String.Buffer = Buffer;
450  String.Length = String.MaximumLength = Length;
451 
452  /* Send it to the debugger directly */
454 }
NTSTATUS NTAPI KdpPrint(_In_ ULONG ComponentId, _In_ ULONG Level, _In_reads_bytes_(Length) PCHAR String, _In_ USHORT Length, _In_ KPROCESSOR_MODE PreviousMode, _In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame, _Out_ PBOOLEAN Handled)
Definition: kdprint.c:331
signed char * PCHAR
Definition: retypes.h:7
#define KdPacketReceived
Definition: kddll.h:5
ULONG LengthOfStringRead
Definition: windbgkd.h:393
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define __cdecl
Definition: accygwin.h:79
VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
Definition: csqtest.c:160
VOID NTAPI KdpMoveMemory(_In_ PVOID Destination, _In_ PVOID Source, _In_ SIZE_T Length)
Definition: kdapi.c:22
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1062
ULONG KdComponentTableSize
Definition: kddata.c:459
#define DPFLTR_MASK
Definition: kdtypes.h:34
KDP_STATUS NTAPI KdReceivePacket(IN ULONG PacketType, OUT PSTRING MessageHeader, OUT PSTRING MessageData, OUT PULONG DataLength, IN OUT PKD_CONTEXT KdContext)
Definition: kddll.c:80
BOOLEAN NTAPI KdpPromptString(_In_ PSTRING PromptString, _In_ PSTRING ResponseString)
Definition: kdio.c:625
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
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:1270
static WCHAR String[]
Definition: stringtable.c:55
VOID NTAPI KdExitDebugger(IN BOOLEAN Enable)
Definition: kdmain.c:317
#define PACKET_MAX_SIZE
Definition: windbgkd.h:18
ULONG ApiNumber
Definition: windbgkd.h:401
CHAR KdpMessageBuffer[0x1000]
Definition: kddata.c:131
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
VOID NTAPI KdpCommandString(IN PSTRING NameString, IN PSTRING CommandString, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT ContextRecord, IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
#define DbgKdGetStringApi
Definition: windbgkd.h:123
BOOLEAN NTAPI KdpPrintString(_In_ PSTRING Output)
Definition: kdio.c:590
#define KdPacketNeedsResend
Definition: kddll.h:7
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
Definition: Header.h:8
#define DbgKdPrintStringApi
Definition: windbgkd.h:122
ULONG LengthOfPromptString
Definition: windbgkd.h:392
CONTEXT ContextFrame
Definition: ketypes.h:531
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
#define STATUS_BREAKPOINT
Definition: ntstatus.h:172
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
#define _Out_
Definition: no_sal2.h:323
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
VOID NTAPI KiRestoreProcessorControlState(IN PKPROCESSOR_STATE ProcessorState)
struct _DBGKD_DEBUG_IO DBGKD_DEBUG_IO
char * va_list
Definition: acmsvcex.h:78
Definition: bufpool.h:45
USHORT ProcessorLevel
Definition: windbgkd.h:402
BOOLEAN NTAPI KdpPollBreakInWithPortLock(VOID)
Definition: kdlock.c:35
KD_CONTEXT KdpContext
Definition: kddata.c:65
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define PCHAR
Definition: match.c:90
_In_ ULONG MaximumResponseLength
Definition: kdfuncs.h:11
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
VOID NTAPI KdpSymbol(IN PSTRING DllPath, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN Unload, IN KPROCESSOR_MODE PreviousMode, IN PCONTEXT ContextRecord, IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
_In_ BOOLEAN Handled
Definition: ketypes.h:337
ULONG Kd_WIN2000_Mask
Definition: kddata.c:147
union _DBGKD_DEBUG_IO::@3419 u
PULONG KdComponentTable[MAX_KD_COMPONENT_TABLE_ENTRIES]
Definition: kddata.c:303
VOID NTAPI KdpReportLoadSymbolsStateChange(IN PSTRING PathName, IN PKD_SYMBOLS_INFO SymbolInfo, IN BOOLEAN Unload, IN OUT PCONTEXT Context)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
KPROCESSOR_STATE ProcessorState
Definition: ketypes.h:579
std::wstring STRING
Definition: fontsub.cpp:33
_IRQL_requires_same_ _In_ PVOID _Inout_ struct _CONTEXT * ContextRecord
Definition: ntbasedef.h:661
char * PBOOLEAN
Definition: retypes.h:11
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
Definition: arc.h:85
VOID NTAPI KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState)
Definition: cpu.c:372
DBGKD_PRINT_STRING PrintString
Definition: windbgkd.h:406
DBGKD_GET_STRING GetString
Definition: windbgkd.h:407
#define _In_reads_bytes_(size)
Definition: no_sal2.h:229
Status
Definition: gdiplustypes.h:24
#define MAXULONG
Definition: typedefs.h:250
#define _In_
Definition: no_sal2.h:204
USHORT NTAPI KdpPrompt(_In_reads_bytes_(PromptLength) PCHAR PromptString, _In_ USHORT PromptLength, _Out_writes_bytes_(MaximumResponseLength) PCHAR ResponseString, _In_ USHORT MaximumResponseLength, _In_ KPROCESSOR_MODE PreviousMode, _In_ PKTRAP_FRAME TrapFrame, _In_ PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdprint.c:234
_SEH2_END
Definition: create.c:4424
VOID __cdecl KdpDprintf(_In_ PCHAR Format,...)
Definition: kdprint.c:431
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
unsigned short USHORT
Definition: pedump.c:61
ULONG Kd_DEFAULT_Mask
Definition: kddata.c:249
static const char const char * DllPath
Definition: image.c:34
#define PACKET_TYPE_KD_DEBUG_IO
Definition: windbgkd.h:44
ULONG KDSTATUS
Definition: kddll.h:4
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define min(a, b)
Definition: monoChain.cc:55
#define _vsnprintf
Definition: xmlstorage.h:202
USHORT KeProcessorLevel
Definition: krnlinit.c:20
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI KdEnterDebugger(IN PKTRAP_FRAME TrapFrame, IN PKEXCEPTION_FRAME ExceptionFrame)
Definition: kdmain.c:309
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID NTAPI KdSendPacket(IN ULONG PacketType, IN PSTRING MessageHeader, IN PSTRING MessageData, IN OUT PKD_CONTEXT KdContext)
Definition: kddll.c:314
BOOLEAN KdDebuggerNotPresent
Definition: kdmain.c:50
VOID NTAPI KdpReportCommandStringStateChange(IN PSTRING NameString, IN PSTRING CommandString, IN OUT PCONTEXT Context)
USHORT Processor
Definition: windbgkd.h:403
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 * Format
Definition: acpixf.h:1212