diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/tdi/nbf/testnbf.c | 1466 |
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 */ |