diff --git a/drivers/network/afd/afd/connect.c b/drivers/network/afd/afd/connect.c index 8d5be87169a..c208465dfec 100644 --- a/drivers/network/afd/afd/connect.c +++ b/drivers/network/afd/afd/connect.c @@ -355,7 +355,7 @@ StreamSocketConnectComplete NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp)); - DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x\n", NextIrp); + DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x with Status = 0x%x\n", NextIrp, Status); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = (NT_SUCCESS(Status) ? ((ULONG_PTR)FCB->Connection.Handle) : 0); @@ -369,6 +369,7 @@ StreamSocketConnectComplete if (NT_SUCCESS(Status)) { + DbgPrint("[AFD, StreamSocketConnectComplete] Making socket into connection\n"); Status = MakeSocketIntoConnection(FCB); if (!NT_SUCCESS(Status)) @@ -377,21 +378,21 @@ StreamSocketConnectComplete return Status; } - FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength, + FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength, FCB->ConnectDataSize); if (FCB->FilledConnectData) { RtlCopyMemory(FCB->ConnectData, - FCB->ConnectInfo->UserData, + FCB->ConnectReturnInfo->UserData, FCB->FilledConnectData); } - FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength, + FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength, FCB->ConnectOptionsSize); if (FCB->FilledConnectOptions) { RtlCopyMemory(FCB->ConnectOptions, - FCB->ConnectInfo->Options, + FCB->ConnectReturnInfo->Options, FCB->FilledConnectOptions); } @@ -415,6 +416,7 @@ StreamSocketConnectComplete SocketStateUnlock(FCB); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + DbgPrint("[AFD, StreamSocketConnectComplete] Leaving. Status = 0x%x\n", Status); return Status; } @@ -430,7 +432,6 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PFILE_OBJECT FileObject = IrpSp->FileObject; PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext; PAFD_CONNECT_INFO ConnectReq; - PTDI_CONNECTION_INFORMATION TargetAddress; AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB)); if (!SocketAcquireStateLock(FCB)) @@ -507,41 +508,42 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, if (!NT_SUCCESS(Status)) break; - Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, &ConnectReq->RemoteAddress); + if (FCB->ConnectReturnInfo) ExFreePool(FCB->ConnectReturnInfo); + Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, &ConnectReq->RemoteAddress); if (NT_SUCCESS(Status)) - Status = TdiBuildConnectionInfo(&TargetAddress, &ConnectReq->RemoteAddress); - else break; + { + if (FCB->ConnectCallInfo) ExFreePool(FCB->ConnectCallInfo); + Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, + &ConnectReq->RemoteAddress); + } + else + break; if (NT_SUCCESS(Status)) { - TargetAddress->UserData = FCB->ConnectData; - TargetAddress->UserDataLength = FCB->ConnectDataSize; - TargetAddress->Options = FCB->ConnectOptions; - TargetAddress->OptionsLength = FCB->ConnectOptionsSize; - - AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); - DbgPrint("[AFD, AfdStreamSocketConnect] Queueing IRP %x\n", Irp); + FCB->ConnectCallInfo->UserData = FCB->ConnectData; + FCB->ConnectCallInfo->UserDataLength = FCB->ConnectDataSize; + FCB->ConnectCallInfo->Options = FCB->ConnectOptions; + FCB->ConnectCallInfo->OptionsLength = FCB->ConnectOptionsSize; FCB->State = SOCKET_STATE_CONNECTING; AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp)); - Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT ); + Status = QueueUserModeIrp(FCB, Irp, FUNCTION_CONNECT); if (Status == STATUS_PENDING) { - Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest, + Status = TdiConnect(&FCB->ConnectIrp.InFlightRequest, FCB->Connection.Object, - TargetAddress, - FCB->ConnectInfo, + FCB->ConnectCallInfo, + FCB->ConnectReturnInfo, &FCB->ConnectIrp.Iosb, StreamSocketConnectComplete, - FCB ); + FCB); } if (Status != STATUS_PENDING) FCB->State = SOCKET_STATE_BOUND; - - ExFreePool(TargetAddress); SocketStateUnlock(FCB); diff --git a/drivers/network/afd/afd/listen.c b/drivers/network/afd/afd/listen.c index 599cd074c7e..86d69540677 100644 --- a/drivers/network/afd/afd/listen.c +++ b/drivers/network/afd/afd/listen.c @@ -43,7 +43,10 @@ SatisfyAccept Status = MakeSocketIntoConnection( FCB ); if (NT_SUCCESS(Status)) - Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, FCB->RemoteAddress); + Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo, FCB->RemoteAddress); + + if (NT_SUCCESS(Status)) + Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, FCB->RemoteAddress); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); } diff --git a/drivers/network/afd/afd/main.c b/drivers/network/afd/afd/main.c index 980c349c104..50bb6245127 100644 --- a/drivers/network/afd/afd/main.c +++ b/drivers/network/afd/afd/main.c @@ -373,6 +373,7 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, } FileObject->FsContext = FCB; + DbgPrint("FileObject->FsContext = 0x%x\n", FCB); /* It seems that UDP sockets are writable from inception */ if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS) @@ -381,8 +382,8 @@ AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, /* A datagram socket is always sendable */ FCB->PollState |= AFD_EVENT_SEND; - FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; - PollReeval( FCB->DeviceExt, FCB->FileObject ); + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); } if (!NT_SUCCESS(Status)) @@ -523,8 +524,11 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, if ( FCB->AddressFrom ) ExFreePool(FCB->AddressFrom); - if (FCB->ConnectInfo) - ExFreePool(FCB->ConnectInfo); + if (FCB->ConnectCallInfo) + ExFreePool(FCB->ConnectCallInfo); + + if (FCB->ConnectReturnInfo) + ExFreePool(FCB->ConnectReturnInfo); if (FCB->ConnectData) ExFreePool(FCB->ConnectData); @@ -596,78 +600,101 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, static NTSTATUS -DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp) +NTAPI +DisconnectComplete(PDEVICE_OBJECT DeviceObject, + PIRP Irp, + PVOID Context) +{ + PAFD_FCB FCB = Context; + PIRP CurrentIrp; + PLIST_ENTRY CurrentEntry; + + if( !SocketAcquireStateLock( FCB ) ) + return STATUS_FILE_CLOSED; + + ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp); + FCB->DisconnectIrp.InFlightRequest = NULL; + + ASSERT(FCB->DisconnectPending); + //ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)); + + if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)) + { + FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, FCB->ConnectReturnInfo->UserDataLength); + if (FCB->FilledDisconnectData) + { + RtlCopyMemory(FCB->DisconnectData, + FCB->ConnectReturnInfo->UserData, + FCB->FilledDisconnectData); + } + + FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, FCB->ConnectReturnInfo->OptionsLength); + if (FCB->FilledDisconnectOptions) + { + RtlCopyMemory(FCB->DisconnectOptions, + FCB->ConnectReturnInfo->Options, + FCB->FilledDisconnectOptions); + } + } + + FCB->DisconnectPending = FALSE; + + while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) + { + CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); + CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); + CurrentIrp->IoStatus.Status = Irp->IoStatus.Status; + CurrentIrp->IoStatus.Information = 0; + UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp)); + (void)IoSetCancelRoutine(CurrentIrp, NULL); + IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT ); + } + + if (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE) + FCB->PollState |= AFD_EVENT_DISCONNECT; + else + FCB->PollState |= AFD_EVENT_ABORT; + FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status; + PollReeval(FCB->DeviceExt, FCB->FileObject); + + SocketStateUnlock(FCB); + + return Irp->IoStatus.Status; +} + +static +NTSTATUS +DoDisconnect(PAFD_FCB FCB) { PAFD_DISCONNECT_INFO DisReq; IO_STATUS_BLOCK Iosb; - PTDI_CONNECTION_INFORMATION ConnectionReturnInfo; - PIO_STACK_LOCATION CurrentIrpSp; - USHORT Flags = 0; NTSTATUS Status; - CurrentIrpSp = IoGetCurrentIrpStackLocation(CurrentIrp); - DisReq = GetLockedData(CurrentIrp, CurrentIrpSp); + ASSERT(FCB->DisconnectPending); - if (DisReq->DisconnectType & AFD_DISCONNECT_SEND) - Flags |= TDI_DISCONNECT_RELEASE; - if (DisReq->DisconnectType & AFD_DISCONNECT_RECV || - DisReq->DisconnectType & AFD_DISCONNECT_ABORT) - Flags |= TDI_DISCONNECT_ABORT; - - Status = TdiBuildNullConnectionInfo(&ConnectionReturnInfo, - FCB->RemoteAddress->Address[0].AddressType); - if (NT_SUCCESS(Status)) + if (FCB->DisconnectIrp.InFlightRequest) { - FCB->ConnectInfo->UserData = FCB->DisconnectData; - FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize; - FCB->ConnectInfo->Options = FCB->DisconnectOptions; - FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize; - - Status = TdiDisconnect(FCB->Connection.Object, - &DisReq->Timeout, - Flags, - &Iosb, - NULL, - NULL, - FCB->ConnectInfo, - ConnectionReturnInfo); - - if (NT_SUCCESS(Status)) - { - FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength); - if (FCB->FilledDisconnectData) - { - RtlCopyMemory(FCB->DisconnectData, - ConnectionReturnInfo->UserData, - FCB->FilledDisconnectData); - } - - FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength); - if (FCB->FilledDisconnectOptions) - { - RtlCopyMemory(FCB->DisconnectOptions, - ConnectionReturnInfo->Options, - FCB->FilledDisconnectOptions); - } - } - - ExFreePool(ConnectionReturnInfo); - - if (Flags & TDI_DISCONNECT_RELEASE) - FCB->PollState |= AFD_EVENT_DISCONNECT; - else - FCB->PollState |= AFD_EVENT_ABORT; - - FCB->PollStatus[FD_CLOSE_BIT] = Status; - PollReeval(FCB->DeviceExt, FCB->FileObject); + return STATUS_PENDING; + } + + FCB->ConnectCallInfo->UserData = FCB->DisconnectData; + FCB->ConnectCallInfo->UserDataLength = FCB->DisconnectDataSize; + FCB->ConnectCallInfo->Options = FCB->DisconnectOptions; + FCB->ConnectCallInfo->OptionsLength = FCB->DisconnectOptionsSize; + + Status = TdiDisconnect(&FCB->DisconnectIrp.InFlightRequest, + FCB->Connection.Object, + &DisReq->Timeout, + FCB->DisconnectFlags, + &Iosb, + DisconnectComplete, + FCB, + FCB->ConnectCallInfo, + FCB->ConnectReturnInfo); + if (Status != STATUS_PENDING) + { + FCB->DisconnectPending = FALSE; } - - CurrentIrp->IoStatus.Status = Status; - CurrentIrp->IoStatus.Information = 0; - UnlockRequest(CurrentIrp, CurrentIrpSp); - (void)IoSetCancelRoutine(CurrentIrp, NULL); - - IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT); return Status; } @@ -675,20 +702,12 @@ DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp) VOID RetryDisconnectCompletion(PAFD_FCB FCB) { - if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND])) + ASSERT(FCB->RemoteAddress); + + if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && FCB->DisconnectPending) { - PIRP CurrentIrp; - PLIST_ENTRY CurrentEntry; - - ASSERT(FCB->RemoteAddress); - - while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) - { - CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); - CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); - - DoDisconnect(FCB, CurrentIrp); - } + /* Sends are done; fire off a TDI_DISCONNECT request */ + DoDisconnect(FCB); } } @@ -702,6 +721,8 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PAFD_DISCONNECT_INFO DisReq; NTSTATUS Status = STATUS_SUCCESS; USHORT Flags = 0; + PLIST_ENTRY CurrentEntry; + PIRP CurrentIrp; if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp); @@ -717,23 +738,52 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) { - if (!FCB->ConnectInfo) + if (!FCB->ConnectCallInfo) return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0); - if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags & TDI_DISCONNECT_ABORT)) + if (FCB->DisconnectPending) { - /* Go ahead an execute the disconnect because we're ready for it */ - Status = DoDisconnect(FCB, Irp); - - /* DoDisconnect takes care of the IRP */ - SocketStateUnlock(FCB); - - return Status; + if (FCB->DisconnectIrp.InFlightRequest) + { + IoCancelIrp(FCB->DisconnectIrp.InFlightRequest); + ASSERT(!FCB->DisconnectIrp.InFlightRequest); + } + else + { + while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT])) + { + CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]); + CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry); + CurrentIrp->IoStatus.Status = STATUS_CANCELLED; + CurrentIrp->IoStatus.Information = 0; + UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp)); + (void)IoSetCancelRoutine(CurrentIrp, NULL); + IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT ); + } + } } - else + + FCB->DisconnectFlags = Flags; + FCB->DisconnectPending = TRUE; + + Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT); + if (Status == STATUS_PENDING) { - /* We have a graceful disconnect waiting on pending sends to complete */ - return LeaveIrpUntilLater(FCB, Irp, FUNCTION_DISCONNECT); + if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (FCB->DisconnectFlags & TDI_DISCONNECT_ABORT)) + { + /* Go ahead an execute the disconnect because we're ready for it */ + Status = DoDisconnect(FCB); + } + + if (Status != STATUS_PENDING) + RemoveEntryList(&Irp->Tail.Overlay.ListEntry); + } + + if (Status == STATUS_PENDING) + { + SocketStateUnlock(FCB); + + return Status; } } @@ -984,6 +1034,8 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject, KIRQL OldIrql; PAFD_ACTIVE_POLL Poll; + DbgPrint("[AFD, AfdCancelHandler] called\n"); + IoReleaseCancelSpinLock(Irp->CancelIrql); if (!SocketAcquireStateLock(FCB)) @@ -1032,37 +1084,43 @@ AfdCancelHandler(PDEVICE_OBJECT DeviceObject, case IOCTL_AFD_SELECT: KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql); - CurrentEntry = DeviceExt->Polls.Flink; - while (CurrentEntry != &DeviceExt->Polls) - { - Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry); - - if (Irp == Poll->Irp) + CurrentEntry = DeviceExt->Polls.Flink; + while (CurrentEntry != &DeviceExt->Polls) { - CleanupPendingIrp(FCB, Irp, IrpSp, Poll); - KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); - SocketStateUnlock(FCB); - return; - } - else - { - CurrentEntry = CurrentEntry->Flink; - } - } + Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry); - KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); + if (Irp == Poll->Irp) + { + CleanupPendingIrp(FCB, Irp, IrpSp, Poll); + KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); + SocketStateUnlock(FCB); - SocketStateUnlock(FCB); + DbgPrint("[AFD, AfdCancelHandler] Cancelled IRP\n"); + + return; + } + else + { + CurrentEntry = CurrentEntry->Flink; + } + } + + KeReleaseSpinLock(&DeviceExt->Lock, OldIrql); + + SocketStateUnlock(FCB); - DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n"); - return; + DbgPrint("WARNING!!! IRP cancellation race could lead to a process hang! (IOCTL_AFD_SELECT)\n"); + return; default: - ASSERT(FALSE); - UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); - return; + ASSERT(FALSE); + UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0); + return; } + DbgPrint("[AFD, AfdCancelHandler] Cancelling MSAFD -> AFD IRPs\n"); + + /* Cancel IRPs from MSAFD to AFD (pending IRPs) */ CurrentEntry = FCB->PendingIrpList[Function].Flink; while (CurrentEntry != &FCB->PendingIrpList[Function]) { diff --git a/drivers/network/afd/afd/select.c b/drivers/network/afd/afd/select.c index acff8593841..4ad10727f96 100644 --- a/drivers/network/afd/afd/select.c +++ b/drivers/network/afd/afd/select.c @@ -141,6 +141,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, UINT i; AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n", FileObject)); + DbgPrint("[AFD, KillSelectsForFCB] Called for FileObject->FsContext = 0x%x\n", FileObject->FsContext); KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql ); @@ -153,6 +154,8 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, PollReq = Irp->AssociatedIrp.SystemBuffer; HandleArray = AFD_HANDLES(PollReq); + DbgPrint("[AFD, KillSelectsForFCB] killing select 0x%x\n", Poll); + for (i = 0; i < PollReq->HandleCount; i++) { AFD_DbgPrint(MAX_TRACE,("Req: %x, This %x\n", @@ -161,6 +164,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, if ((PVOID)HandleArray[i].Handle == FileObject && (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) ) { + DbgPrint("[AFD, KillSelectsForFCB] Zeroing events and signaling socket\n"); ZeroEvents( PollReq->Handles, PollReq->HandleCount ); SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED ); } @@ -170,6 +174,7 @@ VOID KillSelectsForFCB( PAFD_DEVICE_EXTENSION DeviceExt, KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); AFD_DbgPrint(MID_TRACE,("Done\n")); + DbgPrint("[AFD, KillSelectsForFCB] Leaving\n"); } NTSTATUS @@ -191,6 +196,10 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) PollReq->HandleCount, (INT)(PollReq->Timeout.QuadPart))); + DbgPrint("[AFD, AfdSelect] Called. HandleCount = %d, Timeout = %d\n", + PollReq->HandleCount, + (INT)(PollReq->Timeout.QuadPart)); + SET_AFD_HANDLES(PollReq, LockHandles( PollReq->Handles, PollReq->HandleCount )); @@ -266,6 +275,8 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc ); + DbgPrint("[AFD, AfdSelect] Marking IRP with STATUS_PENDING\n"); + Status = STATUS_PENDING; IoMarkIrpPending( Irp ); (void)IoSetCancelRoutine(Irp, AfdCancelHandler); @@ -280,6 +291,7 @@ AfdSelect( PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) KeReleaseSpinLock( &DeviceExt->Lock, OldIrql ); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); + DbgPrint("[AFD, AfdSelect] Leaving. Status = 0x%x\n", Status); return Status; } diff --git a/drivers/network/afd/afd/tdi.c b/drivers/network/afd/afd/tdi.c index c353101a4ed..21f50e9ee33 100644 --- a/drivers/network/afd/afd/tdi.c +++ b/drivers/network/afd/afd/tdi.c @@ -1241,6 +1241,7 @@ NTSTATUS TdiSendDatagram( } NTSTATUS TdiDisconnect( + PIRP *Irp, PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, @@ -1250,10 +1251,6 @@ NTSTATUS TdiDisconnect( PTDI_CONNECTION_INFORMATION RequestConnectionInfo, PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) { PDEVICE_OBJECT DeviceObject; - KEVENT Event; - PIRP Irp; - - KeInitializeEvent(&Event, NotificationEvent, FALSE); if (!TransportObject) { AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n")); @@ -1268,20 +1265,20 @@ NTSTATUS TdiDisconnect( return STATUS_INVALID_PARAMETER; } - Irp = TdiBuildInternalDeviceControlIrp + *Irp = TdiBuildInternalDeviceControlIrp ( TDI_DISCONNECT, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ - &Event, /* Event */ + NULL, /* Event */ Iosb ); /* Status */ - if (!Irp) { + if (!*Irp) { AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } TdiBuildDisconnect - (Irp, /* I/O Request Packet */ + (*Irp, /* I/O Request Packet */ DeviceObject, /* Device object */ TransportObject, /* File object */ CompletionRoutine, /* Completion routine */ @@ -1291,7 +1288,9 @@ NTSTATUS TdiDisconnect( RequestConnectionInfo, /* Indication of who to disconnect */ ReturnConnectionInfo); /* Indication of who disconnected */ - return TdiCall(Irp, DeviceObject, &Event, Iosb); + TdiCall(*Irp, DeviceObject, NULL, Iosb); + + return STATUS_PENDING; } /* EOF */ diff --git a/drivers/network/afd/afd/write.c b/drivers/network/afd/afd/write.c index a2208f997c4..d4f834494a8 100644 --- a/drivers/network/afd/afd/write.c +++ b/drivers/network/afd/afd/write.c @@ -168,11 +168,20 @@ SendComplete break; } + if (FCB->Send.Size - FCB->Send.BytesUsed != 0) + { + FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } + else + { + FCB->PollState &= ~AFD_EVENT_SEND; + } + /* Some data is still waiting */ if (FCB->Send.BytesUsed) { - FCB->PollState &= ~AFD_EVENT_SEND; - Status = TdiSend( &FCB->SendIrp.InFlightRequest, FCB->Connection.Object, 0, @@ -184,12 +193,6 @@ SendComplete RetryDisconnectCompletion(FCB); } - else - { - FCB->PollState |= AFD_EVENT_SEND; - FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; - PollReeval( FCB->DeviceExt, FCB->FileObject ); - } SocketStateUnlock( FCB ); @@ -408,6 +411,7 @@ AfdConnectedSocketWriteData } else { + FCB->PollState &= ~AFD_EVENT_SEND; if (SendReq->AfdFlags & AFD_IMMEDIATE) { AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); @@ -440,6 +444,17 @@ AfdConnectedSocketWriteData Status, TotalBytesCopied)); } + if (SpaceAvail) + { + FCB->PollState |= AFD_EVENT_SEND; + FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } + else + { + FCB->PollState &= ~AFD_EVENT_SEND; + } + RetryDisconnectCompletion(FCB); return UnlockAndMaybeComplete(FCB, Status, Irp, TotalBytesCopied); diff --git a/drivers/network/afd/include/afd.h b/drivers/network/afd/include/afd.h index b3628d3d15e..78ea39833ff 100644 --- a/drivers/network/afd/include/afd.h +++ b/drivers/network/afd/include/afd.h @@ -182,10 +182,12 @@ typedef struct _AFD_FCB { PAFD_DEVICE_EXTENSION DeviceExt; BOOLEAN DelayedAccept; UINT ConnSeq; + USHORT DisconnectFlags; + BOOLEAN DisconnectPending; PTRANSPORT_ADDRESS LocalAddress, RemoteAddress; - PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo; + PTDI_CONNECTION_INFORMATION AddressFrom, ConnectCallInfo, ConnectReturnInfo; AFD_TDI_OBJECT AddressFile, Connection; - AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp; + AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp, DisconnectIrp; AFD_DATA_WINDOW Send, Recv; KMUTEX Mutex; PKEVENT EventSelect; diff --git a/drivers/network/afd/include/tdi_proto.h b/drivers/network/afd/include/tdi_proto.h index a70c810e697..277cf736bbb 100644 --- a/drivers/network/afd/include/tdi_proto.h +++ b/drivers/network/afd/include/tdi_proto.h @@ -16,7 +16,8 @@ NTSTATUS TdiCloseDevice(HANDLE Handle, PFILE_OBJECT FileObject); NTSTATUS TdiDisconnect -( PFILE_OBJECT TransportObject, +( PIRP *Irp, + PFILE_OBJECT TransportObject, PLARGE_INTEGER Time, USHORT Flags, PIO_STATUS_BLOCK Iosb,