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 ********************************************************/
22 DebugPrint(IN PANSI_STRING DebugString
,
26 /* Call the INT2D Service */
27 return DebugService(BREAKPOINT_PRINT
,
30 UlongToPtr(ComponentId
),
36 DebugPrint(IN PANSI_STRING DebugString
,
43 DebugPrompt(IN PCSTRING Output
,
46 /* Call the INT2D Service */
47 return DebugService(BREAKPOINT_PROMPT
,
51 UlongToPtr(Input
->MaximumLength
));
54 /* FUNCTIONS ****************************************************************/
58 vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix
,
63 IN BOOLEAN HandleBreakpoint
)
66 ANSI_STRING DebugString
;
68 PCHAR pBuffer
= Buffer
;
69 ULONG pBufferSize
= sizeof(Buffer
);
71 EXCEPTION_RECORD ExceptionRecord
;
73 /* Check if we should print it or not */
74 if (ComponentId
!= -1 && !NtQueryDebugFilterState(ComponentId
, Level
))
76 /* This message is masked */
77 return STATUS_SUCCESS
;
80 /* For user mode, don't recursively DbgPrint */
81 if (RtlpSetInDbgPrint(TRUE
)) return STATUS_SUCCESS
;
83 /* Initialize the length to 8 */
84 DebugString
.Length
= 0;
86 /* Handle the prefix */
87 if (Prefix
&& *Prefix
)
90 DebugString
.Length
= strlen(Prefix
);
93 if(DebugString
.Length
> sizeof(Buffer
))
95 DebugString
.Length
= sizeof(Buffer
);
99 strncpy(Buffer
, Prefix
, DebugString
.Length
);
101 /* Set the pointer and update the size */
102 pBuffer
= &Buffer
[DebugString
.Length
];
103 pBufferSize
-= DebugString
.Length
;
106 /* Setup the ANSI String */
107 DebugString
.Buffer
= Buffer
;
108 DebugString
.MaximumLength
= sizeof(Buffer
);
109 Length
= _vsnprintf(pBuffer
, pBufferSize
, Format
, ap
);
111 /* Check if we went past the buffer */
114 /* Terminate it if we went over-board */
115 Buffer
[sizeof(Buffer
) - 1] = '\n';
118 Length
= sizeof(Buffer
);
122 DebugString
.Length
+= Length
;
124 /* First, let the debugger know as well */
125 if (RtlpCheckForActiveDebugger(FALSE
))
127 /* Fill out an exception record */
128 ExceptionRecord
.ExceptionCode
= DBG_PRINTEXCEPTION_C
;
129 ExceptionRecord
.ExceptionRecord
= NULL
;
130 ExceptionRecord
.NumberParameters
= 2;
131 ExceptionRecord
.ExceptionFlags
= 0;
132 ExceptionRecord
.ExceptionInformation
[0] = DebugString
.Length
+ 1;
133 ExceptionRecord
.ExceptionInformation
[1] = (ULONG_PTR
)DebugString
.Buffer
;
135 /* Raise the exception */
136 RtlRaiseException(&ExceptionRecord
);
138 /* This code only runs in user-mode, so setting the flag is safe */
139 NtCurrentTeb()->InDbgPrint
= FALSE
;
140 return STATUS_SUCCESS
;
143 /* Call the Debug Print routine */
144 Status
= DebugPrint(&DebugString
, ComponentId
, Level
);
146 /* Check if this was with Control-C */
147 if (HandleBreakpoint
)
149 /* Check if we got a breakpoint */
150 if (Status
== STATUS_BREAKPOINT
)
153 DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C
);
154 Status
= STATUS_SUCCESS
;
158 /* In user-mode, remove the InDbgPrint Flag */
159 RtlpSetInDbgPrint(FALSE
);
170 vDbgPrintExWithPrefix(IN LPCSTR Prefix
,
171 IN ULONG ComponentId
,
176 /* Call the internal routine that also handles ControlC */
177 return vDbgPrintExWithPrefixInternal(Prefix
,
190 vDbgPrintEx(IN ULONG ComponentId
,
195 /* Call the internal routine that also handles ControlC */
196 return vDbgPrintExWithPrefixInternal(NULL
,
209 DbgPrint(PCCH Format
,
214 /* Call the internal routine that also handles ControlC */
215 va_start(ap
, Format
);
216 return vDbgPrintExWithPrefixInternal(NULL
,
230 DbgPrintEx(IN ULONG ComponentId
,
237 /* Call the internal routine that also handles ControlC */
238 va_start(ap
, Format
);
239 return vDbgPrintExWithPrefixInternal(NULL
,
253 DbgPrintReturnControlC(PCH Format
,
258 /* Call the internal routine that also handles ControlC */
259 va_start(ap
, Format
);
260 return vDbgPrintExWithPrefixInternal(NULL
,
273 DbgPrompt(IN PCCH Prompt
,
275 IN ULONG MaximumResponseLength
)
280 /* Setup the input string */
281 Input
.MaximumLength
= MaximumResponseLength
;
282 Input
.Buffer
= Response
;
284 /* Setup the output string */
285 Output
.Length
= strlen (Prompt
);
286 Output
.Buffer
= Prompt
;
288 /* Call the system service */
289 return DebugPrompt(&Output
, &Input
);
297 DbgQueryDebugFilterState(IN ULONG ComponentId
,
300 /* Call the Nt routine */
301 return NtQueryDebugFilterState(ComponentId
, Level
);
309 DbgSetDebugFilterState(IN ULONG ComponentId
,
313 /* Call the Nt routine */
314 return NtSetDebugFilterState(ComponentId
, Level
, State
);
322 DbgLoadImageSymbols(IN PANSI_STRING Name
,
326 PIMAGE_NT_HEADERS NtHeader
;
327 KD_SYMBOLS_INFO SymbolInfo
;
329 /* Setup the symbol data */
330 SymbolInfo
.BaseOfDll
= Base
;
331 SymbolInfo
.ProcessId
= UlongToPtr(ProcessId
);
334 NtHeader
= NULL
; //RtlImageNtHeader(Base);
337 /* Get the rest of the data */
338 SymbolInfo
.CheckSum
= NtHeader
->OptionalHeader
.CheckSum
;
339 SymbolInfo
.SizeOfImage
= NtHeader
->OptionalHeader
.SizeOfImage
;
343 /* No data available */
344 SymbolInfo
.CheckSum
= SymbolInfo
.SizeOfImage
= 0;
347 /* Load the symbols */
348 DebugService2(Name
, &SymbolInfo
, BREAKPOINT_LOAD_SYMBOLS
);
349 return STATUS_SUCCESS
;