Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / rosapps / applications / net / tditest / tditest / tditest.c
diff --git a/rosapps/applications/net/tditest/tditest/tditest.c b/rosapps/applications/net/tditest/tditest/tditest.c
deleted file mode 100644 (file)
index 38ab0d7..0000000
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- * COPYRIGHT:   See COPYING in the top level directory
- * PROJECT:     ReactOS TDI test driver
- * FILE:        tditest.c
- * PURPOSE:     Testing TDI drivers
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- *              Vizzini (vizzini@plasmic.com)
- * REVISIONS:
- *   CSH 01/08-2000 Created
- *   26-Nov-2003 Vizzini Updated to run properly on Win2ksp4
- */
-#include <tditest.h>
-#include <pseh/pseh2.h>
-
-
-#if DBG
-
-/* See debug.h for debug/trace constants */
-ULONG DebugTraceLevel = -1;
-
-#endif /* DBG */
-
-
-HANDLE TdiTransport             = 0;
-PFILE_OBJECT TdiTransportObject = NULL;
-ULONG LocalAddress;
-BOOLEAN OpenError;
-KEVENT StopEvent;
-HANDLE SendThread;
-HANDLE ReceiveThread;
-
-NTSTATUS TdiCall(
-    PIRP Irp,
-    PDEVICE_OBJECT DeviceObject,
-    PIO_STATUS_BLOCK IoStatusBlock,
-    BOOLEAN CanCancel)
-/*
- * FUNCTION: Calls a transport driver device
- * ARGUMENTS:
- *     Irp           = Pointer to I/O Request Packet
- *     DeviceObject  = Pointer to device object to call
- *     IoStatusBlock = Address of buffer with I/O status block
- *     CanCancel     = TRUE if the IRP can be cancelled, FALSE if not
- * RETURNS:
- *     Status of operation
- * NOTES
- *     All requests are completed synchronously. A request may be cancelled
- */
-{
-       KEVENT Event;
-       PKEVENT Events[2];
-       NTSTATUS Status;
-       Events[0] = &StopEvent;
-       Events[1] = &Event;
-
-       KeInitializeEvent(&Event, NotificationEvent, FALSE);
-       Irp->UserEvent = &Event;
-       Irp->UserIosb  = IoStatusBlock;
-
-       Status = IoCallDriver(DeviceObject, Irp);
-
-       if (Status == STATUS_PENDING)
-               {
-                       if (CanCancel)
-                               {
-                                       Status = KeWaitForMultipleObjects(2, (PVOID)Events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
-
-                                       if (KeReadStateEvent(&StopEvent) != 0)
-                                               {
-                                                       if (IoCancelIrp(Irp))
-                                                               {
-                                                                       TDI_DbgPrint(MAX_TRACE, ("Cancelled IRP.\n"));
-                                                               }
-                                                       else
-                                                               {
-                                                                       TDI_DbgPrint(MIN_TRACE, ("Could not cancel IRP.\n"));
-                                                               }
-                                                       return STATUS_CANCELLED;
-                                               }
-                               }
-                       else
-                               Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
-               }
-
-       return (Status == STATUS_SUCCESS)? IoStatusBlock->Status : STATUS_SUCCESS;
-}
-
-
-NTSTATUS TdiOpenDevice(
-    PWSTR Protocol,
-    ULONG EaLength,
-    PFILE_FULL_EA_INFORMATION EaInfo,
-    PHANDLE Handle,
-    PFILE_OBJECT *Object)
-/*
- * FUNCTION: Opens a device
- * ARGUMENTS:
- *     Protocol = Pointer to buffer with name of device
- *     EaLength = Length of EA information
- *     EaInfo   = Pointer to buffer with EA information
- *     Handle   = Address of buffer to place device handle
- *     Object   = Address of buffer to place device object
- * RETURNS:
- *     Status of operation
- */
-{
-       OBJECT_ATTRIBUTES Attr;
-       IO_STATUS_BLOCK Iosb;
-       UNICODE_STRING Name;
-       NTSTATUS Status;
-
-       RtlInitUnicodeString(&Name, Protocol);
-       InitializeObjectAttributes(
-               &Attr,                   /* Attribute buffer */
-               &Name,                   /* Device name */
-               OBJ_CASE_INSENSITIVE,    /* Attributes */
-               NULL,                    /* Root directory */
-               NULL);                   /* Security descriptor */
-
-       Status = ZwCreateFile(
-               Handle,                               /* Return file handle */
-               GENERIC_READ | GENERIC_WRITE,         /* Desired access */
-               &Attr,                                /* Object attributes */
-               &Iosb,                                /* IO status */
-               0,                                    /* Initial allocation size */
-               FILE_ATTRIBUTE_NORMAL,                /* File attributes */
-               FILE_SHARE_READ | FILE_SHARE_WRITE,   /* Share access */
-               FILE_OPEN_IF,                         /* Create disposition */
-               0,                                    /* Create options */
-               EaInfo,                               /* EA buffer */
-               EaLength);                            /* EA length */
-
-       if (NT_SUCCESS(Status))
-               {
-                       Status  = ObReferenceObjectByHandle(
-                               *Handle,                        /* Handle to open file */
-                               GENERIC_READ | GENERIC_WRITE,   /* Access mode */
-                               NULL,                           /* Object type */
-                               KernelMode,                     /* Access mode */
-                               (PVOID*)Object,                 /* Pointer to object */
-                               NULL);                          /* Handle information */
-
-                       if (!NT_SUCCESS(Status))
-                               {
-                                       TDI_DbgPrint(MIN_TRACE, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status));
-                                       ZwClose(*Handle);
-                               }
-               }
-       else
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("ZwCreateFile() failed with status (0x%X)\n", Status));
-               }
-
-    return Status;
-}
-
-
-NTSTATUS TdiCloseDevice(
-    HANDLE Handle,
-    PFILE_OBJECT FileObject)
-{
-       if (FileObject)
-               ObDereferenceObject(FileObject);
-
-       if (Handle)
-               ZwClose(Handle);
-
-       return STATUS_SUCCESS;
-}
-
-
-NTSTATUS TdiOpenTransport(
-    PWSTR Protocol,
-    USHORT Port,
-    PHANDLE Transport,
-    PFILE_OBJECT *TransportObject)
-/*
- * FUNCTION: Opens a transport driver
- * ARGUMENTS:
- *     Protocol        = Pointer to buffer with name of device
- *     Port            = Port number to use
- *     Transport       = Address of buffer to place transport device handle
- *     TransportObject = Address of buffer to place transport object
- * RETURNS:
- *     Status of operation
- */
-{
-       PFILE_FULL_EA_INFORMATION EaInfo;
-       PTA_IP_ADDRESS Address;
-       NTSTATUS Status;
-       ULONG EaLength;
-
-       /* EaName must be 0-termed, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
-       EaLength = sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_IP_ADDRESS) + 1;
-       EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
-
-       if (!EaInfo)
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       RtlZeroMemory(EaInfo, EaLength);
-
-       EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
-
-       /* don't copy the 0; we have already zeroed it */
-       RtlCopyMemory(EaInfo->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH);
-
-       EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS);
-       Address = (PTA_IP_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); // 0-term
-       Address->TAAddressCount                 = 1;
-       Address->Address[0].AddressLength       = TDI_ADDRESS_LENGTH_IP;
-       Address->Address[0].AddressType         = TDI_ADDRESS_TYPE_IP;
-       Address->Address[0].Address[0].sin_port = WH2N(Port);
-       Address->Address[0].Address[0].in_addr  = 0;
-
-       Status = TdiOpenDevice(Protocol, EaLength, EaInfo, Transport, TransportObject);
-
-       ExFreePool(EaInfo);
-
-       return Status;
-}
-
-
-NTSTATUS TdiQueryDeviceControl(
-    PFILE_OBJECT FileObject,
-    ULONG IoControlCode,
-    PVOID InputBuffer,
-    ULONG InputBufferLength,
-    PVOID OutputBuffer,
-    ULONG OutputBufferLength,
-    PULONG Return)
-/*
- * FUNCTION: Queries a device for information
- * ARGUMENTS:
- *     FileObject         = Pointer to device object
- *     IoControlCode      = I/O control code
- *     InputBuffer        = Pointer to buffer with input data
- *     InputBufferLength  = Length of InputBuffer
- *     OutputBuffer       = Address of buffer to place output data
- *     OutputBufferLength = Length of OutputBuffer
- * RETURNS:
- *     Status of operation
- */
-{
-       PDEVICE_OBJECT DeviceObject;
-       PIO_STACK_LOCATION IoStack;
-       IO_STATUS_BLOCK Iosb;
-       NTSTATUS Status;
-       PIRP Irp;
-
-       DeviceObject = IoGetRelatedDeviceObject(FileObject);
-       Irp = IoBuildDeviceIoControlRequest(IoControlCode, DeviceObject, InputBuffer, InputBufferLength, OutputBuffer,
-               OutputBufferLength, FALSE, NULL, NULL);
-
-       if (!Irp)
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("IoBuildDeviceIoControlRequest() failed.\n"));
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       IoStack               = IoGetNextIrpStackLocation(Irp);
-       IoStack->DeviceObject = DeviceObject;
-       IoStack->FileObject   = FileObject;
-       Status = TdiCall(Irp, DeviceObject, &Iosb, FALSE);
-
-       if (Return)
-               *Return = Iosb.Information;
-
-       return Status;
-}
-
-
-NTSTATUS TdiQueryInformationEx(
-    PFILE_OBJECT FileObject,
-    ULONG Entity,
-    ULONG Instance,
-    ULONG Class,
-    ULONG Type,
-    ULONG Id,
-    PVOID OutputBuffer,
-    PULONG OutputLength)
-/*
- * FUNCTION: Extended query for information
- * ARGUMENTS:
- *     FileObject   = Pointer to transport object
- *     Entity       = Entity
- *     Instance     = Instance
- *     Class        = Entity class
- *     Type         = Entity type
- *     Id           = Entity id
- *     OutputBuffer = Address of buffer to place data
- *     OutputLength = Address of buffer with length of OutputBuffer (updated)
- * RETURNS:
- *     Status of operation
- */
-{
-       TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo;
-
-       RtlZeroMemory(&QueryInfo, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX));
-       QueryInfo.ID.toi_entity.tei_entity   = Entity;
-       QueryInfo.ID.toi_entity.tei_instance = Instance;
-       QueryInfo.ID.toi_class = Class;
-       QueryInfo.ID.toi_type  = Type;
-       QueryInfo.ID.toi_id    = Id;
-
-       return TdiQueryDeviceControl(
-               FileObject,                                /* Transport/connection object */
-               IOCTL_TCP_QUERY_INFORMATION_EX,            /* Control code */
-               &QueryInfo,                                /* Input buffer */
-               sizeof(TCP_REQUEST_QUERY_INFORMATION_EX),  /* Input buffer length */
-               OutputBuffer,                              /* Output buffer */
-               *OutputLength,                             /* Output buffer length */
-               OutputLength);                             /* Return information */
-}
-
-
-NTSTATUS TdiQueryAddress(
-    PFILE_OBJECT FileObject,
-    PULONG Address)
-/*
- * FUNCTION: Queries for a local IP address
- * ARGUMENTS:
- *     FileObject = Pointer to file object
- *     Address    = Address of buffer to place local address
- * RETURNS:
- *     Status of operation
- */
-{
-       ULONG i;
-       TDIEntityID *Entities;
-       ULONG EntityCount;
-       ULONG EntityType;
-       IPSNMP_INFO SnmpInfo;
-       PIPADDR_ENTRY IpAddress;
-       ULONG BufferSize;
-       NTSTATUS Status = STATUS_SUCCESS;
-
-       TDI_DbgPrint(MAX_TRACE, ("Called\n"));
-
-       BufferSize = sizeof(TDIEntityID) * 20;
-       Entities   = (TDIEntityID*)ExAllocatePool(NonPagedPool, BufferSize);
-
-       if (!Entities)
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       /* Query device for supported entities */
-       Status = TdiQueryInformationEx(
-               FileObject,          /* File object */
-               GENERIC_ENTITY,      /* Entity */
-               TL_INSTANCE,         /* Instance */
-               INFO_CLASS_GENERIC,  /* Entity class */
-               INFO_TYPE_PROVIDER,  /* Entity type */
-               ENTITY_LIST_ID,      /* Entity id */
-               Entities,            /* Output buffer */
-               &BufferSize);        /* Output buffer size */
-
-       if (!NT_SUCCESS(Status))
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("Unable to get list of supported entities (Status = 0x%X).\n", Status));
-                       ExFreePool(Entities);
-                       return Status;
-               }
-
-       /* Locate an IP entity */
-       EntityCount = BufferSize / sizeof(TDIEntityID);
-
-       TDI_DbgPrint(MAX_TRACE, ("EntityCount = %d\n", EntityCount));
-
-       for (i = 0; i < EntityCount; i++)
-               {
-                       if (Entities[i].tei_entity == CL_NL_ENTITY)
-                               {
-                                       /* Query device for entity type */
-                                       BufferSize = sizeof(EntityType);
-                                       Status = TdiQueryInformationEx(
-                                               FileObject,                  /* File object */
-                                               CL_NL_ENTITY,                /* Entity */
-                                               Entities[i].tei_instance,    /* Instance */
-                                               INFO_CLASS_GENERIC,          /* Entity class */
-                                               INFO_TYPE_PROVIDER,          /* Entity type */
-                                               ENTITY_TYPE_ID,              /* Entity id */
-                                               &EntityType,                 /* Output buffer */
-                                               &BufferSize);                /* Output buffer size */
-
-                                       if (!NT_SUCCESS(Status) || (EntityType != CL_NL_IP))
-                                               {
-                                                       TDI_DbgPrint(MIN_TRACE, ("Unable to get entity of type IP (Status = 0x%X).\n", Status));
-                                                       break;
-                                               }
-
-                                       /* Query device for SNMP information */
-                                       BufferSize = sizeof(SnmpInfo);
-                                       Status = TdiQueryInformationEx(
-                                               FileObject,                  /* File object */
-                                               CL_NL_ENTITY,                /* Entity */
-                                               Entities[i].tei_instance,    /* Instance */
-                                               INFO_CLASS_PROTOCOL,         /* Entity class */
-                                               INFO_TYPE_PROVIDER,          /* Entity type */
-                                               IP_MIB_STATS_ID,             /* Entity id */
-                                               &SnmpInfo,                   /* Output buffer */
-                                               &BufferSize);                /* Output buffer size */
-
-                                       if (!NT_SUCCESS(Status) || (SnmpInfo.NumAddr == 0))
-                                               {
-                                                       TDI_DbgPrint(MIN_TRACE, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status));
-                                                       break;
-                                               }
-
-                                       /* Query device for all IP addresses */
-                                       if (SnmpInfo.NumAddr != 0)
-                                               {
-                                                       BufferSize = SnmpInfo.NumAddr * sizeof(IPADDR_ENTRY);
-                                                       IpAddress = (PIPADDR_ENTRY)ExAllocatePool(NonPagedPool, BufferSize);
-                                                       if (!IpAddress)
-                                                               {
-                                                                       TDI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
-                                                                       break;
-                                                               }
-
-                                               Status = TdiQueryInformationEx(
-                                                       FileObject,                  /* File object */
-                                                       CL_NL_ENTITY,                /* Entity */
-                                                       Entities[i].tei_instance,    /* Instance */
-                                                       INFO_CLASS_PROTOCOL,         /* Entity class */
-                                                       INFO_TYPE_PROVIDER,          /* Entity type */
-                                                       IP_MIB_ADDRTABLE_ENTRY_ID,   /* Entity id */
-                                                       IpAddress,                   /* Output buffer */
-                                                       &BufferSize);                /* Output buffer size */
-
-                                               if (!NT_SUCCESS(Status))
-                                                       {
-                                                               TDI_DbgPrint(MIN_TRACE, ("Unable to get IP address (Status = 0x%X).\n", Status));
-                                                               ExFreePool(IpAddress);
-                                                               break;
-                                                       }
-
-                                               if (SnmpInfo.NumAddr != 1)
-                                                       {
-                                                               /* Skip loopback address */
-                                                               *Address = DN2H(((PIPADDR_ENTRY)((ULONG)IpAddress + sizeof(IPADDR_ENTRY)))->Addr);
-                                                       }
-                                               else
-                                                       {
-                                                               /* Select the first address returned */
-                                                               *Address = DN2H(IpAddress->Addr);
-                                                       }
-                                                               ExFreePool(IpAddress);
-
-                                               }
-                                       else
-                                               {
-                                                       Status = STATUS_UNSUCCESSFUL;
-                                                       break;
-                                       }
-                       }
-       }
-
-       ExFreePool(Entities);
-
-       TDI_DbgPrint(MAX_TRACE, ("Leaving\n"));
-
-       return Status;
-}
-
-
-NTSTATUS TdiSendDatagram(
-    PFILE_OBJECT TransportObject,
-    USHORT Port,
-    ULONG Address,
-    PVOID Buffer,
-    ULONG BufferSize)
-/*
- * FUNCTION: Sends a datagram
- * ARGUMENTS:
- *     TransportObject = Pointer to transport object
- *     Port            = Remote port
- *     Address         = Remote address
- *     Buffer          = Pointer to buffer with data to send
- *     BufferSize      = Length of Buffer
- * RETURNS:
- *     Status of operation
- */
-{
-       PIRP Irp;
-       PMDL Mdl;
-       PDEVICE_OBJECT DeviceObject;
-       PTDI_CONNECTION_INFORMATION ConnectInfo;
-       PTA_IP_ADDRESS TA;
-       PTDI_ADDRESS_IP IpAddress;
-       IO_STATUS_BLOCK Iosb;
-       NTSTATUS Status;
-
-       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)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 */
-               NULL,                /* Event */
-               NULL);               /* Return buffer */
-
-       if (!Irp)
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("TdiBuildInternalDeviceControlIrp() failed.\n"));
-                       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)
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("IoAllocateMdl() failed.\n"));
-                       IoFreeIrp(Irp);
-                       ExFreePool(ConnectInfo);
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       _SEH2_TRY
-       {
-               MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
-       }
-       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-       {
-               TDI_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
-               IoFreeMdl(Mdl);
-               IoFreeIrp(Irp);
-               ExFreePool(ConnectInfo);
-               _SEH2_YIELD(return STATUS_UNSUCCESSFUL);
-       } _SEH2_END;
-
-       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, &Iosb, FALSE);
-
-       ExFreePool(ConnectInfo);
-
-       return Status;
-}
-
-
-NTSTATUS TdiReceiveDatagram(
-    PFILE_OBJECT TransportObject,
-    USHORT Port,
-    PULONG Address,
-    PUCHAR Buffer,
-    PULONG BufferSize)
-/*
- * FUNCTION: Receives a datagram
- * ARGUMENTS:
- *     TransportObject = Pointer to transport object
- *     Port            = Port to receive on
- *     Address         = Address of buffer to place remote address
- *     Buffer          = Address of buffer to place received data
- *     BufferSize      = Address of buffer with length of Buffer (updated)
- * RETURNS:
- *     Status of operation
- */
-{
-       PTDI_CONNECTION_INFORMATION ReceiveInfo;
-       PTDI_CONNECTION_INFORMATION ReturnInfo;
-       PTA_IP_ADDRESS ReturnAddress;
-       PDEVICE_OBJECT DeviceObject;
-       PTDI_ADDRESS_IP IpAddress;
-       IO_STATUS_BLOCK Iosb;
-       PVOID MdlBuffer;
-       NTSTATUS Status;
-       PIRP Irp;
-       PMDL Mdl;
-
-       DeviceObject = IoGetRelatedDeviceObject(TransportObject);
-       if (!DeviceObject)
-               return STATUS_INVALID_PARAMETER;
-
-       ReceiveInfo = (PTDI_CONNECTION_INFORMATION) ExAllocatePool(NonPagedPool,
-               sizeof(TDI_CONNECTION_INFORMATION) +
-               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(TDI_CONNECTION_INFORMATION) +
-               sizeof(TA_IP_ADDRESS));
-
-       RtlCopyMemory(MdlBuffer, Buffer, *BufferSize);
-
-       /* Receive from any address */
-       ReceiveInfo->RemoteAddressLength = 0;
-       ReceiveInfo->RemoteAddress       = NULL;
-
-       ReturnInfo = (PTDI_CONNECTION_INFORMATION) ((ULONG)ReceiveInfo + sizeof(TDI_CONNECTION_INFORMATION));
-       ReturnInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS);
-       ReturnInfo->RemoteAddress       = (PUCHAR) ((ULONG)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);
-       IpAddress->sin_port = WH2N(Port);
-       IpAddress->in_addr  = DH2N(LocalAddress);
-
-       Irp = TdiBuildInternalDeviceControlIrp(
-               TDI_RECEIVE_DATAGRAM,    /* Sub function */
-               DeviceObject,            /* Device object */
-               TransportObject,         /* File object */
-               NULL,                    /* Event */
-               NULL);                   /* Return buffer */
-
-       if (!Irp)
-               {
-                       ExFreePool(MdlBuffer);
-                       ExFreePool(ReceiveInfo);
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       Mdl = IoAllocateMdl(
-               MdlBuffer,      /* Virtual address */
-               *BufferSize,    /* Length of buffer */
-               FALSE,          /* Not secondary */
-               FALSE,          /* Don't charge quota */
-               NULL);          /* Don't use IRP */
-
-       if (!Mdl)
-               {
-                       IoFreeIrp(Irp);
-                       ExFreePool(MdlBuffer);
-                       ExFreePool(ReceiveInfo);
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       _SEH2_TRY
-       {
-               MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess);
-       }
-       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-       {
-               TDI_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
-               IoFreeMdl(Mdl);
-               IoFreeIrp(Irp);
-               ExFreePool(MdlBuffer);
-               ExFreePool(ReceiveInfo);
-               _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
-       } _SEH2_END;
-
-       TdiBuildReceiveDatagram(
-               Irp,                    /* I/O Request Packet */
-               DeviceObject,           /* Device object */
-               TransportObject,        /* File object */
-               NULL,                   /* Completion routine */
-               NULL,                   /* Completion context */
-               Mdl,                    /* Data buffer */
-               *BufferSize,            /* Size of data buffer */
-               ReceiveInfo,            /* Connection information */
-               ReturnInfo,             /* Connection information */
-               TDI_RECEIVE_NORMAL);    /* Flags */
-
-       Status = TdiCall(Irp, DeviceObject, &Iosb, TRUE);
-
-       if (NT_SUCCESS(Status))
-               {
-                       RtlCopyMemory(Buffer, MdlBuffer, Iosb.Information);
-                       *BufferSize = Iosb.Information;
-                       *Address    = DN2H(IpAddress->in_addr);
-               }
-
-       ExFreePool(MdlBuffer);
-       ExFreePool(ReceiveInfo);
-
-       return Status;
-}
-
-
-VOID TdiSendThread(
-    PVOID Context)
-/*
- * FUNCTION: Send thread
- * ARGUMENTS:
- *     Context = Pointer to context information
- * NOTES:
- *     Transmits an UDP packet every two seconds to ourselves on the chosen port
- */
-{
-       KEVENT Event;
-       PKEVENT Events[2];
-       LARGE_INTEGER Timeout;
-       NTSTATUS Status = STATUS_SUCCESS;
-       UCHAR Data[40]  = "Testing one, two, three, ...";
-
-       if (!OpenError)
-               {
-                       Timeout.QuadPart = 10000000L;           /* Second factor */
-                       Timeout.QuadPart *= 2;                  /* Number of seconds */
-                       Timeout.QuadPart = -(Timeout.QuadPart); /* Relative time */
-
-                       KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
-                       Events[0] = &StopEvent;
-                       Events[1] = &Event;
-
-                       while (NT_SUCCESS(Status))
-                               {
-                                       /* Wait until timeout or stop flag is set */
-                                       KeWaitForMultipleObjects( 2, (PVOID)Events, WaitAny, Executive, KernelMode, FALSE, &Timeout, NULL);
-
-                                       if (KeReadStateEvent(&StopEvent) != 0)
-                                               {
-                                                       TDI_DbgPrint(MAX_TRACE, ("Received terminate signal...\n"));
-                                                       break;
-                                               }
-
-                                       DbgPrint("Sending data - '%s'\n", Data);
-
-                                       Status = TdiSendDatagram(TdiTransportObject, TEST_PORT, LocalAddress, Data, sizeof(Data));
-
-                                       if (!NT_SUCCESS(Status))
-                                               DbgPrint("Failed sending data (Status = 0x%X)\n", Status);
-                               }
-               }
-
-       TDI_DbgPrint(MAX_TRACE, ("Terminating send thread...\n"));
-
-       PsTerminateSystemThread(STATUS_SUCCESS);
-}
-
-
-VOID TdiReceiveThread(
-    PVOID Context)
-/*
- * FUNCTION: Receive thread
- * ARGUMENTS:
- *     Context = Pointer to context information
- * NOTES:
- *     Waits until an UDP packet is received on the chosen endpoint and displays the data
- */
-{
-       ULONG Address;
-       UCHAR Data[40];
-       ULONG Size;
-       NTSTATUS Status = STATUS_SUCCESS;
-
-       if (!OpenError)
-               {
-                       while (NT_SUCCESS(Status))
-                               {
-                                       Size = sizeof(Data);
-                                       RtlZeroMemory(Data, Size);
-
-                                       Status = TdiReceiveDatagram(TdiTransportObject, TEST_PORT, &Address, Data, &Size);
-
-                                       if (NT_SUCCESS(Status))
-                                               {
-                                                       DbgPrint("Received data - '%s'\n", Data);
-                                               }
-                                       else
-                                               if (Status != STATUS_CANCELLED)
-                                                       {
-                                                               TDI_DbgPrint(MIN_TRACE, ("Receive error (Status = 0x%X).\n", Status));
-                                                       }
-                                               else
-                                                       {
-                                                               TDI_DbgPrint(MAX_TRACE, ("IRP was cancelled.\n"));
-                                                       }
-                               }
-               }
-
-       TDI_DbgPrint(MAX_TRACE, ("Terminating receive thread...\n"));
-
-       PsTerminateSystemThread(STATUS_SUCCESS);
-}
-
-
-VOID TdiOpenThread(
-    PVOID Context)
-/*
- * FUNCTION: Open thread
- * ARGUMENTS:
- *     Context = Pointer to context information (event)
- */
-{
-       NTSTATUS Status;
-
-       TDI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
-       OpenError = TRUE;
-
-       Status = TdiOpenTransport(UDP_DEVICE_NAME, TEST_PORT, &TdiTransport, &TdiTransportObject);
-
-       if (NT_SUCCESS(Status))
-               {
-                       Status = TdiQueryAddress(TdiTransportObject, &LocalAddress);
-
-                       if (NT_SUCCESS(Status))
-                               {
-                                       OpenError = FALSE;
-                                       DbgPrint("Using local IP address 0x%X\n", LocalAddress);
-                               }
-                       else
-                               {
-                                       TDI_DbgPrint(MIN_TRACE, ("Unable to determine local IP address.\n"));
-                               }
-                       }
-       else
-               TDI_DbgPrint(MIN_TRACE, ("Cannot open transport (Status = 0x%X).\n", Status));
-
-       TDI_DbgPrint(MAX_TRACE, ("Setting close event.\n"));
-
-       KeSetEvent((PKEVENT)Context, 0, FALSE);
-
-       TDI_DbgPrint(MIN_TRACE, ("Leaving.\n"));
-}
-
-
-VOID TdiUnload(
-    PDRIVER_OBJECT DriverObject)
-/*
- * FUNCTION: Unload routine
- * ARGUMENTS:
- *     DriverObject = Pointer to a driver object for this driver
- */
-{
-       PVOID ReceiveThreadObject = 0;
-       PVOID SendThreadObject = 0;
-
-       TDI_DbgPrint(MAX_TRACE, ("Setting stop flag\n"));
-
-       /* Get pointers to the thread objects */
-       ObReferenceObjectByHandle(SendThread, THREAD_ALL_ACCESS, NULL, KernelMode, &SendThreadObject, NULL);
-       ObReferenceObjectByHandle(ReceiveThread, THREAD_ALL_ACCESS, NULL, KernelMode, &ReceiveThreadObject, NULL);
-
-       KeSetEvent(&StopEvent, 0, FALSE);
-
-       /* Wait for send thread to stop */
-       KeWaitForSingleObject(SendThreadObject, Executive, KernelMode, FALSE, NULL);
-
-       /* Wait for receive thread to stop */
-       KeWaitForSingleObject(ReceiveThreadObject, Executive, KernelMode, FALSE, NULL);
-
-       /* Close device */
-       TdiCloseDevice(TdiTransport, TdiTransportObject);
-}
-
-
-NTSTATUS
-NTAPI
-DriverEntry(
-    PDRIVER_OBJECT DriverObject,
-    PUNICODE_STRING RegistryPath)
-/*
- * FUNCTION: Main driver entry point
- * ARGUMENTS:
- *     DriverObject = Pointer to a driver object for this driver
- *     RegistryPath = Registry node for configuration parameters
- * RETURNS:
- *     Status of driver initialization
- */
-{
-       KEVENT Event;
-       NTSTATUS Status;
-       WORK_QUEUE_ITEM WorkItem;
-
-       KeInitializeEvent(&StopEvent, NotificationEvent, FALSE);
-
-       /* Call TdiOpenThread() */
-       KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-       ExInitializeWorkItem(&WorkItem, (PWORKER_THREAD_ROUTINE)TdiOpenThread, &Event);
-       ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
-       KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL);
-
-       /* Create a UDP send thread that sends a dgram every 2 seconds */
-       Status = PsCreateSystemThread(
-               &SendThread,                      /* Thread handle */
-               0,                                /* Desired access */
-               NULL,                             /* Object attributes */
-               NULL,                             /* Process handle */
-               NULL,                             /* Client id */
-               (PKSTART_ROUTINE)TdiSendThread,   /* Start routine */
-               NULL);                            /* Start context */
-
-       if (!NT_SUCCESS(Status))
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for send thread (Status = 0x%X).\n", Status));
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       /* Create a UDP receive thread */
-       Status = PsCreateSystemThread(
-               &ReceiveThread,                       /* Thread handle */
-               0,                                    /* Desired access */
-               NULL,                                 /* Object attributes */
-               NULL,                                 /* Process handle */
-               NULL,                                 /* Client id */
-               (PKSTART_ROUTINE)TdiReceiveThread,    /* Start routine */
-               NULL);                                /* Start context */
-
-       if (!NT_SUCCESS(Status))
-               {
-                       TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for receive thread (Status = 0x%X).\n", Status));
-                       ZwClose(SendThread);
-                       return STATUS_INSUFFICIENT_RESOURCES;
-               }
-
-       DriverObject->DriverUnload = (PDRIVER_UNLOAD)TdiUnload;
-
-       return STATUS_SUCCESS;
-}
-
-/* EOF */
-