/* INCLUDES *****************************************************************/
-#define NDEBUG
#include "vfat.h"
+#define NDEBUG
+#include <debug.h>
+
/* FUNCTIONS ****************************************************************/
-static NTSTATUS VfatFlushFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb)
+static
+NTSTATUS
+VfatFlushFile(
+ PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB Fcb)
{
- IO_STATUS_BLOCK IoStatus;
- NTSTATUS Status;
-
- DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt, Fcb, &Fcb->PathNameU);
-
- CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
- if (IoStatus.Status == STATUS_INVALID_PARAMETER)
- {
- /* FIXME: Caching was possible not initialized */
- IoStatus.Status = STATUS_SUCCESS;
- }
- if (Fcb->Flags & FCB_IS_DIRTY)
- {
- Status = VfatUpdateEntry(Fcb);
- if (!NT_SUCCESS(Status))
- {
- IoStatus.Status = Status;
- }
- }
- return IoStatus.Status;
+ IO_STATUS_BLOCK IoStatus;
+ NTSTATUS Status;
+
+ DPRINT("VfatFlushFile(DeviceExt %p, Fcb %p) for '%wZ'\n", DeviceExt, Fcb, &Fcb->PathNameU);
+
+ CcFlushCache(&Fcb->SectionObjectPointers, NULL, 0, &IoStatus);
+ if (IoStatus.Status == STATUS_INVALID_PARAMETER)
+ {
+ /* FIXME: Caching was possible not initialized */
+ IoStatus.Status = STATUS_SUCCESS;
+ }
+
+ if (BooleanFlagOn(Fcb->Flags, FCB_IS_DIRTY))
+ {
+ Status = VfatUpdateEntry(DeviceExt, Fcb);
+ if (!NT_SUCCESS(Status))
+ {
+ IoStatus.Status = Status;
+ }
+ }
+ return IoStatus.Status;
}
-NTSTATUS VfatFlushVolume(PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb)
+NTSTATUS
+VfatFlushVolume(
+ PDEVICE_EXTENSION DeviceExt,
+ PVFATFCB VolumeFcb)
{
- PLIST_ENTRY ListEntry;
- PVFATFCB Fcb;
- NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
-
- DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
-
- ListEntry = DeviceExt->FcbListHead.Flink;
- while (ListEntry != &DeviceExt->FcbListHead)
- {
- Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
- ListEntry = ListEntry->Flink;
- if (!vfatFCBIsDirectory(Fcb))
- {
- ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
- Status = VfatFlushFile(DeviceExt, Fcb);
- ExReleaseResourceLite (&Fcb->MainResource);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("VfatFlushFile failed, status = %x\n", Status);
- ReturnStatus = Status;
- }
- }
- /* FIXME: Stop flushing if this is a removable media and the media was removed */
- }
- ListEntry = DeviceExt->FcbListHead.Flink;
- while (ListEntry != &DeviceExt->FcbListHead)
- {
- Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
- ListEntry = ListEntry->Flink;
- if (vfatFCBIsDirectory(Fcb))
- {
- ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
- Status = VfatFlushFile(DeviceExt, Fcb);
- ExReleaseResourceLite (&Fcb->MainResource);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("VfatFlushFile failed, status = %x\n", Status);
- ReturnStatus = Status;
- }
- }
- /* FIXME: Stop flushing if this is a removable media and the media was removed */
- }
-
- Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
-
- ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
- Status = VfatFlushFile(DeviceExt, Fcb);
- ExReleaseResourceLite(&DeviceExt->FatResource);
-
- /* FIXME: Flush the buffers from storage device */
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("VfatFlushFile failed, status = %x\n", Status);
- ReturnStatus = Status;
- }
-
- return ReturnStatus;
+ PLIST_ENTRY ListEntry;
+ PVFATFCB Fcb;
+ NTSTATUS Status, ReturnStatus = STATUS_SUCCESS;
+ PIRP Irp;
+ KEVENT Event;
+ IO_STATUS_BLOCK IoStatusBlock;
+
+ DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
+
+ ListEntry = DeviceExt->FcbListHead.Flink;
+ while (ListEntry != &DeviceExt->FcbListHead)
+ {
+ Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
+ ListEntry = ListEntry->Flink;
+ if (!vfatFCBIsDirectory(Fcb))
+ {
+ ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
+ Status = VfatFlushFile(DeviceExt, Fcb);
+ ExReleaseResourceLite (&Fcb->MainResource);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VfatFlushFile failed, status = %x\n", Status);
+ ReturnStatus = Status;
+ }
+ }
+ /* FIXME: Stop flushing if this is a removable media and the media was removed */
+ }
+
+ ListEntry = DeviceExt->FcbListHead.Flink;
+ while (ListEntry != &DeviceExt->FcbListHead)
+ {
+ Fcb = CONTAINING_RECORD(ListEntry, VFATFCB, FcbListEntry);
+ ListEntry = ListEntry->Flink;
+ if (vfatFCBIsDirectory(Fcb))
+ {
+ ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
+ Status = VfatFlushFile(DeviceExt, Fcb);
+ ExReleaseResourceLite (&Fcb->MainResource);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VfatFlushFile failed, status = %x\n", Status);
+ ReturnStatus = Status;
+ }
+ }
+ /* FIXME: Stop flushing if this is a removable media and the media was removed */
+ }
+
+ Fcb = (PVFATFCB) DeviceExt->FATFileObject->FsContext;
+
+ ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
+ Status = VfatFlushFile(DeviceExt, Fcb);
+ ExReleaseResourceLite(&DeviceExt->FatResource);
+
+ /* Prepare an IRP to flush device buffers */
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS,
+ DeviceExt->StorageDevice,
+ NULL, 0, NULL, &Event,
+ &IoStatusBlock);
+ if (Irp != NULL)
+ {
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+
+ Status = IoCallDriver(DeviceExt->StorageDevice, Irp);
+ if (Status == STATUS_PENDING)
+ {
+ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* Ignore device not supporting flush operation */
+ if (Status == STATUS_INVALID_DEVICE_REQUEST)
+ {
+ DPRINT1("Flush not supported, ignored\n");
+ Status = STATUS_SUCCESS;
+
+ }
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("VfatFlushFile failed, status = %x\n", Status);
+ ReturnStatus = Status;
+ }
+
+ return ReturnStatus;
}
-NTSTATUS VfatFlush(PVFAT_IRP_CONTEXT IrpContext)
+NTSTATUS
+VfatFlush(
+ PVFAT_IRP_CONTEXT IrpContext)
{
- NTSTATUS Status;
- PVFATFCB Fcb;
- /*
- * This request is not allowed on the main device object.
- */
- if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
- {
- Status = STATUS_INVALID_DEVICE_REQUEST;
- goto ByeBye;
- }
-
- Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
- ASSERT(Fcb);
-
- if (Fcb->Flags & FCB_IS_VOLUME)
- {
- ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
- Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
- ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
- }
- else
- {
- ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
- Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
- ExReleaseResourceLite (&Fcb->MainResource);
- }
-
-ByeBye:
- IrpContext->Irp->IoStatus.Status = Status;
- IrpContext->Irp->IoStatus.Information = 0;
- IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
- VfatFreeIrpContext(IrpContext);
-
- return (Status);
+ NTSTATUS Status;
+ PVFATFCB Fcb;
+
+ /* This request is not allowed on the main device object. */
+ if (IrpContext->DeviceObject == VfatGlobalData->DeviceObject)
+ {
+ IrpContext->Irp->IoStatus.Information = 0;
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ Fcb = (PVFATFCB)IrpContext->FileObject->FsContext;
+ ASSERT(Fcb);
+
+ if (BooleanFlagOn(Fcb->Flags, FCB_IS_VOLUME))
+ {
+ ExAcquireResourceExclusiveLite(&IrpContext->DeviceExt->DirResource, TRUE);
+ Status = VfatFlushVolume(IrpContext->DeviceExt, Fcb);
+ ExReleaseResourceLite(&IrpContext->DeviceExt->DirResource);
+ }
+ else
+ {
+ ExAcquireResourceExclusiveLite(&Fcb->MainResource, TRUE);
+ Status = VfatFlushFile(IrpContext->DeviceExt, Fcb);
+ ExReleaseResourceLite (&Fcb->MainResource);
+ }
+
+ IrpContext->Irp->IoStatus.Information = 0;
+ return Status;
}
/* EOF */