#include "ntifs.h"
#include "tdi.h"
#include "tdikrnl.h"
#define ADDRESS_LEN (sizeof(FILE_FULL_EA_INFORMATION)+TDI_TRANSPORT_ADDRESS_LENGTH+sizeof(TA_IP_ADDRESS))
#define DN2H(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* DWORD host to network byte order conversion for i386 */
#define DH2N(dw) \
((((dw) & 0xFF000000L) >> 24) | \
(((dw) & 0x00FF0000L) >> 8) | \
(((dw) & 0x0000FF00L) << 8) | \
(((dw) & 0x000000FFL) << 24))
/* WORD network to host order conversion for i386 */
#define WN2H(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
/* WORD host to network byte order conversion for i386 */
#define WH2N(w) \
((((w) & 0xFF00) >> 8) | \
(((w) & 0x00FF) << 8))
NTSTATUS CreateAddress(PHANDLE Handle,PFILE_OBJECT *FileObject)
{
UNICODE_STRING Name;
OBJECT_ATTRIBUTES Attr;
CHAR Buffer[ADDRESS_LEN];
PFILE_FULL_EA_INFORMATION Ea;
PTA_IP_ADDRESS Sin;
IO_STATUS_BLOCK IoStatus;
NTSTATUS Status;
RtlInitUnicodeString(&Name, L"\\Device\\Udp");
InitializeObjectAttributes(&Attr, &Name, OBJ_CASE_INSENSITIVE, 0, 0);
Ea = (PFILE_FULL_EA_INFORMATION) ExAllocatePoolWithTag(NonPagedPool,ADDRESS_LEN,'ABCD');
Ea->NextEntryOffset = 0;
Ea->Flags = 0;
Ea->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
Ea->EaValueLength = sizeof(TA_IP_ADDRESS);
RtlCopyMemory(Ea->EaName, TdiTransportAddress, Ea->EaNameLength + 1);
Sin=(PTA_IP_ADDRESS)(Ea->EaName + Ea->EaNameLength + 1);
Sin->TAAddressCount = 1;
Sin->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
Sin->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
Sin->Address[0].Address[0].sin_port = 0; //
Sin->Address[0].Address[0].in_addr = 0; //本地自动
RtlZeroMemory(Sin->Address[0].Address[0].sin_zero, sizeof(Sin->Address[0].Address[0].sin_zero));
Status= ZwCreateFile(Handle, 0, &Attr, &IoStatus, 0,FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, Ea, sizeof(Buffer));
ExFreePool( (PVOID )Ea ); //释放内存
if (!NT_SUCCESS(Status))
{
return Status;
}
Status = ObReferenceObjectByHandle(*Handle, GENERIC_READ | GENERIC_WRITE, 0,
KernelMode,(PVOID *)FileObject, 0);
return Status;
}
static NTSTATUS TdiCall(
PIRP Irp,
PDEVICE_OBJECT DeviceObject,
PKEVENT Event,
PIO_STATUS_BLOCK Iosb,
PLARGE_INTEGER Timeout)
{
NTSTATUS Status;
Status = IoCallDriver(DeviceObject, Irp);
if ((Status == STATUS_PENDING) && (Event != NULL))
{
Status = KeWaitForSingleObject(Event,
Executive,
KernelMode,
FALSE,
Timeout);
if (Status == STATUS_TIMEOUT)
{
IoCancelIrp(Irp);
Iosb->Status = STATUS_TIMEOUT;
}
Status = Iosb->Status;
}
return Status;
}
NTSTATUS TdiSendDatagram(
PFILE_OBJECT TransportObject,
USHORT Port,
ULONG Address,
PVOID Buffer,
ULONG BufferSize)
{
PIRP Irp;
PMDL Mdl;
PDEVICE_OBJECT DeviceObject;
PTDI_CONNECTION_INFORMATION ConnectInfo;
PTA_IP_ADDRESS TA;
PTDI_ADDRESS_IP IpAddress;
IO_STATUS_BLOCK Iosb;
KEVENT Event;
NTSTATUS Status;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
ConnectInfo = (PTDI_CONNECTION_INFORMATION)
ExAllocatePool(NonPagedPool,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_IP_ADDRESS));
if (!ConnectInfo)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(ConnectInfo, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS));
ConnectInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
ConnectInfo->RemoteAddress = (PUCHAR) ((ULONG_PTR)ConnectInfo + sizeof(TDI_CONNECTION_INFORMATION));
TA = (PTA_IP_ADDRESS)(ConnectInfo->RemoteAddress);
TA->TAAddressCount = 1;
TA->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
TA->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
IpAddress = (PTDI_ADDRESS_IP)(TA->Address[0].Address);
IpAddress->sin_port = WH2N(Port);
IpAddress->in_addr = DH2N(Address);
Irp = TdiBuildInternalDeviceControlIrp(
TDI_SEND_DATAGRAM, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
&Event, /* Event */
&Iosb); /* Return buffer */
if (!Irp)
{
ExFreePool(ConnectInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
Mdl = IoAllocateMdl(
Buffer, /* Virtual address of buffer */
BufferSize, /* Length of buffer */
FALSE, /* Not secondary */
FALSE, /* Don't charge quota */
NULL); /* Don't use IRP */
if (!Mdl)
{
IoFreeIrp(Irp);
ExFreePool(ConnectInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
__try
{
MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
IoFreeMdl(Mdl);
IoFreeIrp(Irp);
ExFreePool(ConnectInfo);
return STATUS_UNSUCCESSFUL;
}
TdiBuildSendDatagram(
Irp, /* I/O Request Packet */
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Completion routine */
NULL, /* Completion context */
Mdl, /* Descriptor for data buffer */
BufferSize, /* Size of data to send */
ConnectInfo); /* Connection information */
Status = TdiCall(Irp, DeviceObject,&Event,&Iosb,NULL);
ExFreePool(ConnectInfo);
return Status;
}
NTSTATUS TdiReceiveDatagram(
PFILE_OBJECT TransportObject,
USHORT Port,
PULONG Address,
PVOID Buffer,
PULONG BufferSize,
PLARGE_INTEGER Timeout)
{
PTDI_CONNECTION_INFORMATION ReceiveInfo;
PTDI_CONNECTION_INFORMATION ReturnInfo;
PTA_IP_ADDRESS ReturnAddress;
PDEVICE_OBJECT DeviceObject;
PTDI_ADDRESS_IP IpAddress;
PTA_IP_ADDRESS TA;
IO_STATUS_BLOCK Iosb;
KEVENT Event;
PVOID MdlBuffer;
NTSTATUS Status;
PIRP Irp;
PMDL Mdl;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DeviceObject = IoGetRelatedDeviceObject(TransportObject);
if (!DeviceObject)
return STATUS_INVALID_PARAMETER;
ReceiveInfo = (PTDI_CONNECTION_INFORMATION) ExAllocatePool(NonPagedPool,
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_IP_ADDRESS) +
sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_IP_ADDRESS));
if (!ReceiveInfo)
return STATUS_INSUFFICIENT_RESOURCES;
MdlBuffer = ExAllocatePool(PagedPool, *BufferSize);
if (!MdlBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(ReceiveInfo, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS) + sizeof(TDI_CONNECTION_INFORMATION) +
sizeof(TA_IP_ADDRESS));
RtlCopyMemory(MdlBuffer, Buffer, *BufferSize);
ReceiveInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
ReceiveInfo->RemoteAddress = (PUCHAR) ((ULONG_PTR)ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION));
TA = (PTA_IP_ADDRESS)(ReceiveInfo->RemoteAddress);
TA->TAAddressCount = 1;
TA->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
TA->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
IpAddress = (PTDI_ADDRESS_IP)(TA->Address[0].Address);
IpAddress->sin_port = WH2N(Port);
IpAddress->in_addr = DH2N(*Address);
ReturnInfo = (PTDI_CONNECTION_INFORMATION) ((ULONG_PTR)ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION) +sizeof(TA_IP_ADDRESS));
ReturnInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
ReturnInfo->RemoteAddress = (PUCHAR) ((ULONG_PTR)ReturnInfo + sizeof(TDI_CONNECTION_INFORMATION));
ReturnAddress = (PTA_IP_ADDRESS)(ReturnInfo->RemoteAddress);
ReturnAddress->TAAddressCount = 1;
ReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP);
ReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
IpAddress = (PTDI_ADDRESS_IP)(ReturnAddress->Address[0].Address);
IpA