[FASTFAT] Fix size checking in VfatGetFileNameInformation()
[reactos.git] / drivers / filesystems / ntfs / dispatch.c
index 4670f45..09140f2 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
+static LONG QueueCount = 0;
+
 /* FUNCTIONS ****************************************************************/
 
+static WORKER_THREAD_ROUTINE NtfsDoRequest;
+
+static
+NTSTATUS
+NtfsQueueRequest(PNTFS_IRP_CONTEXT IrpContext)
+{
+    InterlockedIncrement(&QueueCount);
+    DPRINT("NtfsQueueRequest(IrpContext %p), %d\n", IrpContext, QueueCount);
+
+    ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) &&
+           (IrpContext->Flags & IRPCONTEXT_COMPLETE));
+    IrpContext->Flags |= IRPCONTEXT_CANWAIT;
+    IoMarkIrpPending(IrpContext->Irp);
+    ExInitializeWorkItem(&IrpContext->WorkQueueItem, NtfsDoRequest, IrpContext);
+    ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
+
+    return STATUS_PENDING;
+}
+
+static
+NTSTATUS
+NtfsDispatch(PNTFS_IRP_CONTEXT IrpContext)
+{
+    PIRP Irp = IrpContext->Irp;
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+
+    TRACE_(NTFS, "NtfsDispatch()\n");
+
+    FsRtlEnterFileSystem();
+
+    NtfsIsIrpTopLevel(Irp);
+
+    switch (IrpContext->MajorFunction)
+    {
+        case IRP_MJ_QUERY_VOLUME_INFORMATION:
+            Status = NtfsQueryVolumeInformation(IrpContext);
+            break;
+
+        case IRP_MJ_SET_VOLUME_INFORMATION:
+            Status = NtfsSetVolumeInformation(IrpContext);
+            break;
+
+        case IRP_MJ_QUERY_INFORMATION:
+            Status = NtfsQueryInformation(IrpContext);
+            break;
+
+        case IRP_MJ_DIRECTORY_CONTROL:
+            Status = NtfsDirectoryControl(IrpContext);
+            break;
+
+        case IRP_MJ_READ:
+            Status = NtfsRead(IrpContext);
+            break;
+
+        case IRP_MJ_DEVICE_CONTROL:
+            Status = NtfsDeviceControl(IrpContext);
+             break;
+
+        case IRP_MJ_WRITE:
+            Status = NtfsWrite(IrpContext);
+            break;
+
+        case IRP_MJ_CLOSE:
+            Status = NtfsClose(IrpContext);
+            break;
+
+        case IRP_MJ_CLEANUP:
+            Status = NtfsCleanup(IrpContext);
+            break;
+
+        case IRP_MJ_CREATE:
+            Status = NtfsCreate(IrpContext);
+            break;
+
+        case IRP_MJ_FILE_SYSTEM_CONTROL:
+            Status = NtfsFileSystemControl(IrpContext);
+            break;
+    }
+
+    ASSERT((!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
+           ((IrpContext->Flags & IRPCONTEXT_COMPLETE) && !(IrpContext->Flags & IRPCONTEXT_QUEUE)) ||
+           (!(IrpContext->Flags & IRPCONTEXT_COMPLETE) && (IrpContext->Flags & IRPCONTEXT_QUEUE)));
+
+    if (IrpContext->Flags & IRPCONTEXT_COMPLETE)
+    {
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IrpContext->PriorityBoost);
+    }
+
+    if (IrpContext->Flags & IRPCONTEXT_QUEUE)
+    {
+        /* Reset our status flags before queueing the IRP */
+        IrpContext->Flags |= IRPCONTEXT_COMPLETE;
+        IrpContext->Flags &= ~IRPCONTEXT_QUEUE;
+        Status = NtfsQueueRequest(IrpContext);
+    }
+    else
+    {
+        ExFreeToNPagedLookasideList(&NtfsGlobalData->IrpContextLookasideList, IrpContext);
+    }
+
+    IoSetTopLevelIrp(NULL);
+    FsRtlExitFileSystem();
+
+    return Status;
+}
+
+static
+VOID
+NTAPI
+NtfsDoRequest(PVOID IrpContext)
+{
+    InterlockedDecrement(&QueueCount);
+    DPRINT("NtfsDoRequest(IrpContext %p), MajorFunction %x, %d\n",
+           IrpContext, ((PNTFS_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
+    NtfsDispatch((PNTFS_IRP_CONTEXT)IrpContext);
+}
+
 /*
  * FUNCTION: This function manages IRP for various major functions
  * ARGUMENTS:
@@ -46,41 +166,21 @@ NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,
                 PIRP Irp)
 {
     PNTFS_IRP_CONTEXT IrpContext = NULL;
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+    NTSTATUS Status;
 
     TRACE_(NTFS, "NtfsFsdDispatch()\n");
 
-    FsRtlEnterFileSystem();
-    ASSERT(DeviceObject);
-    ASSERT(Irp);
-
-    NtfsIsIrpTopLevel(Irp);
-
     IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
-    if (IrpContext)
+    if (IrpContext == NULL)
     {
-        switch (IrpContext->MajorFunction)
-        {
-            case IRP_MJ_QUERY_VOLUME_INFORMATION:
-                Status = NtfsQueryVolumeInformation(IrpContext);
-                break;
-
-            case IRP_MJ_SET_VOLUME_INFORMATION:
-                Status = NtfsSetVolumeInformation(IrpContext);
-                break;
-        }
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
     }
     else
-        Status = STATUS_INSUFFICIENT_RESOURCES;
-
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    if (IrpContext)
-        ExFreePoolWithTag(IrpContext, 'PRIN');
-
-    IoSetTopLevelIrp(NULL);
-    FsRtlExitFileSystem();
+    {
+        Status = NtfsDispatch(IrpContext);
+    }
 
-    return Status;
+     return Status;
 }