windows-nt/Source/XPSP1/NT/net/netbeui/sys/testnbf.c
2020-09-26 16:20:57 +08:00

1467 lines
45 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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