NTSTATUS tdi_recv_stream(PFILE_OBJECT connectionFileObject, char *buf, int len, ULONG flags) { PDEVICE_OBJECT devObj; KEVENT event; PIRP irp; PMDL mdl; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } if (len) { mdl = IoAllocateMdl((void*) buf, len, FALSE, FALSE, NULL); if (mdl == NULL) { IoFreeIrp(irp); return STATUS_INSUFFICIENT_RESOURCES; } __try { MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildReceive(irp, devObj, connectionFileObject, NULL, NULL, len ? mdl : 0, flags, len); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } return NT_SUCCESS(status) ? iosb.Information : status; }
NTSTATUS TdiRecv( PFILE_OBJECT ConnectionObject, PVOID Data, ULONG Length ) { NTSTATUS ntStatus; IO_STATUS_BLOCK IoStatus; KEVENT Event; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); PIRP Irp; PMDL Mdl; KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, DeviceObject, ConnectionObject, &Event, &IoStatus))) return STATUS_INSUFFICIENT_RESOURCES; if (!(Mdl = IoAllocateMdl(Data, Length, FALSE, FALSE, Irp))) { IoFreeIrp(Irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(Mdl, KernelMode, IoModifyAccess); TdiBuildReceive(Irp, DeviceObject, ConnectionObject, 0, 0, Mdl, TDI_RECEIVE_NORMAL, Length); ntStatus = IoCallDriver(DeviceObject, Irp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS LpxTdiRecvWithCompletionEvent_TimeOut( IN PFILE_OBJECT ConnectionFileObject, IN PTDI_RECEIVE_CONTEXT TdiReceiveContext, OUT PUCHAR RecvBuffer, IN ULONG RecvLength, IN ULONG Flags, IN PLARGE_INTEGER TimeOut ) { PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; PMDL mdl; ASSERT(ConnectionFileObject); LtDebugPrint (3, ("LpxTdiRecvWithCompletionEvent: Entered\n")); if((RecvBuffer == NULL) || (RecvLength == 0)) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Rcv buffer == NULL or RcvLen == 0.\n")); return STATUS_NOT_IMPLEMENTED; } deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, NULL, NULL ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( RecvBuffer, RecvLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Allocate MDL.\n")); IoFreeIrp(irp); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); TdiBuildReceive( irp, deviceObject, ConnectionFileObject, LpxTdiRecvWithCompletionEventCompletionRoutine, TdiReceiveContext, mdl, Flags, RecvLength ); if(TimeOut) SET_IRP_EXPTIME(irp, CurrentTime().QuadPart + TimeOut->QuadPart); else SET_IRP_EXPTIME(irp, 0); ntStatus = IoCallDriver( deviceObject, irp ); if(!NT_SUCCESS(ntStatus)) { TdiReceiveContext->Irp = NULL; LtDebugPrint(1, ("[LpxTdi]LpxTdiRecv: Failed.\n")); return ntStatus; } TdiReceiveContext->Irp = irp; return ntStatus; }
NTSTATUS LpxTdiRecv_TimeOut( IN PFILE_OBJECT ConnectionFileObject, OUT PUCHAR RecvBuffer, IN ULONG RecvLength, IN ULONG Flags, IN PLONG Result, IN PLARGE_INTEGER TimeOut ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; if((RecvBuffer == NULL) || (RecvLength == 0)) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Rcv buffer == NULL or RcvLen == 0.\n")); return STATUS_INSUFFICIENT_RESOURCES; } LtDebugPrint (3, ("LpxTdiRecv: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } /* try { // // Make MDL. // */ mdl = IoAllocateMdl( RecvBuffer, RecvLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); /* MmProbeAndLockPages( mdl, KernelMode, IoWriteAccess ); } except (EXCEPTION_EXECUTE_HANDLER) { LtDebugPrint(1, ("[LpxTdi]TdiReceive: Can't Convert Non-Paged Memory MDL.\n")); if(mdl){ IoFreeMdl(mdl); //IoFreeIrp(irp); } return STATUS_INSUFFICIENT_RESOURCES; } */ TdiBuildReceive( irp, deviceObject, ConnectionFileObject, LpxTdiRcvCompletionRoutine, NULL, mdl, Flags, RecvLength ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, TimeOut ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiRecv: Failed.\n")); *Result = -1; return ntStatus; } *Result = ioStatusBlock.Information; return ntStatus; }
NTSTATUS LpxTdiRecv_LSTrans( IN PFILE_OBJECT ConnectionFileObject, OUT PUCHAR RecvBuffer, IN ULONG RecvLength, IN ULONG Flags, IN PLARGE_INTEGER TimeOut, OUT PLS_TRANS_STAT TransStat, OUT PLONG Result, IN PLSTRANS_OVERLAPPED OverlappedData ){ KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; BOOLEAN synch; PTRANS_STAT transStat; LtDebugPrint (3, ("LpxTdiRecv_LSTrans: Entered\n")); // // Parameter check // if(OverlappedData) { if(TransStat || Result) { return STATUS_INVALID_PARAMETER; } transStat = (PTRANS_STAT)OverlappedData->TransStat; synch = FALSE; } else { transStat = (PTRANS_STAT)TransStat; synch = TRUE; } if((RecvBuffer == NULL) || (RecvLength == 0)) { LtDebugPrint(1, ("[LpxTdi] LpxTdiRecv_LSTrans: Rcv buffer == NULL or RcvLen == 0.\n")); return STATUS_INSUFFICIENT_RESOURCES; } deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // if(synch) { KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, &event, &ioStatusBlock ); } else { irp = TdiBuildInternalDeviceControlIrp( TDI_RECEIVE, deviceObject, connectionFileObject, NULL, NULL ); } if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi] LpxTdiRecv_LSTrans: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( RecvBuffer, RecvLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi] LpxTdiRecv_LSTrans: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } MmBuildMdlForNonPagedPool(mdl); TdiBuildReceive( irp, deviceObject, ConnectionFileObject, IrpCompletionForUserNotification, OverlappedData, mdl, Flags, RecvLength ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, transStat, TimeOut, synch ); if(synch) { if(ntStatus == STATUS_SUCCESS) { ntStatus = RtlULongPtrToLong(ioStatusBlock.Information, Result); ASSERT(NT_SUCCESS(ntStatus)); } else { LtDebugPrint(1, ("[LpxTdi] LpxTdiRecv_LSTrans: Failed. STATUS=%08lx\n", ntStatus)); *Result = 0; } } #if DBG else { if(ntStatus != STATUS_SUCCESS && ntStatus != STATUS_PENDING) { LtDebugPrint(1, ("[LpxTdi] LpxTdiSend_LSTrans: Failed. STATUS=%08lx\n", ntStatus)); } } #endif return ntStatus; }
NTSTATUS TdiReceive( PIRP *Irp, PFILE_OBJECT TransportObject, USHORT Flags, PCHAR Buffer, UINT BufferLength, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) { PDEVICE_OBJECT DeviceObject; PMDL Mdl; ASSERT(*Irp == NULL); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(TransportObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_RECEIVE, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ NULL, /* Event */ NULL); /* Status */ if (!*Irp) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } AFD_DbgPrint(MID_TRACE, ("Allocating irp for %p:%u\n", Buffer,BufferLength)); Mdl = IoAllocateMdl(Buffer, /* Virtual address */ BufferLength, /* Length of buffer */ FALSE, /* Not secondary */ FALSE, /* Don't charge quota */ NULL); /* Don't use IRP */ if (!Mdl) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); IoCompleteRequest(*Irp, IO_NO_INCREMENT); *Irp = NULL; return STATUS_INSUFFICIENT_RESOURCES; } _SEH2_TRY { AFD_DbgPrint(MID_TRACE, ("probe and lock\n")); MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); AFD_DbgPrint(MID_TRACE, ("probe and lock done\n")); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n")); IoFreeMdl(Mdl); IoCompleteRequest(*Irp, IO_NO_INCREMENT); *Irp = NULL; _SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES); } _SEH2_END; AFD_DbgPrint(MID_TRACE,("AFD>>> Got an MDL: %p\n", Mdl)); TdiBuildReceive(*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion context */ Mdl, /* Data buffer */ Flags, /* Flags */ BufferLength); /* Length of data */ TdiCall(*Irp, DeviceObject, NULL, NULL); /* Does not block... The MDL is deleted in the receive completion routine. */ return STATUS_PENDING; }
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 */