From f6485fab903a8fd42c33d4339af575cecc5dac45 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Fri, 24 Jun 2011 14:06:48 +0000 Subject: [PATCH] [AFD] - 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 --- reactos/drivers/network/afd/afd/connect.c | 37 ++++++++------ reactos/drivers/network/afd/afd/lock.c | 13 ++++- reactos/drivers/network/afd/afd/tdi.c | 60 +++++++---------------- reactos/drivers/network/afd/include/afd.h | 3 +- 4 files changed, 53 insertions(+), 60 deletions(-) diff --git a/reactos/drivers/network/afd/afd/connect.c b/reactos/drivers/network/afd/afd/connect.c index 2c7185e00d9..66eeddac82e 100644 --- a/reactos/drivers/network/afd/afd/connect.c +++ b/reactos/drivers/network/afd/afd/connect.c @@ -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; diff --git a/reactos/drivers/network/afd/afd/lock.c b/reactos/drivers/network/afd/afd/lock.c index 09f73615e5a..93b41e07ab2 100644 --- a/reactos/drivers/network/afd/afd/lock.c +++ b/reactos/drivers/network/afd/afd/lock.c @@ -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; diff --git a/reactos/drivers/network/afd/afd/tdi.c b/reactos/drivers/network/afd/afd/tdi.c index 8443b39136a..cb6e9ca2ab3 100644 --- a/reactos/drivers/network/afd/afd/tdi.c +++ b/reactos/drivers/network/afd/afd/tdi.c @@ -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 */ diff --git a/reactos/drivers/network/afd/include/afd.h b/reactos/drivers/network/afd/include/afd.h index 82ad98d6362..dfa7a3899db 100644 --- a/reactos/drivers/network/afd/include/afd.h +++ b/reactos/drivers/network/afd/include/afd.h @@ -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);