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