Patches by cgutman applied to the branch (see r52125, r52092, r52086, r52083, r52013)

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=52138
This commit is contained in:
Claudiu Mihail 2011-06-07 20:24:54 +00:00
parent e385be59b1
commit c31d8d66b9
13 changed files with 229 additions and 145 deletions

View file

@ -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 )
{

View file

@ -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 )

View file

@ -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;

View file

@ -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;
}

View file

@ -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 */

View file

@ -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 )
/*

View file

@ -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,

View file

@ -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 );

View file

@ -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);
}

View file

@ -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;

View file

@ -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 );

View file

@ -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);

View file

@ -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;
}