/* FUNCTIONS *****************************************************************/
+#ifdef _WINKD_
+
BOOLEAN
NTAPI
-KdpPrintString(IN PSTRING Output)
+KdpPrintString(
+ _In_ PSTRING Output)
{
STRING Data, Header;
DBGKD_DEBUG_IO DebugIo;
- USHORT Length = Output->Length;
+ USHORT Length;
/* Copy the string */
- RtlMoveMemory(KdpMessageBuffer, Output->Buffer, Length);
+ KdpMoveMemory(KdpMessageBuffer,
+ Output->Buffer,
+ Output->Length);
/* Make sure we don't exceed the KD Packet size */
+ Length = Output->Length;
if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
{
/* Normalize length */
BOOLEAN
NTAPI
-KdpPromptString(IN PSTRING PromptString,
- IN PSTRING ResponseString)
+KdpPromptString(
+ _In_ PSTRING PromptString,
+ _In_ PSTRING ResponseString)
{
STRING Data, Header;
DBGKD_DEBUG_IO DebugIo;
- ULONG Length = PromptString->Length;
+ ULONG Length;
KDSTATUS Status;
/* Copy the string to the message buffer */
- RtlCopyMemory(KdpMessageBuffer,
+ KdpMoveMemory(KdpMessageBuffer,
PromptString->Buffer,
PromptString->Length);
/* Make sure we don't exceed the KD Packet size */
+ Length = PromptString->Length;
if ((sizeof(DBGKD_DEBUG_IO) + Length) > PACKET_MAX_SIZE)
{
/* Normalize length */
Header.Buffer = (PCHAR)&DebugIo;
/* Build the data */
- Data.Length = PromptString->Length;
+ Data.Length = Length;
Data.Buffer = KdpMessageBuffer;
/* Send the packet */
} while (Status != KdPacketReceived);
/* Don't copy back a larger response than there is room for */
- Length = min(Length, ResponseString->MaximumLength);
+ Length = min(Length,
+ ResponseString->MaximumLength);
/* Copy back the string and return the length */
- RtlCopyMemory(ResponseString->Buffer, KdpMessageBuffer, Length);
+ KdpMoveMemory(ResponseString->Buffer,
+ KdpMessageBuffer,
+ Length);
ResponseString->Length = (USHORT)Length;
/* Success; we don't need to resend */
/* Save the CPU Control State and save the context */
KiSaveProcessorControlState(&Prcb->ProcessorState);
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ KdpMoveMemory(&Prcb->ProcessorState.ContextFrame,
ContextRecord,
sizeof(CONTEXT));
&Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */
- RtlCopyMemory(ContextRecord,
+ KdpMoveMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
/* Save the CPU Control State and save the context */
KiSaveProcessorControlState(&Prcb->ProcessorState);
- RtlCopyMemory(&Prcb->ProcessorState.ContextFrame,
+ KdpMoveMemory(&Prcb->ProcessorState.ContextFrame,
ContextRecord,
sizeof(CONTEXT));
&Prcb->ProcessorState.ContextFrame);
/* Restore the processor state */
- RtlCopyMemory(ContextRecord,
+ KdpMoveMemory(ContextRecord,
&Prcb->ProcessorState.ContextFrame,
sizeof(CONTEXT));
KiRestoreProcessorControlState(&Prcb->ProcessorState);
KdExitDebugger(Enable);
}
+#else
+
+extern
+BOOLEAN
+NTAPI
+KdpPrintString(
+ _In_ PSTRING Output);
+
+extern
+BOOLEAN
+NTAPI
+KdpPromptString(
+ _In_ PSTRING PromptString,
+ _In_ PSTRING ResponseString);
+
+#endif // _WINKD_
+
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)
+KdpPrompt(
+ _In_reads_bytes_(PromptLength) PCHAR PromptString,
+ _In_ USHORT PromptLength,
+ _Out_writes_bytes_(MaximumResponseLength) PCHAR ResponseString,
+ _In_ USHORT MaximumResponseLength,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _In_ PKTRAP_FRAME TrapFrame,
+ _In_ PKEXCEPTION_FRAME ExceptionFrame)
{
STRING PromptBuffer, ResponseBuffer;
BOOLEAN Enable, Resend;
+ PCHAR SafeResponseString;
+ CHAR CapturedPrompt[512];
+ CHAR SafeResponseBuffer[512];
/* Normalize the lengths */
- PromptLength = min(PromptLength, 512);
- MaximumResponseLength = min(MaximumResponseLength, 512);
+ PromptLength = min(PromptLength,
+ sizeof(CapturedPrompt));
+ MaximumResponseLength = min(MaximumResponseLength,
+ sizeof(SafeResponseBuffer));
/* Check if we need to verify the string */
if (PreviousMode != KernelMode)
{
- /* FIXME: Handle user-mode */
+ /* Handle user-mode buffers safely */
+ _SEH2_TRY
+ {
+ /* Probe and capture the prompt */
+ ProbeForRead(PromptString, PromptLength, 1);
+ KdpMoveMemory(CapturedPrompt, PromptString, PromptLength);
+ PromptString = CapturedPrompt;
+
+ /* Probe and make room for the response */
+ ProbeForWrite(ResponseString, MaximumResponseLength, 1);
+ SafeResponseString = SafeResponseBuffer;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Bad string pointer, bail out */
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END;
+ }
+ else
+ {
+ SafeResponseString = ResponseString;
}
- /* Setup the prompt and response buffers */
+ /* Setup the prompt and response buffers */
PromptBuffer.Buffer = PromptString;
- PromptBuffer.Length = PromptLength;
- ResponseBuffer.Buffer = ResponseString;
+ PromptBuffer.Length = PromptBuffer.MaximumLength = PromptLength;
+ ResponseBuffer.Buffer = SafeResponseString;
ResponseBuffer.Length = 0;
ResponseBuffer.MaximumLength = MaximumResponseLength;
/* Exit the debugger */
KdExitDebugger(Enable);
+ /* Copy back the response if required */
+ if (PreviousMode != KernelMode)
+ {
+ _SEH2_TRY
+ {
+ /* Safely copy back the response to user mode */
+ KdpMoveMemory(ResponseString,
+ ResponseBuffer.Buffer,
+ ResponseBuffer.Length);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* String became invalid after we exited, fail */
+ _SEH2_YIELD(return 0);
+ }
+ _SEH2_END;
+ }
+
/* Return the number of characters received */
return ResponseBuffer.Length;
}
NTSTATUS
NTAPI
-KdpPrint(IN ULONG ComponentId,
- IN ULONG Level,
- IN LPSTR String,
- IN USHORT Length,
- IN KPROCESSOR_MODE PreviousMode,
- IN PKTRAP_FRAME TrapFrame,
- IN PKEXCEPTION_FRAME ExceptionFrame,
- OUT PBOOLEAN Handled)
+KdpPrint(
+ _In_ ULONG ComponentId,
+ _In_ ULONG Level,
+ _In_reads_bytes_(Length) PCHAR String,
+ _In_ USHORT Length,
+ _In_ KPROCESSOR_MODE PreviousMode,
+ _In_ PKTRAP_FRAME TrapFrame,
+ _In_ PKEXCEPTION_FRAME ExceptionFrame,
+ _Out_ PBOOLEAN Handled)
{
- NTSTATUS ReturnStatus;
+ NTSTATUS Status;
BOOLEAN Enable;
STRING OutputString;
+ CHAR CapturedString[512];
- /* Assume failure */
- *Handled = FALSE;
-
- /* Validate the mask */
- if (Level < 32) Level = 1 << Level;
- if (!(Kd_WIN2000_Mask & Level) ||
- ((ComponentId < KdComponentTableSize) &&
- !(*KdComponentTable[ComponentId] & Level)))
+ if (NtQueryDebugFilterState(ComponentId, Level) == (NTSTATUS)FALSE)
{
/* Mask validation failed */
*Handled = TRUE;
return STATUS_SUCCESS;
}
+ /* Assume failure */
+ *Handled = FALSE;
+
/* Normalize the length */
- Length = min(Length, 512);
+ Length = min(Length, sizeof(CapturedString));
- /* Check if we need to verify the buffer */
+ /* Check if we need to verify the string */
if (PreviousMode != KernelMode)
{
- /* FIXME: Support user-mode */
+ /* Capture user-mode buffers */
+ _SEH2_TRY
+ {
+ /* Probe and capture the string */
+ ProbeForRead(String, Length, 1);
+ KdpMoveMemory(CapturedString, String, Length);
+ String = CapturedString;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ /* Bad string pointer, bail out */
+ _SEH2_YIELD(return STATUS_ACCESS_VIOLATION);
+ }
+ _SEH2_END;
}
/* Setup the output string */
OutputString.Buffer = String;
- OutputString.Length = Length;
+ OutputString.Length = OutputString.MaximumLength = Length;
/* Log the print */
//KdLogDbgPrint(&OutputString);
if (KdpPrintString(&OutputString))
{
/* User pressed CTRL-C, breakpoint on return */
- ReturnStatus = STATUS_BREAKPOINT;
+ Status = STATUS_BREAKPOINT;
}
else
{
/* String was printed */
- ReturnStatus = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
}
/* Exit the debugger and return */
KdExitDebugger(Enable);
*Handled = TRUE;
- return ReturnStatus;
+ return Status;
}
VOID
__cdecl
-KdpDprintf(IN PCHAR Format,
- ...)
+KdpDprintf(
+ _In_ PCHAR Format,
+ ...)
{
STRING String;
- CHAR Buffer[100];
USHORT Length;
va_list ap;
+ CHAR Buffer[100];
/* Format the string */
va_start(ap, Format);
sizeof(Buffer),
Format,
ap);
+ va_end(ap);
/* Set it up */
String.Buffer = Buffer;
- String.Length = Length + 1;
+ String.Length = String.MaximumLength = Length;
/* Send it to the debugger directly */
KdpPrintString(&String);
- va_end(ap);
}