- Queue the user-mode connect IRP before calling TdiConnect to avoid a race if the TDI_CONNECT IRP is completed before we get a chance to queue the user-mode IRP to accept the connection
- Change the non-blocking TDI helper functions to always return STATUS_PENDING if the completion function will be called to avoid duplicate handling of IRPs

svn path=/trunk/; revision=52441
This commit is contained in:
Cameron Gutman 2011-06-24 14:06:48 +00:00
parent b1bcc80fd3
commit f6485fab90
4 changed files with 53 additions and 60 deletions

View file

@ -465,23 +465,30 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
TargetAddress->UserDataLength = FCB->ConnectDataSize;
TargetAddress->Options = FCB->ConnectOptions;
TargetAddress->OptionsLength = FCB->ConnectOptionsSize;
FCB->State = SOCKET_STATE_CONNECTING;
AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT );
if (Status == STATUS_PENDING)
{
Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
FCB->Connection.Object,
TargetAddress,
FCB->ConnectInfo,
&FCB->ConnectIrp.Iosb,
StreamSocketConnectComplete,
FCB );
}
if (Status != STATUS_PENDING)
FCB->State = SOCKET_STATE_BOUND;
Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
FCB->Connection.Object,
TargetAddress,
FCB->ConnectInfo,
&FCB->ConnectIrp.Iosb,
StreamSocketConnectComplete,
FCB );
ExFreePool(TargetAddress);
SocketStateUnlock(FCB);
ExFreePool(TargetAddress);
AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
if( Status == STATUS_PENDING ) {
FCB->State = SOCKET_STATE_CONNECTING;
return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT );
}
return Status;
}
break;

View file

