Author: cgutman
Date: Mon May 10 23:14:26 2010
New Revision: 47156
URL:
http://svn.reactos.org/svn/reactos?rev=47156&view=rev
Log:
[AFD]
- Fix signaling socket termination events on disconnect
- Fixes bug 4951
Modified:
trunk/reactos/drivers/network/afd/afd/read.c
Modified: trunk/reactos/drivers/network/afd/afd/read.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/re…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Mon May 10 23:14:26 2010
@@ -26,10 +26,38 @@
#include "tdiconn.h"
#include "debug.h"
-static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
- UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
-
- return !BytesAvailable;
+static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) {
+ NTSTATUS Status = STATUS_PENDING;
+
+ if( !FCB->ReceiveIrp.InFlightRequest ) {
+ AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
+
+ Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
+ FCB->Connection.Object,
+ TDI_RECEIVE_NORMAL,
+ FCB->Recv.Window,
+ FCB->Recv.Size,
+ &FCB->ReceiveIrp.Iosb,
+ ReceiveComplete,
+ FCB );
+
+ if( ( Status == STATUS_SUCCESS && !FCB->ReceiveIrp.Iosb.Information )
||
+ ( !NT_SUCCESS( Status ) ) )
+ {
+ /* The socket has been closed */
+ FCB->PollState |= AFD_EVENT_DISCONNECT;
+ FCB->Overread = TRUE;
+ Status = STATUS_FILE_CLOSED;
+ }
+ else if( Status == STATUS_SUCCESS )
+ {
+ FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
+ FCB->PollState |= AFD_EVENT_RECEIVE;
+ }
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ }
+
+ return Status;
}
static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
@@ -46,7 +74,22 @@
AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n",
BytesAvailable));
- if( CantReadMore(FCB) ) return STATUS_PENDING;
+ if( FCB->Overread ) return STATUS_FILE_CLOSED;
+ if( !BytesAvailable ) {
+ FCB->Recv.Content = FCB->Recv.BytesUsed = 0;
+ Status = RefillSocketBuffer( FCB );
+ if ( Status != STATUS_SUCCESS )
+ return Status;
+
+ /* If RefillSocketBuffer returns STATUS_SUCCESS, we're good to go
+ * If RefillSocketBuffer returns STATUS_PENDING, then it's waiting on the
transport for data
+ * If RefillSocketBuffer returns STATUS_FILE_CLOSED, then the connection was
terminated
+ */
+
+ /* Recalculate BytesAvailable based on new data */
+ BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
+ ASSERT(BytesAvailable);
+ }
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
@@ -88,23 +131,8 @@
if( FCB->Recv.BytesUsed == FCB->Recv.Content ) {
FCB->Recv.BytesUsed = FCB->Recv.Content = 0;
FCB->PollState &= ~AFD_EVENT_RECEIVE;
- PollReeval( FCB->DeviceExt, FCB->FileObject );
-
- if( !FCB->ReceiveIrp.InFlightRequest ) {
- AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
-
- Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
- FCB->Connection.Object,
- TDI_RECEIVE_NORMAL,
- FCB->Recv.Window,
- FCB->Recv.Size,
- &FCB->ReceiveIrp.Iosb,
- ReceiveComplete,
- FCB );
-
- if( Status == STATUS_SUCCESS )
- FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
- }
+
+ RefillSocketBuffer( FCB );
}
return STATUS_SUCCESS;
@@ -159,7 +187,7 @@
}
}
- if( !CantReadMore(FCB) ) {
+ if( !FCB->Recv.Content ) {
FCB->PollState |= AFD_EVENT_RECEIVE;
} else
FCB->PollState &= ~AFD_EVENT_RECEIVE;