Author: cgutman
Date: Fri Jul 1 14:31:37 2011
New Revision: 52497
URL:
http://svn.reactos.org/svn/reactos?rev=52497&view=rev
Log:
[AFD]
- Rewrite disconnect to work asynchronously
Modified:
trunk/reactos/drivers/network/afd/afd/connect.c
trunk/reactos/drivers/network/afd/afd/listen.c
trunk/reactos/drivers/network/afd/afd/main.c
trunk/reactos/drivers/network/afd/afd/tdi.c
trunk/reactos/drivers/network/afd/include/afd.h
trunk/reactos/drivers/network/afd/include/tdi_proto.h
Modified: trunk/reactos/drivers/network/afd/afd/connect.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/co…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/connect.c [iso-8859-1] Fri Jul 1 14:31:37 2011
@@ -332,19 +332,19 @@
return Status;
}
- FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength,
FCB->ConnectDataSize);
+ FCB->FilledConnectData = MIN(FCB->ConnectReturnInfo->UserDataLength,
FCB->ConnectDataSize);
if (FCB->FilledConnectData)
{
RtlCopyMemory(FCB->ConnectData,
- FCB->ConnectInfo->UserData,
+ FCB->ConnectReturnInfo->UserData,
FCB->FilledConnectData);
}
- FCB->FilledConnectOptions = MIN(FCB->ConnectInfo->OptionsLength,
FCB->ConnectOptionsSize);
+ FCB->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength,
FCB->ConnectOptionsSize);
if (FCB->FilledConnectOptions)
{
RtlCopyMemory(FCB->ConnectOptions,
- FCB->ConnectInfo->Options,
+ FCB->ConnectReturnInfo->Options,
FCB->FilledConnectOptions);
}
@@ -380,7 +380,6 @@
PFILE_OBJECT FileObject = IrpSp->FileObject;
PAFD_FCB FCB = FileObject->FsContext;
PAFD_CONNECT_INFO ConnectReq;
- PTDI_CONNECTION_INFORMATION TargetAddress;
AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
@@ -450,21 +449,25 @@
if( !NT_SUCCESS(Status) )
break;
+ if (FCB->ConnectReturnInfo) ExFreePool(FCB->ConnectReturnInfo);
Status = TdiBuildConnectionInfo
- ( &FCB->ConnectInfo,
+ ( &FCB->ConnectReturnInfo,
&ConnectReq->RemoteAddress );
if( NT_SUCCESS(Status) )
- Status = TdiBuildConnectionInfo(&TargetAddress,
+ {
+ if (FCB->ConnectCallInfo) ExFreePool(FCB->ConnectCallInfo);
+ Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo,
&ConnectReq->RemoteAddress);
+ }
else break;
if( NT_SUCCESS(Status) ) {
- TargetAddress->UserData = FCB->ConnectData;
- TargetAddress->UserDataLength = FCB->ConnectDataSize;
- TargetAddress->Options = FCB->ConnectOptions;
- TargetAddress->OptionsLength = FCB->ConnectOptionsSize;
+ FCB->ConnectCallInfo->UserData = FCB->ConnectData;
+ FCB->ConnectCallInfo->UserDataLength = FCB->ConnectDataSize;
+ FCB->ConnectCallInfo->Options = FCB->ConnectOptions;
+ FCB->ConnectCallInfo->OptionsLength = FCB->ConnectOptionsSize;
FCB->State = SOCKET_STATE_CONNECTING;
@@ -474,8 +477,8 @@
{
Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
FCB->Connection.Object,
- TargetAddress,
- FCB->ConnectInfo,
+ FCB->ConnectCallInfo,
+ FCB->ConnectReturnInfo,
&FCB->ConnectIrp.Iosb,
StreamSocketConnectComplete,
FCB );
@@ -483,8 +486,6 @@
if (Status != STATUS_PENDING)
FCB->State = SOCKET_STATE_BOUND;
-
- ExFreePool(TargetAddress);
SocketStateUnlock(FCB);
Modified: trunk/reactos/drivers/network/afd/afd/listen.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/li…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/listen.c [iso-8859-1] Fri Jul 1 14:31:37 2011
@@ -37,7 +37,10 @@
Status = MakeSocketIntoConnection( FCB );
if (NT_SUCCESS(Status))
- Status = TdiBuildConnectionInfo(&FCB->ConnectInfo,
FCB->RemoteAddress);
+ Status = TdiBuildConnectionInfo(&FCB->ConnectCallInfo,
FCB->RemoteAddress);
+
+ if (NT_SUCCESS(Status))
+ Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo,
FCB->RemoteAddress);
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
}
Modified: trunk/reactos/drivers/network/afd/afd/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/ma…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/main.c [iso-8859-1] Fri Jul 1 14:31:37 2011
@@ -472,8 +472,11 @@
if( FCB->AddressFrom )
ExFreePool( FCB->AddressFrom );
- if( FCB->ConnectInfo )
- ExFreePool( FCB->ConnectInfo );
+ if( FCB->ConnectCallInfo )
+ ExFreePool( FCB->ConnectCallInfo );
+
+ if( FCB->ConnectReturnInfo )
+ ExFreePool( FCB->ConnectReturnInfo );
if( FCB->ConnectData )
ExFreePool( FCB->ConnectData );
@@ -534,76 +537,101 @@
static
NTSTATUS
-DoDisconnect(PAFD_FCB FCB, PIRP CurrentIrp)
+NTAPI
+DisconnectComplete(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PVOID Context)
+{
+ PAFD_FCB FCB = Context;
+ PIRP CurrentIrp;
+ PLIST_ENTRY CurrentEntry;
+
+ if( !SocketAcquireStateLock( FCB ) )
+ return STATUS_FILE_CLOSED;
+
+ ASSERT(FCB->DisconnectIrp.InFlightRequest == Irp);
+ FCB->DisconnectIrp.InFlightRequest = NULL;
+
+ ASSERT(FCB->DisconnectPending);
+ //ASSERT(IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) ||
(FCB->DisconnectFlags & TDI_DISCONNECT_ABORT));
+
+ if (NT_SUCCESS(Irp->IoStatus.Status) && (FCB->DisconnectFlags &
TDI_DISCONNECT_RELEASE))
+ {
+ FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize,
FCB->ConnectReturnInfo->UserDataLength);
+ if (FCB->FilledDisconnectData)
+ {
+ RtlCopyMemory(FCB->DisconnectData,
+ FCB->ConnectReturnInfo->UserData,
+ FCB->FilledDisconnectData);
+ }
+
+ FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize,
FCB->ConnectReturnInfo->OptionsLength);
+ if (FCB->FilledDisconnectOptions)
+ {
+ RtlCopyMemory(FCB->DisconnectOptions,
+ FCB->ConnectReturnInfo->Options,
+ FCB->FilledDisconnectOptions);
+ }
+ }
+
+ FCB->DisconnectPending = FALSE;
+
+ while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
+ {
+ CurrentEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
+ CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
+ CurrentIrp->IoStatus.Status = Irp->IoStatus.Status;
+ CurrentIrp->IoStatus.Information = 0;
+ UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
+ (void)IoSetCancelRoutine(CurrentIrp, NULL);
+ IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT );
+ }
+
+ if (FCB->DisconnectFlags & TDI_DISCONNECT_RELEASE)
+ FCB->PollState |= AFD_EVENT_DISCONNECT;
+ else
+ FCB->PollState |= AFD_EVENT_ABORT;
+ FCB->PollStatus[FD_CLOSE_BIT] = Irp->IoStatus.Status;
+ PollReeval(FCB->DeviceExt, FCB->FileObject);
+
+ SocketStateUnlock(FCB);
+
+ return Irp->IoStatus.Status;
+}
+
+static
+NTSTATUS
+DoDisconnect(PAFD_FCB FCB)
{
PAFD_DISCONNECT_INFO DisReq;
IO_STATUS_BLOCK Iosb;
- PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
- PIO_STACK_LOCATION CurrentIrpSp;
- USHORT Flags = 0;
NTSTATUS Status;
- CurrentIrpSp = IoGetCurrentIrpStackLocation(CurrentIrp);
- DisReq = GetLockedData(CurrentIrp, CurrentIrpSp);
-
- if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
- Flags |= TDI_DISCONNECT_RELEASE;
- if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
- DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
- Flags |= TDI_DISCONNECT_ABORT;
-
- Status = TdiBuildNullConnectionInfo(&ConnectionReturnInfo,
-
FCB->RemoteAddress->Address[0].AddressType);
- if (NT_SUCCESS(Status))
- {
- FCB->ConnectInfo->UserData = FCB->DisconnectData;
- FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
- FCB->ConnectInfo->Options = FCB->DisconnectOptions;
- FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
-
- Status = TdiDisconnect(FCB->Connection.Object,
- &DisReq->Timeout,
- Flags,
- &Iosb,
- NULL,
- NULL,
- FCB->ConnectInfo,
- ConnectionReturnInfo);
-
- if (NT_SUCCESS(Status)) {
- FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize,
ConnectionReturnInfo->UserDataLength);
- if (FCB->FilledDisconnectData)
- {
- RtlCopyMemory(FCB->DisconnectData,
- ConnectionReturnInfo->UserData,
- FCB->FilledDisconnectData);
- }
-
- FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize,
ConnectionReturnInfo->OptionsLength);
- if (FCB->FilledDisconnectOptions)
- {
- RtlCopyMemory(FCB->DisconnectOptions,
- ConnectionReturnInfo->Options,
- FCB->FilledDisconnectOptions);
- }
- }
-
- ExFreePool( ConnectionReturnInfo );
-
- if (Flags & TDI_DISCONNECT_RELEASE)
- FCB->PollState |= AFD_EVENT_DISCONNECT;
- else
- FCB->PollState |= AFD_EVENT_ABORT;
- FCB->PollStatus[FD_CLOSE_BIT] = Status;
- PollReeval( FCB->DeviceExt, FCB->FileObject );
- }
-
- CurrentIrp->IoStatus.Status = Status;
- CurrentIrp->IoStatus.Information = 0;
- UnlockRequest(CurrentIrp, CurrentIrpSp);
- (void)IoSetCancelRoutine(CurrentIrp, NULL);
-
- IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT);
+ ASSERT(FCB->DisconnectPending);
+
+ if (FCB->DisconnectIrp.InFlightRequest)
+ {
+ return STATUS_PENDING;
+ }
+
+ FCB->ConnectCallInfo->UserData = FCB->DisconnectData;
+ FCB->ConnectCallInfo->UserDataLength = FCB->DisconnectDataSize;
+ FCB->ConnectCallInfo->Options = FCB->DisconnectOptions;
+ FCB->ConnectCallInfo->OptionsLength = FCB->DisconnectOptionsSize;
+
+ Status = TdiDisconnect(&FCB->DisconnectIrp.InFlightRequest,
+ FCB->Connection.Object,
+ &DisReq->Timeout,
+ FCB->DisconnectFlags,
+ &Iosb,
+ DisconnectComplete,
+ FCB,
+ FCB->ConnectCallInfo,
+ FCB->ConnectReturnInfo);
+ if (Status != STATUS_PENDING)
+ {
+ FCB->DisconnectPending = FALSE;
+ }
return Status;
}
@@ -611,20 +639,12 @@
VOID
RetryDisconnectCompletion(PAFD_FCB FCB)
{
- if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]))
- {
- PIRP CurrentIrp;
- PLIST_ENTRY CurrentEntry;
-
- ASSERT(FCB->RemoteAddress);
-
- while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
- {
- CurrentEntry =
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
- CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP, Tail.Overlay.ListEntry);
-
- DoDisconnect(FCB, CurrentIrp);
- }
+ ASSERT(FCB->RemoteAddress);
+
+ if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) &&
FCB->DisconnectPending)
+ {
+ /* Sends are done; fire off a TDI_DISCONNECT request */
+ DoDisconnect(FCB);
}
}
@@ -636,6 +656,8 @@
PAFD_DISCONNECT_INFO DisReq;
NTSTATUS Status = STATUS_SUCCESS;
USHORT Flags = 0;
+ PLIST_ENTRY CurrentEntry;
+ PIRP CurrentIrp;
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
@@ -651,26 +673,54 @@
if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
{
- if( !FCB->ConnectInfo )
+ if( !FCB->ConnectCallInfo )
return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
Irp, 0 );
+
+ if (FCB->DisconnectPending)
+ {
+ if (FCB->DisconnectIrp.InFlightRequest)
+ {
+ IoCancelIrp(FCB->DisconnectIrp.InFlightRequest);
+ ASSERT(!FCB->DisconnectIrp.InFlightRequest);
+ }
+ else
+ {
+ while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_DISCONNECT]))
+ {
+ CurrentEntry =
RemoveHeadList(&FCB->PendingIrpList[FUNCTION_DISCONNECT]);
+ CurrentIrp = CONTAINING_RECORD(CurrentEntry, IRP,
Tail.Overlay.ListEntry);
+ CurrentIrp->IoStatus.Status = STATUS_CANCELLED;
+ CurrentIrp->IoStatus.Information = 0;
+ UnlockRequest(CurrentIrp, IoGetCurrentIrpStackLocation(CurrentIrp));
+ (void)IoSetCancelRoutine(CurrentIrp, NULL);
+ IoCompleteRequest(CurrentIrp, IO_NETWORK_INCREMENT );
+ }
+ }
+ }
- if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags &
TDI_DISCONNECT_ABORT))
+ FCB->DisconnectFlags = Flags;
+ FCB->DisconnectPending = TRUE;
+
+ Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT);
+ if (Status == STATUS_PENDING)
{
- /* Go ahead an execute the disconnect because we're ready for it */
- Status = DoDisconnect(FCB, Irp);
+ if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) ||
(FCB->DisconnectFlags & TDI_DISCONNECT_ABORT))
+ {
+ /* Go ahead an execute the disconnect because we're ready for it */
+ Status = DoDisconnect(FCB);
+ }
- /* DoDisconnect takes care of the IRP */
+ if (Status != STATUS_PENDING)
+ RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
+ }
+
+ if (Status == STATUS_PENDING)
+ {
SocketStateUnlock(FCB);
-
+
return Status;
}
- else
- {
- /* We have a graceful disconnect waiting on pending sends to complete */
- return LeaveIrpUntilLater(FCB, Irp, FUNCTION_DISCONNECT);
- }
-
}
else
{
Modified: trunk/reactos/drivers/network/afd/afd/tdi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/afd/td…
==============================================================================
--- trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/afd/tdi.c [iso-8859-1] Fri Jul 1 14:31:37 2011
@@ -1228,6 +1228,7 @@
}
NTSTATUS TdiDisconnect(
+ PIRP *Irp,
PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time,
USHORT Flags,
@@ -1237,10 +1238,6 @@
PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
PTDI_CONNECTION_INFORMATION ReturnConnectionInfo) {
PDEVICE_OBJECT DeviceObject;
- KEVENT Event;
- PIRP Irp;
-
- KeInitializeEvent(&Event, NotificationEvent, FALSE);
if (!TransportObject) {
AFD_DbgPrint(MIN_TRACE, ("Bad transport object.\n"));
@@ -1255,20 +1252,20 @@
return STATUS_INVALID_PARAMETER;
}
- Irp = TdiBuildInternalDeviceControlIrp
+ *Irp = TdiBuildInternalDeviceControlIrp
( TDI_DISCONNECT, /* Sub function */
DeviceObject, /* Device object */
TransportObject, /* File object */
- &Event, /* Event */
+ NULL, /* Event */
Iosb ); /* Status */
- if (!Irp) {
+ if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildDisconnect
- (Irp, /* I/O Request Packet */
+ (*Irp, /* I/O Request Packet */
DeviceObject, /* Device object */
TransportObject, /* File object */
CompletionRoutine, /* Completion routine */
@@ -1278,7 +1275,9 @@
RequestConnectionInfo, /* Indication of who to disconnect */
ReturnConnectionInfo); /* Indication of who disconnected */
- return TdiCall(Irp, DeviceObject, &Event, Iosb);
+ TdiCall(*Irp, DeviceObject, NULL, Iosb);
+
+ return STATUS_PENDING;
}
/* EOF */
Modified: trunk/reactos/drivers/network/afd/include/afd.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/includ…
==============================================================================
--- trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/include/afd.h [iso-8859-1] Fri Jul 1 14:31:37 2011
@@ -182,10 +182,12 @@
PAFD_DEVICE_EXTENSION DeviceExt;
BOOLEAN DelayedAccept;
UINT ConnSeq;
+ USHORT DisconnectFlags;
+ BOOLEAN DisconnectPending;
PTRANSPORT_ADDRESS LocalAddress, RemoteAddress;
- PTDI_CONNECTION_INFORMATION AddressFrom, ConnectInfo;
+ PTDI_CONNECTION_INFORMATION AddressFrom, ConnectCallInfo, ConnectReturnInfo;
AFD_TDI_OBJECT AddressFile, Connection;
- AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp;
+ AFD_IN_FLIGHT_REQUEST ConnectIrp, ListenIrp, ReceiveIrp, SendIrp, DisconnectIrp;
AFD_DATA_WINDOW Send, Recv;
KMUTEX Mutex;
PKEVENT EventSelect;
Modified: trunk/reactos/drivers/network/afd/include/tdi_proto.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/afd/includ…
==============================================================================
--- trunk/reactos/drivers/network/afd/include/tdi_proto.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/afd/include/tdi_proto.h [iso-8859-1] Fri Jul 1 14:31:37
2011
@@ -16,7 +16,8 @@
PFILE_OBJECT FileObject);
NTSTATUS TdiDisconnect
-( PFILE_OBJECT TransportObject,
+( PIRP *Irp,
+ PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time,
USHORT Flags,
PIO_STATUS_BLOCK Iosb,