-/*\r
- * PROJECT: ReactOS Kernel\r
- * LICENSE: GPL - See COPYING in the top level directory\r
- * FILE: ntoskrnl/kd64/kdprint.c\r
- * PURPOSE: KD64 Trap Handler Routines\r
- * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)\r
- */\r
-\r
-/* INCLUDES ******************************************************************/\r
-\r
-#include <ntoskrnl.h>\r
-#define NDEBUG\r
-#include <debug.h>\r
-\r
-/* FUNCTIONS *****************************************************************/\r
-\r
-BOOLEAN\r
-NTAPI\r
-KdpPrintString(IN PSTRING Output)\r
-{\r
- STRING Data, Header;\r
- DBGKD_DEBUG_IO DebugIo;\r
- ULONG Length = Output->Length;\r
-\r
- /* Copy the string */\r
- RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);\r
-\r
- /* Make sure we don't exceed the KD Packet size */\r
- if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)\r
- {\r
- /* Normalize length */\r
- Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);\r
- }\r
-\r
- /* Build the packet header */\r
- DebugIo.ApiNumber = DbgKdPrintStringApi;\r
- DebugIo.ProcessorLevel = KeProcessorLevel;\r
- DebugIo.Processor = KeGetCurrentPrcb()->Number;\r
- DebugIo.u.PrintString.LengthOfString = Length;\r
- Header.Length = sizeof(DBGKD_DEBUG_IO);\r
- Header.Buffer = (PCHAR)&DebugIo;\r
-\r
- /* Build the data */\r
- Data.Length = Length;\r
- Data.Buffer = KdpMessageBuffer;\r
-\r
- /* Send the packet */\r
- KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);\r
-\r
- /* Check if the user pressed CTRL+C */\r
- return KdpPollBreakInWithPortLock();\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-KdpCommandString(IN ULONG Length,\r
- IN LPSTR String,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN PCONTEXT ContextRecord,\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame)\r
-{\r
- /* FIXME */\r
- return FALSE;\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-KdpSymbol(IN PSTRING DllPath,\r
- IN PKD_SYMBOLS_INFO DllBase,\r
- IN BOOLEAN Unload,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN PCONTEXT ContextRecord,\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame)\r
-{\r
- BOOLEAN Entered;\r
- PKPRCB Prcb = KeGetCurrentPrcb();\r
- ULONG Status;\r
-\r
- /* Check if we need to do anything */\r
- if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return 0;\r
-\r
- /* Enter the debugger */\r
- Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
-\r
- /* Save the CPU Control State and save the context */\r
- KiSaveProcessorControlState(&Prcb->ProcessorState);\r
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,\r
- ContextRecord,\r
- sizeof(CONTEXT));\r
-\r
- /* Report the new state */\r
- Status = KdpReportLoadSymbolsStateChange(DllPath,\r
- DllBase,\r
- Unload,\r
- &Prcb->ProcessorState.\r
- ContextFrame);\r
-\r
- /* Now restore the processor state, manually again. */\r
- RtlCopyMemory(ContextRecord,\r
- &Prcb->ProcessorState.ContextFrame,\r
- sizeof(CONTEXT));\r
- //KiRestoreProcessorControlState(&Prcb->ProcessorState);\r
-\r
- /* Exit the debugger and clear the CTRL-C state */\r
- KdExitDebugger(Entered);\r
- return 0;\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-KdpPrompt(IN LPSTR InString,\r
- IN ULONG InStringLength,\r
- OUT LPSTR OutString,\r
- IN ULONG OutStringLength,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame)\r
-{\r
- /* FIXME */\r
- return FALSE;\r
-}\r
-\r
-ULONG\r
-NTAPI\r
-KdpPrint(IN ULONG ComponentId,\r
- IN ULONG ComponentMask,\r
- IN LPSTR String,\r
- IN ULONG Length,\r
- IN KPROCESSOR_MODE PreviousMode,\r
- IN PKTRAP_FRAME TrapFrame,\r
- IN PKEXCEPTION_FRAME ExceptionFrame,\r
- OUT PBOOLEAN Status)\r
-{\r
- NTSTATUS ReturnValue;\r
- BOOLEAN Entered;\r
- ANSI_STRING AnsiString;\r
-\r
- /* Assume failure */\r
- *Status = FALSE;\r
-\r
- /* Validate the mask */\r
- if (ComponentMask <= 0x1F) ComponentMask = 1 << ComponentMask;\r
- if (!(Kd_WIN2000_Mask & ComponentMask) ||\r
- ((ComponentId < KdComponentTableSize) &&\r
- !(*KdComponentTable[ComponentId] & ComponentMask)))\r
- {\r
- /* Mask validation failed */\r
- *Status = TRUE;\r
- return FALSE;\r
- }\r
-\r
- /* Normalize the length */\r
- Length = min(Length, 512);\r
-\r
- /* Check if we need to verify the buffer */\r
- if (PreviousMode != KernelMode)\r
- {\r
- /* FIXME: Support user-mode */\r
- }\r
-\r
- /* Setup the ANSI string */\r
- AnsiString.Buffer = String;\r
- AnsiString.Length = (USHORT)Length;\r
-\r
- /* Log the print */\r
- //KdLogDbgPrint(&AnsiString);\r
-\r
- /* Check for a debugger */\r
- if (KdDebuggerNotPresent)\r
- {\r
- /* Fail */\r
- *Status = TRUE;\r
- return (ULONG)STATUS_DEVICE_NOT_CONNECTED;\r
- }\r
-\r
- /* Enter the debugger */\r
- Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);\r
-\r
- /* Print the string */\r
- if (KdpPrintString(&AnsiString))\r
- {\r
- /* User pressed CTRL-C, breakpoint on return */\r
- ReturnValue = STATUS_BREAKPOINT;\r
- }\r
- else\r
- {\r
- /* String was printed */\r
- ReturnValue = STATUS_SUCCESS;\r
- }\r
-\r
- /* Exit the debugger and return */\r
- KdExitDebugger(Entered);\r
- *Status = TRUE;\r
- return ReturnValue;\r
-}\r
-\r
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/kd64/kdprint.c
+ * PURPOSE: KD64 Trap Handler Routines
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
+ * Stefan Ginsberg (stefan.ginsberg@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+BOOLEAN
+NTAPI
+KdpPrintString(IN PSTRING Output)
+{
+ STRING Data, Header;
+ DBGKD_DEBUG_IO DebugIo;
+ USHORT Length = Output->Length;
+
+ /* Copy the string */
+ RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);
+
+ /* Make sure we don't exceed the KD Packet size */
+ if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
+ {
+ /* Normalize length */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
+ }
+
+ /* Build the packet header */
+ DebugIo.ApiNumber = DbgKdPrintStringApi;
+ DebugIo.ProcessorLevel = KeProcessorLevel;
+ DebugIo.Processor = KeGetCurrentPrcb()->Number;
+ DebugIo.u.PrintString.LengthOfString = Length;
+ Header.Length = sizeof(DBGKD_DEBUG_IO);
+ Header.Buffer = (PCHAR)&DebugIo;
+
+ /* Build the data */
+ Data.Length = Length;
+ Data.Buffer = KdpMessageBuffer;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);
+
+ /* Check if the user pressed CTRL+C */
+ return KdpPollBreakInWithPortLock();
+}
+
+BOOLEAN
+NTAPI
+KdpPromptString(IN PSTRING PromptString,
+ IN PSTRING ResponseString)
+{
+ STRING Data, Header;
+ DBGKD_DEBUG_IO DebugIo;
+ ULONG Length = PromptString->Length;
+ KDSTATUS Status;
+
+ /* Copy the string to the message buffer */
+ RtlCopyMemory(KdpMessageBuffer,
+ PromptString->Buffer,
+ PromptString->Length);
+
+ /* Make sure we don't exceed the KD Packet size */
+ if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
+ {
+ /* Normalize length */
+ Length = PACKET_MAX_SIZE - sizeof(DBGKD_DEBUG_IO);
+ }
+
+ /* Build the packet header */
+ DebugIo.ApiNumber = DbgKdGetStringApi;
+ DebugIo.ProcessorLevel = KeProcessorLevel;
+ DebugIo.Processor = KeGetCurrentPrcb()->Number;
+ DebugIo.u.GetString.LengthOfPromptString = Length;
+ DebugIo.u.GetString.LengthOfStringRead = ResponseString->MaximumLength;
+ Header.Length = sizeof(DBGKD_DEBUG_IO);
+ Header.Buffer = (PCHAR)&DebugIo;
+
+ /* Build the data */
+ Data.Length = PromptString->Length;
+ Data.Buffer = KdpMessageBuffer;
+
+ /* Send the packet */
+ KdSendPacket(PACKET_TYPE_KD_DEBUG_IO, &Header, &Data, &KdpContext);
+
+ /* Set the maximum lengths for the receive */
+ Header.MaximumLength = sizeof(DBGKD_DEBUG_IO);
+ Data.MaximumLength = sizeof(KdpMessageBuffer);
+
+ /* Enter receive loop */
+ do
+ {
+ /* Get our reply */
+ Status = KdReceivePacket(PACKET_TYPE_KD_DEBUG_IO,
+ &Header,
+ &Data,
+ &Length,
+ &KdpContext);
+
+ /* Return TRUE if we need to resend */
+ if (Status == KdPacketNeedsResend) return TRUE;
+
+ /* Loop until we succeed */
+ } while (Status != KdPacketReceived);
+
+ /* Don't copy back a larger respone than there is room for */
+ Length = min(Length, ResponseString->MaximumLength);
+
+ /* Copy back the string and return the length */
+ RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length);
+ ResponseString->Length = Length;
+
+ /* Success; we don't need to resend */
+ return FALSE;
+}
+
+VOID
+NTAPI
+KdpCommandString(IN ULONG Length,
+ IN LPSTR String,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PCONTEXT ContextRecord,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ /* FIXME */
+ KdpDprintf("KdpCommandString called\n");
+ while (TRUE);
+}
+
+VOID
+NTAPI
+KdpSymbol(IN PSTRING DllPath,
+ IN PKD_SYMBOLS_INFO DllBase,
+ IN BOOLEAN Unload,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PCONTEXT ContextRecord,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ BOOLEAN Entered;
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ ULONG Status;
+
+ /* Check if we need to do anything */
+ if ((PreviousMode != KernelMode) || (KdDebuggerNotPresent)) return;
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Save the CPU Control State and save the context */
+ KiSaveProcessorControlState(&Prcb->ProcessorState);
+ RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ ContextRecord,
+ sizeof(CONTEXT));
+
+ /* Report the new state */
+ Status = KdpReportLoadSymbolsStateChange(DllPath,
+ DllBase,
+ Unload,
+ &Prcb->ProcessorState.
+ ContextFrame);
+
+ /* Now restore the processor state, manually again. */
+ RtlCopyMemory(ContextRecord,
+ &Prcb->ProcessorState.ContextFrame,
+ sizeof(CONTEXT));
+ KiRestoreProcessorControlState(&Prcb->ProcessorState);
+
+ /* Exit the debugger and clear the CTRL-C state */
+ KdExitDebugger(Entered);
+}
+
+USHORT
+NTAPI
+KdpPrompt(IN LPSTR PromptString,
+ IN USHORT PromptLength,
+ OUT LPSTR ResponseString,
+ IN USHORT MaximumResponseLength,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame)
+{
+ STRING PromptBuffer, ResponseBuffer;
+ BOOLEAN Entered, Resend;
+
+ /* Normalize the lengths */
+ PromptLength = min(PromptLength, 512);
+ MaximumResponseLength = min(MaximumResponseLength, 512);
+
+ /* Check if we need to verify the string */
+ if (PreviousMode != KernelMode)
+ {
+ /* FIXME: Handle user-mode */
+ }
+
+ /* Setup the prompt and response buffers */
+ PromptBuffer.Buffer = PromptString;
+ PromptBuffer.Length = PromptLength;
+ ResponseBuffer.Buffer = ResponseString;
+ ResponseBuffer.Length = 0;
+ ResponseBuffer.MaximumLength = MaximumResponseLength;
+
+ /* Log the print */
+ //KdLogDbgPrint(&PromptBuffer);
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Enter prompt loop */
+ do
+ {
+ /* Send the prompt and receive the response */
+ Resend = KdpPromptString(&PromptBuffer, &ResponseBuffer);
+
+ /* Loop while we need to resend */
+ } while (Resend);
+
+ /* Exit the debugger */
+ KdExitDebugger(Entered);
+
+ /* Return the number of characters received */
+ return ResponseBuffer.Length;
+}
+
+NTSTATUS
+NTAPI
+KdpPrint(IN ULONG ComponentId,
+ IN ULONG ComponentMask,
+ IN LPSTR String,
+ IN USHORT Length,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ OUT PBOOLEAN Status)
+{
+ NTSTATUS ReturnStatus;
+ BOOLEAN Entered;
+ ANSI_STRING AnsiString;
+
+ /* Assume failure */
+ *Status = FALSE;
+
+ /* Validate the mask */
+ if (ComponentMask < 0x20) ComponentMask = 1 << ComponentMask;
+ if (!(Kd_WIN2000_Mask & ComponentMask) ||
+ ((ComponentId < KdComponentTableSize) &&
+ !(*KdComponentTable[ComponentId] & ComponentMask)))
+ {
+ /* Mask validation failed */
+ *Status = TRUE;
+ return FALSE;
+ }
+
+ /* Normalize the length */
+ Length = min(Length, 512);
+
+ /* Check if we need to verify the buffer */
+ if (PreviousMode != KernelMode)
+ {
+ /* FIXME: Support user-mode */
+ }
+
+ /* Setup the ANSI string */
+ AnsiString.Buffer = String;
+ AnsiString.Length = Length;
+
+ /* Log the print */
+ //KdLogDbgPrint(&AnsiString);
+
+ /* Check for a debugger */
+ if (KdDebuggerNotPresent)
+ {
+ /* Fail */
+ *Status = TRUE;
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ /* Enter the debugger */
+ Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
+
+ /* Print the string */
+ if (KdpPrintString(&AnsiString))
+ {
+ /* User pressed CTRL-C, breakpoint on return */
+ ReturnStatus = STATUS_BREAKPOINT;
+ }
+ else
+ {
+ /* String was printed */
+ ReturnStatus = STATUS_SUCCESS;
+ }
+
+ /* Exit the debugger and return */
+ KdExitDebugger(Entered);
+ *Status = TRUE;
+ return ReturnStatus;
+}
+
+VOID
+__cdecl
+KdpDprintf(IN PCHAR Format,
+ ...)
+{
+ STRING String;
+ CHAR Buffer[100];
+ USHORT Length;
+ va_list ap;
+
+ /* Format the string */
+ va_start(ap, Format);
+ Length = (USHORT)_vsnprintf(Buffer,
+ sizeof(Buffer),
+ Format,
+ ap);
+
+ /* Set it up */
+ String.Buffer = Buffer;
+ String.Length = Length + 1;
+
+ /* Send it to the debugger directly */
+ KdpPrintString(&String);
+ va_end(ap);
+}