summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/nbf/testnbf.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/tdi/nbf/testnbf.c1466
1 files changed, 1466 insertions, 0 deletions
diff --git a/private/ntos/tdi/nbf/testnbf.c b/private/ntos/tdi/nbf/testnbf.c
new file mode 100644
index 000000000..91a3ca645
--- /dev/null
+++ b/private/ntos/tdi/nbf/testnbf.c
@@ -0,0 +1,1466 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ testtdi.c
+
+Abstract:
+
+ Kernel Mode test program for any Tdi network provider. This routine is an
+ example of how to use the TDI interface at the kernel level.
+
+Author:
+
+ Dave Beaver (DBeaver) 5 June 1991
+
+Revision History:
+
+--*/
+
+#include "nbf.h"
+#include <ctype.h>
+
+#define TRANSPORT_NAME L"\\Device\\Nbf"
+
+PSZ ServerName = "DCTDISERVER ";
+PSZ ClientName = "DCTDICLIENT ";
+PSZ AnyName = "* ";
+
+static PUCHAR TextBuffer; // dynamically allocated non-paged buffer.
+ULONG c9_Xmt = 0xff;
+ULONG c9_Rcv = 0xff;
+ULONG c9_Iteration = 0xffffffff;
+
+static ULONG TextBufferLength; // size of the above in bytes.
+#define BUFFER_SIZE 0xffff
+PUCHAR RBuff;
+PUCHAR XBuff;
+UCHAR c9_ListBlock[512];
+UCHAR c9_ConnBlock[512];
+
+extern KEVENT TdiSendEvent;
+extern KEVENT TdiReceiveEvent;
+extern KEVENT TdiServerEvent;
+
+ULONG ApcContext;
+
+NTSTATUS
+TSTRCVCompletion(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context
+ )
+{
+ DbgPrint ("TSTRCVCompletion event: %lx\n" , Context);
+// KeSetEvent ((PKEVENT)Context, 0, TRUE);
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ UNREFERENCED_PARAMETER( DeviceObject );
+ UNREFERENCED_PARAMETER( Irp );
+}
+
+#define InitWaitObject(_event)\
+ KeInitializeEvent (\
+ _event,\
+ SynchronizationEvent,\
+ FALSE)
+
+VOID
+NbfTestTimer(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext,
+ IN PVOID SystemArgument1,
+ IN PVOID SystemArgument2
+ );
+
+NTSTATUS
+TtdiOpenAddress (
+ IN PHANDLE FileHandle,
+ IN PSZ Name
+ );
+
+NTSTATUS
+TtdiOpenConnection (
+ IN PHANDLE FileHandle,
+ IN ULONG ConnectionContext
+ );
+
+
+NTSTATUS
+TtdiOpenAddress (
+ IN PHANDLE FileHandle,
+ IN PSZ Name)
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ UNICODE_STRING NameString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PFILE_FULL_EA_INFORMATION EaBuffer;
+ PTDI_ADDRESS_NETBIOS AddressName;
+ PTRANSPORT_ADDRESS Address;
+ PTA_ADDRESS AddressType;
+ int i;
+
+ DbgPrint ("TtdiOpenAddress: Opening ");
+ DbgPrint (Name);
+ DbgPrint (".\n");
+ RtlInitUnicodeString (&NameString, TRANSPORT_NAME);
+ InitializeObjectAttributes (
+ &ObjectAttributes,
+ &NameString,
+ 0,
+ NULL,
+ NULL);
+
+ EaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool (NonPagedPool, 100);
+ if (EaBuffer == NULL) {
+ DbgBreakPoint ();
+ }
+
+ EaBuffer->NextEntryOffset =0;
+ EaBuffer->Flags = 0;
+ EaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
+ EaBuffer->EaValueLength = sizeof (TDI_ADDRESS_NETBIOS);
+
+ for (i=0;i<(int)EaBuffer->EaNameLength;i++) {
+ EaBuffer->EaName[i] = TdiTransportAddress[i];
+ }
+
+ Address = (PTRANSPORT_ADDRESS)&EaBuffer->EaName[EaBuffer->EaNameLength+1];
+ Address->TAAddressCount = 1;
+
+ AddressType = (PTA_ADDRESS)((PUCHAR)Address + sizeof (Address->TAAddressCount));
+
+ AddressType->AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ AddressType->AddressLength = TDI_ADDRESS_LENGTH_NETBIOS;
+
+ AddressName = (PTDI_ADDRESS_NETBIOS)((PUCHAR)AddressType +
+ sizeof (AddressType->AddressType) + sizeof (AddressType->AddressLength));
+ AddressName->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ AddressName->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+
+ for (i=0;i<16;i++) {
+ AddressName->NetbiosName[i] = Name[i];
+ }
+
+ Status = IoCreateFile (
+ FileHandle,
+ 0, // desired access.
+ &ObjectAttributes, // object attributes.
+ &IoStatusBlock, // returned status information.
+ 0, // block size (unused).
+ FO_SYNCHRONOUS_IO, // file attributes.
+ 0,
+ 0,
+ 0, // create options.
+ EaBuffer, // EA buffer.
+ (PUCHAR)&AddressName->NetbiosName[i] - (PUCHAR)EaBuffer + 1, // ea length
+ CreateFileTypeNone,
+ (PVOID)NULL,
+ 0 ); // EA length.
+
+ if (!NT_SUCCESS( Status )) {
+ DbgPrint ("TtdiOpenAddress: FAILURE, NtCreateFile returned status code=%lC.\n", Status);
+ return Status;
+ }
+
+ Status = IoStatusBlock.Status;
+
+ if (!(NT_SUCCESS( Status ))) {
+ DbgPrint ("TtdiOpenAddress: FAILURE, IoStatusBlock.Status contains status code=%lC.\n", Status);
+ }
+
+ DbgPrint ("TtdiOpenAddress: returning\n");
+
+ return Status;
+} /* TtdiOpenAddress */
+
+
+NTSTATUS
+TtdiOpenConnection (IN PHANDLE FileHandle, IN ULONG ConnectionContext)
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ UNICODE_STRING NameString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PFILE_FULL_EA_INFORMATION EaBuffer;
+ int i;
+
+ DbgPrint ("TtdiOpenConnection: Opening Context %lx...\n ",
+ ConnectionContext);
+ RtlInitUnicodeString (&NameString, TRANSPORT_NAME);
+ InitializeObjectAttributes (
+ &ObjectAttributes,
+ &NameString,
+ 0,
+ NULL,
+ NULL);
+
+ EaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool (NonPagedPool, 100);
+ if (EaBuffer == NULL) {
+ DbgBreakPoint ();
+ }
+
+ EaBuffer->NextEntryOffset =0;
+ EaBuffer->Flags = 0;
+ EaBuffer->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
+ EaBuffer->EaValueLength = sizeof (ULONG);
+ for (i=0;i<(int)EaBuffer->EaNameLength;i++) {
+ EaBuffer->EaName[i] = TdiConnectionContext[i];
+ }
+
+ RtlMoveMemory (
+ &EaBuffer->EaName[EaBuffer->EaValueLength + 1],
+ &ConnectionContext,
+ sizeof (PVOID));
+
+ Status = NtCreateFile (
+ FileHandle,
+ 0,
+ &ObjectAttributes, // object attributes.
+ &IoStatusBlock, // returned status information.
+ 0, // block size (unused).
+ FO_SYNCHRONOUS_IO, // file attributes.
+ 0,
+ 0,
+ 0, // create options.
+ EaBuffer, // EA buffer.
+ 100); // EA length.
+
+ if (!NT_SUCCESS( Status )) {
+ DbgPrint ("TtdiOpenConnection: FAILURE, NtCreateFile returned status code=%lC.\n", Status);
+ return Status;
+ }
+
+ Status = IoStatusBlock.Status;
+
+ if (!(NT_SUCCESS( Status ))) {
+ DbgPrint ("TtdiOpenConnection: FAILURE, IoStatusBlock.Status contains status code=%lC.\n", Status);
+ }
+
+ DbgPrint ("TtdiOpenConnection: returning\n");
+
+ return Status;
+} /* TtdiOpenEndpoint */
+
+NTSTATUS
+CloseAddress (IN HANDLE FileHandle)
+{
+ NTSTATUS Status;
+
+ Status = NtClose (FileHandle);
+
+ if (!(NT_SUCCESS( Status ))) {
+ DbgPrint ("CloseAddress: FAILURE, NtClose returned status code=%lC.\n", Status);
+ } else {
+ DbgPrint ("CloseAddress: NT_SUCCESS.\n");
+ }
+
+ return Status;
+} /* CloseAddress */
+
+
+BOOLEAN
+TtdiSend()
+{
+ USHORT i, Iteration, Increment;
+ HANDLE RdrHandle, RdrConnectionHandle;
+ KEVENT Event1;
+ PFILE_OBJECT AddressObject, ConnectionObject;
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ PMDL SendMdl, ReceiveMdl;
+ IO_STATUS_BLOCK Iosb1;
+ TDI_CONNECTION_INFORMATION RequestInformation;
+ TDI_CONNECTION_INFORMATION ReturnInformation;
+ PTRANSPORT_ADDRESS ListenBlock;
+ PTRANSPORT_ADDRESS ConnectBlock;
+ PTDI_ADDRESS_NETBIOS temp;
+ PUCHAR MessageBuffer;
+ ULONG MessageBufferLength;
+ ULONG CurrentBufferLength;
+ PUCHAR SendBuffer;
+ ULONG SendBufferLength;
+ PIRP Irp;
+
+ Status = KeWaitForSingleObject (&TdiSendEvent, Suspended, KernelMode, FALSE, NULL);
+
+ SendBufferLength = (ULONG)BUFFER_SIZE;
+ MessageBufferLength = (ULONG)BUFFER_SIZE;
+
+
+ DbgPrint( "\n****** Start of Send Test ******\n" );
+
+ XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
+ if (XBuff == (PVOID)NULL) {
+ DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n");
+ return FALSE;
+ }
+ RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
+ if (RBuff == (PVOID)NULL) {
+ DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
+ return FALSE;
+ }
+
+ ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+ ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+
+ ListenBlock->TAAddressCount = 1;
+ ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = ClientName[i];
+ }
+
+ ConnectBlock->TAAddressCount = 1;
+ ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = ServerName[i];
+ }
+
+ //
+ // Create an event for the synchronous I/O requests that we'll be issuing.
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Status = TtdiOpenAddress (&RdrHandle, AnyName);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED on open of client: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ RdrHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &AddressObject,
+ NULL);
+
+ //
+ // Open the connection on the transport.
+ //
+
+ Status = TtdiOpenConnection (&RdrConnectionHandle, 1);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ RdrConnectionHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &ConnectionObject,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ //
+ // Get a pointer to the stack location for the first driver. This will be
+ // used to pass the original function codes and parameters.
+ //
+
+ DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_ASSOCIATE_ADDRESS,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+
+ //
+ // Get a pointer to the stack location for the first driver. This will be
+ // used to pass the original function codes and parameters.
+ //
+
+ TdiBuildAssociateAddress (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ RdrHandle);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Event1 Wait Associate: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Associate Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Send Test: AssociateAddress FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Send Test: Success AssociateAddress\n");
+ }
+ }
+
+ //
+ // Post a TdiConnect to the client endpoint.
+ //
+
+ RequestInformation.RemoteAddress = ConnectBlock;
+ RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS);
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_CONNECT,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildConnect (
+ Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ 0,
+ &RequestInformation,
+ &ReturnInformation);
+
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Event1 Wait Connect: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Iosb status Connect: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Send Test: Success Connect Iosb\n");
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Send Test: Connect FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Send Test: Success Connect Immediate\n");
+ }
+ }
+
+ DbgPrint( "\n****** Send Test: SUCCESSFUL TdiConnect: ******\n");
+
+ //
+ // Send/receive 1 or 10 messages.
+ //
+
+ SendBuffer = (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength);
+ if (SendBuffer == NULL) {
+ DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n");
+ }
+ SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool (SendMdl);
+
+ MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
+ if (MessageBuffer == NULL) {
+ DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n");
+ }
+ ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool (ReceiveMdl);
+
+ //
+ // Cycle the buffer length from 0 up through the maximum for Tdi. after a
+ // couple of shots at the full range in one byte steps, increment by ever
+ // increasing amounts to get to the max.
+ //
+
+ CurrentBufferLength = 0;
+ Increment = 1;
+ for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) {
+ CurrentBufferLength += Increment;
+ if (CurrentBufferLength > MessageBufferLength) {
+ CurrentBufferLength = 0;
+ Increment = 1;
+ }
+ if (CurrentBufferLength > 7500) {
+ Increment++;
+ }
+ if ((USHORT)((Iteration / 100) * 100) == Iteration) {
+ DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
+ Iteration, CurrentBufferLength,Iteration % 256);
+ }
+ for (i=0; i<(USHORT)CurrentBufferLength; i++) {
+ SendBuffer [i] = (UCHAR)(i + Iteration % 256 );
+ MessageBuffer [i] = 0; // zap this sucker with something.
+ }
+
+ //
+ // Now issue a send on the client side.
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_SEND,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildSend (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ ReceiveMdl,
+ 0,
+ CurrentBufferLength);
+
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Event1 Wait Send: %lC %d ******\n",
+ Status, Iteration );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Send Test: FAILED Iosb status Send: %lC %d ******\n",
+ Status, Iteration );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Send Test: Success SendIosb\n");
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Send Test: Send FAILED Status: %lC %d ******\n",
+ Status, Iteration );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Send Test: Success Send Immediate\n");
+ }
+ }
+
+ if (Iosb1.Information != CurrentBufferLength) {
+ DbgPrint ("SendTest: Bytes sent <> Send buffer size.\n");
+ DbgPrint ("SendTest: BytesToSend=%ld. BytesSent=%ld.\n",
+ CurrentBufferLength, Iosb1.Information);
+ }
+
+ }
+
+ //
+ // We're done with this endpoint. Close it and get out.
+ //
+
+ Status = CloseAddress (RdrHandle);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED on 2nd Close: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ DbgPrint( "\n****** End of Send Test ******\n" );
+ return TRUE;
+} /* Send */
+
+
+BOOLEAN
+TtdiReceive()
+{
+ USHORT i, Iteration, Increment;
+ SHORT j,k;
+ HANDLE SvrHandle, SvrConnectionHandle;
+ PFILE_OBJECT AddressObject, ConnectionObject;
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ PMDL SendMdl, ReceiveMdl;
+ IO_STATUS_BLOCK Iosb1;
+ TDI_CONNECTION_INFORMATION RequestInformation;
+ TDI_CONNECTION_INFORMATION ReturnInformation;
+ PTRANSPORT_ADDRESS ListenBlock;
+ PTRANSPORT_ADDRESS ConnectBlock;
+ PTDI_ADDRESS_NETBIOS temp;
+ PUCHAR MessageBuffer;
+ ULONG MessageBufferLength;
+ ULONG CurrentBufferLength;
+ PUCHAR SendBuffer;
+ ULONG SendBufferLength;
+ PIRP Irp;
+ KEVENT Event1;
+
+ Status = KeWaitForSingleObject (&TdiReceiveEvent, Suspended, KernelMode, FALSE, NULL);
+
+ SendBufferLength = (ULONG)BUFFER_SIZE;
+ MessageBufferLength = (ULONG)BUFFER_SIZE;
+
+
+ DbgPrint( "\n****** Start of Receive Test ******\n" );
+
+ XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
+ if (XBuff == (PVOID)NULL) {
+ DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n");
+ return FALSE;
+ }
+ RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
+ if (RBuff == (PVOID)NULL) {
+ DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
+ return FALSE;
+ }
+
+ ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+ ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+
+ ListenBlock->TAAddressCount = 1;
+ ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = ClientName[i];
+ }
+
+ ConnectBlock->TAAddressCount = 1;
+ ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = ServerName[i];
+ }
+
+ //
+ // Create an event for the synchronous I/O requests that we'll be issuing.
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Status = TtdiOpenAddress (&SvrHandle, ServerName);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED on open of server Address: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ SvrHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &AddressObject,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED on open of server Address: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = TtdiOpenConnection (&SvrConnectionHandle, 2);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ SvrConnectionHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &ConnectionObject,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ //
+ // Get a pointer to the stack location for the first driver. This will be
+ // used to pass the original function codes and parameters.
+ //
+
+ DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );
+
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_ASSOCIATE_ADDRESS,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ DbgPrint ("Build Irp %lx, Handle %lx \n",
+ Irp, SvrHandle);
+
+ TdiBuildAssociateAddress (
+ Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ SvrHandle);
+ InitWaitObject (&Event1);
+
+ {
+ PULONG Temp=(PULONG)IoGetNextIrpStackLocation (Irp);
+ DbgPrint ("Built IrpSp %lx %lx %lx %lx %lx \n", *(Temp++), *(Temp++),
+ *(Temp++), *(Temp++), *(Temp++));
+ }
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Associate: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Associate Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Receive Test: AssociateAddress FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Receive Test: Success AssociateAddress\n");
+ }
+ }
+
+ RequestInformation.RemoteAddress = ConnectBlock;
+ RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS);
+
+ //
+ // Post a TdiListen to the server endpoint.
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_LISTEN,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildListen (
+ Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ 0,
+ &RequestInformation,
+ &ReturnInformation);
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Listen: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Listen Iosb status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Receive Test: Success Listen IOSB\n");
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Receive Test: Listen FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+ DbgPrint ("********** Receive Test: Success Listen Immediate\n");
+ }
+ }
+
+
+ DbgPrint ("\n****** Receive Test: LISTEN just completed! ******\n");
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_ACCEPT,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildAccept (Irp, DeviceObject, ConnectionObject, NULL, NULL, &RequestInformation, NULL, 0);
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Accept: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Accept Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Receive Test: Accept FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ }
+ }
+
+ //
+ // We have the connection data now. Sanity check it.
+ //
+
+ DbgPrint ("\n****** Receive Test: LISTEN completed successfully! ******\n");
+
+ //
+ // Receive/receive 1 or 10 messages.
+ //
+
+ SendBuffer = (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength);
+ if (SendBuffer == NULL) {
+ DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n");
+ }
+ SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool (SendMdl);
+
+ MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
+ if (MessageBuffer == NULL) {
+ DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n");
+ }
+ ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool (ReceiveMdl);
+
+ //
+ // Cycle the buffer length from 0 up through the maximum for Tdi. after a
+ // couple of shots at the full range in one byte steps, increment by ever
+ // increasing amounts to get to the max.
+ //
+
+ CurrentBufferLength = 0;
+ Increment = 1;
+ for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) {
+ CurrentBufferLength += Increment;
+ if (CurrentBufferLength > MessageBufferLength) {
+ CurrentBufferLength = 0;
+ Increment = 1;
+ }
+ if (CurrentBufferLength > 7500) {
+ Increment++;
+ }
+ if ((USHORT)((Iteration / 100) * 100) == Iteration) {
+ DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
+ Iteration, CurrentBufferLength,Iteration % 256);
+ }
+ for (i=0; i<(USHORT)CurrentBufferLength; i++) {
+ SendBuffer [i] = (UCHAR)(i + Iteration % 256 );
+ MessageBuffer [i] = 0; // zap this sucker with something.
+ }
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_RECEIVE,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildReceive (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ ReceiveMdl,
+ MessageBufferLength);
+
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+// IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Receive: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Receive Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Receive Test: Listen FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ }
+ }
+
+ //
+ // The receive completed. Make sure the data is correct.
+ //
+
+ if (Iosb1.Information != CurrentBufferLength) {
+ DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n",
+ Iteration, CurrentBufferLength,Iteration % 256);
+ DbgPrint ("ReceiveTest: Bytes received <> bytes sent.\n");
+ DbgPrint ("ReceiveTest: BytesToSend=%ld. BytesReceived=%ld.\n",
+ CurrentBufferLength, Iosb1.Information);
+ }
+
+ if (i == (USHORT)CurrentBufferLength) {
+// DbgPrint ("ReceiveTest: Message contains correct data.\n");
+ } else {
+ DbgPrint ("ReceiveTest: Message data corrupted at offset %lx of %lx.\n", (ULONG)i, (ULONG)SendBufferLength);
+ DbgPrint ("ReceiveTest: Data around corrupted location:\n");
+ for (j=-4;j<=3;j++) {
+ DbgPrint ("%08lx ", (ULONG) i+j*16);
+ for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
+ DbgPrint ("%02x",MessageBuffer [k]);
+ }
+ for (k=(SHORT)i+(j*(SHORT)16);k<(SHORT)i+((j+(SHORT)1)*(SHORT)16);k++) {
+ DbgPrint ("%c",MessageBuffer [k]);
+ }
+ DbgPrint ("\n");
+ }
+ DbgPrint ("ReceiveTest: End of Corrupt Data.\n");
+ }
+ }
+
+ //
+ // We're done with this endpoint. Close it and get out.
+ //
+
+ Status = CloseAddress (SvrHandle);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED on 1st Close: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ DbgPrint( "\n****** End of Receive Test ******\n" );
+ return TRUE;
+} /* Receive */
+
+BOOLEAN
+TtdiServer()
+{
+ USHORT i;
+ HANDLE RdrHandle, SrvConnectionHandle;
+ KEVENT Event1;
+ PFILE_OBJECT AddressObject, ConnectionObject;
+ PDEVICE_OBJECT DeviceObject;
+ NTSTATUS Status;
+ PMDL ReceiveMdl;
+ IO_STATUS_BLOCK Iosb1;
+ TDI_CONNECTION_INFORMATION RequestInformation;
+ TDI_CONNECTION_INFORMATION ReturnInformation;
+ PTRANSPORT_ADDRESS ListenBlock;
+ PTRANSPORT_ADDRESS ConnectBlock;
+ PTDI_ADDRESS_NETBIOS temp;
+ PUCHAR MessageBuffer;
+ ULONG MessageBufferLength;
+ ULONG CurrentBufferLength;
+ PIRP Irp;
+
+ Status = KeWaitForSingleObject (&TdiServerEvent, Suspended, KernelMode, FALSE, NULL);
+
+ MessageBufferLength = (ULONG)BUFFER_SIZE;
+
+
+ DbgPrint( "\n****** Start of Server Test ******\n" );
+
+ RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE);
+ if (RBuff == (PVOID)NULL) {
+ DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n");
+ return FALSE;
+ }
+
+ ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+ ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS));
+
+ ListenBlock->TAAddressCount = 1;
+ ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = AnyName[i];
+ }
+
+ ConnectBlock->TAAddressCount = 1;
+ ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS;
+ ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS);
+ temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address;
+
+ temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
+ for (i=0;i<16;i++) {
+ temp->NetbiosName[i] = ServerName[i];
+ }
+
+ //
+ // Create an event for the synchronous I/O requests that we'll be issuing.
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Status = TtdiOpenAddress (&RdrHandle, ServerName);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Server Test: FAILED on open of client: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ RdrHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &AddressObject,
+ NULL);
+
+ //
+ // Now loop forever trying to get a connection from a remote client to
+ // this server. We will create connections until we run out of resources,
+ // and we will echo the data we are sent back along the same connection.
+ // Sends and Receives are always asynchronous, while listens are
+ // synchronous.
+ //
+
+ while (TRUE) {
+
+ //
+ // Open the connection on the transport.
+ //
+
+ Status = TtdiOpenConnection (&SrvConnectionHandle, 1);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Server Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ Status = ObReferenceObjectByHandle (
+ SrvConnectionHandle,
+ 0L,
+ NULL,
+ KernelMode,
+ (PVOID *) &ConnectionObject,
+ NULL);
+
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Server Test: FAILED on open of server Connection: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ //
+ // Get a pointer to the stack location for the first driver. This will be
+ // used to pass the original function codes and parameters.
+ //
+
+ DeviceObject = IoGetRelatedDeviceObject( ConnectionObject );
+
+ //
+ // Now register the device handler for receives
+ //
+
+// Irp = TdiBuildInternalDeviceControlIrp (
+// TDI_SET_EVENT_HANDLER,
+// DeviceObject,
+// ConnectionObject,
+// &Event1,
+// &Iosb1);
+
+// TdiBuildSetEventHandler (Irp,
+// DeviceObject,
+// ConnectionObject,
+// TSTRCVCompletion,
+// &Event1,
+// TDI_RECEIVE_HANDLER,
+// TdiTestReceiveHandler,
+// ConnectionObject);
+
+// Status = IoCallDriver (DeviceObject, Irp);
+
+// if (Status == STATUS_PENDING) {
+// Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+// if (!NT_SUCCESS(Status)) {
+// DbgPrint( "\n****** Server Test: FAILED Event1 Wait Register: %lC ******\n", Status );
+// return FALSE;
+// }
+// if (!NT_SUCCESS(Iosb1.Status)) {
+// DbgPrint( "\n****** Server Test: FAILED Register Iosb status: %lC ******\n", Status );
+// return FALSE;
+// }
+//
+// } else {
+// if (!NT_SUCCESS (Status)) {
+// DbgPrint( "\n****** Server Test: RegisterHandler FAILED Status: %lC ******\n", Status );
+// return FALSE;
+// }
+// }
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_ASSOCIATE_ADDRESS,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildAssociateAddress (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ RdrHandle);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+ // IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Server Test: FAILED Event1 Wait Associate: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Server Test: FAILED Associate Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Server Test: AssociateAddress FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ }
+ }
+
+ //
+ // Post a TdiListen to the server endpoint.
+ //
+
+ RequestInformation.RemoteAddress = ListenBlock;
+ RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) +
+ sizeof (TDI_ADDRESS_NETBIOS);
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_LISTEN,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildListen (
+ Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ 0,
+ &RequestInformation,
+ NULL);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Server Test: FAILED Event1 Wait Listen: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Server Test: FAILED Listen Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Server Test: Listen FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ }
+ }
+
+ DbgPrint ("\n****** Server Test: LISTEN just completed! ******\n");
+
+ //
+ // accept the connection from the remote
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_ACCEPT,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildAccept (
+ Irp,
+ DeviceObject,
+ ConnectionObject,
+ NULL,
+ NULL,
+ &RequestInformation,
+ NULL,
+ 0);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+ // IoFreeIrp (Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Accept: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Accept Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+ DbgPrint( "\n****** Accept Test: Listen FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ }
+ }
+
+ //
+ // Get a buffer for the continued read/write loop.
+ //
+
+ MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength);
+ if (MessageBuffer == NULL) {
+ DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n");
+ }
+ ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL);
+ MmBuildMdlForNonPagedPool (ReceiveMdl);
+
+ //
+ // have a receive buffer, and a connection; go ahead and read and write
+ // until the remote disconnects.
+ //
+
+ while (TRUE) {
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_RECEIVE,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildReceive (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ ReceiveMdl,
+ MessageBufferLength);
+
+ InitWaitObject (&Event1);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Receive: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Receive Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+
+ //
+ // Check to see if the remote has disconnected, which is
+ // the only reason for us shutting down/
+ //
+
+ if (Status == STATUS_REMOTE_DISCONNECT) {
+
+ //
+ // We've been disconnected from; get out
+ //
+
+ NtClose (SrvConnectionHandle);
+ break;
+ }
+
+ DbgPrint( "\n****** Receive Test: Listen FAILED Status: %lC ******\n", Status );
+ return FALSE;
+ } else {
+
+ //
+ // successful return, what length is the data?
+ //
+
+ CurrentBufferLength = Iosb1.Information;
+ }
+ }
+
+ //
+ // send the data back
+ //
+
+ KeInitializeEvent (
+ &Event1,
+ SynchronizationEvent,
+ FALSE);
+
+ Irp = TdiBuildInternalDeviceControlIrp (
+ TDI_SEND,
+ DeviceObject,
+ ConnectionObject,
+ &Event1,
+ &Iosb1);
+
+ TdiBuildSend (Irp,
+ DeviceObject,
+ ConnectionObject,
+ TSTRCVCompletion,
+ &Event1,
+ ReceiveMdl,
+ 0,
+ CurrentBufferLength);
+
+ Status = IoCallDriver (DeviceObject, Irp);
+
+ if (Status == STATUS_PENDING) {
+ Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Event1 Wait Send: %lC ******\n", Status );
+ return FALSE;
+ }
+ if (!NT_SUCCESS(Iosb1.Status)) {
+ DbgPrint( "\n****** Receive Test: FAILED Send Iosb status: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ } else {
+ if (!NT_SUCCESS (Status)) {
+
+ DbgPrint( "\n****** Receive Test: Send FAILED Status: %lC ******\n", Status );
+ NtClose (SrvConnectionHandle);
+ break;
+
+ }
+ }
+ } // end of receive/send while
+
+ IoFreeMdl (ReceiveMdl);
+ ExFreePool (MessageBuffer);
+
+ }
+
+ //
+ // We're done with this address. Close it and get out.
+ //
+
+ Status = CloseAddress (RdrHandle);
+ if (!NT_SUCCESS(Status)) {
+ DbgPrint( "\n****** Send Test: FAILED on 2nd Close: %lC ******\n", Status );
+ return FALSE;
+ }
+
+ DbgPrint( "\n****** End of Send Test ******\n" );
+ return TRUE;
+} /* Server */