Author: cgutman Date: Sun Aug 1 21:00:40 2010 New Revision: 48400
URL: http://svn.reactos.org/svn/reactos?rev=48400&view=rev Log: [AFD]: Revert r42674 and part of r47156
Modified: trunk/reactos/drivers/network/afd/afd/read.c
Modified: trunk/reactos/drivers/network/afd/afd/read.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/rea... ============================================================================== --- trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/afd/afd/read.c [iso-8859-1] Sun Aug 1 21:00:40 2010 @@ -26,8 +26,28 @@ #include "tdiconn.h" #include "debug.h"
-static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) { - NTSTATUS Status = STATUS_PENDING; +static VOID HandleEOFOnIrp( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Information ) +{ + if( ( Status == STATUS_SUCCESS && !FCB->ReceiveIrp.Iosb.Information ) || + ( !NT_SUCCESS( Status ) ) ) + { + /* The socket has been closed */ + FCB->PollState |= AFD_EVENT_DISCONNECT; + FCB->PollStatus[FD_CLOSE_BIT] = Status; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); + } +} + +static BOOLEAN CantReadMore( PAFD_FCB FCB ) { + UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed; + + return !BytesAvailable && + (FCB->PollState & (AFD_EVENT_CLOSE | AFD_EVENT_DISCONNECT)); +} + +static VOID RefillSocketBuffer( PAFD_FCB FCB ) { + NTSTATUS Status;
if( !FCB->ReceiveIrp.InFlightRequest ) { AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n")); @@ -41,25 +61,20 @@ ReceiveComplete, FCB );
- if( ( Status == STATUS_SUCCESS && !FCB->ReceiveIrp.Iosb.Information ) || - ( !NT_SUCCESS( Status ) ) ) - { - /* The socket has been closed */ - FCB->PollState |= AFD_EVENT_DISCONNECT; - FCB->PollStatus[FD_CLOSE_BIT] = Status; - FCB->Overread = TRUE; - Status = STATUS_FILE_CLOSED; - } - else if( Status == STATUS_SUCCESS ) + if( Status == STATUS_SUCCESS && FCB->ReceiveIrp.Iosb.Information ) { FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information; FCB->PollState |= AFD_EVENT_RECEIVE; FCB->PollStatus[FD_READ_BIT] = STATUS_SUCCESS; + + PollReeval( FCB->DeviceExt, FCB->FileObject ); } - PollReeval( FCB->DeviceExt, FCB->FileObject ); + else + { + /* Check for EOF */ + HandleEOFOnIrp(FCB, Status, FCB->ReceiveIrp.Iosb.Information); + } } - - return Status; }
static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, @@ -76,22 +91,8 @@ AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n", BytesAvailable));
- 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); - } + if( CantReadMore(FCB) ) return STATUS_SUCCESS; + if( !BytesAvailable ) return STATUS_PENDING;
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
@@ -156,37 +157,72 @@ AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n", FCB, FCB->Recv.Content));
- /* Try to clear some requests */ - while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { - NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); - NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); - NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); - RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; - - AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq)); - - Status = TryToSatisfyRecvRequestFromBuffer( FCB, RecvReq, &TotalBytesCopied ); - - if( Status == STATUS_PENDING ) { - AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp)); - InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV], - &NextIrp->Tail.Overlay.ListEntry); - break; - } else { - AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, - TotalBytesCopied)); - UnlockBuffers( RecvReq->BufferArray, - RecvReq->BufferCount, FALSE ); - NextIrp->IoStatus.Status = Status; - NextIrp->IoStatus.Information = TotalBytesCopied; - if( NextIrp == Irp ) { - RetStatus = Status; - RetBytesCopied = TotalBytesCopied; + if( CantReadMore( FCB ) ) { + /* Success here means that we got an EOF. Complete a pending read + * with zero bytes if we haven't yet overread, then kill the others. + */ + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { + NextIrpEntry = + RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); + NextIrp = + CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); + NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); + RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + TotalBytesCopied)); + UnlockBuffers( RecvReq->BufferArray, + RecvReq->BufferCount, FALSE ); + Status = NextIrp->IoStatus.Status = + FCB->Overread ? STATUS_END_OF_FILE : STATUS_SUCCESS; + NextIrp->IoStatus.Information = 0; + if( NextIrp == Irp ) RetStatus = Status; + if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); + FCB->Overread = TRUE; + } + } else { + /* Kick the user that receive would be possible now */ + /* XXX Not implemented yet */ + + AFD_DbgPrint(MID_TRACE,("FCB %x Receive data waiting %d\n", + FCB, FCB->Recv.Content)); + /*OskitDumpBuffer( FCB->Recv.Window, FCB->Recv.Content );*/ + + /* Try to clear some requests */ + while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_RECV] ) ) { + NextIrpEntry = + RemoveHeadList(&FCB->PendingIrpList[FUNCTION_RECV]); + NextIrp = + CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); + NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); + RecvReq = NextIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + + AFD_DbgPrint(MID_TRACE,("RecvReq @ %x\n", RecvReq)); + + Status = TryToSatisfyRecvRequestFromBuffer + ( FCB, RecvReq, &TotalBytesCopied ); + + if( Status == STATUS_PENDING ) { + AFD_DbgPrint(MID_TRACE,("Ran out of data for %x\n", NextIrp)); + InsertHeadList(&FCB->PendingIrpList[FUNCTION_RECV], + &NextIrp->Tail.Overlay.ListEntry); + break; + } else { + AFD_DbgPrint(MID_TRACE,("Completing recv %x (%d)\n", NextIrp, + TotalBytesCopied)); + UnlockBuffers( RecvReq->BufferArray, + RecvReq->BufferCount, FALSE ); + NextIrp->IoStatus.Status = Status; + NextIrp->IoStatus.Information = TotalBytesCopied; + if( NextIrp == Irp ) { + RetStatus = Status; + RetBytesCopied = TotalBytesCopied; + } + if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); + IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); + } } - if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); - (void)IoSetCancelRoutine(NextIrp, NULL); - IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); - } }
if( FCB->Recv.Content ) { @@ -249,6 +285,8 @@ SocketStateUnlock( FCB ); return STATUS_INVALID_PARAMETER; } + + HandleEOFOnIrp( FCB, Irp->IoStatus.Status, Irp->IoStatus.Information );
ReceiveActivity( FCB, NULL );