[FASTFAT]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 18 Aug 2010 23:21:15 +0000 (23:21 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Wed, 18 Aug 2010 23:21:15 +0000 (23:21 +0000)
Make our FAT driver PNP aware.
On PNP requests it should handle, it will return STATUS_NOT_IMPLEMENTED.
On the others, it will pass them to lower driver.
This is the first step outside the kernel into getting IoGetRelatedTargetDevice (and so notifications) working.
It doesn't work at the moment, as class2 doesn't handle PNP.

[NTOSKRNL]
Some fixes to IRP cancelation process:
- Renamed IopRemoveThreadIrp() to IopDisassociateThreadIrp() to match Windows 2k3
- Made dead IRP global, to make its debug easier.
- IopDisassociateThreadIrp(), Handle dead IRP at dispatch level, using IoCompletionLock.
- IopDisassociateThreadIrp(), Use the proper error code to write the entry to logs.
- IoCancelIrp(), removed non needed ASSERT, which is even not present on Windows, removed corresponding var as well.
- IoCancelIrp(), fixed parameters to KeBugCheckEx() call.
- IoCancelThreadIo() is pageable.
- IoCancelThreadIo() under Windows isn't using given thread, but using current. Do the same here.
All that stuff doesn't fix bug #5550, it comes from outside.

Patch by Pierre Schweitzer, modified by me to make it compile. If it breaks anything, don't blame me!

svn path=/trunk/; revision=48560

reactos/drivers/filesystems/fastfat/iface.c
reactos/drivers/filesystems/fastfat/misc.c
reactos/drivers/filesystems/fastfat/pnp.c [new file with mode: 0644]
reactos/drivers/filesystems/fastfat/vfat.h
reactos/drivers/filesystems/fastfat/vfatfs.rbuild
reactos/ntoskrnl/io/iomgr/irp.c

index 6bf9715..de9bb16 100644 (file)
@@ -100,6 +100,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = VfatBuildRequest;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = VfatBuildRequest;
+   DriverObject->MajorFunction[IRP_MJ_PNP] = VfatBuildRequest;
 
    DriverObject->DriverUnload = NULL;
 
index 688086a..71d94b5 100644 (file)
@@ -127,6 +127,8 @@ VfatDispatchRequest (IN PVFAT_IRP_CONTEXT IrpContext)
          return VfatCleanup(IrpContext);
       case IRP_MJ_FLUSH_BUFFERS:
          return VfatFlush(IrpContext);
+      case IRP_MJ_PNP:
+         return VfatPnp(IrpContext);
       default:
          DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
          IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
diff --git a/reactos/drivers/filesystems/fastfat/pnp.c b/reactos/drivers/filesystems/fastfat/pnp.c
new file mode 100644 (file)
index 0000000..a1e909e
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * FILE:             drivers/filesystems/fastfat/pnp.c
+ * PURPOSE:          VFAT Filesystem
+ * PROGRAMMER:       Pierre Schweitzer
+ *
+ */
+
+/* INCLUDES *****************************************************************/
+
+#define NDEBUG
+#include "vfat.h"
+
+/* FUNCTIONS ****************************************************************/
+
+NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext)
+{
+  PVCB Vcb = NULL;
+  NTSTATUS Status;
+
+  /* PRECONDITION */
+  ASSERT(IrpContext);
+
+  switch (IrpContext->Stack->MinorFunction)
+  {
+    case IRP_MN_QUERY_REMOVE_DEVICE:
+    case IRP_MN_SURPRISE_REMOVAL:
+    case IRP_MN_REMOVE_DEVICE:
+    case IRP_MN_CANCEL_REMOVE_DEVICE:
+      Status = STATUS_NOT_IMPLEMENTED;
+      break;
+    default:
+      IoSkipCurrentIrpStackLocation(IrpContext->Irp);
+      Vcb = (PVCB)IrpContext->Stack->DeviceObject->DeviceExtension;
+      Status = IoCallDriver(Vcb->StorageDevice, IrpContext->Irp);
+  }
+
+  VfatFreeIrpContext(IrpContext);
+
+  return Status;
+}
index e9c37da..3521d31 100644 (file)
@@ -775,5 +775,8 @@ NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext);
 
 NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb);
 
+/*  --------------------------------------------------------------- pnp.c  */
+
+NTSTATUS VfatPnp(PVFAT_IRP_CONTEXT IrpContext);
 
 /* EOF */
index 56ca836..a8e81d2 100644 (file)
@@ -21,6 +21,7 @@
        <file>fsctl.c</file>
        <file>iface.c</file>
        <file>misc.c</file>
+       <file>pnp.c</file>
        <file>rw.c</file>
        <file>shutdown.c</file>
        <file>string.c</file>
index 53649f1..55d316a 100644 (file)
@@ -18,6 +18,8 @@
 #undef IoCallDriver
 #undef IoCompleteRequest
 
+PIRP IopDeadIrp;
+
 /* PRIVATE FUNCTIONS  ********************************************************/
 
 VOID
