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/connect.c?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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/listen.c?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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/main.c?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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/tdi.c?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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/include/afd.h?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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/include/tdi_proto.h?rev=52497&r1=52496&r2=52497&view=diff
==============================================================================
--- 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,


Reply via email to