Implement a virtualkd compatible kernel debugger transport DLL. I started this, because I didn't manage to get the original one working, but it turned out, the original one works, you only need to use the correct virtualkd version. Anyway, it's there now. A virtualkd version that works with VBox 4.3.16+ can be found here: http://forum.sysprogs.com/viewtopic.php?f=4&t=3370 or here: http://public.avast.com/~hnanicek/VirtualKd.zip
The folder is called kdvm, since I thought about adding support for VMWare as well, but here the original one probably works as well.
Also fix my email address in some files.

svn path=/trunk/; revision=65813
This commit is contained in:
Timo Kreuzer 2014-12-23 17:48:16 +00:00
parent a9305dd7bb
commit 69512e2d9b
14 changed files with 836 additions and 5 deletions

View file

@ -477,7 +477,13 @@ CreateFreeLoaderIniForReactos(
L"ReactOS_Debug", L"\"ReactOS (Debug)\"",
L"Windows2003", ArcPath,
L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
#ifdef _WINKD_
/* ReactOS_VBoxDebug */
CreateFreeLoaderEntry(IniCache, IniSection,
L"ReactOS_VBoxDebug", L"\"ReactOS (VBoxDebug)\"",
L"Windows2003", ArcPath,
L"/DEBUG /DEBUGPORT=VBOX /SOS");
#endif
#if DBG
#ifndef _WINKD_
/* ReactOS_KdSerial */

View file

@ -30,6 +30,7 @@ cdrom.sys=,,,,,,x,,,,,,4
class2.sys=,,,,,,x,,,,,,4
isapnp.sys=,,,,,,,,,,,,4
kdcom.dll=,,,,,,,,,,,,2
kdvbox.dll=,,,,,,,,,,,,2
disk.sys=,,,,,,x,,,,,,4
floppy.sys=,,,,,,x,,,,,,4
i8042prt.sys=,,,,,,,,,,,,4

View file

@ -8,6 +8,7 @@ if(_WINKD_)
add_subdirectory(kdgdb)
else()
add_subdirectory(kdcom)
add_subdirectory(kdvm)
endif()
else()
add_subdirectory(kdrosdbg)

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kdcom.c
* PURPOSE: COM port functions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kddll.h"

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kddll.c
* PURPOSE: Base functions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kddll.h"

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kddll.h
* PURPOSE: Base definitions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#ifndef _KDDLL_H_

View file

@ -3,7 +3,7 @@
* PROJECT: ReactOS kernel
* FILE: drivers/base/kddll/kdserial.c
* PURPOSE: Serial communication functions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@ewactos.org)
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kddll.h"

View file

@ -0,0 +1,15 @@
spec2def(kdvbox.dll kdvm.spec)
add_library(kdvbox SHARED
kdvm.c
kdvbox.c
kdvbox_asm.S
kdvm.rc
${CMAKE_CURRENT_BINARY_DIR}/kdvbox.def)
set_module_type(kdvbox module IMAGEBASE 0x00010000)
set_subsystem(kdvbox native)
add_importlibs(kdvbox ntoskrnl hal)
add_dependencies(kdvbox psdk bugcodes)
add_cd_file(TARGET kdvbox DESTINATION reactos/system32 NO_CAB FOR all)

View file

