NTSTATUS TdiBuildConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Address ) { NTSTATUS Status = TdiBuildNullConnectionInfo ( ConnectionInfo, Address->Address[0].AddressType ); if( NT_SUCCESS(Status) ) TdiBuildConnectionInfoInPlace( *ConnectionInfo, Address ); return Status; }
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; }
NTSTATUS AfdListenSocket( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp ) { NTSTATUS Status = STATUS_SUCCESS; PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = FileObject->FsContext; PAFD_LISTEN_DATA ListenReq; UNREFERENCED_PARAMETER(DeviceObject); AFD_DbgPrint(MID_TRACE,("Called on %p\n", FCB)); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); if( !(ListenReq = LockRequest( Irp, IrpSp, FALSE, NULL )) ) return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, Irp, 0 ); if( FCB->State != SOCKET_STATE_BOUND ) { Status = STATUS_INVALID_PARAMETER; AFD_DbgPrint(MIN_TRACE,("Could not listen an unbound socket\n")); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } FCB->DelayedAccept = ListenReq->UseDelayedAcceptance; AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %p\n", FCB->AddressFile.Handle)); Status = WarmSocketForConnection( FCB ); AFD_DbgPrint(MID_TRACE,("Status from warmsocket %x\n", Status)); if( !NT_SUCCESS(Status) ) return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); Status = TdiBuildNullConnectionInfo ( &FCB->ListenIrp.ConnectionCallInfo, FCB->LocalAddress->Address[0].AddressType ); if (!NT_SUCCESS(Status)) return UnlockAndMaybeComplete(FCB, Status, Irp, 0); Status = TdiBuildNullConnectionInfo ( &FCB->ListenIrp.ConnectionReturnInfo, FCB->LocalAddress->Address[0].AddressType ); if (!NT_SUCCESS(Status)) { ExFreePool(FCB->ListenIrp.ConnectionCallInfo); FCB->ListenIrp.ConnectionCallInfo = NULL; return UnlockAndMaybeComplete(FCB, Status, Irp, 0); } FCB->State = SOCKET_STATE_LISTENING; Status = TdiListen( &FCB->ListenIrp.InFlightRequest, FCB->Connection.Object, &FCB->ListenIrp.ConnectionCallInfo, &FCB->ListenIrp.ConnectionReturnInfo, ListenComplete, FCB ); if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); }