[ros-diffs] [cgutman] 54823: [NDISUIO] - Make reads cancelable - Fix a bug in IOCTL_CANCEL_READ handling

cgutman at svn.reactos.org cgutman at svn.reactos.org
Tue Jan 3 19:37:04 UTC 2012


Author: cgutman
Date: Tue Jan  3 19:37:03 2012
New Revision: 54823

URL: http://svn.reactos.org/svn/reactos?rev=54823&view=rev
Log:
[NDISUIO]
- Make reads cancelable
- Fix a bug in IOCTL_CANCEL_READ handling

Modified:
    branches/wlan-bringup/drivers/network/ndisuio/ioctl.c
    branches/wlan-bringup/drivers/network/ndisuio/readwrite.c

Modified: branches/wlan-bringup/drivers/network/ndisuio/ioctl.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndisuio/ioctl.c?rev=54823&r1=54822&r2=54823&view=diff
==============================================================================
--- branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] (original)
+++ branches/wlan-bringup/drivers/network/ndisuio/ioctl.c [iso-8859-1] Tue Jan  3 19:37:03 2012
@@ -109,7 +109,7 @@
     {
         PacketEntry->PacketLength = 0;
         
-        ExInterlockedInsertTailList(&AdapterContext->PacketList,
+        ExInterlockedInsertHeadList(&AdapterContext->PacketList,
                                     &PacketEntry->ListEntry,
                                     &AdapterContext->Spinlock);
         

Modified: branches/wlan-bringup/drivers/network/ndisuio/readwrite.c
URL: http://svn.reactos.org/svn/reactos/branches/wlan-bringup/drivers/network/ndisuio/readwrite.c?rev=54823&r1=54822&r2=54823&view=diff
==============================================================================
--- branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] (original)
+++ branches/wlan-bringup/drivers/network/ndisuio/readwrite.c [iso-8859-1] Tue Jan  3 19:37:03 2012
@@ -10,6 +10,30 @@
 
 #define NDEBUG
 #include <debug.h>
+
+VOID
+NTAPI
+ReadIrpCancel(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+{
+    PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
+    PNDISUIO_PACKET_ENTRY PacketEntry;
+    
+    /* Release the cancel spin lock */
+    IoReleaseCancelSpinLock(Irp->CancelIrql);
+
+    /* Indicate a 0-byte packet on the queue to cancel the read */
+    PacketEntry = ExAllocatePool(PagedPool, sizeof(NDISUIO_PACKET_ENTRY));
+    if (PacketEntry)
+    {
+        PacketEntry->PacketLength = 0;
+        
+        ExInterlockedInsertHeadList(&AdapterContext->PacketList,
+                                    &PacketEntry->ListEntry,
+                                    &AdapterContext->Spinlock);
+        
+        KeSetEvent(&AdapterContext->PacketReadEvent, IO_NO_INCREMENT, FALSE);
+    }
+}
 
 NTSTATUS
 NTAPI
@@ -19,7 +43,7 @@
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
     PNDISUIO_ADAPTER_CONTEXT AdapterContext = IrpSp->FileObject->FsContext;
     PNDISUIO_OPEN_ENTRY OpenEntry = IrpSp->FileObject->FsContext2;
-    KIRQL OldIrql;
+    KIRQL OldIrql, OldCancelIrql;
     NTSTATUS Status;
     PLIST_ENTRY ListEntry;
     PNDISUIO_PACKET_ENTRY PacketEntry = NULL;
@@ -35,6 +59,22 @@
         
         return STATUS_INVALID_PARAMETER;
     }
+
+    /* Make the read cancellable */
+    IoAcquireCancelSpinLock(&OldCancelIrql);
+    IoSetCancelRoutine(Irp, ReadIrpCancel);
+    if (Irp->Cancel)
+    {
+        IoReleaseCancelSpinLock(OldCancelIrql);
+
+        /* Indicate a 0 byte read */
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        
+        return STATUS_SUCCESS;
+    }
+    IoReleaseCancelSpinLock(OldCancelIrql);
 
     while (TRUE)
     {
@@ -52,10 +92,22 @@
                                            TRUE,
                                            NULL);
             if (Status != STATUS_SUCCESS)
+            {
+                /* Remove the cancel routine */
+                IoAcquireCancelSpinLock(&OldCancelIrql);
+                IoSetCancelRoutine(Irp, NULL);
+                IoReleaseCancelSpinLock(OldCancelIrql);
+
                 break;
+            }
         }
         else
         {
+            /* Remove the cancel routine */
+            IoAcquireCancelSpinLock(&OldCancelIrql);
+            IoSetCancelRoutine(Irp, NULL);
+            IoReleaseCancelSpinLock(OldCancelIrql);
+            
             /* Remove the first packet in the list */
             ListEntry = RemoveHeadList(&AdapterContext->PacketList);
             PacketEntry = CONTAINING_RECORD(ListEntry, NDISUIO_PACKET_ENTRY, ListEntry);




More information about the Ros-diffs mailing list