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

@ -430,7 +430,7 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
case SOCKET_STATE_CREATED: case SOCKET_STATE_CREATED:
if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress ); if( FCB->LocalAddress ) ExFreePool( FCB->LocalAddress );
FCB->LocalAddress = FCB->LocalAddress =
TaCopyTransportAddress( &ConnectReq->RemoteAddress ); TaBuildNullTransportAddress( ConnectReq->RemoteAddress.Address[0].AddressType );
if( FCB->LocalAddress ) if( FCB->LocalAddress )
{ {

View file

@ -117,11 +117,15 @@ static NTSTATUS NTAPI ListenComplete
PLIST_ENTRY NextIrpEntry, QeltEntry; PLIST_ENTRY NextIrpEntry, QeltEntry;
PIRP NextIrp; PIRP NextIrp;
DbgPrint("[AFD, ListenComplete] Called\n");
if( !SocketAcquireStateLock( FCB ) ) if( !SocketAcquireStateLock( FCB ) )
return STATUS_FILE_CLOSED; return STATUS_FILE_CLOSED;
FCB->ListenIrp.InFlightRequest = NULL; 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 ) if( FCB->State == SOCKET_STATE_CLOSED )
{ {
/* Cleanup our IRP queue because the FCB is being destroyed */ /* Cleanup our IRP queue because the FCB is being destroyed */
@ -210,19 +214,30 @@ static NTSTATUS NTAPI ListenComplete
ListEntry ) ); ListEntry ) );
} }
if( FCB->ListenIrp.ConnectionCallInfo ) /* Launch new accept socket */
{ Status = WarmSocketForConnection( FCB );
ExFreePool( FCB->ListenIrp.ConnectionCallInfo );
FCB->ListenIrp.ConnectionCallInfo = NULL;
}
if( FCB->ListenIrp.ConnectionReturnInfo ) if (NT_SUCCESS(Status))
{ {
ExFreePool( FCB->ListenIrp.ConnectionReturnInfo ); Status = TdiBuildNullConnectionInfoInPlace(FCB->ListenIrp.ConnectionCallInfo,
FCB->ListenIrp.ConnectionReturnInfo = NULL; FCB->LocalAddress->Address[0].AddressType);
} ASSERT(Status == STATUS_SUCCESS);
FCB->NeedsNewListen = TRUE; 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 (Status == STATUS_PENDING)
Status = STATUS_SUCCESS;
}
/* Trigger a select return if appropriate */ /* Trigger a select return if appropriate */
if( !IsListEmpty( &FCB->PendingConnections ) ) if( !IsListEmpty( &FCB->PendingConnections ) )
@ -236,6 +251,8 @@ static NTSTATUS NTAPI ListenComplete
SocketStateUnlock( FCB ); SocketStateUnlock( FCB );
DbgPrint("[AFD, ListenComplete] Leaving. Status = 0x%x\n", Status);
return Status; return Status;
} }
@ -306,9 +323,6 @@ NTSTATUS AfdListenSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
if (NT_SUCCESS(Status))
FCB->NeedsNewListen = FALSE;
AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status)); AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
DbgPrint("[AfdListenSocket] 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( !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; for( PendingConn = FCB->PendingConnections.Flink;
PendingConn != &FCB->PendingConnections; PendingConn != &FCB->PendingConnections;
PendingConn = PendingConn->Flink ) 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")); AFD_DbgPrint(MID_TRACE,("Probe and lock pages\n"));
_SEH2_TRY { _SEH2_TRY {
MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode, MmProbeAndLockPages( MapBuf[i].Mdl, KernelMode,
Write ? IoModifyAccess : IoReadAccess ); Write ? IoReadAccess : IoModifyAccess );
} _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
LockFailed = TRUE; LockFailed = TRUE;
} _SEH2_END; } _SEH2_END;

View file

