NTSTATUS TdiBuildNullConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type ) /* * FUNCTION: Builds a NULL TDI connection information structure * ARGUMENTS: * ConnectionInfo = Address of buffer pointer to allocate connection * information in * Type = TDI style address type (TDI_ADDRESS_TYPE_XXX). * RETURNS: * Status of operation */ { PTDI_CONNECTION_INFORMATION ConnInfo; ULONG TdiAddressSize; NTSTATUS Status; TdiAddressSize = TaLengthOfTransportAddressByType(Type); if (!TdiAddressSize) { AFD_DbgPrint(MIN_TRACE,("Invalid parameter\n")); *ConnectionInfo = NULL; return STATUS_INVALID_PARAMETER; } ConnInfo = (PTDI_CONNECTION_INFORMATION) ExAllocatePool(NonPagedPool, sizeof(TDI_CONNECTION_INFORMATION) + TdiAddressSize); if (!ConnInfo) { *ConnectionInfo = NULL; return STATUS_INSUFFICIENT_RESOURCES; } Status = TdiBuildNullConnectionInfoInPlace( ConnInfo, Type ); if (!NT_SUCCESS(Status)) { ExFreePool( ConnInfo ); ConnInfo = NULL; } *ConnectionInfo = ConnInfo; 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; }