mirror of
https://github.com/reactos/reactos.git
synced 2025-03-01 03:45:16 +00:00
[DRIVERS] Add kdnet.dll
This is still very incomplete.
This commit is contained in:
parent
c1c8f59eab
commit
db271c2228
5 changed files with 601 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
add_subdirectory(beep)
|
||||
add_subdirectory(bootvid)
|
||||
add_subdirectory(condrv)
|
||||
add_subdirectory(kdnet)
|
||||
add_subdirectory(kdstub)
|
||||
|
||||
if(_WINKD_)
|
||||
|
|
16
drivers/base/kdnet/CMakeLists.txt
Normal file
16
drivers/base/kdnet/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
spec2def(kdnet.dll kdnet.spec ADD_IMPORTLIB)
|
||||
|
||||
list(APPEND SOURCE
|
||||
kdnet.c
|
||||
)
|
||||
|
||||
add_library(kdnet MODULE
|
||||
${SOURCE}
|
||||
kdnet.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/kdnet.def)
|
||||
|
||||
set_module_type(kdnet kerneldll ENTRYPOINT 0)
|
||||
set_subsystem(kdnet native)
|
||||
add_importlibs(kdnet ntoskrnl hal kdstub)
|
||||
add_dependencies(kdnet psdk bugcodes)
|
||||
add_cd_file(TARGET kdnet DESTINATION reactos/system32 NO_CAB FOR all)
|
570
drivers/base/kdnet/kdnet.c
Normal file
570
drivers/base/kdnet/kdnet.c
Normal file
|
@ -0,0 +1,570 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
|
||||
* PURPOSE: Base functions for the kernel network debugger
|
||||
* COPYRIGHT: Copyright 2009-2016 Timo Kreuzer <timo.kreuzer@reactos.org>
|
||||
* Copyright 2022 Hervé Poussineau <hpoussin@reactos.org>
|
||||
*/
|
||||
|
||||
#define NOEXTAPI
|
||||
#include <ntifs.h>
|
||||
#include <windbgkd.h>
|
||||
#include <arc/arc.h>
|
||||
#include <kddll.h>
|
||||
#include <kdnetextensibility.h>
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
ULONG CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
||||
ULONG RemotePacketId = INITIAL_PACKET_ID;
|
||||
PKDNET_EXTENSIBILITY_EXPORTS KdNetExtensibilityExports = NULL;
|
||||
|
||||
/******************************************************************************
|
||||
* \name KdpCalculateChecksum
|
||||
* \brief Calculates the checksum for the packet data.
|
||||
* \param Buffer Pointer to the packet data.
|
||||
* \param Length Length of data in bytes.
|
||||
* \return The calculated checksum.
|
||||
* \sa http://www.vista-xp.co.uk/forums/technical-reference-library/2540-basics-debugging.html
|
||||
*/
|
||||
ULONG
|
||||
NTAPI
|
||||
KdpCalculateChecksum(
|
||||
IN PVOID Buffer,
|
||||
IN ULONG Length)
|
||||
{
|
||||
PUCHAR ByteBuffer = Buffer;
|
||||
ULONG Checksum = 0;
|
||||
|
||||
while (Length-- > 0)
|
||||
{
|
||||
Checksum += (ULONG)*ByteBuffer++;
|
||||
}
|
||||
return Checksum;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdpSendControlPacket(
|
||||
IN USHORT PacketType,
|
||||
IN ULONG PacketId OPTIONAL)
|
||||
{
|
||||
PKD_PACKET Packet;
|
||||
NTSTATUS Status;
|
||||
ULONG TxHandle;
|
||||
|
||||
Status = KdGetTxPacket(NULL, &TxHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return;
|
||||
Packet = KdGetPacketAddress(NULL, TxHandle);
|
||||
if (!Packet)
|
||||
return;
|
||||
ASSERT(KdGetPacketLength(NULL, TxHandle) >= sizeof(KD_PACKET));
|
||||
|
||||
Packet->PacketLeader = CONTROL_PACKET_LEADER;
|
||||
Packet->PacketId = PacketId;
|
||||
Packet->ByteCount = 0;
|
||||
Packet->Checksum = 0;
|
||||
Packet->PacketType = PacketType;
|
||||
|
||||
KdSendTxPacket(NULL, TxHandle, sizeof(KD_PACKET));
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* \name KdpReceivePacketLeader
|
||||
* \brief Receives a packet leader from the KD port.
|
||||
* \param PacketLeader Pointer to an ULONG that receives the packet leader.
|
||||
* \return KdPacketReceived if successful.
|
||||
* KdPacketTimedOut if the receive timed out.
|
||||
* KdPacketNeedsResend if a breakin byte was detected.
|
||||
*/
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdpReceivePacketLeader(
|
||||
OUT PULONG PacketLeader,
|
||||
IN PUCHAR *pRxPacket,
|
||||
IN PULONG pRxLength)
|
||||
{
|
||||
UCHAR Index = 0, Byte, Buffer[4];
|
||||
|
||||
/* Set first character to 0 */
|
||||
Buffer[0] = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (*pRxLength == 0)
|
||||
{
|
||||
/* End of RX packet. Check if we already got a breakin byte */
|
||||
if (Buffer[0] == BREAKIN_PACKET_BYTE)
|
||||
return KdPacketNeedsResend;
|
||||
|
||||
/* Report timeout */
|
||||
return KdPacketTimedOut;
|
||||
}
|
||||
|
||||
/* Receive a single byte */
|
||||
Byte = **pRxPacket;
|
||||
++(*pRxPacket);
|
||||
--(*pRxLength);
|
||||
|
||||
/* Check if this is a valid packet leader byte */
|
||||
if (Byte == PACKET_LEADER_BYTE ||
|
||||
Byte == CONTROL_PACKET_LEADER_BYTE)
|
||||
{
|
||||
/* Check if we match the first byte */
|
||||
if (Byte != Buffer[0])
|
||||
{
|
||||
/* No, this is the new byte 0! */
|
||||
Index = 0;
|
||||
}
|
||||
|
||||
/* Store the byte in the buffer */
|
||||
Buffer[Index] = Byte;
|
||||
|
||||
/* Continue with next byte */
|
||||
Index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for breakin byte */
|
||||
if (Byte == BREAKIN_PACKET_BYTE)
|
||||
{
|
||||
Index = 0;
|
||||
Buffer[0] = Byte;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Restart */
|
||||
Index = 0;
|
||||
Buffer[0] = 0;
|
||||
}
|
||||
while (Index < 4);
|
||||
|
||||
/* Return the received packet leader */
|
||||
*PacketLeader = *(PULONG)Buffer;
|
||||
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* \name KdpReceiveBuffer
|
||||
* \brief Receives data from the KD port and fills a buffer.
|
||||
* \param Buffer Pointer to a buffer that receives the data.
|
||||
* \param Size Size of data to receive in bytes.
|
||||
* \return KdPacketReceived if successful.
|
||||
* KdPacketTimedOut if the receive timed out.
|
||||
*/
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdpReceiveBuffer(
|
||||
OUT PVOID Buffer,
|
||||
IN ULONG Size,
|
||||
IN PUCHAR *pRxPacket,
|
||||
IN PULONG pRxLength)
|
||||
{
|
||||
if (*pRxLength < Size)
|
||||
{
|
||||
*pRxLength = 0;
|
||||
return KdPacketTimedOut;
|
||||
}
|
||||
|
||||
RtlCopyMemory(Buffer, *pRxPacket, Size);
|
||||
(*pRxPacket) += Size;
|
||||
(*pRxLength) -= Size;
|
||||
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD0Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdD3Transition(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize0(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdDebuggerInitialize1(IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL)
|
||||
{
|
||||
KDNET_EXTENSIBILITY_IMPORTS ImportTable = {0};
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = KdInitializeLibrary(&ImportTable, LoaderBlock ? LoaderBlock->LoadOptions : NULL, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
KdNetExtensibilityExports = ImportTable.Exports;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdRestore(IN BOOLEAN SleepTransition)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KdSave(IN BOOLEAN SleepTransition)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdSetHiberRange(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
KDSTATUS
|
||||
NTAPI
|
||||
KdReceivePacket(
|
||||
_In_ ULONG PacketType,
|
||||
_Out_ PSTRING MessageHeader,
|
||||
_Out_ PSTRING MessageData,
|
||||
_Out_ PULONG DataLength,
|
||||
_Inout_ PKD_CONTEXT Context)
|
||||
{
|
||||
UCHAR Byte = 0;
|
||||
KDSTATUS KdStatus;
|
||||
KD_PACKET Packet;
|
||||
ULONG Checksum, MessageDataLength;
|
||||
ULONG RxHandle, RxLength;
|
||||
PVOID RxPacket;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Special handling for breakin packet */
|
||||
if (PacketType == PACKET_TYPE_KD_POLL_BREAKIN)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Status = KdGetRxPacket(NULL, &RxHandle, &RxPacket, &RxLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Report timeout */
|
||||
return KdPacketTimedOut;
|
||||
}
|
||||
|
||||
/* Step 1 - Read PacketLeader */
|
||||
KdStatus = KdpReceivePacketLeader(&Packet.PacketLeader, (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 2 - Read PacketType */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.PacketType, sizeof(USHORT), (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive a PacketType. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Check if we got a resend packet */
|
||||
if (Packet.PacketLeader == CONTROL_PACKET_LEADER &&
|
||||
Packet.PacketType == PACKET_TYPE_KD_RESEND)
|
||||
{
|
||||
return KdPacketNeedsResend;
|
||||
}
|
||||
|
||||
/* Step 3 - Read ByteCount */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.ByteCount, sizeof(USHORT), (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive ByteCount. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 4 - Read PacketId */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.PacketId, sizeof(ULONG), (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive PacketId. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 5 - Read Checksum */
|
||||
KdStatus = KdpReceiveBuffer(&Packet.Checksum, sizeof(ULONG), (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive Checksum. */
|
||||
return KdStatus;
|
||||
}
|
||||
|
||||
/* Step 6 - Handle control packets */
|
||||
if (Packet.PacketLeader == CONTROL_PACKET_LEADER)
|
||||
{
|
||||
switch (Packet.PacketType)
|
||||
{
|
||||
case PACKET_TYPE_KD_ACKNOWLEDGE:
|
||||
/* Are we waiting for an ACK packet? */
|
||||
if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE &&
|
||||
Packet.PacketId == (CurrentPacketId & ~SYNC_PACKET_ID))
|
||||
{
|
||||
/* Remote acknowledges the last packet */
|
||||
CurrentPacketId ^= 1;
|
||||
return KdPacketReceived;
|
||||
}
|
||||
/* That's not what we were waiting for, start over */
|
||||
continue;
|
||||
|
||||
case PACKET_TYPE_KD_RESET:
|
||||
CurrentPacketId = INITIAL_PACKET_ID;
|
||||
RemotePacketId = INITIAL_PACKET_ID;
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESET, 0);
|
||||
/* Fall through */
|
||||
|
||||
case PACKET_TYPE_KD_RESEND:
|
||||
/* Remote wants us to resend the last packet */
|
||||
return KdPacketNeedsResend;
|
||||
|
||||
default:
|
||||
/* We got an invalid packet, ignore it and start over */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we wait for an ack packet? */
|
||||
if (PacketType == PACKET_TYPE_KD_ACKNOWLEDGE)
|
||||
{
|
||||
/* We received something different */
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
CurrentPacketId ^= 1;
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
||||
/* Get size of the message header */
|
||||
MessageHeader->Length = MessageHeader->MaximumLength;
|
||||
|
||||
/* Packet smaller than expected or too big? */
|
||||
if (Packet.ByteCount < MessageHeader->Length ||
|
||||
Packet.ByteCount > PACKET_MAX_SIZE)
|
||||
{
|
||||
MessageHeader->Length = Packet.ByteCount;
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive the message header data */
|
||||
KdStatus = KdpReceiveBuffer(MessageHeader->Buffer,
|
||||
MessageHeader->Length,
|
||||
(PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive data. Packet needs to be resent. */
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Calculate checksum for the header data */
|
||||
Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
|
||||
MessageHeader->Length);
|
||||
|
||||
/* Calculate the length of the message data */
|
||||
MessageDataLength = Packet.ByteCount - MessageHeader->Length;
|
||||
|
||||
/* Shall we receive message data? */
|
||||
if (MessageData)
|
||||
{
|
||||
/* Set the length of the message data */
|
||||
MessageData->Length = (USHORT)MessageDataLength;
|
||||
|
||||
/* Do we have data? */
|
||||
if (MessageData->Length)
|
||||
{
|
||||
/* Receive the message data */
|
||||
KdStatus = KdpReceiveBuffer(MessageData->Buffer,
|
||||
MessageData->Length,
|
||||
(PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived)
|
||||
{
|
||||
/* Didn't receive data. Start over. */
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Add cheksum for message data */
|
||||
Checksum += KdpCalculateChecksum(MessageData->Buffer,
|
||||
MessageData->Length);
|
||||
}
|
||||
}
|
||||
|
||||
/* We must receive a PACKET_TRAILING_BYTE now */
|
||||
KdStatus = KdpReceiveBuffer(&Byte, sizeof(UCHAR), (PUCHAR*)&RxPacket, &RxLength);
|
||||
if (KdStatus != KdPacketReceived || Byte != PACKET_TRAILING_BYTE)
|
||||
{
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Compare checksum */
|
||||
if (Packet.Checksum != Checksum)
|
||||
{
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_RESEND, 0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Acknowledge the received packet */
|
||||
KdpSendControlPacket(PACKET_TYPE_KD_ACKNOWLEDGE, Packet.PacketId);
|
||||
|
||||
/* Check if the received PacketId is ok */
|
||||
if (Packet.PacketId != RemotePacketId)
|
||||
{
|
||||
/* Continue with next packet */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Did we get the right packet type? */
|
||||
if (PacketType == Packet.PacketType)
|
||||
{
|
||||
/* Yes, return success */
|
||||
RemotePacketId ^= 1;
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
||||
/* We received something different, ignore it. */
|
||||
}
|
||||
|
||||
return KdPacketReceived;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KdSendPacket(
|
||||
_In_ ULONG PacketType,
|
||||
_In_ PSTRING MessageHeader,
|
||||
_In_ PSTRING MessageData,
|
||||
_Inout_ PKD_CONTEXT Context)
|
||||
{
|
||||
PKD_PACKET Packet;
|
||||
KDSTATUS KdStatus;
|
||||
ULONG Retries;
|
||||
ULONG TxHandle, DataLength;
|
||||
NTSTATUS Status;
|
||||
|
||||
Status = KdGetTxPacket(NULL, &TxHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return;
|
||||
Packet = KdGetPacketAddress(NULL, TxHandle);
|
||||
ASSERT(Packet);
|
||||
ASSERT(KdGetPacketLength(NULL, TxHandle) >= sizeof(KD_PACKET));
|
||||
|
||||
/* Initialize a KD_PACKET */
|
||||
Packet->PacketLeader = PACKET_LEADER;
|
||||
Packet->PacketType = (USHORT)PacketType;
|
||||
Packet->ByteCount = MessageHeader->Length;
|
||||
Packet->Checksum = KdpCalculateChecksum(MessageHeader->Buffer,
|
||||
MessageHeader->Length);
|
||||
|
||||
/* If we have message data, add it to the packet */
|
||||
if (MessageData)
|
||||
{
|
||||
Packet->ByteCount += MessageData->Length;
|
||||
Packet->Checksum += KdpCalculateChecksum(MessageData->Buffer,
|
||||
MessageData->Length);
|
||||
}
|
||||
|
||||
if (KdGetPacketLength(NULL, TxHandle) < sizeof(KD_PACKET) + Packet->ByteCount + 1)
|
||||
{
|
||||
/* Release TX packet */
|
||||
KdSendTxPacket(NULL, TxHandle, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Copy message header and message data to packet */
|
||||
RtlCopyMemory(Packet + 1, MessageHeader->Buffer, MessageHeader->Length);
|
||||
if (MessageData)
|
||||
RtlCopyMemory((PUCHAR)(Packet + 1) + MessageHeader->Length, MessageData->Buffer, MessageData->Length);
|
||||
|
||||
/* Finalize with a trailing byte */
|
||||
((PUCHAR)(Packet + 1))[Packet->ByteCount] = PACKET_TRAILING_BYTE;
|
||||
|
||||
Retries = 3;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Set the packet id */
|
||||
Packet->PacketId = CurrentPacketId;
|
||||
|
||||
/* Send the packet to the KD port */
|
||||
KdSendTxPacket(NULL, TxHandle, sizeof(KD_PACKET) + Packet->ByteCount + 1);
|
||||
|
||||
/* Wait for acknowledge */
|
||||
KdStatus = KdReceivePacket(PACKET_TYPE_KD_ACKNOWLEDGE,
|
||||
NULL,
|
||||
NULL,
|
||||
&DataLength,
|
||||
NULL);
|
||||
|
||||
/* Did we succeed? */
|
||||
if (KdStatus == KdPacketReceived)
|
||||
{
|
||||
/* Packet received, we can quit the loop */
|
||||
CurrentPacketId &= ~SYNC_PACKET_ID;
|
||||
Retries = 3;
|
||||
break;
|
||||
}
|
||||
else if (KdStatus == KdPacketTimedOut)
|
||||
{
|
||||
/* Timeout, decrement the retry count */
|
||||
if (Retries > 0)
|
||||
Retries--;
|
||||
|
||||
/*
|
||||
* If the retry count reaches zero, bail out
|
||||
* for packet types allowed to timeout.
|
||||
*/
|
||||
if (Retries == 0)
|
||||
{
|
||||
ULONG MessageId = *(PULONG)MessageHeader->Buffer;
|
||||
switch (PacketType)
|
||||
{
|
||||
case PACKET_TYPE_KD_DEBUG_IO:
|
||||
{
|
||||
if (MessageId != DbgKdPrintStringApi) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_TYPE_KD_STATE_CHANGE32:
|
||||
case PACKET_TYPE_KD_STATE_CHANGE64:
|
||||
{
|
||||
if (MessageId != DbgKdLoadSymbolsStateChange) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
case PACKET_TYPE_KD_FILE_IO:
|
||||
{
|
||||
if (MessageId != DbgKdCreateFileApi) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset debugger state */
|
||||
CurrentPacketId = INITIAL_PACKET_ID | SYNC_PACKET_ID;
|
||||
RemotePacketId = INITIAL_PACKET_ID;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Packet timed out, send it again */
|
||||
}
|
||||
}
|
5
drivers/base/kdnet/kdnet.rc
Normal file
5
drivers/base/kdnet/kdnet.rc
Normal file
|
@ -0,0 +1,5 @@
|
|||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Kernel Debugger Network Extension DLL"
|
||||
#define REACTOS_STR_INTERNAL_NAME "kdnet"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "kdnet.dll"
|
||||
#include <reactos/version.rc>
|
9
drivers/base/kdnet/kdnet.spec
Normal file
9
drivers/base/kdnet/kdnet.spec
Normal file
|
@ -0,0 +1,9 @@
|
|||
@ 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)
|
||||
@ stdcall KdSetHiberRange()
|
Loading…
Reference in a new issue