@ -381,6 +381,8 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
UINT Function; UINT Function;
PIRP CurrentIrp; PIRP CurrentIrp;
DbgPrint("[AFD, AfdCleanupSocket] Called\n");
if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp); if( !SocketAcquireStateLock( FCB ) ) return LostSocket(Irp);
for (Function = 0; Function < MAX_FUNCTIONS; Function++) for (Function = 0; Function < MAX_FUNCTIONS; Function++)
@ -400,6 +402,8 @@ AfdCleanupSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE ); KillSelectsForFCB( FCB->DeviceExt, FileObject, FALSE );
DbgPrint("[AFD, AfdCleanupSocket] Leaving\n");
return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0); return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
} }
@ -414,8 +418,12 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
AFD_DbgPrint(MID_TRACE, AFD_DbgPrint(MID_TRACE,
("AfdClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp)); ("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->State = SOCKET_STATE_CLOSED;
FCB->PollState = AFD_EVENT_CLOSE; FCB->PollState = AFD_EVENT_CLOSE;
@ -479,7 +487,10 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
ExFreePool( FCB->RemoteAddress ); ExFreePool( FCB->RemoteAddress );
if( FCB->Connection.Object ) if( FCB->Connection.Object )
{
TdiDisassociateAddressFile(FCB->Connection.Object);
ObDereferenceObject(FCB->Connection.Object); ObDereferenceObject(FCB->Connection.Object);
}
if( FCB->AddressFile.Object ) if( FCB->AddressFile.Object )
ObDereferenceObject(FCB->AddressFile.Object); ObDereferenceObject(FCB->AddressFile.Object);
@ -510,6 +521,7 @@ AfdCloseSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
AFD_DbgPrint(MID_TRACE, ("Returning success.\n")); AFD_DbgPrint(MID_TRACE, ("Returning success.\n"));
DbgPrint("[AfdCloseSocket] Leaving\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -430,6 +430,55 @@ NTSTATUS TdiAssociateAddressFile(
return Status; 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 NTSTATUS TdiListen
( PIRP *Irp, ( PIRP *Irp,
@ -1244,7 +1293,7 @@ NTSTATUS TdiDisconnect(
} }
Irp = TdiBuildInternalDeviceControlIrp Irp = TdiBuildInternalDeviceControlIrp
( TDI_SEND_DATAGRAM, /* Sub function */ ( TDI_DISCONNECT, /* Sub function */
DeviceObject, /* Device object */ DeviceObject, /* Device object */
TransportObject, /* File object */ TransportObject, /* File object */
&Event, /* Event */ &Event, /* Event */

View file

@ -38,7 +38,14 @@ UINT TaLengthOfAddress( PTA_ADDRESS Addr ) {
} }
UINT TaLengthOfTransportAddress( PTRANSPORT_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)); AFD_DbgPrint(MID_TRACE,("AddrLen %x\n", AddrLen));
return AddrLen; return AddrLen;
} }
@ -77,7 +84,26 @@ PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ) {
return A; 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, ( PTDI_CONNECTION_INFORMATION ConnInfo,
ULONG Type ) ULONG Type )
/* /*

View file

@ -179,7 +179,7 @@ typedef struct _AFD_FCB {
PVOID CurrentThread; PVOID CurrentThread;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PAFD_DEVICE_EXTENSION DeviceExt; PAFD_DEVICE_EXTENSION DeviceExt;
BOOLEAN DelayedAccept, NeedsNewListen; BOOLEAN DelayedAccept;
UINT ConnSeq; UINT ConnSeq;
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress; PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo; PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo;
@ -360,6 +360,9 @@ NTSTATUS TdiAssociateAddressFile(
HANDLE AddressHandle, HANDLE AddressHandle,
PFILE_OBJECT ConnectionObject); PFILE_OBJECT ConnectionObject);
NTSTATUS TdiDisassociateAddressFile(
PFILE_OBJECT ConnectionObject);
NTSTATUS TdiListen NTSTATUS TdiListen
( PIRP *Irp, ( PIRP *Irp,
PFILE_OBJECT ConnectionObject, PFILE_OBJECT ConnectionObject,

View file

@ -7,6 +7,7 @@
typedef VOID *PTDI_CONNECTION_INFO_PAIR; typedef VOID *PTDI_CONNECTION_INFO_PAIR;
PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress ); PTRANSPORT_ADDRESS TaCopyTransportAddress( PTRANSPORT_ADDRESS OtherAddress );
PTRANSPORT_ADDRESS TaBuildNullTransportAddress(UINT AddressType);
UINT TaLengthOfAddress( PTA_ADDRESS Addr ); UINT TaLengthOfAddress( PTA_ADDRESS Addr );
UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr ); UINT TaLengthOfTransportAddress( PTRANSPORT_ADDRESS Addr );
VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source ); VOID TaCopyAddressInPlace( PTA_ADDRESS Target, PTA_ADDRESS Source );
@ -19,7 +20,7 @@ NTSTATUS TdiBuildConnectionInfoInPlace
( PTDI_CONNECTION_INFORMATION ConnInfo, PTRANSPORT_ADDRESS Name ); ( PTDI_CONNECTION_INFORMATION ConnInfo, PTRANSPORT_ADDRESS Name );
NTSTATUS TdiBuildConnectionInfo NTSTATUS TdiBuildConnectionInfo
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Name ); ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, PTRANSPORT_ADDRESS Name );
NTSTATUS TdiBuildNullConnectionInfoToPlace NTSTATUS TdiBuildNullConnectionInfoInPlace
( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type ); ( PTDI_CONNECTION_INFORMATION ConnInfo, ULONG Type );
NTSTATUS TdiBuildNullConnectionInfo NTSTATUS TdiBuildNullConnectionInfo
( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type ); ( PTDI_CONNECTION_INFORMATION *ConnectionInfo, ULONG Type );

View file

@ -1880,6 +1880,7 @@ NdisIPnPStartDevice(
{ {
NDIS_DbgPrint(MIN_TRACE, ("Failed to open configuration key\n")); NDIS_DbgPrint(MIN_TRACE, ("Failed to open configuration key\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
NdisCloseConfiguration(ConfigHandle);
return NdisStatus; return NdisStatus;
} }
@ -2218,48 +2219,54 @@ NdisIDispatchPnp(
NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device start\n")); NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device start\n"));
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; return Status;
case IRP_MN_STOP_DEVICE: case IRP_MN_STOP_DEVICE:
Status = NdisIForwardIrpAndWait(Adapter, Irp);
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
{
Status = NdisIPnPStopDevice(DeviceObject, Irp); Status = NdisIPnPStopDevice(DeviceObject, Irp);
} if (!NT_SUCCESS(Status))
else NDIS_DbgPrint(MIN_TRACE, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n"));
NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed device stop\n")); Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; break;
case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_QUERY_STOP_DEVICE:
Status = NdisIPnPQueryStopDevice(DeviceObject, Irp); Status = NdisIPnPQueryStopDevice(DeviceObject, Irp);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
if (Status != STATUS_SUCCESS)
{
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
NDIS_DbgPrint(MIN_TRACE, ("Failing miniport halt request\n"));
return Status;
}
break; break;
case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE:
case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE:
Status = NdisIForwardIrpAndWait(Adapter, Irp);
if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
{
Status = NdisIPnPCancelStopDevice(DeviceObject, Irp); Status = NdisIPnPCancelStopDevice(DeviceObject, Irp);
}
else
{
NDIS_DbgPrint(MIN_TRACE, ("Lower driver failed cancel stop/remove request\n"));
}
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; return Status;
case IRP_MN_QUERY_PNP_DEVICE_STATE: case IRP_MN_QUERY_PNP_DEVICE_STATE:
Status = NDIS_STATUS_SUCCESS; Status = NDIS_STATUS_SUCCESS;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information |= Adapter->NdisMiniportBlock.PnPFlags; Irp->IoStatus.Information |= Adapter->NdisMiniportBlock.PnPFlags;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
break; break;
default: default:
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(Adapter->NdisMiniportBlock.NextDeviceObject, Irp);
break; 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 ListenRequest; /* Queued listen requests */
LIST_ENTRY ReceiveRequest; /* Queued receive requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */
LIST_ENTRY SendRequest; /* Queued send requests */ LIST_ENTRY SendRequest; /* Queued send requests */
struct _CONNECTION_ENDPOINT *Next; /* Next connection in address file list */
} CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT;

View file

@ -209,6 +209,7 @@ VOID NTAPI DispCancelListenRequest(
IoReleaseCancelSpinLock(Irp->CancelIrql); IoReleaseCancelSpinLock(Irp->CancelIrql);
TI_DbgPrint(DEBUG_IRP, ("Called.\n")); TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
DbgPrint("[TCPIP, DispCancelListenRequest] Called\n");
IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp = IoGetCurrentIrpStackLocation(Irp);
FileObject = IrpSp->FileObject; FileObject = IrpSp->FileObject;
@ -219,7 +220,10 @@ VOID NTAPI DispCancelListenRequest(
#if DBG #if DBG
if (!Irp->Cancel) if (!Irp->Cancel)
{
TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n")); TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n"));
DbgPrint("[TCPIP, DispCancelListenRequest] Irp->Cancel is FALSE, should be TRUE\n");
}
#endif #endif
/* Try canceling the request */ /* Try canceling the request */
@ -233,6 +237,7 @@ VOID NTAPI DispCancelListenRequest(
} }
TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
DbgPrint("[TCPIP, DispCancelListenRequest] Leaving\n");
} }
@ -265,7 +270,7 @@ NTSTATUS DispTdiAssociateAddress(
PTDI_REQUEST_KERNEL_ASSOCIATE Parameters; PTDI_REQUEST_KERNEL_ASSOCIATE Parameters;
PTRANSPORT_CONTEXT TranContext; PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION IrpSp;
PCONNECTION_ENDPOINT Connection; PCONNECTION_ENDPOINT Connection, LastConnection;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL; PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status; NTSTATUS Status;
@ -349,20 +354,27 @@ NTSTATUS DispTdiAssociateAddress(
LockObjectAtDpcLevel(AddrFile); LockObjectAtDpcLevel(AddrFile);
ReferenceObject(AddrFile);
Connection->AddressFile = AddrFile;
/* Add connection endpoint to the address file */ /* Add connection endpoint to the address file */
ReferenceObject(Connection); ReferenceObject(Connection);
if (AddrFile->Connection == NULL)
AddrFile->Connection = Connection; AddrFile->Connection = Connection;
else
{
LastConnection = AddrFile->Connection;
while (LastConnection->Next != NULL)
LastConnection = LastConnection->Next;
LastConnection->Next = Connection;
}
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ReferenceObject(AddrFile);
ObDereferenceObject(FileObject); Connection->AddressFile = AddrFile;
UnlockObjectFromDpcLevel(AddrFile); UnlockObjectFromDpcLevel(AddrFile);
UnlockObject(Connection, OldIrql); UnlockObject(Connection, OldIrql);
return Status; ObDereferenceObject(FileObject);
return STATUS_SUCCESS;
} }
@ -440,10 +452,11 @@ NTSTATUS DispTdiDisassociateAddress(
* Status of operation * Status of operation
*/ */
{ {
PCONNECTION_ENDPOINT Connection; PCONNECTION_ENDPOINT Connection, LastConnection;
PTRANSPORT_CONTEXT TranContext; PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp; PIO_STACK_LOCATION IrpSp;
KIRQL OldIrql; KIRQL OldIrql;
NTSTATUS Status;
TI_DbgPrint(DEBUG_IRP, ("Called.\n")); TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
@ -473,19 +486,42 @@ NTSTATUS DispTdiDisassociateAddress(
LockObjectAtDpcLevel(Connection->AddressFile); LockObjectAtDpcLevel(Connection->AddressFile);
/* Remove this connection from the address file */ /* Unlink this connection from the address file */
DereferenceObject(Connection->AddressFile->Connection); if (Connection->AddressFile->Connection == Connection)
Connection->AddressFile->Connection = NULL; {
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); UnlockObjectFromDpcLevel(Connection->AddressFile);
if (Status == STATUS_SUCCESS)
{
/* Remove the address file from this connection */ /* Remove the address file from this connection */
DereferenceObject(Connection->AddressFile); DereferenceObject(Connection->AddressFile);
Connection->AddressFile = NULL; Connection->AddressFile = NULL;
}
UnlockObject(Connection, OldIrql); UnlockObject(Connection, OldIrql);
return STATUS_SUCCESS; return Status;
} }
@ -618,10 +654,9 @@ NTSTATUS DispTdiListen(
if( !Connection->AddressFile->Listener ) if( !Connection->AddressFile->Listener )
Status = STATUS_NO_MEMORY; Status = STATUS_NO_MEMORY;
if( NT_SUCCESS(Status) ) if( NT_SUCCESS(Status) ) {
{ Connection->AddressFile->Listener->AddressFile =
ReferenceObject(Connection->AddressFile); Connection->AddressFile;
Connection->AddressFile->Listener->AddressFile = Connection->AddressFile;
Status = TCPSocket( Connection->AddressFile->Listener, Status = TCPSocket( Connection->AddressFile->Listener,
Connection->AddressFile->Family, Connection->AddressFile->Family,

View file

@ -161,6 +161,9 @@ VOID AddrFileFree(
TI_DbgPrint(MID_TRACE, ("Called.\n")); 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 */ /* Remove address file from the global list */
TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql); TcpipAcquireSpinLock(&AddressFileListLock, &OldIrql);
RemoveEntryList(&AddrFile->ListEntry); RemoveEntryList(&AddrFile->ListEntry);
@ -377,17 +380,14 @@ NTSTATUS FileCloseAddress(
if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER; if (!Request->Handle.AddressHandle) return STATUS_INVALID_PARAMETER;
LockObject(AddrFile, &OldIrql); 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 ) if( AddrFile->Listener )
{ {
AddrFile->Listener->AddressFile = NULL; AddrFile->Listener->AddressFile = NULL;
TCPClose( AddrFile->Listener ); TCPClose( AddrFile->Listener );
} }
if( AddrFile->Connection )
{
AddrFile->Connection->AddressFile = NULL;
DereferenceObject( AddrFile->Connection );
}
UnlockObject(AddrFile, OldIrql); UnlockObject(AddrFile, OldIrql);
DereferenceObject(AddrFile); DereferenceObject(AddrFile);

View file

@ -342,13 +342,14 @@ NTSTATUS TCPClose
{ {
KIRQL OldIrql; KIRQL OldIrql;
PVOID Socket; PVOID Socket;
PADDRESS_FILE AddressFile = NULL;
PCONNECTION_ENDPOINT AddressConnection = NULL;
LockObject(Connection, &OldIrql); LockObject(Connection, &OldIrql);
Socket = Connection->SocketContext; Socket = Connection->SocketContext;
Connection->SocketContext = NULL; 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 */ /* Don't try to close again if the other side closed us already */
if (Socket) if (Socket)
{ {
@ -357,27 +358,9 @@ NTSTATUS TCPClose
FlushAllQueues(Connection, STATUS_CANCELLED); 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); UnlockObject(Connection, OldIrql);
DereferenceObject(Connection); DereferenceObject(Connection);
if (AddressConnection)
DereferenceObject(AddressConnection);
if (AddressFile)
DereferenceObject(AddressFile);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }