Made a nice function CantReadMore which tells if we can't possibly fill the buffer any longer, and don't have waiting data. Return an EOF in every case where a read could hit EOF from tcpip, Return a hard error thereafter. Modified: trunk/reactos/drivers/net/afd/afd/read.c _____
Modified: trunk/reactos/drivers/net/afd/afd/read.c --- trunk/reactos/drivers/net/afd/afd/read.c 2005-02-08 22:52:16 UTC (rev 13473) +++ trunk/reactos/drivers/net/afd/afd/read.c 2005-02-09 08:38:46 UTC (rev 13474) @@ -28,6 +28,13 @@
static VOID ProcessClose( PAFD_FCB FCB );
+BOOLEAN CantReadMore( PAFD_FCB FCB ) { + UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed; + + return !BytesAvailable && + (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT)); +} + NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied ) { @@ -41,7 +48,7 @@ AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n", BytesAvailable));
- if( FCB->PollState & AFD_EVENT_CLOSE ) return STATUS_SUCCESS; + if( CantReadMore(FCB) ) return STATUS_SUCCESS; if( !BytesAvailable ) return STATUS_PENDING;
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount); @@ -213,6 +220,24 @@
Status = STATUS_SUCCESS; } else { + /* Success here means that we got an EOF. Close all pending reads + * with EOF. Data won't have been available before. */ + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { + NextIrpEntry = + RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); + NextIrp = + CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); + NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); + RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + TotalBytesCopied)); + UnlockBuffers( RecvReq->BufferArray, + RecvReq->BufferCount, FALSE ); + NextIrp->IoStatus.Status = Status; + NextIrp->IoStatus.Information = 0; + IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); + } ProcessClose( FCB ); }
@@ -272,7 +297,7 @@
/* Check if we're not closed down yet */
- if( !(FCB->PollState & AFD_EVENT_CLOSE ) ) { + if( !CantReadMore(FCB) ) { AFD_DbgPrint(MID_TRACE,("Not EOF yet\n")); if( FCB->ReceiveIrp.InFlightRequest ) { AFD_DbgPrint(MID_TRACE,("We're waiting on a previous irp\n")); @@ -288,6 +313,9 @@ Status = STATUS_END_OF_FILE;
ProcessClose( FCB ); + + return UnlockAndMaybeComplete + ( FCB, STATUS_SUCCESS, Irp, 0, NULL, FALSE); }
if( NT_SUCCESS(Status) ) {