@ -0,0 +1,60 @@
/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/base/kdvm/kdvbox.c
* PURPOSE: VBOX data exchange function for kdvbox
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kdvm.h"
typedef struct
{
ULONG SendSize;
ULONG BufferSize;
} KDVBOX_SEND_HEADER, *PKDVBOX_SEND_HEADER;
typedef struct
{
ULONG ReceivedDataSize;
} KDVBOX_RECEIVE_HEADER, *PKDVBOX_RECEIVE_HEADER;
VOID
NTAPI
KdVmPrepareBuffer(VOID)
{
KdVmBufferPos = sizeof(KDVBOX_SEND_HEADER);
}
VOID
NTAPI
KdVmKdVmExchangeData(
_Out_ PVOID* ReceiveData,
_Out_ PULONG ReceiveDataSize)
{
PKDVBOX_SEND_HEADER SendHeader;
PKDVBOX_RECEIVE_HEADER ReceiveHeader;
/* Setup the send-header */
SendHeader = (PKDVBOX_SEND_HEADER)KdVmDataBuffer;
SendHeader->SendSize = KdVmBufferPos - sizeof(KDVBOX_SEND_HEADER);
SendHeader->BufferSize = KDVM_BUFFER_SIZE;
//KdpDbgPrint("Sending buffer:\n");
//KdVmDbgDumpBuffer(KdVmDataBuffer, KdVmBufferPos);
/* Do the data exchange */
KdVmExchange((ULONG_PTR)KdVmBufferPhysicalAddress.QuadPart, 0);
/* Reset the buffer position */
KdVmBufferPos = sizeof(KDVBOX_SEND_HEADER);
/* Get the receive-header and return information about the received data */
ReceiveHeader = (PKDVBOX_RECEIVE_HEADER)KdVmDataBuffer;
*ReceiveData = KdVmDataBuffer + sizeof(KDVBOX_RECEIVE_HEADER);
*ReceiveDataSize = ReceiveHeader->ReceivedDataSize;
//KdpDbgPrint("got data:\n");
//KdVmDbgDumpBuffer(KdVmDataBuffer, *ReceiveDataSize + sizeof(*ReceiveHeader));
}

View file

@ -0,0 +1,24 @@
#include <asm.inc>
.code
#ifdef _M_IX86
PUBLIC @KdVmExchange@8
FUNC @KdVmExchange@8
xchg eax, ecx
mov edx, HEX(5659)
out dx, eax
ret
ENDFUNC
#else
PUBLIC KdVmExchange
FUNC KdVmExchange
xchg rax, rcx
mov edx, HEX(5659)
out dx, rax
ret
ENDFUNC
#endif
END

View file

