mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +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 NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
|
||||||
UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
|
UNICODE_STRING VolumeNameU = RTL_CONSTANT_STRING(L"\\$$Volume$$");
|
||||||
ULONG HashTableSize;
|
ULONG HashTableSize;
|
||||||
|
ULONG eocMark;
|
||||||
FATINFO FatInfo;
|
FATINFO FatInfo;
|
||||||
|
|
||||||
DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
|
DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
|
||||||
|
@ -460,6 +461,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
DeviceExt->GetNextCluster = FAT12GetNextCluster;
|
DeviceExt->GetNextCluster = FAT12GetNextCluster;
|
||||||
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
|
DeviceExt->FindAndMarkAvailableCluster = FAT12FindAndMarkAvailableCluster;
|
||||||
DeviceExt->WriteCluster = FAT12WriteCluster;
|
DeviceExt->WriteCluster = FAT12WriteCluster;
|
||||||
|
DeviceExt->CleanShutBitMask = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FAT16:
|
case FAT16:
|
||||||
|
@ -467,6 +469,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
DeviceExt->GetNextCluster = FAT16GetNextCluster;
|
DeviceExt->GetNextCluster = FAT16GetNextCluster;
|
||||||
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
|
DeviceExt->FindAndMarkAvailableCluster = FAT16FindAndMarkAvailableCluster;
|
||||||
DeviceExt->WriteCluster = FAT16WriteCluster;
|
DeviceExt->WriteCluster = FAT16WriteCluster;
|
||||||
|
DeviceExt->CleanShutBitMask = 0x8000;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FAT32:
|
case FAT32:
|
||||||
|
@ -474,6 +477,7 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
DeviceExt->GetNextCluster = FAT32GetNextCluster;
|
DeviceExt->GetNextCluster = FAT32GetNextCluster;
|
||||||
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
|
DeviceExt->FindAndMarkAvailableCluster = FAT32FindAndMarkAvailableCluster;
|
||||||
DeviceExt->WriteCluster = FAT32WriteCluster;
|
DeviceExt->WriteCluster = FAT32WriteCluster;
|
||||||
|
DeviceExt->CleanShutBitMask = 0x80000000;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,6 +580,20 @@ VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
||||||
|
|
||||||
/* read volume label */
|
/* read volume label */
|
||||||
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
|
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;
|
Status = STATUS_SUCCESS;
|
||||||
ByeBye:
|
ByeBye:
|
||||||
|
@ -787,6 +805,56 @@ VfatRosQueryLcnMapping(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: File system control
|
* FUNCTION: File system control
|
||||||
|
@ -822,6 +890,12 @@ NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
||||||
Status = VfatRosQueryLcnMapping(IrpContext);
|
Status = VfatRosQueryLcnMapping(IrpContext);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case FSCTL_IS_VOLUME_DIRTY:
|
||||||
|
Status = VfatIsVolumeDirty(IrpContext);
|
||||||
|
break;
|
||||||
|
case FSCTL_MARK_VOLUME_DIRTY:
|
||||||
|
Status = VfatMarkVolumeDirty(IrpContext);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
ULONG eocMark;
|
||||||
|
|
||||||
DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
|
DPRINT("VfatShutdown(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
|
||||||
|
|
||||||
|
@ -64,6 +65,17 @@ VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
|
|
||||||
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
|
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);
|
Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
|
||||||
if (NT_SUCCESS(Status))
|
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 RtlDowncaseUnicodeString(PUNICODE_STRING, PCUNICODE_STRING, BOOLEAN);
|
||||||
NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING, PCUNICODE_STRING, BOOLEAN);
|
NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING, PCUNICODE_STRING, BOOLEAN);
|
||||||
#undef DeleteFile /* FIXME */
|
#undef DeleteFile /* FIXME */
|
||||||
|
#define VOLUME_IS_DIRTY 0x00000001 /* FIXME */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_ROS_CC_AND_FS
|
#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_VOLUME_LOCKED 0x0001
|
||||||
#define VCB_DISMOUNT_PENDING 0x0002
|
#define VCB_DISMOUNT_PENDING 0x0002
|
||||||
#define VCB_IS_FATX 0x0004
|
#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
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -257,6 +260,7 @@ typedef struct DEVICE_EXTENSION
|
||||||
PGET_NEXT_CLUSTER GetNextCluster;
|
PGET_NEXT_CLUSTER GetNextCluster;
|
||||||
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
|
PFIND_AND_MARK_AVAILABLE_CLUSTER FindAndMarkAvailableCluster;
|
||||||
PWRITE_CLUSTER WriteCluster;
|
PWRITE_CLUSTER WriteCluster;
|
||||||
|
ULONG CleanShutBitMask;
|
||||||
|
|
||||||
/* Pointers to functions for manipulating directory entries. */
|
/* Pointers to functions for manipulating directory entries. */
|
||||||
PGET_NEXT_DIR_ENTRY GetNextDirEntry;
|
PGET_NEXT_DIR_ENTRY GetNextDirEntry;
|
||||||
|
|
Loading…
Reference in a new issue