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;