Author: cmihail
Date: Sun Jul  3 12:03:49 2011
New Revision: 52516

URL: http://svn.reactos.org/svn/reactos?rev=52516&view=rev
Log:
[AFD]
merge r52497
- Rewrite disconnect to work asynchronously

merge r52492
- Fix several bugs related to the FD_WRITE event
- We would not set the sendable poll state if the socket had data waiting to be 
sent even if there was buffer space
- We did not set the poll state after performing a send
- We did not clear the sendable poll state if we ran out of buffer space

Modified:
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h
    branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/connect.c 
[iso-8859-1] Sun Jul  3 12:03:49 2011
@@ -355,7 +355,7 @@
            NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, 
Tail.Overlay.ListEntry);
            
         AFD_DbgPrint(MID_TRACE,("Completing connect %x\n", NextIrp));
-        DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 
0x%x\n", NextIrp);
+        DbgPrint("[AFD, StreamSocketConnectComplete] Completing connect 0x%x 
with Status = 0x%x\n", NextIrp, Status);
            
         NextIrp->IoStatus.Status = Status;
            NextIrp->IoStatus.Information = (NT_SUCCESS(Status) ? 
((ULONG_PTR)FCB->Connection.Handle) : 0);
@@ -369,6 +369,7 @@
 
     if (NT_SUCCESS(Status))
     {
+        DbgPrint("[AFD, StreamSocketConnectComplete] Making socket into 
connection\n");
            Status = MakeSocketIntoConnection(FCB);
 
            if (!NT_SUCCESS(Status))
@@ -377,21 +378,21 @@
                return Status;
            }
 
-        FCB->FilledConnectData = MIN(FCB->ConnectInfo->UserDataLength,
+        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->FilledConnectOptions = MIN(FCB->ConnectReturnInfo->OptionsLength,
                                         FCB->ConnectOptionsSize);
         if (FCB->FilledConnectOptions)
         {
             RtlCopyMemory(FCB->ConnectOptions,
-                            FCB->ConnectInfo->Options,
+                            FCB->ConnectReturnInfo->Options,
                             FCB->FilledConnectOptions);
         }
 
@@ -415,6 +416,7 @@
     SocketStateUnlock(FCB);
 
     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+    DbgPrint("[AFD, StreamSocketConnectComplete] Leaving. Status = 0x%x\n", 
Status);
 
     return Status;
 }
@@ -430,7 +432,6 @@
     PFILE_OBJECT FileObject = IrpSp->FileObject;
     PAFD_FCB FCB = (PAFD_FCB)FileObject->FsContext;
     PAFD_CONNECT_INFO ConnectReq;
-    PTDI_CONNECTION_INFORMATION TargetAddress;
     AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
 
     if (!SocketAcquireStateLock(FCB))
@@ -507,41 +508,42 @@
                if (!NT_SUCCESS(Status))
                    break;
 
-               Status = TdiBuildConnectionInfo(&FCB->ConnectInfo, 
&ConnectReq->RemoteAddress);
+               if (FCB->ConnectReturnInfo) ExFreePool(FCB->ConnectReturnInfo);
+                   Status = TdiBuildConnectionInfo(&FCB->ConnectReturnInfo, 
&ConnectReq->RemoteAddress);
 
             if (NT_SUCCESS(Status))
-                Status = TdiBuildConnectionInfo(&TargetAddress, 
&ConnectReq->RemoteAddress);
-            else break;
+            {
+                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;
-
-                   AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
-                DbgPrint("[AFD, AfdStreamSocketConnect] Queueing IRP %x\n", 
Irp);
+                    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;
         
                 AFD_DbgPrint(MID_TRACE,("Queueing IRP %x\n", Irp));
-                Status = QueueUserModeIrp( FCB, Irp, FUNCTION_CONNECT );
+                Status = QueueUserModeIrp(FCB, Irp, FUNCTION_CONNECT);
                 if (Status == STATUS_PENDING)
                 {
-                    Status = TdiConnect( &FCB->ConnectIrp.InFlightRequest,
+                    Status = TdiConnect(&FCB->ConnectIrp.InFlightRequest,
                                         FCB->Connection.Object,
-                                        TargetAddress,
-                                        FCB->ConnectInfo,
+                                        FCB->ConnectCallInfo,
+                                        FCB->ConnectReturnInfo,
                                         &FCB->ConnectIrp.Iosb,
                                         StreamSocketConnectComplete,
-                                        FCB );
+                                        FCB);
                 }
         
                 if (Status != STATUS_PENDING)
                     FCB->State = SOCKET_STATE_BOUND;
-
-                ExFreePool(TargetAddress);
         
                 SocketStateUnlock(FCB);
 

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/listen.c 
[iso-8859-1] Sun Jul  3 12:03:49 2011
@@ -43,7 +43,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: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c [iso-8859-1] 
(original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/main.c [iso-8859-1] 
Sun Jul  3 12:03:49 2011
@@ -373,6 +373,7 @@
     }
 
     FileObject->FsContext = FCB;
+    DbgPrint("FileObject->FsContext = 0x%x\n", FCB);
 
     /* It seems that UDP sockets are writable from inception */
     if (FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS)
@@ -381,8 +382,8 @@
         
            /* A datagram socket is always sendable */
            FCB->PollState |= AFD_EVENT_SEND;
-            FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
-            PollReeval( FCB->DeviceExt, FCB->FileObject );
+        FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
+        PollReeval( FCB->DeviceExt, FCB->FileObject );
     }
 
     if (!NT_SUCCESS(Status))
@@ -523,8 +524,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);
@@ -596,78 +600,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;
 }
