- Fix shutdown() for datagram sockets
- Share some code between SD_BOTH and SD_RECEIVE

svn path=/trunk/; revision=53144
This commit is contained in:
Cameron Gutman 2011-08-08 21:57:06 +00:00
parent 2c6c184457
commit 44bc45f23c
3 changed files with 54 additions and 20 deletions

View file

@ -680,38 +680,52 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY, return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
Irp, 0 ); Irp, 0 );
/* Shutdown(SD_SEND) */ /* Send direction only */
if ((DisReq->DisconnectType & AFD_DISCONNECT_SEND) && if ((DisReq->DisconnectType & AFD_DISCONNECT_SEND) &&
!(DisReq->DisconnectType & AFD_DISCONNECT_RECV)) !(DisReq->DisconnectType & AFD_DISCONNECT_RECV))
{ {
/* Perform a controlled disconnect */ /* Perform a controlled disconnect */
Flags = TDI_DISCONNECT_RELEASE; Flags = TDI_DISCONNECT_RELEASE;
} }
/* Shutdown(SD_RECEIVE) */ /* Receive direction or both */
else if ((DisReq->DisconnectType & AFD_DISCONNECT_RECV) && else
!(DisReq->DisconnectType & AFD_DISCONNECT_SEND))
{ {
/* Mark that we can't issue another receive request */ /* Mark that we can't issue another receive request */
FCB->TdiReceiveClosed = TRUE; FCB->TdiReceiveClosed = TRUE;
/* Discard any pending data */ /* These are only for connection-oriented sockets */
FCB->Recv.Content = 0; if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
FCB->Recv.BytesUsed = 0; {
/* Try to cancel a pending TDI receive IRP if there was one in progress */
if (FCB->ReceiveIrp.InFlightRequest)
IoCancelIrp(FCB->ReceiveIrp.InFlightRequest);
/* Mark us as overread to complete future reads with an error */ /* Discard any pending data */
FCB->Overread = TRUE; FCB->Recv.Content = 0;
FCB->Recv.BytesUsed = 0;
/* Mark us as overread to complete future reads with an error */
FCB->Overread = TRUE;
/* Set a successful close status to indicate a shutdown on overread */
FCB->PollStatus[FD_CLOSE_BIT] = STATUS_SUCCESS;
}
/* Clear the receive event */ /* Clear the receive event */
FCB->PollState &= ~AFD_EVENT_RECEIVE; FCB->PollState &= ~AFD_EVENT_RECEIVE;
/* We're done (no need to tell the TDI transport driver) */ /* Receive direction only */
return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 ); if ((DisReq->DisconnectType & AFD_DISCONNECT_RECV) &&
} !(DisReq->DisconnectType & AFD_DISCONNECT_SEND))
/* Shutdown(SD_BOTH) */ {
else /* No need to tell the transport driver for receive direction only */
{ return UnlockAndMaybeComplete( FCB, STATUS_SUCCESS, Irp, 0 );
/* Perform an abortive disconnect */ }
Flags = TDI_DISCONNECT_ABORT; else
{
/* Perform an abortive disconnect */
Flags = TDI_DISCONNECT_ABORT;
}
} }
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)) if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
@ -785,9 +799,10 @@ AfdDisconnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
ExFreePool(FCB->RemoteAddress); ExFreePool(FCB->RemoteAddress);
FCB->RemoteAddress = NULL; FCB->RemoteAddress = NULL;
FCB->PollState &= ~AFD_EVENT_SEND;
} }
FCB->PollState &= ~AFD_EVENT_SEND;
FCB->SendClosed = TRUE;
} }
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );

View file

@ -27,8 +27,13 @@ static VOID HandleReceiveComplete( PAFD_FCB FCB, NTSTATUS Status, ULONG_PTR Info
{ {
FCB->Recv.BytesUsed = 0; FCB->Recv.BytesUsed = 0;
/* We got closed while the receive was in progress */
if (FCB->TdiReceiveClosed)
{
FCB->Recv.Content = 0;
}
/* Receive successful with new data */ /* Receive successful with new data */
if (Status == STATUS_SUCCESS && Information) else if (Status == STATUS_SUCCESS && Information)
{ {
FCB->Recv.Content = Information; FCB->Recv.Content = Information;
} }
@ -693,6 +698,13 @@ AfdPacketSocketReadData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete return UnlockAndMaybeComplete
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 ); ( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
} }
if (FCB->TdiReceiveClosed)
{
AFD_DbgPrint(MIN_TRACE,("Receive closed\n"));
return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
}
if( !(RecvReq = LockRequest( Irp, IrpSp )) ) if( !(RecvReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0 ); ( FCB, STATUS_NO_MEMORY, Irp, 0 );

View file

@ -516,6 +516,13 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
return UnlockAndMaybeComplete return UnlockAndMaybeComplete
( FCB, STATUS_INVALID_PARAMETER, Irp, 0 ); ( FCB, STATUS_INVALID_PARAMETER, Irp, 0 );
} }
if (FCB->SendClosed)
{
AFD_DbgPrint(MIN_TRACE,("No more sends\n"));
return UnlockAndMaybeComplete(FCB, STATUS_FILE_CLOSED, Irp, 0);
}
if( !(SendReq = LockRequest( Irp, IrpSp )) ) if( !(SendReq = LockRequest( Irp, IrpSp )) )
return UnlockAndMaybeComplete return UnlockAndMaybeComplete
( FCB, STATUS_NO_MEMORY, Irp, 0 ); ( FCB, STATUS_NO_MEMORY, Irp, 0 );