@ -0,0 +1,561 @@
/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/base/kdvm/kdvm.c
* PURPOSE: VM independent function for kdvbox/kd
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#include "kdvm.h"
static CHAR KdVmCmdMagic[] = "~kdVMvA ";
static CHAR KdVmReplyMagic[] = "++kdVMvA ";
static const UCHAR KDVM_CMD_TestConnection = 't';
static const UCHAR KDVM_CMD_ReceivePacket = 'r';
static const UCHAR KDVM_CMD_SendPacket = 's';
static const UCHAR KDVM_CMD_VersionReport = 'v';
UCHAR KdVmDataBuffer[KDVM_BUFFER_SIZE];
PHYSICAL_ADDRESS KdVmBufferPhysicalAddress;
ULONG KdVmBufferPos;
PFNDBGPRNT KdpDbgPrint;
/* PRIVATE FUNCTIONS **********************************************************/
static
VOID
KdVmDbgDumpRow(
_In_ PUCHAR Buffer,
_In_ ULONG Size)
{
ULONG i;
for (i = 0;i < Size; i++)
{
KdpDbgPrint("%02x ", Buffer[i]);
}
KdpDbgPrint("\n");
}
VOID
NTAPI
KdVmDbgDumpBuffer(
_In_ PVOID Buffer,
_In_ ULONG Size)
{
PUCHAR CurrentRow;
ULONG i;
CurrentRow = Buffer;
for (i = 0; i < (Size / 16); i++)
{
KdVmDbgDumpRow(CurrentRow, 16);
CurrentRow += 16;
}
KdVmDbgDumpRow(CurrentRow, (Size % 16));
}
static
BOOLEAN
KdVmAddToBuffer(
_In_ PVOID Data,
_In_ ULONG DataSize)
{
if (((KdVmBufferPos + DataSize) > KDVM_BUFFER_SIZE) ||
((KdVmBufferPos + DataSize) < KdVmBufferPos))
{
KDDBGPRINT("KdVmAddToBuffer: Buffer overflow! Need %lu, remaining: %lu\n",
DataSize, KDVM_BUFFER_SIZE - KdVmBufferPos);
return FALSE;
}
RtlCopyMemory(&KdVmDataBuffer[KdVmBufferPos], Data, DataSize);
KdVmBufferPos += DataSize;
return TRUE;
}
static
BOOLEAN
KdVmAddCommandToBuffer(
_In_ UCHAR Command,
_In_ PVOID Buffer,
_In_ SIZE_T BufferSize)
{
KDVM_CMD_HEADER Header;
RtlCopyMemory(&Header.Magic, KdVmCmdMagic, sizeof(Header.Magic));
Header.Command = Command;
if (!KdVmAddToBuffer(&Header, sizeof(Header)))
return FALSE;
if (!KdVmAddToBuffer(Buffer, BufferSize))
return FALSE;
return TRUE;
}
static
PVOID
KdVmSendReceive(
_Out_ PULONG ReceiveDataSize)
{
PVOID ReceiveData;
PKDVM_RECEIVE_HEADER ReceiveHeader;
KdVmKdVmExchangeData(&ReceiveData, ReceiveDataSize);
ReceiveHeader = ReceiveData;
if (*ReceiveDataSize < sizeof(*ReceiveHeader))
{
KDDBGPRINT("KdVmSendReceive: received data too small: 0x%x\n", *ReceiveDataSize);
*ReceiveDataSize = 0;
return NULL;
}
if (ReceiveHeader->Id != 0x2031 /* '01' */)
{
KDDBGPRINT("KdVmSendReceive: got invalid Id: 0x%x\n", ReceiveHeader->Id);
*ReceiveDataSize = 0;
return NULL;
}
if (RtlEqualMemory(ReceiveHeader->Magic, KdVmReplyMagic, 9))
{
KDDBGPRINT("KdVmSendReceive: got invalid Magic: '%*s'\n",
sizeof(KdVmReplyMagic), ReceiveHeader->Magic);
*ReceiveDataSize = 0;
return NULL;
}
*ReceiveDataSize -= sizeof(*ReceiveHeader);
return (PVOID)(ReceiveHeader + 1);
}
static
NTSTATUS
KdVmNegotiateProtocolVersions(VOID)
{
ULONG Version = KDRPC_PROTOCOL_VERSION;
ULONG ReceivedSize;
PULONG ReceivedVersion;
KDDBGPRINT("KdVmNegotiateProtocolVersions()\n");
/* Prepare the buffer */
KdVmPrepareBuffer();
if (!KdVmAddCommandToBuffer(KDVM_CMD_VersionReport, &Version, sizeof(Version)))
{
KDDBGPRINT("Failed to do VersionReport\n");
return STATUS_CONNECTION_REFUSED;
}
ReceivedVersion = KdVmSendReceive(&ReceivedSize);
if (ReceivedSize != sizeof(ULONG))
{
KDDBGPRINT("Invalid size for VersionReport: %lx\n", ReceivedSize);
return STATUS_CONNECTION_REFUSED;
}
if (*ReceivedVersion != KDRPC_PROTOCOL_VERSION)
{
KDDBGPRINT("Invalid Version: %lx\n", *ReceivedVersion);
return STATUS_CONNECTION_REFUSED; //STATUS_PROTOCOL_NOT_SUPPORTED;
}
return STATUS_SUCCESS;
}
static
BOOLEAN
TestConnectionOnChannel(VOID)
{
UCHAR TestBuffer[KDRPC_TEST_BUFFER_SIZE];
PUCHAR ReceivedBuffer;
ULONG i, ReceivedSize;
/* Prepare the buffer */
KdVmPrepareBuffer();
for (i = 0; i < sizeof(TestBuffer); i++)
TestBuffer[i] = (UCHAR)i;
if (!KdVmAddCommandToBuffer(KDVM_CMD_TestConnection, TestBuffer, sizeof(TestBuffer)))
{
KDDBGPRINT("Failed to do TestConnection\n");
return FALSE;
}
ReceivedBuffer = KdVmSendReceive(&ReceivedSize);
if (ReceivedSize != sizeof(TestBuffer))
{
KDDBGPRINT("Invalid size for TestConnection: %lx\n", ReceivedSize);
return FALSE;
}
for (i = 0; i < sizeof(TestBuffer); i++)
{
if (ReceivedBuffer[i] != (UCHAR)(i ^ 0x55))
{
KDDBGPRINT("Wrong test data @ %lx, expected %x, got %x\n",
i, (UCHAR)(i ^ 0x55), TestBuffer[i]);
return FALSE;
}
}
KDDBGPRINT("TestConnectionOnChannel: success\n");
return TRUE;
}
static
BOOLEAN
KdVmTestConnectionWithHost(VOID)
{
ULONG i, j;
KDDBGPRINT("KdVmTestConnectionWithHost()\n");
for (j = 0; j < 2; j++)
{
//VMWareRPC::OpenChannel
for (i = 0; i < CONNECTION_TEST_ROUNDS / 2; i++)
{
if (!TestConnectionOnChannel())
{
return FALSE;
}
}
}
return TRUE;
}
/* PUBLIC FUNCTIONS ***********************************************************/
NTSTATUS
NTAPI
KdD0Transition(VOID)
{
/* Nothing to do */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdD3Transition(VOID)
{
/* Nothing to do */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdSave(
_In_ BOOLEAN SleepTransition)
{
/* Nothing to do */
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
KdRestore(
_In_ BOOLEAN SleepTransition)
{
/* Nothing to do */
return STATUS_SUCCESS;
}
/******************************************************************************
* \name KdDebuggerInitialize0
* \brief Phase 0 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
*/
NTSTATUS
NTAPI
KdDebuggerInitialize0(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR CommandLine, PortString;
NTSTATUS Status;
/* Check if we have a LoaderBlock */
if (LoaderBlock != NULL)
{
/* HACK */
KdpDbgPrint = LoaderBlock->u.I386.CommonDataArea;
KDDBGPRINT("KdDebuggerInitialize0\n");
/* Get the Command Line */
CommandLine = LoaderBlock->LoadOptions;
/* Upcase it */
_strupr(CommandLine);
/* Check if we got the /DEBUGPORT parameter */
PortString = strstr(CommandLine, "DEBUGPORT");
if (PortString)
{
/* Move past the actual string, to reach the port*/
PortString += strlen("DEBUGPORT");
/* Now get past any spaces and skip the equal sign */
while (*PortString == ' ') PortString++;
PortString++;
/* Do we have a serial port? */
if (strncmp(PortString, "VBOX", 3) != 0)
{
KDDBGPRINT("Invalid debugport: '%s'\n", CommandLine);
return STATUS_INVALID_PARAMETER;
}
}
}
/* Get the physical address of the data buffer */
KdVmBufferPhysicalAddress = MmGetPhysicalAddress(KdVmDataBuffer);
KDDBGPRINT("KdVmBufferPhysicalAddress = %llx\n", KdVmBufferPhysicalAddress.QuadPart);
Status = KdVmNegotiateProtocolVersions();
if (!NT_SUCCESS(Status))
return Status;
if (!KdVmTestConnectionWithHost())
return STATUS_CONNECTION_REFUSED;
return STATUS_SUCCESS;
}
/******************************************************************************
* \name KdDebuggerInitialize1
* \brief Phase 1 initialization.
* \param [opt] LoaderBlock Pointer to the Loader parameter block. Can be NULL.
* \return Status
*/
NTSTATUS
NTAPI
KdDebuggerInitialize1(
_In_opt_ PLOADER_PARAMETER_BLOCK LoaderBlock)
{
/* Nothing to do */
KDDBGPRINT("KdDebuggerInitialize1()\n");
return STATUS_SUCCESS;
}
VOID
NTAPI
KdSendPacket(
_In_ ULONG PacketType,
_In_ PSTRING MessageHeader,
_In_ PSTRING MessageData,
_Inout_ PKD_CONTEXT KdContext)
{
KDVM_SEND_PKT_REQUEST SendPktRequest;
PKDVM_SEND_PKT_RESULT SendPktResult;
ULONG ReceivedSize;
KDDBGPRINT("KdSendPacket(0x%lx, ...)\n", PacketType);
do
{
RtlZeroMemory(&SendPktRequest, sizeof(SendPktRequest));
SendPktRequest.PacketType = PacketType;
SendPktRequest.Info.KdDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
SendPktRequest.Info.KdDebuggerEnabledAvailable = 1;
SendPktRequest.Info.KdDebuggerEnabled = SharedUserData->KdDebuggerEnabled;
if (MessageHeader != NULL)
{
SendPktRequest.MessageHeader.Length = MessageHeader->Length;
SendPktRequest.MessageHeader.MaximumLength = MessageHeader->MaximumLength;
SendPktRequest.HeaderSize = MessageHeader->Length;
}
if (MessageData != NULL)
{
SendPktRequest.MessageData.Length = MessageData->Length;
SendPktRequest.MessageData.MaximumLength = MessageData->MaximumLength;
SendPktRequest.DataSize = MessageData->Length;
}
if (KdContext != NULL)
{
RtlCopyMemory(&SendPktRequest.KdContext,
KdContext,
sizeof(SendPktRequest.KdContext));
}
/* Prepare the buffer */
KdVmPrepareBuffer();
if (!KdVmAddCommandToBuffer(KDVM_CMD_SendPacket, &SendPktRequest, sizeof(SendPktRequest)))
{
KDDBGPRINT("KdSendPacket: Failed to add SendPacket command\n");
return;
}
if (MessageHeader != NULL)
{
if (!KdVmAddToBuffer(MessageHeader->Buffer, MessageHeader->Length))
{
KDDBGPRINT("KdSendPacket: Failed to add MessageHeader\n");
return;
}
}
if (MessageData != NULL)
{
if (!KdVmAddToBuffer(MessageData->Buffer, MessageData->Length))
{
KDDBGPRINT("KdSendPacket: Failed to add MessageData\n");
return;
}
}
SendPktResult = KdVmSendReceive(&ReceivedSize);
if (ReceivedSize != sizeof(*SendPktResult))
{
KDDBGPRINT("KdSendPacket: Invalid size for SendPktResult: %lx\n", ReceivedSize);
return;
}
if (KdContext != NULL)
{
RtlCopyMemory(KdContext,
&SendPktResult->KdContext,
sizeof(SendPktResult->KdContext));
}
KD_DEBUGGER_NOT_PRESENT = SendPktResult->Info.KdDebuggerNotPresent;
if (SendPktResult->Info.KdDebuggerEnabledAvailable)
SharedUserData->KdDebuggerEnabled = SendPktResult->Info.KdDebuggerEnabled != 0;
if (SendPktResult->Info.RetryKdSendPacket)
{
KDDBGPRINT("KdSendPacket: RetryKdSendPacket!\n");
}
} while (SendPktResult->Info.RetryKdSendPacket);
KDDBGPRINT("KdSendPacket: Success!\n");
}
KDP_STATUS
NTAPI
KdReceivePacket(
_In_ ULONG PacketType,
_Out_ PSTRING MessageHeader,
_Out_ PSTRING MessageData,
_Out_ PULONG DataLength,
_Inout_opt_ PKD_CONTEXT KdContext)
{
KDVM_RECV_PKT_REQUEST RecvPktRequest;
PKDVM_RECV_PKT_RESULT RecvPktResult;
ULONG ReceivedSize, ExpectedSize;
PUCHAR Buffer;
KDDBGPRINT("KdReceivePacket(0x%lx, ...)\n", PacketType);
/* Prepare the buffer */
KdVmPrepareBuffer();
RtlZeroMemory(&RecvPktRequest, sizeof(RecvPktRequest));
RecvPktRequest.PacketType = PacketType;
RecvPktRequest.Info.KdDebuggerNotPresent = KD_DEBUGGER_NOT_PRESENT;
RecvPktRequest.Info.KdDebuggerEnabledAvailable = 1;
RecvPktRequest.Info.KdDebuggerEnabled = SharedUserData->KdDebuggerEnabled;
if (MessageHeader != NULL)
{
RecvPktRequest.MessageHeader.Length = MessageHeader->Length;
RecvPktRequest.MessageHeader.MaximumLength = MessageHeader->MaximumLength;
}
if (MessageData != NULL)
{
RecvPktRequest.MessageData.Length = MessageData->Length;
RecvPktRequest.MessageData.MaximumLength = MessageData->MaximumLength;
}
if (KdContext != NULL)
{
RtlCopyMemory(&RecvPktRequest.KdContext,
KdContext,
sizeof(RecvPktRequest.KdContext));
}
if (!KdVmAddCommandToBuffer(KDVM_CMD_ReceivePacket, &RecvPktRequest, sizeof(RecvPktRequest)))
{
KDDBGPRINT("KdReceivePacket: Failed to add SendPacket command\n");
return KDP_PACKET_RESEND;
}
RecvPktResult = KdVmSendReceive(&ReceivedSize);
if (ReceivedSize < sizeof(*RecvPktResult))
{
KDDBGPRINT("KdReceivePacket: Invalid size for RecvPktResult: %lx\n", ReceivedSize);
return KDP_PACKET_RESEND;
}
ExpectedSize = sizeof(*RecvPktResult) +
RecvPktResult->HeaderSize +
RecvPktResult->DataSize;
if (ReceivedSize != ExpectedSize)
{
KDDBGPRINT("KdReceivePacket: Invalid size for RecvPktResult: %lu, expected %lu\n",
ReceivedSize, ExpectedSize);
return KDP_PACKET_RESEND;
}
if (KdContext != NULL)
{
RtlCopyMemory(KdContext,
&RecvPktResult->KdContext,
sizeof(RecvPktResult->KdContext));
}
Buffer = (PUCHAR)(RecvPktResult + 1);
if (MessageHeader != NULL)
{
MessageHeader->Length = RecvPktResult->MessageHeader.Length;
if ((MessageHeader->Buffer != NULL) &&
(MessageHeader->MaximumLength >= RecvPktResult->HeaderSize))
{
RtlCopyMemory(MessageHeader->Buffer,
Buffer,
RecvPktResult->HeaderSize);
}
else
{
KDDBGPRINT("MessageHeader not good\n");
}
}
Buffer += RecvPktResult->HeaderSize;
if (MessageData != NULL)
{
MessageData->Length = RecvPktResult->MessageData.Length;
if ((MessageData->Buffer != NULL) &&
(MessageData->MaximumLength >= RecvPktResult->DataSize))
{
RtlCopyMemory(MessageData->Buffer,
Buffer,
RecvPktResult->DataSize);
}
else
{
KDDBGPRINT("MessageData not good\n");
}
}
if (DataLength != NULL)
*DataLength = RecvPktResult->FullSize;
KDDBGPRINT("KdReceivePacket: returning status %u\n", RecvPktResult->KdStatus);
return RecvPktResult->KdStatus;
}

View file

@ -0,0 +1,150 @@
/*
* COPYRIGHT: GPL, see COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/base/kdvm/kdvm.h
* PURPOSE: Base definitions for the kernel debugger.
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#ifndef _KDDLL_H_
#define _KDDLL_H_
#define NOEXTAPI
#include <ntifs.h>
#include <windbgkd.h>
#include <arc/arc.h>
#undef RtlEqualMemory
#define RtlEqualMemory(a, b, c) (RtlCompareMemory(a, b, c) != c)
//#define KDDEBUG /* uncomment to enable debugging this dll */
typedef ULONG (*PFNDBGPRNT)(const char *Format, ...);
extern PFNDBGPRNT KdpDbgPrint;
#ifndef KDDEBUG
#define KDDBGPRINT(...)
#else
#define KDDBGPRINT KdpDbgPrint
#endif
#define KDRPC_PROTOCOL_VERSION 0x101
#define CONNECTION_TEST_ROUNDS 2 /*100*/
#define KDVM_BUFFER_SIZE (131072 + 1024)
#define KDRPC_TEST_BUFFER_SIZE 512
extern UCHAR KdVmDataBuffer[KDVM_BUFFER_SIZE];
extern PHYSICAL_ADDRESS KdVmBufferPhysicalAddress;
extern ULONG KdVmBufferPos;
typedef enum
{
KDP_PACKET_RECEIVED = 0,
KDP_PACKET_TIMEOUT = 1,
KDP_PACKET_RESEND = 2
} KDP_STATUS;
typedef struct _KDVM_MARSHAL_STRING
{
USHORT Length;
USHORT MaximumLength;
} KDVM_MARSHAL_STRING;
#pragma pack(push,1)
typedef struct
{
CHAR Magic[8];
UCHAR Command;
} KDVM_CMD_HEADER;
typedef struct
{
USHORT Id;
CHAR Magic[9];
} KDVM_RECEIVE_HEADER, *PKDVM_RECEIVE_HEADER;
typedef struct _KDVM_CONTEXT
{
ULONG RetryCount;
BOOLEAN BreakInRequested;
UCHAR align;
} KDVM_CONTEXT, *PKDVM_CONTEXT;
typedef struct
{
struct
{
UCHAR KdDebuggerNotPresent : 1;
UCHAR RetryKdSendPacket : 1;
UCHAR KdDebuggerEnabledAvailable : 1;
};
BOOLEAN KdDebuggerEnabled;
USHORT Unused;
} KDVM_SENDPACKET_INFO;
typedef struct _KDVM_SEND_PKT_REQUEST
{
KDVM_MARSHAL_STRING MessageHeader;
KDVM_MARSHAL_STRING MessageData;
KDVM_CONTEXT KdContext;
ULONG PacketType;
ULONG HeaderSize;
ULONG DataSize;
KDVM_SENDPACKET_INFO Info;
} KDVM_SEND_PKT_REQUEST, *PKDVM_SEND_PKT_REQUEST;
typedef struct _KDVM_SEND_PKT_RESULT
{
UCHAR CommandType;
KDVM_CONTEXT KdContext;
KDVM_SENDPACKET_INFO Info;
} KDVM_SEND_PKT_RESULT, *PKDVM_SEND_PKT_RESULT;
typedef struct
{
ULONG PacketType;
KDVM_SENDPACKET_INFO Info;
KDVM_MARSHAL_STRING MessageHeader;
KDVM_MARSHAL_STRING MessageData;
KDVM_CONTEXT KdContext;
} KDVM_RECV_PKT_REQUEST;
typedef struct
{
UCHAR CommandType;
KDVM_MARSHAL_STRING MessageHeader;
KDVM_MARSHAL_STRING MessageData;
KDVM_CONTEXT KdContext;
KDP_STATUS KdStatus;
ULONG FullSize;
ULONG HeaderSize;
ULONG DataSize;
KDVM_SENDPACKET_INFO Info;
} KDVM_RECV_PKT_RESULT, *PKDVM_RECV_PKT_RESULT;
#pragma pack(pop)
VOID
NTAPI
KdVmDbgDumpBuffer(
_In_ PVOID Buffer,
_In_ ULONG Size);
VOID
FASTCALL
KdVmExchange(
_In_ ULONG_PTR PhysicalAddress,
_In_ SIZE_T BufferSize);
VOID
NTAPI
KdVmPrepareBuffer(
VOID);
VOID
NTAPI
KdVmKdVmExchangeData(
_Out_ PVOID* ReceiveData,
_Out_ PULONG ReceiveDataSize);
#endif /* _KDDLL_H_ */

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Kernel Debugger COM Extension DLL"
#define REACTOS_STR_INTERNAL_NAME "kdcom"
#define REACTOS_STR_ORIGINAL_FILENAME "kdcom.dll"
#include <reactos/version.rc>

View file

@ -0,0 +1,8 @@
@ stdcall KdD0Transition()
@ stdcall KdD3Transition()
@ stdcall KdDebuggerInitialize0(ptr)
@ stdcall KdDebuggerInitialize1(ptr)
@ stdcall KdReceivePacket(long ptr ptr ptr ptr)
@ stdcall KdRestore(long)
@ stdcall KdSave(long)
@ stdcall KdSendPacket(long ptr ptr ptr)