mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implement FSCTL_IS_VOLUME_DIRTY and FSCTL_MARK_VOLUME_DIRTY
svn path=/trunk/; revision=14636
This commit is contained in:
parent
5942162766
commit
f5129193e2
3 changed files with 90 additions and 0 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue