NTSTATUS TdiConnect( PIRP *Irp, PFILE_OBJECT ConnectionObject, PTDI_CONNECTION_INFORMATION ConnectionCallInfo, PTDI_CONNECTION_INFORMATION ConnectionReturnInfo, PIO_COMPLETION_ROUTINE CompletionRoutine, PVOID CompletionContext) /* * FUNCTION: Connect a connection endpoint to a remote peer * ARGUMENTS: * ConnectionObject = Pointer to connection endpoint file object * RemoteAddress = Pointer to remote address * RETURNS: * Status of operation */ { PDEVICE_OBJECT DeviceObject; AFD_DbgPrint(MAX_TRACE, ("Called\n")); ASSERT(*Irp == NULL); if (!ConnectionObject) { AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); return STATUS_INVALID_PARAMETER; } DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); if (!DeviceObject) { AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); return STATUS_INVALID_PARAMETER; } *Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, /* Sub function */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ NULL, /* Event */ NULL); /* Status */ if (!*Irp) { return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildConnect(*Irp, /* IRP */ DeviceObject, /* Device object */ ConnectionObject, /* File object */ CompletionRoutine, /* Completion routine */ CompletionContext, /* Completion routine context */ NULL, /* Time */ ConnectionCallInfo, /* Request connection information */ ConnectionReturnInfo); /* Return connection information */ TdiCall(*Irp, DeviceObject, NULL, NULL); return STATUS_PENDING; }
NTSTATUS TdiConnect( PFILE_OBJECT ConnectionObject, ULONG Addr, USHORT Port, PIO_STATUS_BLOCK AsyncIoStatus ) { NTSTATUS ntStatus; PIRP Irp; PDEVICE_OBJECT DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); TA_IP_ADDRESS DstAddr = {1, {TDI_ADDRESS_LENGTH_IP, TDI_ADDRESS_TYPE_IP, {Port, Addr}}}; TDI_CONNECTION_INFORMATION Dst = {0, 0, 0, 0, sizeof DstAddr, &DstAddr}; KEVENT Event; IO_STATUS_BLOCK IoStatus = {0, (ULONG_PTR)&Event}; PIO_STATUS_BLOCK pIoStatus = &IoStatus; if (AsyncIoStatus) pIoStatus = AsyncIoStatus; else KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!(Irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, DeviceObject, ConnectionObject, (PKEVENT)pIoStatus->Information, pIoStatus))) return STATUS_INSUFFICIENT_RESOURCES; TdiBuildConnect(Irp, DeviceObject, ConnectionObject, 0, 0, 0, &Dst, 0); ntStatus = IoCallDriver(DeviceObject, Irp); if ((ntStatus == STATUS_PENDING) && (!AsyncIoStatus)) ntStatus = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); return(ntStatus); }
NTSTATUS LpxTdiConnect( IN PFILE_OBJECT ConnectionFileObject, IN PTDI_ADDRESS_LPX Address ) { KEVENT event; PDEVICE_OBJECT deviceObject; PIRP irp; IO_STATUS_BLOCK ioStatusBlock; UCHAR buffer[ FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX ]; PTRANSPORT_ADDRESS serverTransportAddress; PTA_ADDRESS taAddress; PTDI_ADDRESS_LPX addressName; NTSTATUS ntStatus; TDI_CONNECTION_INFORMATION connectionInfomation; LtDebugPrint (3, ("[LpxTdi] LpxTdiConnect: Entered\n")); // // Make Event. // KeInitializeEvent(&event, NotificationEvent, FALSE); deviceObject = IoGetRelatedDeviceObject(ConnectionFileObject); // // Make IRP. // irp = TdiBuildInternalDeviceControlIrp( TDI_CONNECT, deviceObject, connectionFileObject, &event, &ioStatusBlock ); if(irp == NULL) { LtDebugPrint(1, ("[LpxTdi]TdiConnect: Can't Build IRP.\n")); return STATUS_INSUFFICIENT_RESOURCES; } serverTransportAddress = (PTRANSPORT_ADDRESS)buffer; serverTransportAddress->TAAddressCount = 1; taAddress = (PTA_ADDRESS)serverTransportAddress->Address; taAddress->AddressType = TDI_ADDRESS_TYPE_LPX; taAddress->AddressLength = TDI_ADDRESS_LENGTH_LPX; addressName = (PTDI_ADDRESS_LPX)taAddress->Address; RtlCopyMemory( addressName, Address, TDI_ADDRESS_LENGTH_LPX ); // // Make Connection Info... // RtlZeroMemory( &connectionInfomation, sizeof(TDI_CONNECTION_INFORMATION) ); connectionInfomation.UserDataLength = 0; connectionInfomation.UserData = NULL; connectionInfomation.OptionsLength = 0; connectionInfomation.Options = NULL; connectionInfomation.RemoteAddress = serverTransportAddress; connectionInfomation.RemoteAddressLength = FIELD_OFFSET(TRANSPORT_ADDRESS, Address) + FIELD_OFFSET(TA_ADDRESS, Address) + TDI_ADDRESS_LENGTH_LPX; TdiBuildConnect( irp, deviceObject, ConnectionFileObject, NULL, NULL, NULL, &connectionInfomation, NULL ); irp->MdlAddress = NULL; ntStatus = LpxTdiIoCallDriver( deviceObject, irp, &ioStatusBlock, &event, NULL ); if(!NT_SUCCESS(ntStatus)) { LtDebugPrint(1, ("[LpxTdi]TdiConnect: Failed.\n")); } return ntStatus; }
NTSTATUS tdi_connect(PFILE_OBJECT connectionFileObject, ULONG addr, USHORT port) { PDEVICE_OBJECT devObj; KEVENT event; PTDI_CONNECTION_INFORMATION remoteInfo; PTA_IP_ADDRESS remoteAddr; PTDI_CONNECTION_INFORMATION returnInfo; PTA_IP_ADDRESS returnAddr; PIRP irp; IO_STATUS_BLOCK iosb; NTSTATUS status; devObj = IoGetRelatedDeviceObject(connectionFileObject); KeInitializeEvent(&event, NotificationEvent, FALSE); remoteInfo = HttpDiskMalloc( 2 * sizeof (TDI_CONNECTION_INFORMATION) + 2 * sizeof (TA_IP_ADDRESS) ); if (remoteInfo == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(remoteInfo, 2 * sizeof(TDI_CONNECTION_INFORMATION) + 2 * sizeof(TA_IP_ADDRESS)); remoteInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); remoteInfo->RemoteAddress = (PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION); remoteAddr = (PTA_IP_ADDRESS) remoteInfo->RemoteAddress; remoteAddr->TAAddressCount = 1; remoteAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; remoteAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; remoteAddr->Address[0].Address[0].sin_port = port; remoteAddr->Address[0].Address[0].in_addr = addr; returnInfo = (PTDI_CONNECTION_INFORMATION)((PUCHAR)remoteInfo + sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); returnInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); returnInfo->RemoteAddress = (PUCHAR)returnInfo + sizeof(TDI_CONNECTION_INFORMATION); returnAddr = (PTA_IP_ADDRESS) returnInfo->RemoteAddress; returnAddr->TAAddressCount = 1; returnAddr->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; returnAddr->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; irp = TdiBuildInternalDeviceControlIrp(TDI_CONNECT, devObj, connectionFileObject, &event, &iosb); if (irp == NULL) { ExFreePool(remoteInfo); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildConnect(irp, devObj, connectionFileObject, NULL, NULL, NULL, remoteInfo, returnInfo); status = IoCallDriver(devObj, irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); status = iosb.Status; } ExFreePool(remoteInfo); return status; }
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 KTdiStreamSocket::Connect(IN USHORT wPort, IN ULONG dwAddress, ULONG dwTimeOut) { //KLocker locker(&m_KSynchroObject); BOOLEAN bRes = FALSE; PIRP pIrp = NULL, pIrpError = NULL; PDEVICE_OBJECT pDeviceObject; NTSTATUS NtStatus; PTDI_CONNECTION_INFORMATION pRequestConnectionInfo = NULL; PTDI_CONNECTION_INFORMATION pReturnConnectionInfo; PTA_IP_ADDRESS pRequestAddress; PTDI_ADDRESS_IP pIp; IO_STATUS_BLOCK IoStatusBlock; LARGE_INTEGER TimeOut; PLARGE_INTEGER pTimeOut = NULL; __try { if (m_bOpen == TRUE && m_bBind == TRUE && m_bListen == FALSE && Disconnect() == TRUE) { m_nRemotePort = wPort; m_nRemoteAddress = dwAddress; if (dwTimeOut != 0) { pTimeOut = &TimeOut; TimeOut.QuadPart = dwTimeOut * 10000; // msec -> 100 nsec intervals TimeOut.QuadPart = -TimeOut.QuadPart; } pDeviceObject = IoGetRelatedDeviceObject(m_pTdiConnectionObject); pRequestConnectionInfo = (PTDI_CONNECTION_INFORMATION) new char[sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)]; if (pRequestConnectionInfo != NULL) { memset(pRequestConnectionInfo, 0, sizeof(TDI_CONNECTION_INFORMATION) + sizeof(TA_IP_ADDRESS)); pReturnConnectionInfo = NULL; pRequestConnectionInfo->RemoteAddressLength = sizeof(TA_IP_ADDRESS); pRequestConnectionInfo->RemoteAddress = (PUCHAR)pRequestConnectionInfo + sizeof(TDI_CONNECTION_INFORMATION); pRequestAddress = (PTA_IP_ADDRESS)(pRequestConnectionInfo->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);; pIrp = TdiBuildInternalDeviceControlIrp( TDI_CONNECT, pDeviceObject, m_pTdiConnectionObject, NULL, NULL); pIrpError = pIrp; if (pIrp != NULL) { TdiBuildConnect( pIrp, pDeviceObject, m_pTdiConnectionObject, NULL, NULL, pTimeOut, pRequestConnectionInfo, pReturnConnectionInfo); pIrpError = NULL; NtStatus = TdiCall(pIrp, pDeviceObject, &IoStatusBlock); if (NT_SUCCESS(NtStatus)) { m_bConnected = TRUE; bRes = TRUE; } else { DbgPrint ("TdiConnect: ERROR (%08x)!!!\n", NtStatus); } } delete[] pRequestConnectionInfo; pRequestConnectionInfo = NULL; } } } __finally { if (pIrpError != NULL) IoFreeIrp(pIrpError); if (pRequestConnectionInfo != NULL) delete[] pRequestConnectionInfo; } return bRes; }