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)
10 /* INCLUDES *****************************************************************/
17 /* PRIVATE FUNCTIONS ********************************************************/
21 DebugPrint(IN PANSI_STRING DebugString
,
25 /* Call the INT2D Service */
26 //return STATUS_SUCCESS;
27 return DebugService(BREAKPOINT_PRINT
,
30 UlongToPtr(ComponentId
),
36 DebugPrompt(IN PCSTRING Output
,
39 /* Call the INT2D Service */
40 return DebugService(BREAKPOINT_PROMPT
,
44 UlongToPtr(Input
->MaximumLength
));
47 /* FUNCTIONS ****************************************************************/
51 vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix
,
56 IN BOOLEAN HandleBreakpoint
)
59 ANSI_STRING DebugString
;
61 PCHAR pBuffer
= Buffer
;
62 ULONG pBufferSize
= sizeof(Buffer
);
64 EXCEPTION_RECORD ExceptionRecord
;
66 /* Check if we should print it or not */
67 if (ComponentId
!= -1 && !NtQueryDebugFilterState(ComponentId
, Level
))
69 /* This message is masked */
70 return STATUS_SUCCESS
;
73 /* For user mode, don't recursively DbgPrint */
74 if (RtlpSetInDbgPrint(TRUE
)) return STATUS_SUCCESS
;
76 /* Initialize the length to 8 */
77 DebugString
.Length
= 0;
79 /* Handle the prefix */
80 if (Prefix
&& *Prefix
)
83 DebugString
.Length
= strlen(Prefix
);
86 if(DebugString
.Length
> sizeof(Buffer
))
88 DebugString
.Length
= sizeof(Buffer
);
92 strncpy(Buffer
, Prefix
, DebugString
.Length
);
94 /* Set the pointer and update the size */
95 pBuffer
= &Buffer
[DebugString
.Length
];
96 pBufferSize
-= DebugString
.Length
;
99 /* Setup the ANSI String */
100 DebugString
.Buffer
= Buffer
;
101 DebugString
.MaximumLength
= sizeof(Buffer
);
102 Length
= _vsnprintf(pBuffer
, pBufferSize
, Format
, ap
);
104 /* Check if we went past the buffer */
107 /* Terminate it if we went over-board */
108 Buffer
[sizeof(Buffer
) - 1] = '\n';
111 Length
= sizeof(Buffer
);
115 DebugString
.Length
+= (USHORT
)Length
;
117 /* First, let the debugger know as well */
118 if (RtlpCheckForActiveDebugger(FALSE
))
120 /* Fill out an exception record */
121 ExceptionRecord
.ExceptionCode
= DBG_PRINTEXCEPTION_C
;
122 ExceptionRecord
.ExceptionRecord
= NULL
;
123 ExceptionRecord
.NumberParameters
= 2;
124 ExceptionRecord
.ExceptionFlags
= 0;
125 ExceptionRecord
.ExceptionInformation
[0] = DebugString
.Length
+ 1;
126 ExceptionRecord
.ExceptionInformation
[1] = (ULONG_PTR
)DebugString
.Buffer
;
128 /* Raise the exception */
129 RtlRaiseException(&ExceptionRecord
);
131 /* This code only runs in user-mode, so setting the flag is safe */
132 NtCurrentTeb()->InDbgPrint
= FALSE
;
133 return STATUS_SUCCESS
;
136 /* Call the Debug Print routine */
137 Status
= DebugPrint(&DebugString
, ComponentId
, Level
);
139 /* Check if this was with Control-C */
140 if (HandleBreakpoint
)
142 /* Check if we got a breakpoint */
143 if (Status
== STATUS_BREAKPOINT
)
146 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
147 Status
= STATUS_SUCCESS
;
151 /* In user-mode, remove the InDbgPrint Flag */
152 RtlpSetInDbgPrint(FALSE
);
163 vDbgPrintExWithPrefix(IN LPCSTR Prefix
,
164 IN ULONG ComponentId
,
169 /* Call the internal routine that also handles ControlC */
170 return vDbgPrintExWithPrefixInternal(Prefix
,
183 vDbgPrintEx(IN ULONG ComponentId
,
188 /* Call the internal routine that also handles ControlC */
189 return vDbgPrintExWithPrefixInternal(NULL
,
202 DbgPrint(PCCH Format
,
207 /* Call the internal routine that also handles ControlC */
208 va_start(ap
, Format
);
209 return vDbgPrintExWithPrefixInternal(NULL
,
223 DbgPrintEx(IN ULONG ComponentId
,
230 /* Call the internal routine that also handles ControlC */
231 va_start(ap
, Format
);
232 return vDbgPrintExWithPrefixInternal(NULL
,
246 DbgPrintReturnControlC(PCH Format
,
251 /* Call the internal routine that also handles ControlC */
252 va_start(ap
, Format
);
253 return vDbgPrintExWithPrefixInternal(NULL
,
266 DbgPrompt(IN PCCH Prompt
,
268 IN ULONG MaximumResponseLength
)
273 /* Setup the input string */
274 Input
.MaximumLength
= (USHORT
)MaximumResponseLength
;
275 Input
.Buffer
= Response
;
277 /* Setup the output string */
278 Output
.Length
= strlen(Prompt
);
279 Output
.Buffer
= Prompt
;
281 /* Call the system service */
282 return DebugPrompt(&Output
, &Input
);
290 DbgQueryDebugFilterState(IN ULONG ComponentId
,
293 /* Call the Nt routine */
294 return NtQueryDebugFilterState(ComponentId
, Level
);
302 DbgSetDebugFilterState(IN ULONG ComponentId
,
306 /* Call the Nt routine */
307 return NtSetDebugFilterState(ComponentId
, Level
, State
);
315 DbgLoadImageSymbols(IN PANSI_STRING Name
,
319 PIMAGE_NT_HEADERS NtHeader
;
320 KD_SYMBOLS_INFO SymbolInfo
;
322 /* Setup the symbol data */
323 SymbolInfo
.BaseOfDll
= Base
;
324 SymbolInfo
.ProcessId
= (ULONG
)ProcessId
;
327 NtHeader
= NULL
; //RtlImageNtHeader(Base);
330 /* Get the rest of the data */
331 SymbolInfo
.CheckSum
= NtHeader
->OptionalHeader
.CheckSum
;
332 SymbolInfo
.SizeOfImage
= NtHeader
->OptionalHeader
.SizeOfImage
;
336 /* No data available */
337 SymbolInfo
.CheckSum
= SymbolInfo
.SizeOfImage
= 0;
340 /* Load the symbols */
341 DebugService2(Name
, &SymbolInfo
, BREAKPOINT_LOAD_SYMBOLS
);
342 return STATUS_SUCCESS
;
350 DbgUnLoadImageSymbols(IN PANSI_STRING Name
,
352 IN ULONG_PTR ProcessId
)
354 KD_SYMBOLS_INFO SymbolInfo
;
356 /* Setup the symbol data */
357 SymbolInfo
.BaseOfDll
= Base
;
358 SymbolInfo
.ProcessId
= (ULONG
)ProcessId
;
359 SymbolInfo
.CheckSum
= SymbolInfo
.SizeOfImage
= 0;
361 /* Load the symbols */
362 DebugService2(Name
, &SymbolInfo
, BREAKPOINT_UNLOAD_SYMBOLS
);