From 94c4d9da6dabf4dd53b19176d3c019906f371c41 Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Wed, 14 Jun 2023 23:40:03 +0200 Subject: [PATCH] [0.4.13][AFD] ReceiveActivity: Don't return STATUS_FILE_CLOSED in case of FCB overread (#4972) fix CORE-18328 'FileZilla 3.8 unable to list content of a remote directory due to undue ECONNRESET' I tested to list the contents of ftp.heise.de and downloaded some files from its pub. by porting back: 0.4.15-dev-5870-g 9f9b81e3961462698294c0858f113757a23d58a4 [AFD] ReceiveActivity: Don't return STATUS_FILE_CLOSED in case of FCB overread CORE-18328 (#4972) --- drivers/network/afd/afd/main.c | 3 --- drivers/network/afd/afd/read.c | 20 ++++++-------------- drivers/network/afd/include/afd.h | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/drivers/network/afd/afd/main.c b/drivers/network/afd/afd/main.c index db017035341..5466aa9036a 100644 --- a/drivers/network/afd/afd/main.c +++ b/drivers/network/afd/afd/main.c @@ -751,9 +751,6 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, FCB->Recv.Content = 0; FCB->Recv.BytesUsed = 0; - /* Mark us as overread to complete future reads with an error */ - FCB->Overread = TRUE; - /* Set a successful receive status to indicate a shutdown on overread */ FCB->LastReceiveStatus = STATUS_SUCCESS; diff --git a/drivers/network/afd/afd/read.c b/drivers/network/afd/afd/read.c index e786faa2515..ab146aafe1d 100644 --- a/drivers/network/afd/afd/read.c +++ b/drivers/network/afd/afd/read.c @@ -175,23 +175,15 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { TotalBytesCopied)); UnlockBuffers( RecvReq->BufferArray, RecvReq->BufferCount, FALSE ); - if (FCB->Overread && FCB->LastReceiveStatus == STATUS_SUCCESS) - { - /* Overread after a graceful disconnect so complete with an error */ - Status = STATUS_FILE_CLOSED; - } - else - { - /* Unexpected disconnect by the remote host or initial read after a graceful disconnect */ - Status = FCB->LastReceiveStatus; - } + + Status = FCB->LastReceiveStatus; + NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = 0; if( NextIrp == Irp ) RetStatus = Status; if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); - FCB->Overread = TRUE; } } else { /* Kick the user that receive would be possible now */ @@ -492,7 +484,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information); } - else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) && + else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) && ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) { AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); @@ -519,7 +511,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, Status = ReceiveActivity( FCB, Irp ); if( Status == STATUS_PENDING && - !(RecvReq->AfdFlags & AFD_OVERLAPPED) && + !(RecvReq->AfdFlags & AFD_OVERLAPPED) && ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) { AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); Status = STATUS_CANT_WAIT; @@ -772,7 +764,7 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, return UnlockAndMaybeComplete(FCB, Status, Irp, Irp->IoStatus.Information); } - else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) && + else if (!(RecvReq->AfdFlags & AFD_OVERLAPPED) && ((RecvReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) { AFD_DbgPrint(MID_TRACE,("Nonblocking\n")); diff --git a/drivers/network/afd/include/afd.h b/drivers/network/afd/include/afd.h index 21aaac5f426..2ddfcf4ad2d 100644 --- a/drivers/network/afd/include/afd.h +++ b/drivers/network/afd/include/afd.h @@ -159,7 +159,7 @@ typedef struct _AFD_STORED_DATAGRAM { } AFD_STORED_DATAGRAM, *PAFD_STORED_DATAGRAM; typedef struct _AFD_FCB { - BOOLEAN Locked, Critical, Overread, NonBlocking, OobInline, TdiReceiveClosed, SendClosed; + BOOLEAN Locked, Critical, NonBlocking, OobInline, TdiReceiveClosed, SendClosed; UINT State, Flags, GroupID, GroupType; KIRQL OldIrql; UINT LockCount;