Fix build with gcc 4.1.2
[reactos.git] / reactos / lib / rtl / debug.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Run-Time Library
4 * FILE: ntoskrnl/rtl/dbgprint.c
5 * PURPOSE: Debug Print and Prompt routines
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Royce Mitchel III
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <rtl.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 /* PRIVATE FUNCTIONS ********************************************************/
18
19 NTSTATUS
20 NTAPI
21 DebugPrint(IN PANSI_STRING DebugString,
22 IN ULONG ComponentId,
23 IN ULONG Level)
24 {
25 return STATUS_SUCCESS;
26
27 /* Call the INT2D Service */
28 return DebugService(BREAKPOINT_PRINT,
29 DebugString->Buffer,
30 DebugString->Length,
31 UlongToPtr(ComponentId),
32 UlongToPtr(Level));
33 }
34
35 NTSTATUS
36 NTAPI
37 DebugPrompt(IN PCSTRING Output,
38 IN PSTRING Input)
39 {
40 /* Call the INT2D Service */
41 return DebugService(BREAKPOINT_PROMPT,
42 Output->Buffer,
43 Output->Length,
44 Input->Buffer,
45 UlongToPtr(Input->MaximumLength));
46 }
47
48 /* FUNCTIONS ****************************************************************/
49
50 ULONG
51 NTAPI
52 vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix,
53 IN ULONG ComponentId,
54 IN ULONG Level,
55 IN LPCSTR Format,
56 IN va_list ap,
57 IN BOOLEAN HandleBreakpoint)
58 {
59 NTSTATUS Status;
60 ANSI_STRING DebugString;
61 CHAR Buffer[512];
62 PCHAR pBuffer = Buffer;
63 ULONG pBufferSize = sizeof(Buffer);
64 ULONG Length;
65 EXCEPTION_RECORD ExceptionRecord;
66
67 /* Check if we should print it or not */
68 if (ComponentId != -1 && !NtQueryDebugFilterState(ComponentId, Level))
69 {
70 /* This message is masked */
71 return STATUS_SUCCESS;
72 }
73
74 /* For user mode, don't recursively DbgPrint */
75 if (RtlpSetInDbgPrint(TRUE)) return STATUS_SUCCESS;
76
77 /* Initialize the length to 8 */
78 DebugString.Length = 0;
79
80 /* Handle the prefix */
81 if (Prefix && *Prefix)
82 {
83 /* Get the length */
84 DebugString.Length = strlen(Prefix);
85
86 /* Normalize it */
87 if(DebugString.Length > sizeof(Buffer))
88 {
89 DebugString.Length = sizeof(Buffer);
90 }
91
92 /* Copy it */
93 strncpy(Buffer, Prefix, DebugString.Length);
94
95 /* Set the pointer and update the size */
96 pBuffer = &Buffer[DebugString.Length];
97 pBufferSize -= DebugString.Length;
98 }
99
100 /* Setup the ANSI String */
101 DebugString.Buffer = Buffer;
102 DebugString.MaximumLength = sizeof(Buffer);
103 Length = _vsnprintf(pBuffer, pBufferSize, Format, ap);
104
105 /* Check if we went past the buffer */
106 if (Length == -1)
107 {
108 /* Terminate it if we went over-board */
109 Buffer[sizeof(Buffer) - 1] = '\n';
110
111 /* Put maximum */
112 Length = sizeof(Buffer);
113 }
114
115 /* Update length */
116 DebugString.Length += Length;
117
118 /* First, let the debugger know as well */
119 if (RtlpCheckForActiveDebugger(FALSE))
120 {
121 /* Fill out an exception record */
122 ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;
123 ExceptionRecord.ExceptionRecord = NULL;
124 ExceptionRecord.NumberParameters = 2;
125 ExceptionRecord.ExceptionFlags = 0;
126 ExceptionRecord.ExceptionInformation[0] = DebugString.Length + 1;
127 ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)DebugString.Buffer;
128
129 /* Raise the exception */
130 RtlRaiseException(&ExceptionRecord);
131
132 /* This code only runs in user-mode, so setting the flag is safe */
133 NtCurrentTeb()->InDbgPrint = FALSE;
134 return STATUS_SUCCESS;
135 }
136
137 /* Call the Debug Print routine */
138 Status = DebugPrint(&DebugString, ComponentId, Level);
139
140 /* Check if this was with Control-C */
141 if (HandleBreakpoint)
142 {
143 /* Check if we got a breakpoint */
144 if (Status == STATUS_BREAKPOINT)
145 {
146 /* Breakpoint */
147 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
148 Status = STATUS_SUCCESS;
149 }
150 }
151
152 /* In user-mode, remove the InDbgPrint Flag */
153 RtlpSetInDbgPrint(FALSE);
154
155 /* Return */
156 return Status;
157 }
158
159 /*
160 * @implemented
161 */
162 ULONG
163 NTAPI
164 vDbgPrintExWithPrefix(IN LPCSTR Prefix,
165 IN ULONG ComponentId,
166 IN ULONG Level,
167 IN LPCSTR Format,
168 IN va_list ap)
169 {
170 /* Call the internal routine that also handles ControlC */
171 return vDbgPrintExWithPrefixInternal(Prefix,
172 ComponentId,
173 Level,
174 Format,
175 ap,
176 TRUE);
177 }
178
179 /*
180 * @implemented
181 */
182 ULONG
183 NTAPI
184 vDbgPrintEx(IN ULONG ComponentId,
185 IN ULONG Level,
186 IN LPCSTR Format,
187 IN va_list ap)
188 {
189 /* Call the internal routine that also handles ControlC */
190 return vDbgPrintExWithPrefixInternal(NULL,
191 ComponentId,
192 Level,
193 Format,
194 ap,
195 TRUE);
196 }
197
198 /*
199 * @implemented
200 */
201 ULONG
202 __cdecl
203 DbgPrint(PCCH Format,
204 ...)
205 {
206 va_list ap;
207
208 /* Call the internal routine that also handles ControlC */
209 va_start(ap, Format);
210 return vDbgPrintExWithPrefixInternal(NULL,
211 -1,
212 DPFLTR_ERROR_LEVEL,
213 Format,
214 ap,
215 TRUE);
216 va_end(ap);
217 }
218
219 /*
220 * @implemented
221 */
222 ULONG
223 __cdecl
224 DbgPrintEx(IN ULONG ComponentId,
225 IN ULONG Level,
226 IN PCCH Format,
227 ...)
228 {
229 va_list ap;
230
231 /* Call the internal routine that also handles ControlC */
232 va_start(ap, Format);
233 return vDbgPrintExWithPrefixInternal(NULL,
234 ComponentId,
235 Level,
236 Format,
237 ap,
238 TRUE);
239 va_end(ap);
240 }
241
242 /*
243 * @implemented
244 */
245 ULONG
246 __cdecl
247 DbgPrintReturnControlC(PCH Format,
248 ...)
249 {
250 va_list ap;
251
252 /* Call the internal routine that also handles ControlC */
253 va_start(ap, Format);
254 return vDbgPrintExWithPrefixInternal(NULL,
255 -1,
256 DPFLTR_ERROR_LEVEL,
257 Format,
258 ap,
259 FALSE);
260 }
261
262 /*
263 * @implemented
264 */
265 ULONG
266 NTAPI
267 DbgPrompt(IN PCCH Prompt,
268 OUT PCH Response,
269 IN ULONG MaximumResponseLength)
270 {
271 CSTRING Output;
272 STRING Input;
273
274 /* Setup the input string */
275 Input.MaximumLength = MaximumResponseLength;
276 Input.Buffer = Response;
277
278 /* Setup the output string */
279 Output.Length = strlen(Prompt);
280 Output.Buffer = Prompt;
281
282 /* Call the system service */
283 return DebugPrompt(&Output, &Input);
284 }
285
286 /*
287 * @implemented
288 */
289 BOOLEAN
290 NTAPI
291 DbgQueryDebugFilterState(IN ULONG ComponentId,
292 IN ULONG Level)
293 {
294 /* Call the Nt routine */
295 return NtQueryDebugFilterState(ComponentId, Level);
296 }
297
298 /*
299 * @implemented
300 */
301 NTSTATUS
302 NTAPI
303 DbgSetDebugFilterState(IN ULONG ComponentId,
304 IN ULONG Level,
305 IN BOOLEAN State)
306 {
307 /* Call the Nt routine */
308 return NtSetDebugFilterState(ComponentId, Level, State);
309 }
310
311 /*
312 * @implemented
313 */
314 NTSTATUS
315 NTAPI
316 DbgLoadImageSymbols(IN PANSI_STRING Name,
317 IN PVOID Base,
318 IN ULONG_PTR ProcessId)
319 {
320 PIMAGE_NT_HEADERS NtHeader;
321 KD_SYMBOLS_INFO SymbolInfo;
322
323 /* Setup the symbol data */
324 SymbolInfo.BaseOfDll = Base;
325 SymbolInfo.ProcessId = ProcessId;
326
327 /* Get NT Headers */
328 NtHeader = NULL; //RtlImageNtHeader(Base);
329 if (NtHeader)
330 {
331 /* Get the rest of the data */
332 SymbolInfo.CheckSum = NtHeader->OptionalHeader.CheckSum;
333 SymbolInfo.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
334 }
335 else
336 {
337 /* No data available */
338 SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
339 }
340
341 /* Load the symbols */
342 DebugService2(Name, &SymbolInfo, BREAKPOINT_LOAD_SYMBOLS);
343 return STATUS_SUCCESS;
344 }
345
346 /*
347 * @implemented
348 */
349 VOID
350 NTAPI
351 DbgUnLoadImageSymbols(IN PANSI_STRING Name,
352 IN PVOID Base,
353 IN ULONG_PTR ProcessId)
354 {
355 KD_SYMBOLS_INFO SymbolInfo;
356
357 /* Setup the symbol data */
358 SymbolInfo.BaseOfDll = Base;
359 SymbolInfo.ProcessId = ProcessId;
360 SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
361
362 /* Load the symbols */
363 DebugService2(Name, &SymbolInfo, BREAKPOINT_UNLOAD_SYMBOLS);
364 }
365
366 /* EOF */