- Fix signaling socket termination events on disconnect
- Fixes bug 4951

svn path=/trunk/; revision=47156
This commit is contained in:
Cameron Gutman 2010-05-10 21:14:26 +00:00
parent 7335bf8947
commit 609171f4ac

View file

@ -26,10 +26,38 @@
#include "tdiconn.h"
#include "debug.h"
static BOOLEAN CantReadMore( PAFD_FCB FCB ) {
UINT BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed;
static NTSTATUS RefillSocketBuffer( PAFD_FCB FCB ) {
NTSTATUS Status = STATUS_PENDING;
return !BytesAvailable;
if( !FCB->ReceiveIrp.InFlightRequest ) {
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
FCB->Connection.Object,
TDI_RECEIVE_NORMAL,
FCB->Recv.Window,
FCB->Recv.Size,
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
if( ( Status == STATUS_SUCCESS && !FCB->ReceiveIrp.Iosb.Information ) ||
( !NT_SUCCESS( Status ) ) )
{
/* The socket has been closed */
FCB->PollState |= AFD_EVENT_DISCONNECT;
FCB->Overread = TRUE;
Status = STATUS_FILE_CLOSED;
}
else if( Status == STATUS_SUCCESS )
{
FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
FCB->PollState |= AFD_EVENT_RECEIVE;
}
PollReeval( FCB->DeviceExt, FCB->FileObject );
}
return Status;
}
static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
@ -46,7 +74,22 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %d\n",
BytesAvailable));
if( CantReadMore(FCB) ) return STATUS_PENDING;
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);
}
Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount);
@ -88,23 +131,8 @@ static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB,
if( FCB->Recv.BytesUsed == FCB->Recv.Content ) {
FCB->Recv.BytesUsed = FCB->Recv.Content = 0;
FCB->PollState &= ~AFD_EVENT_RECEIVE;
PollReeval( FCB->DeviceExt, FCB->FileObject );
if( !FCB->ReceiveIrp.InFlightRequest ) {
AFD_DbgPrint(MID_TRACE,("Replenishing buffer\n"));
Status = TdiReceive( &FCB->ReceiveIrp.InFlightRequest,
FCB->Connection.Object,
TDI_RECEIVE_NORMAL,
FCB->Recv.Window,
FCB->Recv.Size,
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
if( Status == STATUS_SUCCESS )
FCB->Recv.Content = FCB->ReceiveIrp.Iosb.Information;
}
RefillSocketBuffer( FCB );
}
return STATUS_SUCCESS;
@ -159,7 +187,7 @@ static NTSTATUS ReceiveActivity( PAFD_FCB FCB, PIRP Irp ) {
}
}
if( !CantReadMore(FCB) ) {
if( !FCB->Recv.Content ) {
FCB->PollState |= AFD_EVENT_RECEIVE;
} else
FCB->PollState &= ~AFD_EVENT_RECEIVE;