Implement FSCTL_IS_VOLUME_DIRTY and FSCTL_MARK_VOLUME_DIRTY Modified: trunk/reactos/drivers/fs/vfat/fsctl.c Modified: trunk/reactos/drivers/fs/vfat/shutdown.c Modified: trunk/reactos/drivers/fs/vfat/vfat.h _____
Modified: trunk/reactos/drivers/fs/vfat/fsctl.c --- trunk/reactos/drivers/fs/vfat/fsctl.c 2005-04-16 12:50:33 UTC (rev 14635) +++ trunk/reactos/drivers/fs/vfat/fsctl.c 2005-04-16 16:04:38 UTC (rev 14636) @@ -373,6 +373,7 @@
UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\$$Fat$$"); UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\$$Volume$$"); ULONG HashTableSize; + ULONG eocMark; FATINFO FatInfo;
DPRINT("VfatMount(IrpContext %x)\n", IrpContext); @@ -460,6 +461,7 @@ DeviceExt->GetNextCluster = FAT12GetNextCluster; DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster; DeviceExt->WriteCluster = FAT12WriteCluster; + DeviceExt->CleanShutBitMask = 0; break;
case FAT16: @@ -467,6 +469,7 @@ DeviceExt->GetNextCluster = FAT16GetNextCluster; DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster; DeviceExt->WriteCluster = FAT16WriteCluster; + DeviceExt->CleanShutBitMask = 0x8000; break;
case FAT32: @@ -474,6 +477,7 @@ DeviceExt->GetNextCluster = FAT32GetNextCluster; DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster; DeviceExt->WriteCluster = FAT32WriteCluster; + DeviceExt->CleanShutBitMask = 0x80000000; break; }
@@ -576,6 +580,20 @@
/* read volume label */ ReadVolumeLabel(DeviceExt, DeviceObject->Vpb); + + /* read clean shutdown bit status */ + Status = GetNextCluster(DeviceExt, 1, &eocMark); + if (NT_SUCCESS(Status)) + { + if (eocMark & DeviceExt->CleanShutBitMask) + { + /* unset clean shutdown bit */ + eocMark &= ~DeviceExt->CleanShutBitMask; + WriteCluster(DeviceExt, 1, eocMark); + VolumeFcb->Flags |= VCB_CLEAR_DIRTY; + } + } + VolumeFcb->Flags |= VCB_IS_DIRTY;
Status = STATUS_SUCCESS; ByeBye: @@ -787,6 +805,56 @@ } #endif
+static NTSTATUS +VfatIsVolumeDirty(PVFAT_IRP_CONTEXT IrpContext) +{ + PULONG Flags; + + DPRINT("VfatIsVolumeDirty(IrpContext %x)\n", IrpContext); + + if (IrpContext->Stack->Parameters.FileSystemControl.OutputBufferLength != sizeof(ULONG)) + return STATUS_INVALID_BUFFER_SIZE; + else if (!IrpContext->Irp->AssociatedIrp.SystemBuffer) + return STATUS_INVALID_USER_BUFFER; + + Flags = (PULONG)IrpContext->Irp->AssociatedIrp.SystemBuffer; + *Flags = 0; + + if (IrpContext->DeviceExt->VolumeFcb->Flags & VCB_IS_DIRTY + && !(IrpContext->DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)) + { + *Flags |= VOLUME_IS_DIRTY; + } + + return STATUS_SUCCESS; +} + +static NTSTATUS +VfatMarkVolumeDirty(PVFAT_IRP_CONTEXT IrpContext) +{ + ULONG eocMark; + PDEVICE_EXTENSION DeviceExt; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT("VfatMarkVolumeDirty(IrpContext %x)\n", IrpContext); + DeviceExt = IrpContext->DeviceExt; + + if (!(DeviceExt->VolumeFcb->Flags & VCB_IS_DIRTY)) + { + Status = GetNextCluster(DeviceExt, 1, &eocMark); + if (NT_SUCCESS(Status)) + { + /* unset clean shutdown bit */ + eocMark &= ~DeviceExt->CleanShutBitMask; + Status = WriteCluster(DeviceExt, 1, eocMark); + } + } + + DeviceExt->VolumeFcb->Flags &= ~VCB_CLEAR_DIRTY; + + return Status; +} + NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext) /* * FUNCTION: File system control @@ -822,6 +890,12 @@ Status = VfatRosQueryLcnMapping(IrpContext); break; #endif + case FSCTL_IS_VOLUME_DIRTY: + Status = VfatIsVolumeDirty(IrpContext); + break; + case FSCTL_MARK_VOLUME_DIRTY: + Status = VfatMarkVolumeDirty(IrpContext); + break; default: Status = STATUS_INVALID_DEVICE_REQUEST; } _____
Modified: trunk/reactos/drivers/fs/vfat/shutdown.c --- trunk/reactos/drivers/fs/vfat/shutdown.c 2005-04-16 12:50:33 UTC (rev 14635) +++ trunk/reactos/drivers/fs/vfat/shutdown.c 2005-04-16 16:04:38 UTC (rev 14636) @@ -48,6 +48,7 @@
NTSTATUS Status; PLIST_ENTRY ListEntry; PDEVICE_EXTENSION DeviceExt; + ULONG eocMark;
DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
@@ -64,6 +65,17 @@ ListEntry = ListEntry->Flink;
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE); + if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY) + { + /* set clean shutdown bit */ + Status = GetNextCluster(DeviceExt, 1, &eocMark); + if (NT_SUCCESS(Status)) + { + eocMark |= DeviceExt->CleanShutBitMask; + if (NT_SUCCESS(WriteCluster(DeviceExt, 1, eocMark))) + DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY; + } + } Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb); if (NT_SUCCESS(Status)) { _____
Modified: trunk/reactos/drivers/fs/vfat/vfat.h --- trunk/reactos/drivers/fs/vfat/vfat.h 2005-04-16 12:50:33 UTC (rev 14635) +++ trunk/reactos/drivers/fs/vfat/vfat.h 2005-04-16 16:04:38 UTC (rev 14636) @@ -13,6 +13,7 @@
NTSTATUS NTAPI RtlDowncaseUnicodeString(PUNICODE_STRING, PCUNICODE_STRING, BOOLEAN); NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING, PCUNICODE_STRING, BOOLEAN); #undef DeleteFile /* FIXME */ +#define VOLUME_IS_DIRTY 0x00000001 /* FIXME */ #endif
#ifdef USE_ROS_CC_AND_FS @@ -193,6 +194,8 @@ #define VCB_VOLUME_LOCKED 0x0001 #define VCB_DISMOUNT_PENDING 0x0002 #define VCB_IS_FATX 0x0004 +#define VCB_IS_DIRTY 0x4000 /* Volume is dirty */ +#define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */
typedef struct { @@ -257,6 +260,7 @@ PGET_NEXT_CLUSTER GetNextCluster; PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster; PWRITE_CLUSTER WriteCluster; + ULONG CleanShutBitMask;
/* Pointers to functions for manipulating directory entries. */ PGET_NEXT_DIR_ENTRY GetNextDirEntry;