- KdDebuggerNotPresent should be FALSE by default.
[reactos.git] / reactos / ntoskrnl / kd64 / kdprint.c
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 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14
15 CHAR KdpMessageBuffer[4096];
16
17 /* FUNCTIONS *****************************************************************/
18
19 BOOLEAN
20 NTAPI
21 KdpPrintString(IN PSTRING Output)
22 {
23 STRING Data, Header;
24 DBGKD_DEBUG_IO DebugIo;
25 ULONG Length = Output->Length;
26
27 /* Copy the string */
28 RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);
29
30 /* Make sure we don't exceed the KD Packet size */
31 if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
32 {
33 /* Normalize length */
34 Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
35 }
36
37 /* Build the packet header */
38 DebugIo.ApiNumber = DbgKdPrintStringApi;
39 DebugIo.ProcessorLevel = KeProcessorLevel;
40 DebugIo.Processor = KeGetCurrentPrcb()->Number;
41 DebugIo.u.PrintString.LengthOfString = Length;
42 Header.Length = sizeof(DBGKD_DEBUG_IO);
43 Header.Buffer = (PCHAR)&DebugIo;
44
45 /* Build the data */
46 Data.Length = Length;
47 Data.Buffer = KdpMessageBuffer;
48
49 /* Send the packet */
50 KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);
51
52 /* Check if the user pressed CTRL+C */
53 return KdpPollBreakInWithPortLock();
54 }
55
56 ULONG
57 NTAPI
58 KdpCommandString(IN ULONG Length,
59 IN LPSTR String,
60 IN KPROCESSOR_MODE PreviousMode,
61 IN PCONTEXT ContextRecord,
62 IN PKTRAP_FRAME TrapFrame,
63 IN PKEXCEPTION_FRAME ExceptionFrame)
64 {
65 /* FIXME */
66 return FALSE;
67 }
68
69 ULONG
70 NTAPI
71 KdpSymbol(IN LPSTR DllPath,
72 IN ULONG DllBase,
73 IN BOOLEAN Unload,
74 IN KPROCESSOR_MODE PreviousMode,
75 IN PCONTEXT ContextRecord,
76 IN PKTRAP_FRAME TrapFrame,
77 IN PKEXCEPTION_FRAME ExceptionFrame)
78 {
79 BOOLEAN Entered;
80 PKPRCB Prcb = KeGetCurrentPrcb();
81 ULONG Status;
82
83 /* Check if we need to do anything */
84 if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;
85
86 /* Enter the debugger */
87 Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
88
89 /* Save the CPU Control State and save the context */
90 KiSaveProcessorControlState(&Prcb->ProcessorState);
91 RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
92 ContextRecord,
93 sizeof(CONTEXT));
94
95 /* Report the new state */
96 #if 0
97 Status = KdpReportLoadSymbolsStateChange(DllPath,
98 DllBase,
99 Unload,
100 &Prcb->
101 ProcessorState.ContextFrame);
102 #else
103 Status = FALSE;
104 #endif
105
106 /* Now restore the processor state, manually again. */
107 RtlCopyMemory(ContextRecord,
108 &Prcb->ProcessorState.ContextFrame,
109 sizeof(CONTEXT));
110 KiRestoreProcessorControlState(&Prcb->ProcessorState);
111
112 /* Exit the debugger and clear the CTRL-C state */
113 KdExitDebugger(Entered);
114 return 0;
115 }
116
117 ULONG
118 NTAPI
119 KdpPrompt(IN LPSTR InString,
120 IN ULONG InStringLength,
121 OUT LPSTR OutString,
122 IN ULONG OutStringLength,
123 IN KPROCESSOR_MODE PreviousMode,
124 IN PKTRAP_FRAME TrapFrame,
125 IN PKEXCEPTION_FRAME ExceptionFrame)
126 {
127 /* FIXME */
128 return FALSE;
129 }
130
131 ULONG
132 NTAPI
133 KdpPrint(IN ULONG ComponentId,
134 IN ULONG ComponentMask,
135 IN LPSTR String,
136 IN ULONG Length,
137 IN KPROCESSOR_MODE PreviousMode,
138 IN PKTRAP_FRAME TrapFrame,
139 IN PKEXCEPTION_FRAME ExceptionFrame,
140 OUT PBOOLEAN Status)
141 {
142 NTSTATUS ReturnValue;
143 BOOLEAN Entered;
144 ANSI_STRING AnsiString;
145
146 /* Assume failure */
147 *Status = FALSE;
148
149 /* Validate the mask */
150 if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;
151 if (!(Kd_WIN2000_Mask & ComponentMask) ||
152 ((ComponentId < KdComponentTableSize) &&
153 !(*KdComponentTable[ComponentId] & ComponentMask)))
154 {
155 /* Mask validation failed */
156 *Status = TRUE;
157 return FALSE;
158 }
159
160 /* Normalize the length */
161 Length = min(Length, 512);
162
163 /* Check if we need to verify the buffer */
164 if (PreviousMode != KernelMode)
165 {
166 /* FIXME: Support user-mode */
167 }
168
169 /* Setup the ANSI string */
170 AnsiString.Buffer = String;
171 AnsiString.Length = (USHORT)Length;
172
173 /* Log the print */
174 //KdLogDbgPrint(&AnsiString);
175
176 /* Check for a debugger */
177 if (KdDebuggerNotPresent)
178 {
179 /* Fail */
180 *Status = TRUE;
181 return (ULONG)STATUS_DEVICE_NOT_CONNECTED;
182 }
183
184 /* Enter the debugger */
185 Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
186
187 /* Print the string */
188 if (KdpPrintString(&AnsiString))
189 {
190 /* User pressed CTRL-C, breakpoint on return */
191 ReturnValue = STATUS_BREAKPOINT;
192 }
193 else
194 {
195 /* String was printed */
196 ReturnValue = STATUS_SUCCESS;
197 }
198
199 /* Exit the debugger and return */
200 KdExitDebugger(Entered);
201 *Status = TRUE;
202 return ReturnValue;
203 }
204