"<@Christoph_vW> please commit something" -- aye sir
[reactos.git] / reactos / ntoskrnl / kd64 / kdprint.c
index 2f35592..135b1ed 100644 (file)
-/*\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 response 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);
+}