static LONG QueueCount = 0;
+static VOID VfatFreeIrpContext(PVFAT_IRP_CONTEXT);
+static PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT, PIRP);
+static NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT);
+
/* FUNCTIONS ****************************************************************/
static
if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
{
- Status = STATUS_INVALID_DEVICE_REQUEST;
- goto Fail;
+ return STATUS_INVALID_DEVICE_REQUEST;
}
if (*Fcb->Attributes & FILE_ATTRIBUTE_DIRECTORY)
{
- Status = STATUS_INVALID_PARAMETER;
- goto Fail;
+ return STATUS_INVALID_PARAMETER;
}
+ IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
Status = FsRtlProcessFileLock(&Fcb->FileLock,
IrpContext->Irp,
NULL);
-
- VfatFreeIrpContext(IrpContext);
- return Status;
-
-Fail:
- IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest(IrpContext->Irp, (CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
- VfatFreeIrpContext(IrpContext);
return Status;
}
{
IoSkipCurrentIrpStackLocation(IrpContext->Irp);
+ IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
+
return IoCallDriver(IrpContext->DeviceExt->StorageDevice, IrpContext->Irp);
}
VfatDispatchRequest(
IN PVFAT_IRP_CONTEXT IrpContext)
{
+ NTSTATUS Status;
+
DPRINT("VfatDispatchRequest (IrpContext %p), is called for %s\n", IrpContext,
IrpContext->MajorFunction >= IRP_MJ_MAXIMUM_FUNCTION ? "????" : MajorFunctionNames[IrpContext->MajorFunction]);
ASSERT(IrpContext);
+ FsRtlEnterFileSystem();
+
switch (IrpContext->MajorFunction)
{
case IRP_MJ_CLOSE:
- return VfatClose(IrpContext);
+ Status = VfatClose(IrpContext);
+ break;
+
case IRP_MJ_CREATE:
- return VfatCreate(IrpContext);
+ Status = VfatCreate(IrpContext);
+ break;
+
case IRP_MJ_READ:
- return VfatRead (IrpContext);
+ Status = VfatRead(IrpContext);
+ break;
+
case IRP_MJ_WRITE:
- return VfatWrite (IrpContext);
+ Status = VfatWrite (IrpContext);
+ break;
+
case IRP_MJ_FILE_SYSTEM_CONTROL:
- return VfatFileSystemControl(IrpContext);
+ Status = VfatFileSystemControl(IrpContext);
+ break;
+
case IRP_MJ_QUERY_INFORMATION:
- return VfatQueryInformation (IrpContext);
+ Status = VfatQueryInformation (IrpContext);
+ break;
+
case IRP_MJ_SET_INFORMATION:
- return VfatSetInformation (IrpContext);
+ Status = VfatSetInformation (IrpContext);
+ break;
+
case IRP_MJ_DIRECTORY_CONTROL:
- return VfatDirectoryControl(IrpContext);
+ Status = VfatDirectoryControl(IrpContext);
+ break;
+
case IRP_MJ_QUERY_VOLUME_INFORMATION:
- return VfatQueryVolumeInformation(IrpContext);
+ Status = VfatQueryVolumeInformation(IrpContext);
+ break;
+
case IRP_MJ_SET_VOLUME_INFORMATION:
- return VfatSetVolumeInformation(IrpContext);
+ Status = VfatSetVolumeInformation(IrpContext);
+ break;
+
case IRP_MJ_LOCK_CONTROL:
- return VfatLockControl(IrpContext);
+ Status = VfatLockControl(IrpContext);
+ break;
+
case IRP_MJ_DEVICE_CONTROL:
- return VfatDeviceControl(IrpContext);
+ Status = VfatDeviceControl(IrpContext);
+ break;
+
case IRP_MJ_CLEANUP:
- return VfatCleanup(IrpContext);
+ Status = VfatCleanup(IrpContext);
+ break;
+
case IRP_MJ_FLUSH_BUFFERS:
- return VfatFlush(IrpContext);
+ Status = VfatFlush(IrpContext);
+ break;
+
case IRP_MJ_PNP:
- return VfatPnp(IrpContext);
+ Status = VfatPnp(IrpContext);
+ break;
+
default:
DPRINT1("Unexpected major function %x\n", IrpContext->MajorFunction);
- IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
- IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
- VfatFreeIrpContext(IrpContext);
- return STATUS_DRIVER_INTERNAL_ERROR;
+ Status = STATUS_DRIVER_INTERNAL_ERROR;
+ }
+
+ 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)
+ {
+ IrpContext->Irp->IoStatus.Status = Status;
+ IoCompleteRequest(IrpContext->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 = VfatQueueRequest(IrpContext);
+ }
+ else
+ {
+ /* Unless the IRP was queued, always free the IRP context */
+ VfatFreeIrpContext(IrpContext);
}
+
+ FsRtlExitFileSystem();
+
+ return Status;
}
NTSTATUS
}
else
{
- FsRtlEnterFileSystem();
Status = VfatDispatchRequest(IrpContext);
- FsRtlExitFileSystem();
}
return Status;
}
+static
VOID
VfatFreeIrpContext(
PVFAT_IRP_CONTEXT IrpContext)
ExFreeToNPagedLookasideList(&VfatGlobalData->IrpContextLookasideList, IrpContext);
}
+static
PVFAT_IRP_CONTEXT
VfatAllocateIrpContext(
PDEVICE_OBJECT DeviceObject,
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
IrpContext->FileObject = IrpContext->Stack->FileObject;
- IrpContext->Flags = 0;
+ IrpContext->Flags = IRPCONTEXT_COMPLETE;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
MajorFunction == IRP_MJ_DEVICE_CONTROL ||
MajorFunction == IRP_MJ_SHUTDOWN)
}
KeInitializeEvent(&IrpContext->Event, NotificationEvent, FALSE);
IrpContext->RefCount = 0;
+ IrpContext->PriorityBoost = IO_NO_INCREMENT;
}
return IrpContext;
}
InterlockedDecrement(&QueueCount);
DPRINT("VfatDoRequest(IrpContext %p), MajorFunction %x, %d\n",
IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, QueueCount);
- FsRtlEnterFileSystem();
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
- FsRtlExitFileSystem();
}
+static
NTSTATUS
VfatQueueRequest(
PVFAT_IRP_CONTEXT IrpContext)
ASSERT(IrpContext != NULL);
ASSERT(IrpContext->Irp != NULL);
+ ASSERT(!(IrpContext->Flags & IRPCONTEXT_QUEUE) &&
+ (IrpContext->Flags & IRPCONTEXT_COMPLETE));
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoMarkIrpPending(IrpContext->Irp);
PVOID
VfatGetUserBuffer(
- IN PIRP Irp)
+ IN PIRP Irp,
+ IN BOOLEAN Paging)
{
ASSERT(Irp);
if (Irp->MdlAddress)
{
- /* This call may be in the paging path, so use maximum priority */
- /* FIXME: call with normal priority in the non-paging path */
- return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);
+ return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, (Paging ? HighPagePriority : NormalPagePriority));
}
else
{