[AFD]
authorCameron Gutman <aicommander@gmail.com>
Mon, 10 May 2010 21:14:26 +0000 (21:14 +0000)
committerCameron Gutman <aicommander@gmail.com>
Mon, 10 May 2010 21:14:26 +0000 (21:14 +0000)
- Fix signaling socket termination events on disconnect
- Fixes bug 4951

svn path=/trunk/; revision=47156

reactos/drivers/network/afd/afd/read.c

index e7e9a6e..3c6ddaa 100644 (file)
 #include "tdiconn.h"
 #include "debug.h"
 
 #include "tdiconn.h"
 #include "debug.h"
 
-static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
-    UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
+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 !BytesAvailable;
+       return Status;
 }
 
 static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
 }
 
 static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
@@ -46,7 +74,22 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
     AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n",
                                                        BytesAvailable));
 
     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);
 
 
     Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
 
@@ -88,23 +131,8 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
     if( FCB->Recv.BytesUsed == FCB->Recv.Content ) {
                FCB->Recv.BytesUsed = FCB->Recv.Content = 0;
         FCB->PollState &= ~AFD_EVENT_RECEIVE;
     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;
     }
 
     return STATUS_SUCCESS;
@@ -159,7 +187,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
           }
     }
 
           }
     }
 
-    if( !CantReadMore(FCB) ) {
+    if( !FCB->Recv.Content ) {
                FCB->PollState |= AFD_EVENT_RECEIVE;
     } else
                FCB->PollState &= ~AFD_EVENT_RECEIVE;
                FCB->PollState |= AFD_EVENT_RECEIVE;
     } else
                FCB->PollState &= ~AFD_EVENT_RECEIVE;