@@ -675,20 +702,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);
     }
 }
 
@@ -702,6 +721,8 @@
     PAFD_DISCONNECT_INFO DisReq;
     NTSTATUS Status = STATUS_SUCCESS;
     USHORT Flags = 0;
+    PLIST_ENTRY CurrentEntry;
+    PIRP CurrentIrp;
 
     if (!SocketAcquireStateLock(FCB))
         return LostSocket(Irp);
@@ -717,23 +738,52 @@
 
     if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
     {
-        if (!FCB->ConnectInfo)
+        if (!FCB->ConnectCallInfo)
             return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 
0);
         
-        if (IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) || (Flags & 
TDI_DISCONNECT_ABORT))
-        {
-            /* Go ahead an execute the disconnect because we're ready for it */
-            Status = DoDisconnect(FCB, Irp);
+        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 );
+                }
+            }
+        }
+        
+        FCB->DisconnectFlags = Flags;
+        FCB->DisconnectPending = TRUE;
+        
+        Status = QueueUserModeIrp(FCB, Irp, FUNCTION_DISCONNECT);
+        if (Status == STATUS_PENDING)
+        {
+            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);
         }
 
     }
@@ -983,6 +1033,8 @@
     PAFD_DEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
     KIRQL OldIrql;
     PAFD_ACTIVE_POLL Poll;
+
+    DbgPrint("[AFD, AfdCancelHandler] called\n");
 
     IoReleaseCancelSpinLock(Irp->CancelIrql);
     
@@ -1032,37 +1084,43 @@
         case IOCTL_AFD_SELECT:
             KeAcquireSpinLock(&DeviceExt->Lock, &OldIrql);
 
-        CurrentEntry = DeviceExt->Polls.Flink;
-        while (CurrentEntry != &DeviceExt->Polls)
-        {
-            Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, ListEntry);
-
-            if (Irp == Poll->Irp)
+            CurrentEntry = DeviceExt->Polls.Flink;
+            while (CurrentEntry != &DeviceExt->Polls)
             {
-                CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
-                KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
-                SocketStateUnlock(FCB);
-                return;
+                Poll = CONTAINING_RECORD(CurrentEntry, AFD_ACTIVE_POLL, 
ListEntry);
+
+                if (Irp == Poll->Irp)
+                {
+                    CleanupPendingIrp(FCB, Irp, IrpSp, Poll);
+                    KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
+                    SocketStateUnlock(FCB);
+
+                    DbgPrint("[AFD, AfdCancelHandler] Cancelled IRP\n");
+
+                    return;
+                }
+                else
+                {
+                    CurrentEntry = CurrentEntry->Flink;
+                }
             }
-            else
-            {
-                CurrentEntry = CurrentEntry->Flink;
-            }
-        }
-
-        KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
-
-        SocketStateUnlock(FCB);
+
+            KeReleaseSpinLock(&DeviceExt->Lock, OldIrql);
+
+            SocketStateUnlock(FCB);
             
