Implement FSCTL_IS_VOLUME_DIRTY and FSCTL_MARK_VOLUME_DIRTY

svn path=/trunk/; revision=14636
This commit is contained in:
Hervé Poussineau 2005-04-16 16:04:38 +00:00
parent 5942162766
commit f5129193e2
3 changed files with 90 additions and 0 deletions

View file

@ -373,6 +373,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
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 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
DeviceExt->GetNextCluster = FAT12GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT12WriteCluster;
DeviceExt->CleanShutBitMask = 0;
break;
case FAT16:
@ -467,6 +469,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
DeviceExt->GetNextCluster = FAT16GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT16WriteCluster;
DeviceExt->CleanShutBitMask = 0x8000;
break;
case FAT32:
@ -474,6 +477,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
DeviceExt->GetNextCluster = FAT32GetNextCluster;
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
DeviceExt->WriteCluster = FAT32WriteCluster;
DeviceExt->CleanShutBitMask = 0x80000000;
break;
}
@ -576,6 +580,20 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
/* 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 @@ VfatRosQueryLcnMapping(PVFAT_IRP_CONTEXT IrpContext)
}
#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 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
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;
}

View file

@ -48,6 +48,7 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS Status;
PLIST_ENTRY ListEntry;
PDEVICE_EXTENSION DeviceExt;
ULONG eocMark;
DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
@ -64,6 +65,17 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
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))
{

View file

@ -13,6 +13,7 @@ NTSTATUS NTAPI RtlOemStringToUnicodeString(PUNICODE_STRING, CONST STRING *, BOOL
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 @@ typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
#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 @@ typedef struct DEVICE_EXTENSION
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;