[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 9f9b81e396 [AFD] ReceiveActivity: Don't return STATUS_FILE_CLOSED in case of FCB overread CORE-18328 (#4972)
This commit is contained in:
Joachim Henze 2023-06-14 23:40:03 +02:00
parent de21806b74
commit 94c4d9da6d
3 changed files with 7 additions and 18 deletions

View file

@ -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;

View file

@ -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"));

View file

@ -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;