--- 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;
}
--- 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))
{
--- 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;