-        DbgPrint("WARNING!!! IRP cancellation race could lead to a process 
hang! (IOCTL_AFD_SELECT)\n");
-        return;
+            DbgPrint("WARNING!!! IRP cancellation race could lead to a process 
hang! (IOCTL_AFD_SELECT)\n");
+            return;
             
         default:
-        ASSERT(FALSE);
-        UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
-        return;
-    }
-
+            ASSERT(FALSE);
+            UnlockAndMaybeComplete(FCB, STATUS_CANCELLED, Irp, 0);
+            return;
+    }
+
+    DbgPrint("[AFD, AfdCancelHandler] Cancelling MSAFD -> AFD IRPs\n");
+
+    /* Cancel IRPs from MSAFD to AFD (pending IRPs) */
     CurrentEntry = FCB->PendingIrpList[Function].Flink;
     while (CurrentEntry != &FCB->PendingIrpList[Function])
     {

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/select.c 
[iso-8859-1] Sun Jul  3 12:03:49 2011
@@ -141,6 +141,7 @@
     UINT i;
 
     AFD_DbgPrint(MID_TRACE,("Killing selects that refer to %x\n", FileObject));
+    DbgPrint("[AFD, KillSelectsForFCB] Called for FileObject->FsContext = 
0x%x\n", FileObject->FsContext);
 
     KeAcquireSpinLock( &DeviceExt->Lock, &OldIrql );
 
@@ -152,6 +153,8 @@
         Irp = Poll->Irp;
         PollReq = Irp->AssociatedIrp.SystemBuffer;
         HandleArray = AFD_HANDLES(PollReq);
+
+        DbgPrint("[AFD, KillSelectsForFCB] killing select 0x%x\n", Poll);
 
         for (i = 0; i < PollReq->HandleCount; i++)
         {
@@ -161,6 +164,7 @@
             if ((PVOID)HandleArray[i].Handle == FileObject &&
                 (!OnlyExclusive || (OnlyExclusive && Poll->Exclusive)) )
             {
+                DbgPrint("[AFD, KillSelectsForFCB] Zeroing events and 
signaling socket\n");
                 ZeroEvents( PollReq->Handles, PollReq->HandleCount );
                 SignalSocket( Poll, NULL, PollReq, STATUS_CANCELLED );
             }
@@ -170,6 +174,7 @@
     KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
 
     AFD_DbgPrint(MID_TRACE,("Done\n"));
+    DbgPrint("[AFD, KillSelectsForFCB] Leaving\n");
 }
 
 NTSTATUS
@@ -191,6 +196,10 @@
                            PollReq->HandleCount,
                            (INT)(PollReq->Timeout.QuadPart)));
 
+    DbgPrint("[AFD, AfdSelect] Called. HandleCount = %d, Timeout = %d\n",
+                PollReq->HandleCount,
+                           (INT)(PollReq->Timeout.QuadPart));
+
     SET_AFD_HANDLES(PollReq,
                    LockHandles( PollReq->Handles, PollReq->HandleCount ));
 
@@ -266,6 +275,8 @@
 
             KeSetTimer( &Poll->Timer, PollReq->Timeout, &Poll->TimeoutDpc );
 
+            DbgPrint("[AFD, AfdSelect] Marking IRP with STATUS_PENDING\n");
+
             Status = STATUS_PENDING;
             IoMarkIrpPending( Irp );
             (void)IoSetCancelRoutine(Irp, AfdCancelHandler);
@@ -280,6 +291,7 @@
        KeReleaseSpinLock( &DeviceExt->Lock, OldIrql );
 
     AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
+    DbgPrint("[AFD, AfdSelect] Leaving. Status = 0x%x\n", Status);
 
     return Status;
 }

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c [iso-8859-1] 
(original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/tdi.c [iso-8859-1] 
Sun Jul  3 12:03:49 2011
@@ -1241,6 +1241,7 @@
 }
 
 NTSTATUS TdiDisconnect(
+    PIRP *Irp,
     PFILE_OBJECT TransportObject,
     PLARGE_INTEGER Time,
     USHORT Flags,
@@ -1250,10 +1251,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"));
@@ -1268,20 +1265,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 */
@@ -1291,7 +1288,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: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c [iso-8859-1] 
(original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/afd/write.c [iso-8859-1] 
Sun Jul  3 12:03:49 2011
@@ -168,11 +168,20 @@
             break;
     }
 
+    if (FCB->Send.Size - FCB->Send.BytesUsed != 0)
+    {
+               FCB->PollState |= AFD_EVENT_SEND;
+               FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
+               PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+    else
+    {
+        FCB->PollState &= ~AFD_EVENT_SEND;
+    }
+
     /* Some data is still waiting */
     if (FCB->Send.BytesUsed)
     {
-               FCB->PollState &= ~AFD_EVENT_SEND;
-
                Status = TdiSend( &FCB->SendIrp.InFlightRequest,
                                                  FCB->Connection.Object,
                                                  0,
@@ -183,12 +192,6 @@
                                                  FCB );
 
         RetryDisconnectCompletion(FCB);
-    }
-    else
-    {
-               FCB->PollState |= AFD_EVENT_SEND;
-               FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
-               PollReeval( FCB->DeviceExt, FCB->FileObject );
     }
 
     SocketStateUnlock( FCB );
@@ -408,6 +411,7 @@
     }
     else
     {
+        FCB->PollState &= ~AFD_EVENT_SEND;
         if (SendReq->AfdFlags & AFD_IMMEDIATE)
         {
             AFD_DbgPrint(MID_TRACE,("Nonblocking\n"));
@@ -438,6 +442,17 @@
         
         AFD_DbgPrint(MID_TRACE,("Dismissing request: %x (%d)\n",
                                 Status, TotalBytesCopied));
+    }
+
+    if (SpaceAvail)
+    {
+        FCB->PollState |= AFD_EVENT_SEND;
+               FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS;
+               PollReeval( FCB->DeviceExt, FCB->FileObject );
+    }
+    else
+    {
+        FCB->PollState &= ~AFD_EVENT_SEND;
     }
 
     RetryDisconnectCompletion(FCB);

Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h 
[iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/afd.h 
[iso-8859-1] Sun Jul  3 12:03:49 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: branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h?rev=52516&r1=52515&r2=52516&view=diff
==============================================================================
--- branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h 
[iso-8859-1] (original)
+++ branches/GSoC_2011/TcpIpDriver/drivers/network/afd/include/tdi_proto.h 
[iso-8859-1] Sun Jul  3 12:03:49 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