@ -287,12 +287,13 @@ NTSTATUS LostSocket( PIRP Irp ) {
return Status;
}
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
NTSTATUS QueueUserModeIrp(PAFD_FCB FCB, PIRP Irp, UINT Function)
{
NTSTATUS Status;
/* Add the IRP to the queue in all cases (so AfdCancelHandler will work properly) */
InsertTailList( &FCB->PendingIrpList[Function],
&Irp->Tail.Overlay.ListEntry );
&Irp->Tail.Overlay.ListEntry );
/* Acquire the cancel spin lock and check the cancel bit */
IoAcquireCancelSpinLock(&Irp->CancelIrql);
@ -319,6 +320,14 @@ NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
Status = STATUS_CANCELLED;
}
return Status;
}
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function ) {
NTSTATUS Status;
Status = QueueUserModeIrp(FCB, Irp, Function);
SocketStateUnlock( FCB );
return Status;

View file

@ -325,7 +325,6 @@ NTSTATUS TdiConnect(
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
@ -360,9 +359,9 @@ NTSTATUS TdiConnect(
ConnectionCallInfo, /* Request connection information */
ConnectionReturnInfo); /* Return connection information */
Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, Iosb);
return Status;
return STATUS_PENDING;
}
@ -380,7 +379,6 @@ NTSTATUS TdiAssociateAddressFile(
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
@ -415,9 +413,7 @@ NTSTATUS TdiAssociateAddressFile(
NULL,
AddressHandle);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
NTSTATUS TdiDisassociateAddressFile(
@ -432,7 +428,6 @@ NTSTATUS TdiDisassociateAddressFile(
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
@ -465,9 +460,7 @@ NTSTATUS TdiDisassociateAddressFile(
NULL,
NULL);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
NTSTATUS TdiListen
@ -489,7 +482,6 @@ NTSTATUS TdiListen
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
AFD_DbgPrint(MAX_TRACE, ("Called\n"));
@ -523,9 +515,9 @@ NTSTATUS TdiListen
*RequestConnectionInfo, /* Request connection information */
*ReturnConnectionInfo); /* Return connection information */
Status = TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
return Status;
return STATUS_PENDING;
}
@ -549,7 +541,6 @@ NTSTATUS TdiSetEventHandler(
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
@ -587,9 +578,7 @@ NTSTATUS TdiSetEventHandler(
Handler,
Context);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
@ -670,7 +659,6 @@ NTSTATUS TdiQueryInformation(
{
PDEVICE_OBJECT DeviceObject;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
@ -705,9 +693,7 @@ NTSTATUS TdiQueryInformation(
QueryType,
MdlBuffer);
Status = TdiCall(Irp, DeviceObject, &Event, &Iosb);
return Status;
return TdiCall(Irp, DeviceObject, &Event, &Iosb);
}
NTSTATUS TdiQueryInformationEx(
@ -897,7 +883,6 @@ NTSTATUS TdiSend
PVOID CompletionContext )
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_SUCCESS;
PMDL Mdl;
ASSERT(*Irp == NULL);
@ -960,11 +945,11 @@ NTSTATUS TdiSend
Flags, /* Flags */
BufferLength); /* Length of data */
Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, Iosb);
/* Does not block... The MDL is deleted in the receive completion
routine. */
return Status;
return STATUS_PENDING;
}
NTSTATUS TdiReceive(
@ -977,7 +962,6 @@ NTSTATUS TdiReceive(
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
{
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject;
PMDL Mdl;
@ -1028,7 +1012,7 @@ NTSTATUS TdiReceive(
AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
IoFreeMdl(Mdl);
IoCompleteRequest(*Irp, IO_NO_INCREMENT);
*Irp = NULL;
*Irp = NULL;
_SEH2_YIELD(return STATUS_INSUFFICIENT_RESOURCES);
} _SEH2_END;
@ -1044,14 +1028,11 @@ NTSTATUS TdiReceive(
BufferLength); /* Length of data */
Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, Iosb);
/* Does not block... The MDL is deleted in the receive completion
routine. */
AFD_DbgPrint(MID_TRACE,("Status %x Information %d\n",
Status, Iosb->Information));
return Status;
return STATUS_PENDING;
}
@ -1078,7 +1059,6 @@ NTSTATUS TdiReceiveDatagram(
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
PMDL Mdl;
ASSERT(*Irp == NULL);
@ -1144,11 +1124,11 @@ NTSTATUS TdiReceiveDatagram(
Addr,
Flags); /* Length of data */
Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, Iosb);
/* Does not block... The MDL is deleted in the receive completion
routine. */
return Status;
return STATUS_PENDING;
}
@ -1174,7 +1154,6 @@ NTSTATUS TdiSendDatagram(
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
PMDL Mdl;
ASSERT(*Irp == NULL);
@ -1241,11 +1220,11 @@ NTSTATUS TdiSendDatagram(
BufferLength, /* Bytes to send */
Addr); /* Address */
Status = TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, Iosb);
/* Does not block... The MDL is deleted in the send completion
routine. */
return Status;
return STATUS_PENDING;
}
NTSTATUS TdiDisconnect(
@ -1258,7 +1237,6 @@ NTSTATUS TdiDisconnect(
PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) {
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
@ -1300,9 +1278,7 @@ NTSTATUS TdiDisconnect(
RequestConnectionInfo, /* Indication of who to disconnect */
ReturnConnectionInfo); /* Indication of who disconnected */
Status = TdiCall(Irp, DeviceObject, &Event, Iosb);
return Status;
return TdiCall(Irp, DeviceObject, &Event, Iosb);
}
/* EOF */

View file

@ -302,11 +302,12 @@ VOID UnlockHandles( PAFD_HANDLE HandleArray, UINT HandleCount );
PVOID LockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp );
PVOID GetLockedData( PIRP Irp, PIO_STACK_LOCATION IrpSp );
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function );
NTSTATUS QueueUserModeIrp(PAFD_FCB FCB, PIRP Irp, UINT Function);
/* main.c */
VOID OskitDumpBuffer( PCHAR Buffer, UINT Len );
NTSTATUS LeaveIrpUntilLater( PAFD_FCB FCB, PIRP Irp, UINT Function );
VOID DestroySocket( PAFD_FCB FCB );
VOID NTAPI AfdCancelHandler(PDEVICE_OBJECT DeviceObject,
PIRP Irp);