-/*\r
- * COPYRIGHT: See COPYING in the top level directory\r
- * PROJECT: ReactOS Run-Time Library\r
- * FILE: ntoskrnl/rtl/dbgprint.c\r
- * PURPOSE: Debug Print and Prompt routines\r
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)\r
- * Royce Mitchel III\r
- */\r
-\r
-/* INCLUDES *****************************************************************/\r
-\r
-#include <rtl.h>\r
-\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* PRIVATE FUNCTIONS ********************************************************/\r
-\r
-#if 0\r
-NTSTATUS\r
-NTAPI\r
-DebugPrint(IN PANSI_STRING DebugString,\r
- IN ULONG ComponentId,\r
- IN ULONG Level)\r
-{\r
- /* Call the INT2D Service */\r
- return DebugService(BREAKPOINT_PRINT,\r
- DebugString->Buffer,\r
- DebugString->Length,\r
- UlongToPtr(ComponentId),\r
- UlongToPtr(Level)); \r
-}\r
-#else\r
-NTSTATUS\r
-NTAPI\r
-DebugPrint(IN PANSI_STRING DebugString,\r
- IN ULONG ComponentId,\r
- IN ULONG Level);\r
-#endif\r
-\r
-NTSTATUS\r
-NTAPI\r
-DebugPrompt(IN PANSI_STRING Output,\r
- IN PANSI_STRING Input)\r
-{\r
- /* Call the INT2D Service */\r
- return DebugService(BREAKPOINT_PROMPT,\r
- Output->Buffer,\r
- Output->Length,\r
- Input->Buffer,\r
- UlongToPtr(Input->MaximumLength));\r
-}\r
-\r
-/* FUNCTIONS ****************************************************************/\r
-\r
-ULONG\r
-NTAPI\r
-vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix,\r
- IN ULONG ComponentId,\r
- IN ULONG Level,\r
- IN LPCSTR Format,\r
- IN va_list ap,\r
- IN BOOLEAN HandleBreakpoint)\r
-{\r
- NTSTATUS Status;\r
- ANSI_STRING DebugString;\r
- CHAR Buffer[512];\r
- PCHAR pBuffer = Buffer;\r
- ULONG pBufferSize = sizeof(Buffer);\r
- ULONG Length;\r
- EXCEPTION_RECORD ExceptionRecord;\r
-\r
- /* Check if we should print it or not */\r
- if (ComponentId != -1 && !NtQueryDebugFilterState(ComponentId, Level))\r
- {\r
- /* This message is masked */\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- /* For user mode, don't recursively DbgPrint */\r
- if (RtlpSetInDbgPrint(TRUE)) return STATUS_SUCCESS;\r
-\r
- /* Initialize the length to 8 */\r
- DebugString.Length = 0;\r
-\r
- /* Handle the prefix */\r
- if (Prefix && *Prefix)\r
- {\r
- /* Get the length */\r
- DebugString.Length = strlen(Prefix);\r
-\r
- /* Normalize it */\r
- if(DebugString.Length > sizeof(Buffer))\r
- {\r
- DebugString.Length = sizeof(Buffer);\r
- }\r
-\r
- /* Copy it */\r
- strncpy(Buffer, Prefix, DebugString.Length);\r
-\r
- /* Set the pointer and update the size */\r
- pBuffer = &Buffer[DebugString.Length];\r
- pBufferSize -= DebugString.Length;\r
- }\r
-\r
- /* Setup the ANSI String */\r
- DebugString.Buffer = Buffer;\r
- DebugString.MaximumLength = sizeof(Buffer);\r
- Length = _vsnprintf(pBuffer, pBufferSize, Format, ap);\r
-\r
- /* Check if we went past the buffer */\r
- if (Length == -1)\r
- {\r
- /* Terminate it if we went over-board */\r
- Buffer[sizeof(Buffer) - 1] = '\n';\r
-\r
- /* Put maximum */\r
- Length = sizeof(Buffer);\r
- }\r
-\r
- /* Update length */\r
- DebugString.Length += Length;\r
-\r
- /* First, let the debugger know as well */\r
- if (RtlpCheckForActiveDebugger(FALSE))\r
- {\r
- /* Fill out an exception record */\r
- ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;\r
- ExceptionRecord.ExceptionRecord = NULL;\r
- ExceptionRecord.NumberParameters = 2;\r
- ExceptionRecord.ExceptionFlags = 0;\r
- ExceptionRecord.ExceptionInformation[0] = DebugString.Length + 1;\r
- ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)DebugString.Buffer;\r
-\r
- /* Raise the exception */\r
- RtlRaiseException(&ExceptionRecord);\r
-\r
- /* This code only runs in user-mode, so setting the flag is safe */\r
- NtCurrentTeb()->InDbgPrint = FALSE;\r
- return STATUS_SUCCESS;\r
- }\r
-\r
- /* Call the Debug Print routine */\r
- Status = DebugPrint(&DebugString, ComponentId, Level);\r
-\r
- /* Check if this was with Control-C */\r
- if (HandleBreakpoint)\r
- {\r
- /* Check if we got a breakpoint */\r
- if (Status == STATUS_BREAKPOINT)\r
- {\r
- /* Breakpoint */\r
- DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);\r
- Status = STATUS_SUCCESS;\r
- }\r
- }\r
-\r
- /* In user-mode, remove the InDbgPrint Flag */\r
- RtlpSetInDbgPrint(FALSE);\r
-\r
- /* Return */\r
- return Status;\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-NTAPI\r
-vDbgPrintExWithPrefix(IN LPCSTR Prefix,\r
- IN ULONG ComponentId,\r
- IN ULONG Level,\r
- IN LPCSTR Format,\r
- IN va_list ap)\r
-{\r
- /* Call the internal routine that also handles ControlC */\r
- return vDbgPrintExWithPrefixInternal(Prefix,\r
- ComponentId,\r
- Level,\r
- Format,\r
- ap,\r
- TRUE);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-NTAPI\r
-vDbgPrintEx(IN ULONG ComponentId,\r
- IN ULONG Level,\r
- IN LPCSTR Format,\r
- IN va_list ap)\r
-{\r
- /* Call the internal routine that also handles ControlC */\r
- return vDbgPrintExWithPrefixInternal(NULL,\r
- ComponentId,\r
- Level,\r
- Format,\r
- ap,\r
- TRUE);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-__cdecl\r
-DbgPrint(PCCH Format,\r
- ...)\r
-{\r
- va_list ap;\r
-\r
- /* Call the internal routine that also handles ControlC */\r
- va_start(ap, Format);\r
- return vDbgPrintExWithPrefixInternal(NULL,\r
- -1,\r
- DPFLTR_ERROR_LEVEL,\r
- Format,\r
- ap,\r
- TRUE);\r
- va_end(ap);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-__cdecl\r
-DbgPrintEx(IN ULONG ComponentId,\r
- IN ULONG Level,\r
- IN PCCH Format,\r
- ...)\r
-{\r
- va_list ap;\r
-\r
- /* Call the internal routine that also handles ControlC */\r
- va_start(ap, Format);\r
- return vDbgPrintExWithPrefixInternal(NULL,\r
- ComponentId,\r
- Level,\r
- Format,\r
- ap,\r
- TRUE);\r
- va_end(ap);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-__cdecl\r
-DbgPrintReturnControlC(PCH Format,\r
- ...)\r
-{\r
- va_list ap;\r
-\r
- /* Call the internal routine that also handles ControlC */\r
- va_start(ap, Format);\r
- return vDbgPrintExWithPrefixInternal(NULL,\r
- -1,\r
- DPFLTR_ERROR_LEVEL,\r
- Format,\r
- ap,\r
- FALSE);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-ULONG\r
-NTAPI\r
-DbgPrompt(PCH OutputString,\r
- PCH InputString,\r
- ULONG InputSize)\r
-{\r
- ANSI_STRING Output;\r
- ANSI_STRING Input;\r
-\r
- /* Setup the input string */\r
- Input.MaximumLength = InputSize;\r
- Input.Buffer = InputString;\r
-\r
- /* Setup the output string */\r
- Output.Length = strlen (OutputString);\r
- Output.Buffer = OutputString;\r
-\r
- /* Call the system service */\r
- return DebugPrompt(&Output, &Input);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-BOOLEAN\r
-NTAPI\r
-DbgQueryDebugFilterState(IN ULONG ComponentId,\r
- IN ULONG Level)\r
-{\r
- /* Call the Nt routine */\r
- return NtQueryDebugFilterState(ComponentId, Level);\r
-}\r
-\r
-/*\r
- * @implemented\r
- */\r
-NTSTATUS\r
-NTAPI\r
-DbgSetDebugFilterState(IN ULONG ComponentId,\r
- IN ULONG Level,\r
- IN BOOLEAN State)\r
-{\r
- /* Call the Nt routine */\r
- return NtSetDebugFilterState(ComponentId, Level, State);\r
-}\r
-\r
-/*\r
- * @unimplemented\r
- */\r
-NTSTATUS\r
-NTAPI\r
-DbgLoadImageSymbols(IN PUNICODE_STRING Name,\r
- IN ULONG Base,\r
- IN ULONG Unknown3)\r
-{\r
- UNIMPLEMENTED;\r
- return STATUS_NOT_IMPLEMENTED;\r
-}\r
-/* EOF */\r
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Run-Time Library
+ * FILE: lib/rtl/debug.c
+ * PURPOSE: Debug Print and Prompt routines
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
+ * Royce Mitchel III
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <rtl.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* PRIVATE FUNCTIONS ********************************************************/
+
+NTSTATUS
+NTAPI
+DebugPrint(IN PANSI_STRING DebugString,
+ IN ULONG ComponentId,
+ IN ULONG Level)
+{
+ /* Call the INT2D Service */
+ return DebugService(BREAKPOINT_PRINT,
+ DebugString->Buffer,
+ DebugString->Length,
+ UlongToPtr(ComponentId),
+ UlongToPtr(Level));
+}
+
+NTSTATUS
+NTAPI
+DebugPrompt(IN PCSTRING Output,
+ IN PSTRING Input)
+{
+ /* Call the INT2D Service */
+ return DebugService(BREAKPOINT_PROMPT,
+ Output->Buffer,
+ Output->Length,
+ Input->Buffer,
+ UlongToPtr(Input->MaximumLength));
+}
+
+/* FUNCTIONS ****************************************************************/
+
+ULONG
+NTAPI
+vDbgPrintExWithPrefixInternal(IN LPCSTR Prefix,
+ IN ULONG ComponentId,
+ IN ULONG Level,
+ IN LPCSTR Format,
+ IN va_list ap,
+ IN BOOLEAN HandleBreakpoint)
+{
+ NTSTATUS Status;
+ ANSI_STRING DebugString;
+ CHAR Buffer[512];
+ ULONG Length, PrefixLength;
+ EXCEPTION_RECORD ExceptionRecord;
+
+ /* Check if we should print it or not */
+ if ((ComponentId != -1U) &&
+ !(NtQueryDebugFilterState(ComponentId, Level)))
+ {
+ /* This message is masked */
+ return STATUS_SUCCESS;
+ }
+
+ /* For user mode, don't recursively DbgPrint */
+ if (RtlpSetInDbgPrint(TRUE)) return STATUS_SUCCESS;
+
+ /* Guard against incorrect pointers */
+ _SEH2_TRY
+ {
+ /* Get the length and normalize it */
+ PrefixLength = strlen(Prefix);
+ if (PrefixLength > sizeof(Buffer)) PrefixLength = sizeof(Buffer);
+
+ /* Copy it */
+ strncpy(Buffer, Prefix, PrefixLength);
+
+ /* Do the printf */
+ Length = _vsnprintf(Buffer + PrefixLength,
+ sizeof(Buffer) - PrefixLength,
+ Format,
+ ap);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Fail */
+ Length = PrefixLength = 0;
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ /* Check if we went past the buffer */
+ if (Length == -1U)
+ {
+ /* Terminate it if we went over-board */
+ Buffer[sizeof(Buffer) - 1] = '\n';
+
+ /* Put maximum */
+ Length = sizeof(Buffer);
+ }
+ else
+ {
+ /* Add the prefix */
+ Length += PrefixLength;
+ }
+
+ /* Build the string */
+ DebugString.Length = Length;
+ DebugString.Buffer = Buffer;
+
+ /* First, let the debugger know as well */
+ if (RtlpCheckForActiveDebugger(FALSE))
+ {
+ /* Fill out an exception record */
+ ExceptionRecord.ExceptionCode = DBG_PRINTEXCEPTION_C;
+ ExceptionRecord.ExceptionRecord = NULL;
+ ExceptionRecord.NumberParameters = 2;
+ ExceptionRecord.ExceptionFlags = 0;
+ ExceptionRecord.ExceptionInformation[0] = DebugString.Length + 1;
+ ExceptionRecord.ExceptionInformation[1] = (ULONG_PTR)DebugString.Buffer;
+
+ /* Raise the exception */
+ RtlRaiseException(&ExceptionRecord);
+
+ /* This code only runs in user-mode, so setting the flag is safe */
+ NtCurrentTeb()->InDbgPrint = FALSE;
+ return STATUS_SUCCESS;
+ }
+
+ /* Call the Debug Print routine */
+ Status = DebugPrint(&DebugString, ComponentId, Level);
+
+ /* Check if this was with Control-C */
+ if (HandleBreakpoint)
+ {
+ /* Check if we got a breakpoint */
+ if (Status == STATUS_BREAKPOINT)
+ {
+ /* Breakpoint */
+ //DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
+ Status = STATUS_SUCCESS;
+ }
+ }
+
+ /* In user-mode, remove the InDbgPrint Flag */
+ RtlpSetInDbgPrint(FALSE);
+
+ /* Return */
+ return Status;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+vDbgPrintExWithPrefix(IN LPCSTR Prefix,
+ IN ULONG ComponentId,
+ IN ULONG Level,
+ IN LPCSTR Format,
+ IN va_list ap)
+{
+ /* Call the internal routine that also handles ControlC */
+ return vDbgPrintExWithPrefixInternal(Prefix,
+ ComponentId,
+ Level,
+ Format,
+ ap,
+ TRUE);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+vDbgPrintEx(IN ULONG ComponentId,
+ IN ULONG Level,
+ IN LPCSTR Format,
+ IN va_list ap)
+{
+ /* Call the internal routine that also handles ControlC */
+ return vDbgPrintExWithPrefixInternal("",
+ ComponentId,
+ Level,
+ Format,
+ ap,
+ TRUE);
+}
+
+/*
+ * @implemented
+ */
+ULONG
+__cdecl
+DbgPrint(PCCH Format,
+ ...)
+{
+ ULONG n;
+ va_list ap;
+
+ /* Call the internal routine that also handles ControlC */
+ va_start(ap, Format);
+ n = vDbgPrintExWithPrefixInternal("",
+ -1,
+ DPFLTR_ERROR_LEVEL,
+ Format,
+ ap,
+ TRUE);
+ va_end(ap);
+ return n;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+__cdecl
+DbgPrintEx(IN ULONG ComponentId,
+ IN ULONG Level,
+ IN PCCH Format,
+ ...)
+{
+ ULONG n;
+ va_list ap;
+
+ /* Call the internal routine that also handles ControlC */
+ va_start(ap, Format);
+ n = vDbgPrintExWithPrefixInternal("",
+ ComponentId,
+ Level,
+ Format,
+ ap,
+ TRUE);
+ va_end(ap);
+ return n;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+__cdecl
+DbgPrintReturnControlC(PCH Format,
+ ...)
+{
+ ULONG n;
+ va_list ap;
+
+ /* Call the internal routine that also handles ControlC */
+ va_start(ap, Format);
+ n = vDbgPrintExWithPrefixInternal("",
+ -1,
+ DPFLTR_ERROR_LEVEL,
+ Format,
+ ap,
+ FALSE);
+ va_end(ap);
+ return n;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+DbgPrompt(IN PCCH Prompt,
+ OUT PCH Response,
+ IN ULONG MaximumResponseLength)
+{
+ CSTRING Output;
+ STRING Input;
+
+ /* Setup the input string */
+ Input.MaximumLength = (USHORT)MaximumResponseLength;
+ Input.Buffer = Response;
+
+ /* Setup the output string */
+ Output.Length = strlen(Prompt);
+ Output.Buffer = Prompt;
+
+ /* Call the system service */
+ return DebugPrompt(&Output, &Input);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+DbgQueryDebugFilterState(IN ULONG ComponentId,
+ IN ULONG Level)
+{
+ /* Call the Nt routine */
+ return NtQueryDebugFilterState(ComponentId, Level);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+DbgSetDebugFilterState(IN ULONG ComponentId,
+ IN ULONG Level,
+ IN BOOLEAN State)
+{
+ /* Call the Nt routine */
+ return NtSetDebugFilterState(ComponentId, Level, State);
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+DbgLoadImageSymbols(IN PANSI_STRING Name,
+ IN PVOID Base,
+ IN ULONG_PTR ProcessId)
+{
+ PIMAGE_NT_HEADERS NtHeader;
+ KD_SYMBOLS_INFO SymbolInfo;
+
+ /* Setup the symbol data */
+ SymbolInfo.BaseOfDll = Base;
+ SymbolInfo.ProcessId = (ULONG)ProcessId;
+
+ /* Get NT Headers */
+ NtHeader = RtlImageNtHeader(Base);
+ if (NtHeader)
+ {
+ /* Get the rest of the data */
+ SymbolInfo.CheckSum = NtHeader->OptionalHeader.CheckSum;
+ SymbolInfo.SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
+ }
+ else
+ {
+ /* No data available */
+ SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
+ }
+
+ /* Load the symbols */
+ DebugService2(Name, &SymbolInfo, BREAKPOINT_LOAD_SYMBOLS);
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+DbgUnLoadImageSymbols(IN PANSI_STRING Name,
+ IN PVOID Base,
+ IN ULONG_PTR ProcessId)
+{
+ KD_SYMBOLS_INFO SymbolInfo;
+
+ /* Setup the symbol data */
+ SymbolInfo.BaseOfDll = Base;
+ SymbolInfo.ProcessId = (ULONG)ProcessId;
+ SymbolInfo.CheckSum = SymbolInfo.SizeOfImage = 0;
+
+ /* Load the symbols */
+ DebugService2(Name, &SymbolInfo, BREAKPOINT_UNLOAD_SYMBOLS);
+}