|
|
/*++
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 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 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 */
|