NTSTATUS tdi_send_stream(PFILE_OBJECT connectionFileObject, const 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_SEND, 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, IoReadAccess); status = STATUS_SUCCESS; } __except (EXCEPTION_EXECUTE_HANDLER) { IoFreeMdl(mdl); IoFreeIrp(irp); status = STATUS_INVALID_USER_BUFFER; } if (!NT_SUCCESS(status)) { return status; } } TdiBuildSend(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 TdiSend( PFILE_OBJECT ConnectionObject, PVOID Data, ULONG Length ) { NTSTATUS ntStatus; KEVENT Event; PIRP Irp; PMDL Mdl; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); IO_STATUS_BLOCK IoStatus; KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_SEND, 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); TdiBuildSend(Irp, DeviceObject, ConnectionObject, 0, 0, Mdl, 0, Length); ntStatus = IoCallDriver(DeviceObject, Irp); if (ntStatus == STATUS_PENDING) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus == STATUS_SUCCESS ? IoStatus.Status : ntStatus); }
NTSTATUS LpxTdiSendEx( IN PFILE_OBJECT ConnectionFileObject, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, IN PKEVENT CompEvent, IN PLARGE_INTEGER TimeOut, IN OUT PVOID CompletionContext, OUT PIO_STATUS_BLOCK IoStatusBlock ) { PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; PMDL mdl; LtDebugPrint (3, ("[LPXTDI]LpxTdiSendEx: Entered\n")); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, CompEvent, IoStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); if(CompletionContext) { TdiBuildSend( irp, deviceObject, ConnectionFileObject, LpxTdiSendCompletionRoutine, CompletionContext, mdl, Flags, SendLength ); } else { TdiBuildSend( irp, deviceObject, ConnectionFileObject, NULL, NULL, mdl, Flags, SendLength ); } ntStatus = LpxTdiIoCallDriver( deviceObject, irp, IoStatusBlock, CompEvent, TimeOut ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSendEx: Failed.\n")); } return ntStatus; }
NTSTATUS LpxTdiSend_TimeOut( IN PFILE_OBJECT ConnectionFileObject, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, OUT PLONG Result, IN PLARGE_INTEGER TimeOut ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; LtDebugPrint (3, ("LpxTdiSend: Entered\n")); // // Send bytes is restricted below 64 KBytes. // Removed. // Now NDAS service will control request data size. // Write size will be controlled by retransmits // SendLength = SendLength > LPXTDI_BYTEPERPACKET?LPXTDI_BYTEPERPACKET:SendLength; // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiSend: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } /* try { // // Make MDL. // */ mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiSend: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); /* MmProbeAndLockPages( mdl, KernelMode, IoReadAccess ); } except (EXCEPTION_EXECUTE_HANDLER) { LtDebugPrint(1, ("[LpxTdi]TdiSend: Can't Convert Non-Paged Memory MDL.\n")); if(mdl){ IoFreeMdl(mdl); } return STATUS_INSUFFICIENT_RESOURCES; } if(!MmIsNonPagedSystemAddressValid(MmGetMdlVirtualAddress(mdl))) { if(mdl){ IoFreeMdl(mdl); }; return STATUS_INSUFFICIENT_RESOURCES; } */ TdiBuildSend( irp, deviceObject, ConnectionFileObject, LpxTdiSendCompletionRoutine, NULL, mdl, Flags, SendLength ); ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, TimeOut ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]LpxTdiSend: Failed.\n")); *Result = -1; return ntStatus; } *Result = ioStatusBlock.Information; return ntStatus; }
NTSTATUS LpxTdiSend_LSTrans( IN PFILE_OBJECT ConnectionFileObject, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, IN PLARGE_INTEGER TimeOut, OUT PLS_TRANS_STAT TransStat, OUT PLONG Result, IN PLSTRANS_OVERLAPPED OverlappedData ){ PDEVICE_OBJECT deviceObject; PIRP irp; NTSTATUS ntStatus; PMDL mdl; BOOLEAN synch; KEVENT event; IO_STATUS_BLOCK ioStatusBlock; PTRANS_STAT transStat; LtDebugPrint (3, ("[LPXTDI] LpxTdiSend_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((SendBuffer == NULL) || (SendLength == 0)) { LtDebugPrint(1, ("[LpxTdi] LpxTdiSend_LSTrans: SendBuffer == NULL or SendLen == 0.\n")); return STATUS_INSUFFICIENT_RESOURCES; } // // Get the related device ( LPX's control device ) // deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // if(synch) { // Synchronous KeInitializeEvent(&event, NotificationEvent, FALSE); irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, &event, &ioStatusBlock ); } else { irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, NULL, NULL ); } if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi] LpxTdiSend_LSTrans: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { LtDebugPrint(1, ("[LpxTdi] LpxTdiSend_LSTrans: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } MmBuildMdlForNonPagedPool(mdl); TdiBuildSend( irp, deviceObject, ConnectionFileObject, IrpCompletionForUserNotification, OverlappedData, mdl, Flags, SendLength); 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] LpxTdiSend_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 TdiSend( 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_SEND, /* 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 { MmProbeAndLockPages(Mdl, (*Irp)->RequestorMode, IoModifyAccess); } _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)); TdiBuildSend(*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 TtdiSend() { USHORT i, Iteration, Increment; HANDLE RdrHandle, RdrConnectionHandle; KEVENT Event1; PFILE_OBJECT AddressObject, ConnectionObject; PDEVICE_OBJECT DeviceObject; NTSTATUS Status; PMDL SendMdl, ReceiveMdl; IO_STATUS_BLOCK Iosb1; TDI_CONNECTION_INFORMATION RequestInformation; TDI_CONNECTION_INFORMATION ReturnInformation; PTRANSPORT_ADDRESS ListenBlock; PTRANSPORT_ADDRESS ConnectBlock; PTDI_ADDRESS_NETBIOS temp; PUCHAR MessageBuffer; ULONG MessageBufferLength; ULONG CurrentBufferLength; PUCHAR SendBuffer; ULONG SendBufferLength; PIRP Irp; Status = KeWaitForSingleObject (&TdiSendEvent, Suspended, KernelMode, FALSE, NULL); SendBufferLength = (ULONG)BUFFER_SIZE; MessageBufferLength = (ULONG)BUFFER_SIZE; DbgPrint( "\n****** Start of Send Test ******\n" ); XBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE); if (XBuff == (PVOID)NULL) { DbgPrint ("Unable to allocate nonpaged pool for send buffer exiting\n"); return FALSE; } RBuff = ExAllocatePool (NonPagedPool, BUFFER_SIZE); if (RBuff == (PVOID)NULL) { DbgPrint ("Unable to allocate nonpaged pool for receive buffer exiting\n"); return FALSE; } ListenBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) + sizeof (TDI_ADDRESS_NETBIOS)); ConnectBlock = ExAllocatePool (NonPagedPool, sizeof (TRANSPORT_ADDRESS) + sizeof (TDI_ADDRESS_NETBIOS)); ListenBlock->TAAddressCount = 1; ListenBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS; ListenBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS); temp = (PTDI_ADDRESS_NETBIOS)ListenBlock->Address[0].Address; temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE; for (i=0;i<16;i++) { temp->NetbiosName[i] = ClientName[i]; } ConnectBlock->TAAddressCount = 1; ConnectBlock->Address[0].AddressType = TDI_ADDRESS_TYPE_NETBIOS; ConnectBlock->Address[0].AddressLength = sizeof (TDI_ADDRESS_NETBIOS); temp = (PTDI_ADDRESS_NETBIOS)ConnectBlock->Address[0].Address; temp->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE; for (i=0;i<16;i++) { temp->NetbiosName[i] = ServerName[i]; } // // Create an event for the synchronous I/O requests that we'll be issuing. // KeInitializeEvent ( &Event1, SynchronizationEvent, FALSE); Status = TtdiOpenAddress (&RdrHandle, AnyName); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED on open of client: %lC ******\n", Status ); return FALSE; } Status = ObReferenceObjectByHandle ( RdrHandle, 0L, NULL, KernelMode, (PVOID *) &AddressObject, NULL); // // Open the connection on the transport. // Status = TtdiOpenConnection (&RdrConnectionHandle, 1); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED on open of server Connection: %lC ******\n", Status ); return FALSE; } Status = ObReferenceObjectByHandle ( RdrConnectionHandle, 0L, NULL, KernelMode, (PVOID *) &ConnectionObject, NULL); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED on open of server Connection: %lC ******\n", Status ); return FALSE; } // // Get a pointer to the stack location for the first driver. This will be // used to pass the original function codes and parameters. // DeviceObject = IoGetRelatedDeviceObject( ConnectionObject ); Irp = TdiBuildInternalDeviceControlIrp ( TDI_ASSOCIATE_ADDRESS, DeviceObject, ConnectionObject, &Event1, &Iosb1); // // Get a pointer to the stack location for the first driver. This will be // used to pass the original function codes and parameters. // TdiBuildAssociateAddress (Irp, DeviceObject, ConnectionObject, TSTRCVCompletion, &Event1, RdrHandle); Status = IoCallDriver (DeviceObject, Irp); // IoFreeIrp (Irp); if (Status == STATUS_PENDING) { Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED Event1 Wait Associate: %lC ******\n", Status ); return FALSE; } if (!NT_SUCCESS(Iosb1.Status)) { DbgPrint( "\n****** Send Test: FAILED Associate Iosb status: %lC ******\n", Status ); return FALSE; } } else { if (!NT_SUCCESS (Status)) { DbgPrint( "\n****** Send Test: AssociateAddress FAILED Status: %lC ******\n", Status ); return FALSE; } else { DbgPrint ("********** Send Test: Success AssociateAddress\n"); } } // // Post a TdiConnect to the client endpoint. // RequestInformation.RemoteAddress = ConnectBlock; RequestInformation.RemoteAddressLength = sizeof (TRANSPORT_ADDRESS) + sizeof (TDI_ADDRESS_NETBIOS); KeInitializeEvent ( &Event1, SynchronizationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp ( TDI_CONNECT, DeviceObject, ConnectionObject, &Event1, &Iosb1); TdiBuildConnect ( Irp, DeviceObject, ConnectionObject, TSTRCVCompletion, &Event1, 0, &RequestInformation, &ReturnInformation); InitWaitObject (&Event1); Status = IoCallDriver (DeviceObject, Irp); // IoFreeIrp (Irp); if (Status == STATUS_PENDING) { Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED Event1 Wait Connect: %lC ******\n", Status ); return FALSE; } if (!NT_SUCCESS(Iosb1.Status)) { DbgPrint( "\n****** Send Test: FAILED Iosb status Connect: %lC ******\n", Status ); return FALSE; } else { DbgPrint ("********** Send Test: Success Connect Iosb\n"); } } else { if (!NT_SUCCESS (Status)) { DbgPrint( "\n****** Send Test: Connect FAILED Status: %lC ******\n", Status ); return FALSE; } else { DbgPrint ("********** Send Test: Success Connect Immediate\n"); } } DbgPrint( "\n****** Send Test: SUCCESSFUL TdiConnect: ******\n"); // // Send/receive 1 or 10 messages. // SendBuffer = (PUCHAR)ExAllocatePool (NonPagedPool, SendBufferLength); if (SendBuffer == NULL) { DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n"); } SendMdl = IoAllocateMdl (SendBuffer, SendBufferLength, FALSE, FALSE, NULL); MmBuildMdlForNonPagedPool (SendMdl); MessageBuffer=(PUCHAR)ExAllocatePool (NonPagedPool, MessageBufferLength); if (MessageBuffer == NULL) { DbgPrint ("\n****** Send Test: ExAllocatePool failed! ******\n"); } ReceiveMdl = IoAllocateMdl (MessageBuffer, MessageBufferLength, FALSE, FALSE, NULL); MmBuildMdlForNonPagedPool (ReceiveMdl); // // Cycle the buffer length from 0 up through the maximum for Tdi. after a // couple of shots at the full range in one byte steps, increment by ever // increasing amounts to get to the max. // CurrentBufferLength = 0; Increment = 1; for (Iteration=1; Iteration<(USHORT)c9_Iteration; Iteration++) { CurrentBufferLength += Increment; if (CurrentBufferLength > MessageBufferLength) { CurrentBufferLength = 0; Increment = 1; } if (CurrentBufferLength > 7500) { Increment++; } if ((USHORT)((Iteration / 100) * 100) == Iteration) { DbgPrint ("Iteration #%d Buffer Length: %lx Buffer Start: %x\n", Iteration, CurrentBufferLength,Iteration % 256); } for (i=0; i<(USHORT)CurrentBufferLength; i++) { SendBuffer [i] = (UCHAR)(i + Iteration % 256 ); MessageBuffer [i] = 0; // zap this sucker with something. } // // Now issue a send on the client side. // KeInitializeEvent ( &Event1, SynchronizationEvent, FALSE); Irp = TdiBuildInternalDeviceControlIrp ( TDI_SEND, DeviceObject, ConnectionObject, &Event1, &Iosb1); TdiBuildSend (Irp, DeviceObject, ConnectionObject, TSTRCVCompletion, &Event1, ReceiveMdl, 0, CurrentBufferLength); InitWaitObject (&Event1); Status = IoCallDriver (DeviceObject, Irp); // IoFreeIrp (Irp); if (Status == STATUS_PENDING) { Status = KeWaitForSingleObject (&Event1, Suspended, KernelMode, TRUE, NULL); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED Event1 Wait Send: %lC %d ******\n", Status, Iteration ); return FALSE; } if (!NT_SUCCESS(Iosb1.Status)) { DbgPrint( "\n****** Send Test: FAILED Iosb status Send: %lC %d ******\n", Status, Iteration ); return FALSE; } else { DbgPrint ("********** Send Test: Success SendIosb\n"); } } else { if (!NT_SUCCESS (Status)) { DbgPrint( "\n****** Send Test: Send FAILED Status: %lC %d ******\n", Status, Iteration ); return FALSE; } else { DbgPrint ("********** Send Test: Success Send Immediate\n"); } } if (Iosb1.Information != CurrentBufferLength) { DbgPrint ("SendTest: Bytes sent <> Send buffer size.\n"); DbgPrint ("SendTest: BytesToSend=%ld. BytesSent=%ld.\n", CurrentBufferLength, Iosb1.Information); } } // // We're done with this endpoint. Close it and get out. // Status = CloseAddress (RdrHandle); if (!NT_SUCCESS(Status)) { DbgPrint( "\n****** Send Test: FAILED on 2nd Close: %lC ******\n", Status ); return FALSE; } DbgPrint( "\n****** End of Send Test ******\n" ); return TRUE; } /* Send */
BOOLEAN 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 */
NTSTATUS TcpTdiSend( IN PFILE_OBJECT ConnectionFileObject, IN PUCHAR SendBuffer, IN ULONG SendLength, IN ULONG Flags, OUT PLONG Result ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; NTSTATUS ntStatus; PMDL mdl; TCPLtDebugPrint (3, ("TcpTdiSend: Entered\n")); SendLength = SendLength > TCPTDI_BYTEPERPACKET?TCPTDI_BYTEPERPACKET:SendLength ; // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_SEND, deviceObject, ConnectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { TCPLtDebugPrint(1, ("[TcpTdi]TdiSend: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } // try { // // Make MDL. // mdl = IoAllocateMdl( SendBuffer, SendLength, FALSE, FALSE, irp ); if(mdl == NULL) { TCPLtDebugPrint(1, ("[TcpTdi]TdiSend: Can't Allocate MDL.\n")); return STATUS_INSUFFICIENT_RESOURCES; } mdl->Next = NULL; MmBuildMdlForNonPagedPool(mdl); // MmProbeAndLockPages( // mdl, // KernelMode, // IoReadAccess // ); // } except (EXCEPTION_EXECUTE_HANDLER) { // TCPLtDebugPrint(1, ("[TcpTdi]TdiSend: Can't Convert Non-Paged Memory MDL.\n")); // if(mdl){ // IoFreeMdl(mdl); // } // return STATUS_INSUFFICIENT_RESOURCES; // } // if(!MmIsNonPagedSystemAddressValid(MmGetMdlVirtualAddress(mdl))) // { // if(mdl){ // IoFreeMdl(mdl); // }; // return STATUS_INSUFFICIENT_RESOURCES; // } TdiBuildSend( irp, deviceObject, ConnectionFileObject, TcpTdiSendCompletionRoutine, NULL, mdl, Flags, SendLength ); ntStatus = TcpTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event ); if(!NT_SUCCESS(ntStatus)) { TCPLtDebugPrint(1, ("[TcpTdi]TcpTdiSend: Failed.\n")); *Result = -1; return ntStatus; } *Result = ioStatusBlock.Information; return ntStatus; }
/* BOOLEAN KTdiStreamSocket::Listen(IN USHORT wRemotePort, IN ULONG dwRemoteAddress) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; //PTDI_CONNECTION_INFORMATION pRequestListenInfo = NULL; //PTDI_CONNECTION_INFORMATION pReturnConnectionInfo; PTA_IP_ADDRESS pRequestAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && Disconnect() == TRUE) { m_nRemotePort = wPort; m_nRemoteAddress = dwAddress; pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); m_pRequestListenInfo = (PTDI_CONNECTION_INFORMATION) new char[2*sizeof(TDI_CONNECTION_INFORMATION) + 2*sizeof(TA_IP_ADDRESS) + sizeof(ULONG)]; if (m_pRequestListenInfo != NULL) { memset(m_pRequestListenInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS) + sizeof(ULONG)); m_pReturnListenInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); m_pReturnListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); m_pReturnListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION); m_pRequestListenInfo->Options = (PVOID) ((PUCHAR)m_pReturnListenInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); *((ULONG*)(m_pRequestListenInfo->Options)) = TDI_QUERY_ACCEPT; m_pRequestListenInfo->OptionsLength = sizeof(ULONG); if (m_nRemoteAddress != 0) { m_pRequestListenInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); m_pRequestListenInfo->RemoteAddress = (PUCHAR)m_pRequestListenInfo + sizeof(TDI_CONNECTION_INFORMATION); pRequestAddress = (PTA_IP_ADDRESS)(m_pRequestListenInfo->RemoteAddress); pRequestAddress->TAAddressCount = 1; pRequestAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pRequestAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIp = (PTDI_ADDRESS_IP)(pRequestAddress->Address[0].Address); pIp->sin_port = W_LITTLE_TO_BIG_ENDIAN(m_nRemotePort); pIp->in_addr = D_LITTLE_TO_BIG_ENDIAN(m_nRemoteAddress);; } else { m_pRequestListenInfo->RemoteAddressLength = 0; m_pRequestListenInfo->RemoteAddress = NULL; } pIrp = TdiBuildInternalDeviceControlIrp( TDI_LISTEN, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildListen( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, TDI_QUERY_ACCEPT, // flags m_pRequestListenInfo, m_pReturnListenInfo); pIrpError = NULL; KeInitializeEvent(&m_kAcceptDestroyEvent, NotificationEvent, FALSE); KeInitializeEvent(&m_kListenEvent, NotificationEvent, FALSE); pIrp->UserEvent = &m_kListenEvent; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, FALSE); if (NT_SUCCESS(NtStatus)) { DbgPrint ("TdiListen: OK (%08x)!!!\n", NtStatus); m_bListen = TRUE; bRes = TRUE; } else { DbgPrint ("TdiListen: ERROR (%08x)!!!\n", NtStatus); delete[] m_pRequestListenInfo; m_pRequestListenInfo = NULL; } } } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); if (m_bListen == FALSE && m_pRequestListenInfo != NULL) delete[] m_pRequestListenInfo; } return bRes; } BOOLEAN KTdiStreamSocket::Accept(ULONG dwTimeOut) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; PTA_IP_ADDRESS pReturnAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; PVOID pkEvents[2]; LARGE_INTEGER TimeOut; PLARGE_INTEGER pTimeOut = NULL; //m_KSynchroObject.Lock(); __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bConnected == FALSE && m_bListen == TRUE) { if (dwTimeOut != 0) { pTimeOut = &TimeOut; TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals TimeOut.QuadPart = -TimeOut.QuadPart; } pkEvents[0] = &m_kListenEvent; pkEvents[1] = &m_kAcceptDestroyEvent; NtStatus = KeWaitForMultipleObjects(2, pkEvents, WaitAny, Suspended, KernelMode, FALSE, pTimeOut, NULL); if (NtStatus == 0) { pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pReturnAddress = (PTA_IP_ADDRESS)(m_pReturnListenInfo->RemoteAddress); pReturnAddress->TAAddressCount = 1; pReturnAddress->Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); pReturnAddress->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; pIrp = TdiBuildInternalDeviceControlIrp( TDI_ACCEPT, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildAccept( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, m_pRequestListenInfo, m_pReturnListenInfo); pIrpError = NULL; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock, TRUE); if (NT_SUCCESS(NtStatus)) { m_bConnected = TRUE; bRes = TRUE; pIp = (PTDI_ADDRESS_IP)(pReturnAddress->Address[0].Address); m_nRemotePort = W_BIG_TO_LITTLE_ENDIAN(pIp->sin_port); m_nRemoteAddress = D_BIG_TO_LITTLE_ENDIAN(pIp->in_addr); DbgPrint ("TdiAccept: OK (%08x : %04x)!!!\n", m_nRemoteAddress, m_nRemotePort); } else { DbgPrint ("TdiAccept: ERROR (%08x)!!!\n", NtStatus); } } } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); } //m_KSynchroObject.UnLock(); return bRes; } */ ULONG KTdiStreamSocket::Send(PVOID pData, ULONG dwSize) { //KLocker locker(&m_KSynchroObject); PIRP pIrp = NULL, pIrpError = NULL; PMDL pMdl; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; IO_STATUS_BLOCK IoStatusBlock; ULONG dwBytesSended = 0; //m_KSynchroObject.Lock(); __try { if (m_bOpen == TRUE && m_bConnected == TRUE && dwSize != 0) { pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pIrp = TdiBuildInternalDeviceControlIrp ( TDI_SEND, // sub function pDeviceObject, // pointer to device object m_pTdiConnectionObject, // pointer to control object NULL, // pointer to event NULL); // pointer to return buffer pIrpError = pIrp; if (pIrp == NULL) // validate pointer { NtStatus = STATUS_INSUFFICIENT_RESOURCES; } else { pMdl = IoAllocateMdl( pData, // buffer pointer - virtual address dwSize, // length FALSE, // not secondary FALSE, // don't charge quota NULL); // don't use irp if (pMdl != NULL) // validate mdl pointer { __try { MmProbeAndLockPages(pMdl, KernelMode, IoModifyAccess); // probe & lock } __except(EXCEPTION_EXECUTE_HANDLER) { DbgPrint("EXCEPTION: MmProbeAndLockPages\n"); IoFreeMdl(pMdl); pMdl = NULL; } } if (pMdl != NULL) { TdiBuildSend( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, pMdl, 0, dwSize); pIrpError = NULL; //m_KSynchroObject.UnLock(); NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); //m_KSynchroObject.Lock(); if (NT_SUCCESS(NtStatus)) { dwBytesSended = IoStatusBlock.Information; } else { DbgPrint ("TdiSend: ERROR (%08x)!!!\n", NtStatus); Disconnect(); } } } }