NTSTATUS VfatFlushVolume( PDEVICE_EXTENSION DeviceExt, PVFATFCB VolumeFcb) { PLIST_ENTRY ListEntry; PVFATFCB Fcb; NTSTATUS Status, ReturnStatus = STATUS_SUCCESS; PIRP Irp; KEVENT Event; IO_STATUS_BLOCK IoStatusBlock; DPRINT("VfatFlushVolume(DeviceExt %p, VolumeFcb %p)\n", DeviceExt, VolumeFcb); ASSERT(VolumeFcb == 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 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; }