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 DebugService(BREAKPOINT_PRINT
,
29 UlongToPtr(ComponentId
),
35 DebugPrompt(IN PCSTRING Output
,
38 /* Call the INT2D Service */
39 return DebugService(BREAKPOINT_PROMPT
,
43 UlongToPtr(Input
->MaximumLength
));
46 /* FUNCTIONS ****************************************************************/
50 vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix
,
55 IN BOOLEAN HandleBreakpoint
)
58 ANSI_STRING DebugString
;
60 PCHAR pBuffer
= Buffer
;
61 ULONG pBufferSize
= sizeof(Buffer
);
63 EXCEPTION_RECORD ExceptionRecord
;
65 /* Check if we should print it or not */
66 if (ComponentId
!= -1 && !NtQueryDebugFilterState(ComponentId
, Level
))
68 /* This message is masked */
69 return STATUS_SUCCESS
;
72 /* For user mode, don't recursively DbgPrint */
73 if (RtlpSetInDbgPrint(TRUE
)) return STATUS_SUCCESS
;
75 /* Initialize the length to 8 */
76 DebugString
.Length
= 0;
78 /* Handle the prefix */
79 if (Prefix
&& *Prefix
)
82 DebugString
.Length
= strlen(Prefix
);
85 if(DebugString
.Length
> sizeof(Buffer
))
87 DebugString
.Length
= sizeof(Buffer
);
91 strncpy(Buffer
, Prefix
, DebugString
.Length
);
93 /* Set the pointer and update the size */
94 pBuffer
= &Buffer
[DebugString
.Length
];
95 pBufferSize
-= DebugString
.Length
;
98 /* Setup the ANSI String */
99 DebugString
.Buffer
= Buffer
;
100 DebugString
.MaximumLength
= sizeof(Buffer
);
101 Length
= _vsnprintf(pBuffer
, pBufferSize
, Format
, ap
);
103 /* Check if we went past the buffer */
106 /* Terminate it if we went over-board */
107 Buffer
[sizeof(Buffer
) - 1] = '\n';
110 Length
= sizeof(Buffer
);
114 DebugString
.Length
+= (USHORT
)Length
;
116 /* First, let the debugger know as well */
117 if (RtlpCheckForActiveDebugger(FALSE
))
119 /* Fill out an exception record */
120 ExceptionRecord
.ExceptionCode
= DBG_PRINTEXCEPTION_C
;
121 ExceptionRecord
.ExceptionRecord
= NULL
;
122 ExceptionRecord
.NumberParameters
= 2;
123 ExceptionRecord
.ExceptionFlags
= 0;
124 ExceptionRecord
.ExceptionInformation
[0] = DebugString
.Length
+ 1;
125 ExceptionRecord
.ExceptionInformation
[1] = (ULONG_PTR
)DebugString
.Buffer
;
127 /* Raise the exception */
128 RtlRaiseException(&ExceptionRecord
);
130 /* This code only runs in user-mode, so setting the flag is safe */
131 NtCurrentTeb()->InDbgPrint
= FALSE
;
132 return STATUS_SUCCESS
;
135 /* Call the Debug Print routine */
136 Status
= DebugPrint(&DebugString
, ComponentId
, Level
);
138 /* Check if this was with Control-C */
139 if (HandleBreakpoint
)
141 /* Check if we got a breakpoint */
142 if (Status
== STATUS_BREAKPOINT
)
145 //DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
146 Status
= STATUS_SUCCESS
;
150 /* In user-mode, remove the InDbgPrint Flag */
151 RtlpSetInDbgPrint(FALSE
);
162 vDbgPrintExWithPrefix(IN LPCSTR Prefix
,
163 IN ULONG ComponentId
,
168 /* Call the internal routine that also handles ControlC */
169 return vDbgPrintExWithPrefixInternal(Prefix
,
182 vDbgPrintEx(IN ULONG ComponentId
,
187 /* Call the internal routine that also handles ControlC */
188 return vDbgPrintExWithPrefixInternal(NULL
,
201 DbgPrint(PCCH Format
,
206 /* Call the internal routine that also handles ControlC */
207 va_start(ap
, Format
);
208 return vDbgPrintExWithPrefixInternal(NULL
,
222 DbgPrintEx(IN ULONG ComponentId
,
229 /* Call the internal routine that also handles ControlC */
230 va_start(ap
, Format
);
231 return vDbgPrintExWithPrefixInternal(NULL
,
245 DbgPrintReturnControlC(PCH Format
,
250 /* Call the internal routine that also handles ControlC */
251 va_start(ap
, Format
);
252 return vDbgPrintExWithPrefixInternal(NULL
,
265 DbgPrompt(IN PCCH Prompt
,
267 IN ULONG MaximumResponseLength
)
272 /* Setup the input string */
273 Input
.MaximumLength
= (USHORT
)MaximumResponseLength
;
274 Input
.Buffer
= Response
;
276 /* Setup the output string */
277 Output
.Length
= strlen(Prompt
);
278 Output
.Buffer
= Prompt
;
280 /* Call the system service */
281 return DebugPrompt(&Output
, &Input
);
289 DbgQueryDebugFilterState(IN ULONG ComponentId
,
292 /* Call the Nt routine */
293 return NtQueryDebugFilterState(ComponentId
, Level
);
301 DbgSetDebugFilterState(IN ULONG ComponentId
,
305 /* Call the Nt routine */
306 return NtSetDebugFilterState(ComponentId
, Level
, State
);
314 DbgLoadImageSymbols(IN PANSI_STRING Name
,
318 PIMAGE_NT_HEADERS NtHeader
;
319 KD_SYMBOLS_INFO SymbolInfo
;
321 /* Setup the symbol data */
322 SymbolInfo
.BaseOfDll
= Base
;
323 SymbolInfo
.ProcessId
= (ULONG
)ProcessId
;
326 NtHeader
= RtlImageNtHeader(Base
);
329 /* Get the rest of the data */
330 SymbolInfo
.CheckSum
= NtHeader
->OptionalHeader
.CheckSum
;
331 SymbolInfo
.SizeOfImage
= NtHeader
->OptionalHeader
.SizeOfImage
;
335 /* No data available */
336 SymbolInfo
.CheckSum
= SymbolInfo
.SizeOfImage
= 0;
339 /* Load the symbols */
340 DebugService2(Name
, &SymbolInfo
, BREAKPOINT_LOAD_SYMBOLS
);
341 return STATUS_SUCCESS
;
349 DbgUnLoadImageSymbols(IN PANSI_STRING Name
,
351 IN ULONG_PTR ProcessId
)
353 KD_SYMBOLS_INFO SymbolInfo
;
355 /* Setup the symbol data */
356 SymbolInfo
.BaseOfDll
= Base
;
357 SymbolInfo
.ProcessId
= (ULONG
)ProcessId
;
358 SymbolInfo
.CheckSum
= SymbolInfo
.SizeOfImage
= 0;
360 /* Load the symbols */
361 DebugService2(Name
, &SymbolInfo
, BREAKPOINT_UNLOAD_SYMBOLS
);