@@ -112,10 +114,9 @@ IopAbortInterruptedIrp(IN PKEVENT EventObject,
 
 VOID
 NTAPI
-IopRemoveThreadIrp(VOID)
+IopDisassociateThreadIrp(VOID)
 {
-    KIRQL OldIrql;
-    PIRP DeadIrp;
+    KIRQL OldIrql, LockIrql;
     PETHREAD IrpThread;
     PLIST_ENTRY IrpEntry;
     PIO_ERROR_LOG_PACKET ErrorLogEntry;
@@ -134,36 +135,41 @@ IopRemoveThreadIrp(VOID)
         return;
     }
 
+    /* Ensure no one will come disturb */
+    LockIrql = KeAcquireQueuedSpinLock(LockQueueIoCompletionLock);
+
     /* Get the misbehaving IRP */
     IrpEntry = IrpThread->IrpList.Flink;
-    DeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
+    IopDeadIrp = CONTAINING_RECORD(IrpEntry, IRP, ThreadListEntry);
     IOTRACE(IO_IRP_DEBUG,
             "%s - Deassociating IRP %p for %p\n",
             __FUNCTION__,
-            DeadIrp,
+            IopDeadIrp,
             IrpThread);
 
     /* Don't cancel the IRP if it's already been completed far */
-    if (DeadIrp->CurrentLocation == (DeadIrp->StackCount + 2))
+    if (IopDeadIrp->CurrentLocation == (IopDeadIrp->StackCount + 2))
     {
         /* Return */
+        KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql);
         KeLowerIrql(OldIrql);
         return;
     }
 
     /* Disown the IRP! */
-    DeadIrp->Tail.Overlay.Thread = NULL;
+    IopDeadIrp->Tail.Overlay.Thread = NULL;
     RemoveHeadList(&IrpThread->IrpList);
-    InitializeListHead(&DeadIrp->ThreadListEntry);
+    InitializeListHead(&IopDeadIrp->ThreadListEntry);
 
     /* Get the stack location and check if it's valid */
-    IoStackLocation = IoGetCurrentIrpStackLocation(DeadIrp);
-    if (DeadIrp->CurrentLocation <= DeadIrp->StackCount)
+    IoStackLocation = IoGetCurrentIrpStackLocation(IopDeadIrp);
+    if (IopDeadIrp->CurrentLocation <= IopDeadIrp->StackCount)
     {
         /* Get the device object */
         DeviceObject = IoStackLocation->DeviceObject;
     }
 
+    KeReleaseQueuedSpinLock(LockQueueIoCompletionLock, LockIrql);
     /* Lower IRQL now, since we have the pointers we need */
     KeLowerIrql(OldIrql);
 
@@ -176,7 +182,7 @@ IopRemoveThreadIrp(VOID)
         if (ErrorLogEntry)
         {
             /* Write the entry */
-            ErrorLogEntry->ErrorCode = 0xBAADF00D; /* FIXME */
+            ErrorLogEntry->ErrorCode = IO_DRIVER_CANCEL_TIMEOUT;
             IoWriteErrorLogEntry(ErrorLogEntry);
         }
     }
@@ -982,14 +988,12 @@ NTAPI
 IoCancelIrp(IN PIRP Irp)
 {
     KIRQL OldIrql;
-    KIRQL IrqlAtEntry;
     PDRIVER_CANCEL CancelRoutine;
     IOTRACE(IO_IRP_DEBUG,
             "%s - Canceling IRP %p\n",
             __FUNCTION__,
             Irp);
     ASSERT(Irp->Type == IO_TYPE_IRP);
-    IrqlAtEntry = KeGetCurrentIrql();
 
     /* Acquire the cancel lock and cancel the IRP */
     IoAcquireCancelSpinLock(&OldIrql);
@@ -1005,7 +1009,7 @@ IoCancelIrp(IN PIRP Irp)
             /* It is, bugcheck */
             KeBugCheckEx(CANCEL_STATE_IN_COMPLETED_IRP,
                          (ULONG_PTR)Irp,
-                         0,
+                         (ULONG_PTR)CancelRoutine,
                          0,
                          0);
         }
@@ -1013,7 +1017,6 @@ IoCancelIrp(IN PIRP Irp)
         /* Set the cancel IRQL And call the routine */
         Irp->CancelIrql = OldIrql;
         CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
-       ASSERT(IrqlAtEntry == KeGetCurrentIrql());
         return TRUE;
     }
 
@@ -1034,6 +1037,11 @@ IoCancelThreadIo(IN PETHREAD Thread)
     LARGE_INTEGER Interval;
     PLIST_ENTRY ListHead, NextEntry;
     PIRP Irp;
+    PAGED_CODE();
+
+    /* Windows isn't using given thread, but using current. */
+    Thread = PsGetCurrentThread();
+
     IOTRACE(IO_IRP_DEBUG,
             "%s - Canceling IRPs for Thread %p\n",
             __FUNCTION__,
@@ -1077,7 +1085,7 @@ IoCancelThreadIo(IN PETHREAD Thread)
         {
             /* Print out a message and remove the IRP */
             DPRINT1("Broken driver did not complete!\n");
-            IopRemoveThreadIrp();
+            IopDisassociateThreadIrp();
         }
 
         /* Raise the IRQL Again */