NTSTATUS TdiOpenAddressFile( PUNICODE_STRING DeviceName, PTRANSPORT_ADDRESS Name, ULONG ShareType, PHANDLE AddressHandle, PFILE_OBJECT *AddressObject) /* * FUNCTION: Opens an IPv4 address file object * ARGUMENTS: * DeviceName = Pointer to counted string with name of device * Name = Pointer to socket name (IPv4 address family) * AddressHandle = Address of buffer to place address file handle * AddressObject = Address of buffer to place address file object * RETURNS: * Status of operation */ { PFILE_FULL_EA_INFORMATION EaInfo; NTSTATUS Status; ULONG EaLength; PTRANSPORT_ADDRESS Address; AFD_DbgPrint(MAX_TRACE, ("Called. DeviceName (%wZ) Name (%p)\n", DeviceName, Name)); /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */ EaLength = sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + TaLengthOfTransportAddress( Name ) + 1; EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength); if (!EaInfo) return STATUS_INSUFFICIENT_RESOURCES; RtlZeroMemory(EaInfo, EaLength); EaInfo->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH; /* Don't copy the terminating 0; we have already zeroed it */ RtlCopyMemory(EaInfo->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH); EaInfo->EaValueLength = sizeof(TA_IP_ADDRESS); Address = (PTRANSPORT_ADDRESS)(EaInfo->EaName + TDI_TRANSPORT_ADDRESS_LENGTH + 1); /* 0-terminated */ TaCopyTransportAddressInPlace( Address, Name ); Status = TdiOpenDevice(DeviceName, EaLength, EaInfo, ShareType, AddressHandle, AddressObject); ExFreePool(EaInfo); return Status; }
PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) { UINT AddrLen; PTRANSPORT_ADDRESS A; AddrLen = TaLengthOfTransportAddress( OtherAddress ); if (!AddrLen) return NULL; A = ExAllocatePool( NonPagedPool, AddrLen ); if( A ) TaCopyTransportAddressInPlace( A, OtherAddress ); return A; }
static NTSTATUS SatisfyPreAccept( PIRP Irp, PAFD_TDI_OBJECT_QELT Qelt ) { PAFD_RECEIVED_ACCEPT_DATA ListenReceive = (PAFD_RECEIVED_ACCEPT_DATA)Irp->AssociatedIrp.SystemBuffer; PTA_IP_ADDRESS IPAddr; ListenReceive->SequenceNumber = Qelt->Seq; AFD_DbgPrint(MID_TRACE,("Giving SEQ %u to userland\n", Qelt->Seq)); AFD_DbgPrint(MID_TRACE,("Socket Address (K) %p (U) %p\n", &ListenReceive->Address, Qelt->ConnInfo->RemoteAddress)); TaCopyTransportAddressInPlace( &ListenReceive->Address, Qelt->ConnInfo->RemoteAddress ); IPAddr = (PTA_IP_ADDRESS)&ListenReceive->Address; AFD_DbgPrint(MID_TRACE,("IPAddr->TAAddressCount %d\n", IPAddr->TAAddressCount)); AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressType %u\n", IPAddr->Address[0].AddressType)); AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].AddressLength %u\n", IPAddr->Address[0].AddressLength)); AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_port %x\n", IPAddr->Address[0].Address[0].sin_port)); AFD_DbgPrint(MID_TRACE,("IPAddr->Address[0].Address[0].sin_addr %x\n", IPAddr->Address[0].Address[0].in_addr)); if( Irp->MdlAddress ) UnlockRequest( Irp, IoGetCurrentIrpStackLocation( Irp ) ); Irp->IoStatus.Information = ((PCHAR)&IPAddr[1]) - ((PCHAR)ListenReceive); Irp->IoStatus.Status = STATUS_SUCCESS; (void)IoSetCancelRoutine(Irp, NULL); IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); return STATUS_SUCCESS; }
static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { NTSTATUS Status = STATUS_SUCCESS; PAFD_FCB FCB = (PAFD_FCB)Context; PAFD_TDI_OBJECT_QELT Qelt; PLIST_ENTRY NextIrpEntry; PIRP NextIrp; UNREFERENCED_PARAMETER(DeviceObject); if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; ASSERT(FCB->ListenIrp.InFlightRequest == Irp); FCB->ListenIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_PREACCEPT]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } /* Free ConnectionReturnInfo and ConnectionCallInfo */ if (FCB->ListenIrp.ConnectionReturnInfo) { ExFreePool(FCB->ListenIrp.ConnectionReturnInfo); FCB->ListenIrp.ConnectionReturnInfo = NULL; } if (FCB->ListenIrp.ConnectionCallInfo) { ExFreePool(FCB->ListenIrp.ConnectionCallInfo); FCB->ListenIrp.ConnectionCallInfo = NULL; } SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } AFD_DbgPrint(MID_TRACE,("Completing listen request.\n")); AFD_DbgPrint(MID_TRACE,("IoStatus was %x\n", Irp->IoStatus.Status)); if (Irp->IoStatus.Status != STATUS_SUCCESS) { SocketStateUnlock(FCB); return Irp->IoStatus.Status; } Qelt = ExAllocatePool( NonPagedPool, sizeof(*Qelt) ); if( !Qelt ) { Status = STATUS_NO_MEMORY; } else { UINT AddressType = FCB->LocalAddress->Address[0].AddressType; Qelt->Object = FCB->Connection; Qelt->Seq = FCB->ConnSeq++; AFD_DbgPrint(MID_TRACE,("Address Type: %u (RA %p)\n", AddressType, FCB->ListenIrp. ConnectionReturnInfo->RemoteAddress)); Status = TdiBuildNullConnectionInfo( &Qelt->ConnInfo, AddressType ); if( NT_SUCCESS(Status) ) { TaCopyTransportAddressInPlace ( Qelt->ConnInfo->RemoteAddress, FCB->ListenIrp.ConnectionReturnInfo->RemoteAddress ); InsertTailList( &FCB->PendingConnections, &Qelt->ListEntry ); } } /* Satisfy a pre-accept request if one is available */ if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ) && !IsListEmpty( &FCB->PendingConnections ) ) { PLIST_ENTRY PendingIrp = RemoveHeadList( &FCB->PendingIrpList[FUNCTION_PREACCEPT] ); PLIST_ENTRY PendingConn = FCB->PendingConnections.Flink; SatisfyPreAccept ( CONTAINING_RECORD( PendingIrp, IRP, Tail.Overlay.ListEntry ), CONTAINING_RECORD( PendingConn, AFD_TDI_OBJECT_QELT, ListEntry ) ); } /* Launch new accept socket */ Status = WarmSocketForConnection( FCB ); if (NT_SUCCESS(Status)) { Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionCallInfo, FCB->LocalAddress->Address[0].AddressType); ASSERT(Status == STATUS_SUCCESS); Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionReturnInfo, FCB->LocalAddress->Address[0].AddressType); ASSERT(Status == STATUS_SUCCESS); Status = TdiListen( &FCB->ListenIrp.InFlightRequest, FCB->Connection.Object, &FCB->ListenIrp.ConnectionCallInfo, &FCB->ListenIrp.ConnectionReturnInfo, ListenComplete, FCB ); if (Status == STATUS_PENDING) Status = STATUS_SUCCESS; } /* Trigger a select return if appropriate */ if( !IsListEmpty( &FCB->PendingConnections ) ) { FCB->PollState |= AFD_EVENT_ACCEPT; FCB->PollStatus[FD_ACCEPT_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } else FCB->PollState &= ~AFD_EVENT_ACCEPT; SocketStateUnlock( FCB ); return Status; }