#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_SET_INFORMATION:
+ Status = NtfsSetInformation(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:
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;
}