Read: Generalized EOF condition slightly.
      Remember to check for failure when locking address buffer.
Lock: SEH to protect from bad address length ptr.
Modified: trunk/reactos/drivers/net/afd/afd/lock.c
Modified: trunk/reactos/drivers/net/afd/afd/read.c

Modified: trunk/reactos/drivers/net/afd/afd/lock.c
--- trunk/reactos/drivers/net/afd/afd/lock.c	2005-04-08 05:35:20 UTC (rev 14542)
+++ trunk/reactos/drivers/net/afd/afd/lock.c	2005-04-08 11:04:13 UTC (rev 14543)
@@ -11,6 +11,7 @@
 #include "tdi_proto.h"
 #include "tdiconn.h"
 #include "debug.h"
+#include "pseh.h"
 
 /* Lock a method_neither request so it'll be available from DISPATCH_LEVEL */
 PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
@@ -49,21 +50,31 @@
     UINT Size = sizeof(AFD_WSABUF) * (Count + Lock);
     PAFD_WSABUF NewBuf = ExAllocatePool( PagedPool, Size * 2 );
     PMDL NewMdl;
+    INT NewBufferLen;
 
     AFD_DbgPrint(MID_TRACE,("Called\n"));
 
     if( NewBuf ) {
 	PAFD_MAPBUF MapBuf = (PAFD_MAPBUF)(NewBuf + Count + Lock);
 
-	RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
+        _SEH_TRY {
+            RtlCopyMemory( NewBuf, Buf, sizeof(AFD_WSABUF) * Count );
+            NewBufferLen = *AddressLen;
+        } _SEH_HANDLE {
+            AFD_DbgPrint(MIN_TRACE,("Access violation copying buffer info "
+                                    "from userland (%x %x)\n", 
+                                    Buf, AddressLen));
+            ExFreePool( NewBuf );
+            return NULL;
+        } _SEH_END;
 
-	if( LockAddress ) {
-	    NewBuf[Count].buf = AddressBuf;
-	    NewBuf[Count].len = *AddressLen;
-	    Count++;
-	    NewBuf[Count].buf = (PVOID)AddressLen;
-	    NewBuf[Count].len = sizeof(*AddressLen);
-	    Count++;
+        if( LockAddress ) {
+            NewBuf[Count].buf = AddressBuf;
+            NewBuf[Count].len = NewBufferLen;
+            Count++;
+            NewBuf[Count].buf = (PVOID)AddressLen;
+            NewBuf[Count].len = sizeof(*AddressLen);
+            Count++;
 	}
 
 	for( i = 0; i < Count; i++ ) {

Modified: trunk/reactos/drivers/net/afd/afd/read.c
--- trunk/reactos/drivers/net/afd/afd/read.c	2005-04-08 05:35:20 UTC (rev 14542)
+++ trunk/reactos/drivers/net/afd/afd/read.c	2005-04-08 11:04:13 UTC (rev 14543)
@@ -33,6 +33,14 @@
         (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT));
 }
 
+VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, UINT Information ) {
+    if( Status == STATUS_SUCCESS && Information == 0 ) {
+        AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
+        FCB->PollState |= AFD_EVENT_CLOSE /*| AFD_EVENT_DISCONNECT */;
+        PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+}
+
 NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
 					    PAFD_RECV_INFO RecvReq,
 					    PUINT TotalBytesCopied ) {
@@ -101,15 +109,9 @@
 				 ReceiveComplete,
 				 FCB );
 
-	    if( Status == STATUS_SUCCESS ) {
-		if( !FCB->ReceiveIrp.Iosb.Information ) {
-		    AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
-                    FCB->PollState |= AFD_EVENT_DISCONNECT;
-                    PollReeval( FCB->DeviceExt, FCB->FileObject );
-		}
-		FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
-	    }
-	    
+            if( Status == STATUS_SUCCESS ) 
+                FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
+            HandleEOFOnIrp( FCB, Status, FCB->Recv.Content );
 	    SocketCalloutLeave( FCB );
 	}
     }
@@ -149,6 +151,8 @@
             if( NextIrp == Irp ) RetStatus = Status;
             IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT );
             FCB->Overread = TRUE;
+            //FCB->PollState |= AFD_EVENT_DISCONNECT;
+            PollReeval( FCB->DeviceExt, FCB->FileObject );
         }
     } else {
 	/* Kick the user that receive would be possible now */
@@ -233,14 +237,8 @@
         return STATUS_UNSUCCESSFUL;
     }
     
-    Status = FCB->ReceiveIrp.Iosb.Status;
+    HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
 
-    if( Irp->IoStatus.Status == STATUS_SUCCESS && 
-        Irp->IoStatus.Information == 0 ) {
-        AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n"));
-        FCB->PollState |= AFD_EVENT_DISCONNECT;
-    }
-
     ReceiveActivity( FCB, NULL );
     
     PollReeval( FCB->DeviceExt, FCB->FileObject );
@@ -249,7 +247,7 @@
 
     AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status));
 
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS STDCALL
@@ -260,7 +258,7 @@
     PAFD_FCB FCB = FileObject->FsContext;
     PAFD_RECV_INFO RecvReq;
     UINT TotalBytesCopied = 0;
-
+    
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
@@ -294,6 +292,11 @@
 					NULL, NULL,
 					TRUE, FALSE );
 
+    if( !RecvReq->BufferArray ) {
+        return UnlockAndMaybeComplete( FCB, STATUS_ACCESS_VIOLATION,
+                                       Irp, 0, NULL, FALSE );
+    }
+
     Irp->IoStatus.Status = STATUS_PENDING;
     Irp->IoStatus.Information = 0;