diff --git a/drivers/network/afd/afd/connect.c b/drivers/network/afd/afd/connect.c index 837a97506f1..ac735bbdfa3 100644 --- a/drivers/network/afd/afd/connect.c +++ b/drivers/network/afd/afd/connect.c @@ -427,10 +427,10 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp, case SOCKET_STATE_CONNECTING: return LeaveIrpUntilLater( FCB, Irp, FUNCTION_CONNECT ); - case SOCKET_STATE_CREATED: - if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress ); - FCB->LocalAddress = - TaCopyTransportAddress( &ConnectReq->RemoteAddress ); + case SOCKET_STATE_CREATED: + if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress ); + FCB->LocalAddress = + TaBuildNullTransportAddress( ConnectReq->RemoteAddress.Address[0].AddressType ); if( FCB->LocalAddress ) { diff --git a/drivers/network/afd/afd/listen.c b/drivers/network/afd/afd/listen.c index 4184cea8a40..be64e556bdf 100644 --- a/drivers/network/afd/afd/listen.c +++ b/drivers/network/afd/afd/listen.c @@ -117,11 +117,15 @@ static NTSTATUS NTAPI ListenComplete PLIST_ENTRY NextIrpEntry, QeltEntry; PIRP NextIrp; + DbgPrint("[AFD, ListenComplete] Called\n"); + if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; FCB->ListenIrp.InFlightRequest = NULL; + DbgPrint("[AFD, ListenComplete] FCB->State = 0x%x (should be 0x%x)\n", FCB->State, SOCKET_STATE_CLOSED); + if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ @@ -210,20 +214,31 @@ static NTSTATUS NTAPI ListenComplete ListEntry ) ); } - if( FCB->ListenIrp.ConnectionCallInfo ) + /* Launch new accept socket */ + Status = WarmSocketForConnection( FCB ); + + if (NT_SUCCESS(Status)) { - ExFreePool( FCB->ListenIrp.ConnectionCallInfo ); - FCB->ListenIrp.ConnectionCallInfo = NULL; - } + Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionCallInfo, + FCB->LocalAddress->Address[0].AddressType); + ASSERT(Status == STATUS_SUCCESS); + + Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionReturnInfo, + FCB->LocalAddress->Address[0].AddressType); + ASSERT(Status == STATUS_SUCCESS); + + Status = TdiListen( &FCB->ListenIrp.InFlightRequest, + FCB->Connection.Object, + &FCB->ListenIrp.ConnectionCallInfo, + &FCB->ListenIrp.ConnectionReturnInfo, + &FCB->ListenIrp.Iosb, + ListenComplete, + FCB ); - if( FCB->ListenIrp.ConnectionReturnInfo ) - { - ExFreePool( FCB->ListenIrp.ConnectionReturnInfo ); - FCB->ListenIrp.ConnectionReturnInfo = NULL; + if (Status == STATUS_PENDING) + Status = STATUS_SUCCESS; } - FCB->NeedsNewListen = TRUE; - /* Trigger a select return if appropriate */ if( !IsListEmpty( &FCB->PendingConnections ) ) { @@ -236,6 +251,8 @@ static NTSTATUS NTAPI ListenComplete SocketStateUnlock( FCB ); + DbgPrint("[AFD, ListenComplete] Leaving. Status = 0x%x\n", Status); + return Status; } @@ -306,9 +323,6 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, if (Status == STATUS_PENDING) Status = STATUS_SUCCESS; - if (NT_SUCCESS(Status)) - FCB->NeedsNewListen = FALSE; - AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); DbgPrint("[AfdListenSocket] Returning %x\n", Status); @@ -377,54 +391,6 @@ NTSTATUS AfdAccept( PDEVICE_OBJECT DeviceObject, PIRP Irp, if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp ); - if( FCB->NeedsNewListen ) - { - AFD_DbgPrint(MID_TRACE,("ADDRESSFILE: %x\n", FCB->AddressFile.Handle)); - DbgPrint("[AfdAccept] ADDRESSFILE: %x\n", FCB->AddressFile.Handle); - - /* Launch new accept socket */ - Status = WarmSocketForConnection( FCB ); - - if( Status == STATUS_SUCCESS ) - { - Status = TdiBuildNullConnectionInfo - ( &FCB->ListenIrp.ConnectionCallInfo, - FCB->LocalAddress->Address[0].AddressType ); - - if (!NT_SUCCESS(Status)) - return UnlockAndMaybeComplete(FCB, Status, Irp, 0); - - Status = TdiBuildNullConnectionInfo - ( &FCB->ListenIrp.ConnectionReturnInfo, - FCB->LocalAddress->Address[0].AddressType ); - - if (!NT_SUCCESS(Status)) - { - ExFreePool(FCB->ListenIrp.ConnectionCallInfo); - FCB->ListenIrp.ConnectionCallInfo = NULL; - return UnlockAndMaybeComplete(FCB, Status, Irp, 0); - } - - Status = TdiListen( &FCB->ListenIrp.InFlightRequest, - FCB->Connection.Object, - &FCB->ListenIrp.ConnectionCallInfo, - &FCB->ListenIrp.ConnectionReturnInfo, - &FCB->ListenIrp.Iosb, - ListenComplete, - FCB ); - - if( Status == STATUS_PENDING ) - Status = STATUS_SUCCESS; - - if( !NT_SUCCESS(Status) ) - return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); - - FCB->NeedsNewListen = FALSE; - } - else - return UnlockAndMaybeComplete( FCB, Status, Irp, 0 ); - } - for( PendingConn = FCB->PendingConnections.Flink; PendingConn != &FCB->PendingConnections; PendingConn = PendingConn->Flink ) diff --git a/drivers/network/afd/afd/lock.c b/drivers/network/afd/afd/lock.c index dcc4f24089a..5aa640a4b9b 100644 --- a/drivers/network/afd/afd/lock.c +++ b/drivers/network/afd/afd/lock.c @@ -123,7 +123,7 @@ PAFD_WSABUF LockBuffers( PAFD_WSABUF Buf, UINT Count, AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n")); _SEH2_TRY { MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode, - Write ? IoModifyAccess : IoReadAccess ); + Write ? IoReadAccess : IoModifyAccess ); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { LockFailed = TRUE; } _SEH2_END; diff --git a/drivers/network/afd/afd/main.c b/drivers/network/afd/afd/main.c index 57553328f48..7a709ac7036 100644 --- a/drivers/network/afd/afd/main.c +++ b/drivers/network/afd/afd/main.c @@ -381,6 +381,8 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, UINT Function; PIRP CurrentIrp; + DbgPrint("[AFD, AfdCleanupSocket] Called\n"); + if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp); for (Function = 0; Function < MAX_FUNCTIONS; Function++) @@ -400,6 +402,8 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE ); + DbgPrint("[AFD, AfdCleanupSocket] Leaving\n"); + return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); } @@ -414,8 +418,12 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, AFD_DbgPrint(MID_TRACE, ("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp)); + DbgPrint("[AfdCloseSocket] Called\n"); - if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; + if( !SocketAcquireStateLock( FCB ) ) + return STATUS_FILE_CLOSED; + + DbgPrint("[AfdCloseSocket] Setting closed state\n"); FCB->State = SOCKET_STATE_CLOSED; FCB->PollState = AFD_EVENT_CLOSE; @@ -479,7 +487,10 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, ExFreePool( FCB->RemoteAddress ); if( FCB->Connection.Object ) - ObDereferenceObject(FCB->Connection.Object); + { + TdiDisassociateAddressFile(FCB->Connection.Object); + ObDereferenceObject(FCB->Connection.Object); + } if( FCB->AddressFile.Object ) ObDereferenceObject(FCB->AddressFile.Object); @@ -510,6 +521,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp, IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); AFD_DbgPrint(MID_TRACE, ("Returning success.\n")); + DbgPrint("[AfdCloseSocket] Leaving\n"); return STATUS_SUCCESS; } diff --git a/drivers/network/afd/afd/tdi.c b/drivers/network/afd/afd/tdi.c index fb78fb60710..da5802f9df0 100644 --- a/drivers/network/afd/afd/tdi.c +++ b/drivers/network/afd/afd/tdi.c @@ -430,6 +430,55 @@ NTSTATUS TdiAssociateAddressFile( return Status; } +NTSTATUS TdiDisassociateAddressFile( + PFILE_OBJECT ConnectionObject) +/* + * FUNCTION: Disassociates a connection endpoint from an address file object + * ARGUMENTS: + * ConnectionObject = Connection endpoint file object + * RETURNS: + * Status of operation + */ +{ + PDEVICE_OBJECT DeviceObject; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + KEVENT Event; + PIRP Irp; + + AFD_DbgPrint(MAX_TRACE, ("Called. ConnectionObject (0x%X)\n", ConnectionObject)); + + if (!ConnectionObject) { + AFD_DbgPrint(MIN_TRACE, ("Bad connection object.\n")); + return STATUS_INVALID_PARAMETER; + } + + DeviceObject = IoGetRelatedDeviceObject(ConnectionObject); + if (!DeviceObject) { + AFD_DbgPrint(MIN_TRACE, ("Bad device object.\n")); + return STATUS_INVALID_PARAMETER; + } + + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + Irp = TdiBuildInternalDeviceControlIrp(TDI_DISASSOCIATE_ADDRESS, /* Sub function */ + DeviceObject, /* Device object */ + ConnectionObject, /* File object */ + &Event, /* Event */ + &Iosb); /* Status */ + if (!Irp) + return STATUS_INSUFFICIENT_RESOURCES; + + TdiBuildDisassociateAddress(Irp, + DeviceObject, + ConnectionObject, + NULL, + NULL); + + Status = TdiCall(Irp, DeviceObject, &Event, &Iosb); + + return Status; +} NTSTATUS TdiListen ( PIRP *Irp, @@ -1244,7 +1293,7 @@ NTSTATUS TdiDisconnect( } Irp = TdiBuildInternalDeviceControlIrp - ( TDI_SEND_DATAGRAM, /* Sub function */ + ( TDI_DISCONNECT, /* Sub function */ DeviceObject, /* Device object */ TransportObject, /* File object */ &Event, /* Event */ diff --git a/drivers/network/afd/afd/tdiconn.c b/drivers/network/afd/afd/tdiconn.c index c95ed3bd423..4aa764c230f 100644 --- a/drivers/network/afd/afd/tdiconn.c +++ b/drivers/network/afd/afd/tdiconn.c @@ -38,7 +38,14 @@ UINT TaLengthOfAddress( PTA_ADDRESS Addr ) { } UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ) { - UINT AddrLen = 2 * sizeof( ULONG ) + Addr->Address[0].AddressLength; + UINT AddrLen = sizeof(ULONG) + TaLengthOfAddress(&Addr->Address[0]); + AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen)); + return AddrLen; +} + +UINT TaLengthOfTransportAddressByType(UINT AddressType) +{ + UINT AddrLen = sizeof(ULONG) + 2 * sizeof(USHORT) + TdiAddressSizeFromType(AddressType); AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen)); return AddrLen; } @@ -77,7 +84,26 @@ PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) { return A; } -static NTSTATUS TdiBuildNullConnectionInfoInPlace +PTRANSPORT_ADDRESS TaBuildNullTransportAddress(UINT AddressType) +{ + UINT AddrLen; + PTRANSPORT_ADDRESS A; + + AddrLen = TaLengthOfTransportAddressByType(AddressType); + A = ExAllocatePool(NonPagedPool, AddrLen); + + if (A) + { + A->TAAddressCount = 1; + A->Address[0].AddressLength = TdiAddressSizeFromType(AddressType); + A->Address[0].AddressType = AddressType; + RtlZeroMemory(A->Address[0].Address, A->Address[0].AddressLength); + } + + return A; +} + +NTSTATUS TdiBuildNullConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type ) /* diff --git a/drivers/network/afd/include/afd.h b/drivers/network/afd/include/afd.h index ac3a286cd6c..5eb882d2908 100644 --- a/drivers/network/afd/include/afd.h +++ b/drivers/network/afd/include/afd.h @@ -179,7 +179,7 @@ typedef struct _AFD_FCB { PVOID CurrentThread; PFILE_OBJECT FileObject; PAFD_DEVICE_EXTENSION DeviceExt; - BOOLEAN DelayedAccept, NeedsNewListen; + BOOLEAN DelayedAccept; UINT ConnSeq; PTRANSPORT_ADDRESS LocalAddress, RemoteAddress; PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo; @@ -360,6 +360,9 @@ NTSTATUS TdiAssociateAddressFile( HANDLE AddressHandle, PFILE_OBJECT ConnectionObject); +NTSTATUS TdiDisassociateAddressFile( + PFILE_OBJECT ConnectionObject); + NTSTATUS TdiListen ( PIRP *Irp, PFILE_OBJECT ConnectionObject, diff --git a/drivers/network/afd/include/tdiconn.h b/drivers/network/afd/include/tdiconn.h index 54f83fc722a..c06d930b2da 100644 --- a/drivers/network/afd/include/tdiconn.h +++ b/drivers/network/afd/include/tdiconn.h @@ -7,6 +7,7 @@ typedef VOID *PTDI_CONNECTION_INFO_PAIR; PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ); +PTRANSPORT_ADDRESS TaBuildNullTransportAddress(UINT AddressType); UINT TaLengthOfAddress( PTA_ADDRESS Addr ); UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ); VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source ); @@ -19,7 +20,7 @@ NTSTATUS TdiBuildConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnInfo, PTRANSPORT_ADDRESS Name ); NTSTATUS TdiBuildConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Name ); -NTSTATUS TdiBuildNullConnectionInfoToPlace +NTSTATUS TdiBuildNullConnectionInfoInPlace ( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type ); NTSTATUS TdiBuildNullConnectionInfo ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type ); diff --git a/drivers/network/ndis/ndis/miniport.c b/drivers/network/ndis/ndis/miniport.c index dd6227f2137..1c189b92477 100644 --- a/drivers/network/ndis/ndis/miniport.c +++ b/drivers/network/ndis/ndis/miniport.c @@ -1880,6 +1880,7 @@ NdisIPnPStartDevice( { NDIS_DbgPrint(MIN_TRACE, ("Failed to open configuration key\n")); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); + NdisCloseConfiguration(ConfigHandle); return NdisStatus; } @@ -2218,48 +2219,54 @@ NdisIDispatchPnp( NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device start\n")); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - break; + return Status; case IRP_MN_STOP_DEVICE: - Status = NdisIForwardIrpAndWait(Adapter, Irp); - if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status)) - { - Status = NdisIPnPStopDevice(DeviceObject, Irp); - } - else - NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device stop\n")); - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Status = NdisIPnPStopDevice(DeviceObject, Irp); + if (!NT_SUCCESS(Status)) + NDIS_DbgPrint(MIN_TRACE, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n")); + Irp->IoStatus.Status = STATUS_SUCCESS; break; case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: Status = NdisIPnPQueryStopDevice(DeviceObject, Irp); Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + if (Status != STATUS_SUCCESS) + { + IoCompleteRequest(Irp, IO_NO_INCREMENT); + NDIS_DbgPrint(MIN_TRACE, ("Failing miniport halt request\n")); + return Status; + } break; case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: - Status = NdisIPnPCancelStopDevice(DeviceObject, Irp); + Status = NdisIForwardIrpAndWait(Adapter, Irp); + if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status)) + { + Status = NdisIPnPCancelStopDevice(DeviceObject, Irp); + } + else + { + NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed cancel stop/remove request\n")); + } Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - break; + return Status; case IRP_MN_QUERY_PNP_DEVICE_STATE: Status = NDIS_STATUS_SUCCESS; Irp->IoStatus.Status = Status; Irp->IoStatus.Information |= Adapter->NdisMiniportBlock.PnPFlags; - IoCompleteRequest(Irp, IO_NO_INCREMENT); break; default: - IoSkipCurrentIrpStackLocation(Irp); - Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp); break; } - return Status; + IoSkipCurrentIrpStackLocation(Irp); + return IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp); } diff --git a/drivers/network/tcpip/include/titypes.h b/drivers/network/tcpip/include/titypes.h index cb48cb4d30b..2ab4aa4141b 100644 --- a/drivers/network/tcpip/include/titypes.h +++ b/drivers/network/tcpip/include/titypes.h @@ -268,6 +268,8 @@ typedef struct _CONNECTION_ENDPOINT { LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ LIST_ENTRY SendRequest; /* Queued send requests */ + + struct _CONNECTION_ENDPOINT *Next; /* Next connection in address file list */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/drivers/network/tcpip/tcpip/dispatch.c b/drivers/network/tcpip/tcpip/dispatch.c index 38a5049a424..2fcd3bd0b5e 100644 --- a/drivers/network/tcpip/tcpip/dispatch.c +++ b/drivers/network/tcpip/tcpip/dispatch.c @@ -209,6 +209,7 @@ VOID NTAPI DispCancelListenRequest( IoReleaseCancelSpinLock(Irp->CancelIrql); TI_DbgPrint(DEBUG_IRP, ("Called.\n")); + DbgPrint("[TCPIP, DispCancelListenRequest] Called\n"); IrpSp = IoGetCurrentIrpStackLocation(Irp); FileObject = IrpSp->FileObject; @@ -219,7 +220,10 @@ VOID NTAPI DispCancelListenRequest( #if DBG if (!Irp->Cancel) + { TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n")); + DbgPrint("[TCPIP, DispCancelListenRequest] Irp->Cancel is FALSE, should be TRUE\n"); + } #endif /* Try canceling the request */ @@ -233,6 +237,7 @@ VOID NTAPI DispCancelListenRequest( } TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); + DbgPrint("[TCPIP, DispCancelListenRequest] Leaving\n"); } @@ -262,14 +267,14 @@ NTSTATUS DispTdiAssociateAddress( * Status of operation */ { - PTDI_REQUEST_KERNEL_ASSOCIATE Parameters; - PTRANSPORT_CONTEXT TranContext; - PIO_STACK_LOCATION IrpSp; - PCONNECTION_ENDPOINT Connection; - PFILE_OBJECT FileObject; - PADDRESS_FILE AddrFile = NULL; - NTSTATUS Status; - KIRQL OldIrql; + PTDI_REQUEST_KERNEL_ASSOCIATE Parameters; + PTRANSPORT_CONTEXT TranContext; + PIO_STACK_LOCATION IrpSp; + PCONNECTION_ENDPOINT Connection, LastConnection; + PFILE_OBJECT FileObject; + PADDRESS_FILE AddrFile = NULL; + NTSTATUS Status; + KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiAssociateAddress] Called\n")); @@ -349,20 +354,27 @@ NTSTATUS DispTdiAssociateAddress( LockObjectAtDpcLevel(AddrFile); + /* Add connection endpoint to the address file */ + ReferenceObject(Connection); + if (AddrFile->Connection == NULL) + AddrFile->Connection = Connection; + else + { + LastConnection = AddrFile->Connection; + while (LastConnection->Next != NULL) + LastConnection = LastConnection->Next; + LastConnection->Next = Connection; + } + ReferenceObject(AddrFile); Connection->AddressFile = AddrFile; - /* Add connection endpoint to the address file */ - ReferenceObject(Connection); - AddrFile->Connection = Connection; - - /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ - ObDereferenceObject(FileObject); - UnlockObjectFromDpcLevel(AddrFile); UnlockObject(Connection, OldIrql); - return Status; + ObDereferenceObject(FileObject); + + return STATUS_SUCCESS; } @@ -440,10 +452,11 @@ NTSTATUS DispTdiDisassociateAddress( * Status of operation */ { - PCONNECTION_ENDPOINT Connection; + PCONNECTION_ENDPOINT Connection, LastConnection; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; KIRQL OldIrql; + NTSTATUS Status; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -473,19 +486,42 @@ NTSTATUS DispTdiDisassociateAddress( LockObjectAtDpcLevel(Connection->AddressFile); - /* Remove this connection from the address file */ - DereferenceObject(Connection->AddressFile->Connection); - Connection->AddressFile->Connection = NULL; + /* Unlink this connection from the address file */ + if (Connection->AddressFile->Connection == Connection) + { + Connection->AddressFile->Connection = Connection->Next; + DereferenceObject(Connection); + Status = STATUS_SUCCESS; + } + else + { + LastConnection = Connection->AddressFile->Connection; + while (LastConnection->Next != Connection && LastConnection->Next != NULL) + LastConnection = LastConnection->Next; + if (LastConnection->Next == Connection) + { + LastConnection->Next = Connection->Next; + DereferenceObject(Connection); + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_INVALID_PARAMETER; + } + } UnlockObjectFromDpcLevel(Connection->AddressFile); - /* Remove the address file from this connection */ - DereferenceObject(Connection->AddressFile); - Connection->AddressFile = NULL; + if (Status == STATUS_SUCCESS) + { + /* Remove the address file from this connection */ + DereferenceObject(Connection->AddressFile); + Connection->AddressFile = NULL; + } UnlockObject(Connection, OldIrql); - return STATUS_SUCCESS; + return Status; } @@ -618,12 +654,11 @@ NTSTATUS DispTdiListen( if( !Connection->AddressFile->Listener ) Status = STATUS_NO_MEMORY; - if( NT_SUCCESS(Status) ) - { - ReferenceObject(Connection->AddressFile); - Connection->AddressFile->Listener->AddressFile = Connection->AddressFile; + if( NT_SUCCESS(Status) ) { + Connection->AddressFile->Listener->AddressFile = + Connection->AddressFile; - Status = TCPSocket( Connection->AddressFile->Listener, + Status = TCPSocket( Connection->AddressFile->Listener, Connection->AddressFile->Family, SOCK_STREAM, Connection->AddressFile->Protocol ); diff --git a/drivers/network/tcpip/tcpip/fileobjs.c b/drivers/network/tcpip/tcpip/fileobjs.c index d7b7905c369..b4c8893bb09 100644 --- a/drivers/network/tcpip/tcpip/fileobjs.c +++ b/drivers/network/tcpip/tcpip/fileobjs.c @@ -161,6 +161,9 @@ VOID AddrFileFree( TI_DbgPrint(MID_TRACE, ("Called.\n")); + /* We should not be associated with a connection here */ + ASSERT(!AddrFile->Connection); + /* Remove address file from the global list */ TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); RemoveEntryList(&AddrFile->ListEntry); @@ -377,17 +380,14 @@ NTSTATUS FileCloseAddress( if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER; LockObject(AddrFile, &OldIrql); - /* We have to close this connection because we started it */ + + /* We have to close this listener because we started it */ if( AddrFile->Listener ) { AddrFile->Listener->AddressFile = NULL; TCPClose( AddrFile->Listener ); } - if( AddrFile->Connection ) - { - AddrFile->Connection->AddressFile = NULL; - DereferenceObject( AddrFile->Connection ); - } + UnlockObject(AddrFile, OldIrql); DereferenceObject(AddrFile); diff --git a/lib/drivers/ip/transport/tcp/tcp.c b/lib/drivers/ip/transport/tcp/tcp.c index d9967c1f2bb..6f3488146b3 100644 --- a/lib/drivers/ip/transport/tcp/tcp.c +++ b/lib/drivers/ip/transport/tcp/tcp.c @@ -342,13 +342,14 @@ NTSTATUS TCPClose { KIRQL OldIrql; PVOID Socket; - PADDRESS_FILE AddressFile = NULL; - PCONNECTION_ENDPOINT AddressConnection = NULL; LockObject(Connection, &OldIrql); Socket = Connection->SocketContext; Connection->SocketContext = NULL; + /* We should not be associated to an address file at this point */ + ASSERT(!Connection->AddressFile); + /* Don't try to close again if the other side closed us already */ if (Socket) { @@ -357,27 +358,9 @@ NTSTATUS TCPClose FlushAllQueues(Connection, STATUS_CANCELLED); } - if (Connection->AddressFile) - { - LockObjectAtDpcLevel(Connection->AddressFile); - if (Connection->AddressFile->Connection == Connection) - { - AddressConnection = Connection->AddressFile->Connection; - Connection->AddressFile->Connection = NULL; - } - UnlockObjectFromDpcLevel(Connection->AddressFile); - - AddressFile = Connection->AddressFile; - Connection->AddressFile = NULL; - } - UnlockObject(Connection, OldIrql); DereferenceObject(Connection); - if (AddressConnection) - DereferenceObject(AddressConnection); - if (AddressFile) - DereferenceObject(AddressFile); return STATUS_SUCCESS; }