diff --git a/reactos/drivers/net/afd/afd/lock.c b/reactos/drivers/net/afd/afd/lock.c index e60929ae261..c173ead9ab5 100644 --- a/reactos/drivers/net/afd/afd/lock.c +++ b/reactos/drivers/net/afd/afd/lock.c @@ -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 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, 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++ ) { diff --git a/reactos/drivers/net/afd/afd/read.c b/reactos/drivers/net/afd/afd/read.c index 631305b2296..569da4619f2 100644 --- a/reactos/drivers/net/afd/afd/read.c +++ b/reactos/drivers/net/afd/afd/read.c @@ -33,6 +33,14 @@ BOOLEAN CantReadMore( PAFD_FCB FCB ) { (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 @@ NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, 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 @@ NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) { 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,13 +237,7 @@ NTSTATUS DDKAPI ReceiveComplete return STATUS_UNSUCCESSFUL; } - Status = FCB->ReceiveIrp.Iosb.Status; - - if( Irp->IoStatus.Status == STATUS_SUCCESS && - Irp->IoStatus.Information == 0 ) { - AFD_DbgPrint(MID_TRACE,("Looks like an EOF\n")); - FCB->PollState |= AFD_EVENT_DISCONNECT; - } + HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information ); ReceiveActivity( FCB, NULL ); @@ -249,7 +247,7 @@ NTSTATUS DDKAPI ReceiveComplete AFD_DbgPrint(MID_TRACE,("Returned %x\n", Status)); - return Status; + return STATUS_SUCCESS; } NTSTATUS STDCALL @@ -260,7 +258,7 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 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 @@ AfdConnectedSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp, 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;