static NTSTATUS SatisfyAccept( PAFD_DEVICE_EXTENSION DeviceExt, PIRP Irp, PFILE_OBJECT NewFileObject, PAFD_TDI_OBJECT_QELT Qelt ) { PAFD_FCB FCB = NewFileObject->FsContext; NTSTATUS Status; UNREFERENCED_PARAMETER(DeviceExt); if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); /* Transfer the connection to the new socket, launch the opening read */ AFD_DbgPrint(MID_TRACE,("Completing a real accept (FCB %p)\n", FCB)); FCB->Connection = Qelt->Object; if( FCB->RemoteAddress ) ExFreePool( FCB->RemoteAddress ); FCB->RemoteAddress = TaCopyTransportAddress( Qelt->ConnInfo->RemoteAddress ); if( !FCB->RemoteAddress ) Status = STATUS_NO_MEMORY; else Status = MakeSocketIntoConnection( FCB ); if (NT_SUCCESS(Status)) Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress); if (NT_SUCCESS(Status)) Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); }
static NTSTATUS NTAPI StreamSocketConnectComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { NTSTATUS Status = Irp->IoStatus.Status; PAFD_FCB FCB = (PAFD_FCB)Context; PLIST_ENTRY NextIrpEntry; PIRP NextIrp; AFD_DbgPrint(MID_TRACE,("Called: FCB %p, FO %p\n", Context, FCB->FileObject)); /* I was wrong about this before as we can have pending writes to a not * yet connected socket */ if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; AFD_DbgPrint(MID_TRACE,("Irp->IoStatus.Status = %x\n", Irp->IoStatus.Status)); ASSERT(FCB->ConnectIrp.InFlightRequest == Irp); FCB->ConnectIrp.InFlightRequest = NULL; if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]); 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 ); } SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } if( !NT_SUCCESS(Irp->IoStatus.Status) ) { FCB->PollState |= AFD_EVENT_CONNECT_FAIL; FCB->PollStatus[FD_CONNECT_BIT] = Irp->IoStatus.Status; AFD_DbgPrint(MID_TRACE,("Going to bound state\n")); FCB->State = SOCKET_STATE_BOUND; PollReeval( FCB->DeviceExt, FCB->FileObject ); } /* Succeed pending irps on the FUNCTION_CONNECT list */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_CONNECT] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_CONNECT]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); AFD_DbgPrint(MID_TRACE,("Completing connect %p\n", NextIrp)); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } if( NT_SUCCESS(Status) ) { Status = MakeSocketIntoConnection( FCB ); if( !NT_SUCCESS(Status) ) { SocketStateUnlock( FCB ); return Status; } FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength, FCB->ConnectDataSize); if (FCB->FilledConnectData) { RtlCopyMemory(FCB->ConnectData, FCB->ConnectReturnInfo->UserData, FCB->FilledConnectData); } FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength, FCB->ConnectOptionsSize); if (FCB->FilledConnectOptions) { RtlCopyMemory(FCB->ConnectOptions, FCB->ConnectReturnInfo->Options, FCB->FilledConnectOptions); } if( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); AFD_DbgPrint(MID_TRACE,("Launching send request %p\n", NextIrp)); Status = AfdConnectedSocketWriteData ( DeviceObject, NextIrp, IoGetCurrentIrpStackLocation( NextIrp ), FALSE ); } if( Status == STATUS_PENDING ) Status = STATUS_SUCCESS; } SocketStateUnlock( FCB ); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); return Status; }