reactos/ntoskrnl/kd64/kdprint.c
Art Yerkes c501d8112c Create a branch for network fixes.
svn path=/branches/aicom-network-fixes/; revision=34994
2008-08-01 11:32:26 +00:00

199 lines
5.4 KiB
C

/*
* 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)
*/
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
BOOLEAN
NTAPI
KdpPrintString(IN PSTRING Output)
{
STRING Data, Header;
DBGKD_DEBUG_IO DebugIo;
ULONG 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();
}
ULONG
NTAPI
KdpCommandString(IN ULONG Length,
IN LPSTR String,
IN KPROCESSOR_MODE PreviousMode,
IN PCONTEXT ContextRecord,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
/* FIXME */
return FALSE;
}
ULONG
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 0;
/* 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);
return 0;
}
ULONG
NTAPI
KdpPrompt(IN LPSTR InString,
IN ULONG InStringLength,
OUT LPSTR OutString,
IN ULONG OutStringLength,
IN KPROCESSOR_MODE PreviousMode,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
/* FIXME */
return FALSE;
}
ULONG
NTAPI
KdpPrint(IN ULONG ComponentId,
IN ULONG ComponentMask,
IN LPSTR String,
IN ULONG Length,
IN KPROCESSOR_MODE PreviousMode,
IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame,
OUT PBOOLEAN Status)
{
NTSTATUS ReturnValue;
BOOLEAN Entered;
ANSI_STRING AnsiString;
/* Assume failure */
*Status = FALSE;
/* Validate the mask */
if (ComponentMask <= 0x1F) 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 = (USHORT)Length;
/* Log the print */
//KdLogDbgPrint(&AnsiString);
/* Check for a debugger */
if (KdDebuggerNotPresent)
{
/* Fail */
*Status = TRUE;
return (ULONG)STATUS_DEVICE_NOT_CONNECTED;
}
/* Enter the debugger */
Entered = KdEnterDebugger(TrapFrame, ExceptionFrame);
/* Print the string */
if (KdpPrintString(&AnsiString))
{
/* User pressed CTRL-C, breakpoint on return */
ReturnValue = STATUS_BREAKPOINT;
}
else
{
/* String was printed */
ReturnValue = STATUS_SUCCESS;
}
/* Exit the debugger and return */
KdExitDebugger(Entered);
*Status = TRUE;
return ReturnValue;
}