Read: Generalized EOF condition slightly.

Remember to check for failure when locking address buffer.
Lock: SEH to protect from bad address length ptr.

svn path=/trunk/; revision=14543
This commit is contained in:
Art Yerkes 2005-04-08 11:04:13 +00:00
parent e2303991a6
commit c0282425ac
2 changed files with 40 additions and 26 deletions

View file

@ -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++ ) {

View file

@ -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;