From fed8bf35b48fec9f2b6ec9431d5a9069fe78921e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sat, 23 Aug 2008 11:41:04 +0000 Subject: [PATCH] - Perform volume operations as described in http://msdn.microsoft.com/en-us/library/aa364562(VS.85).aspx : Open, Lock, Work, Dismount, Unlock, Close. - Our fastfat driver doesn't support lock/unlock and dismount operations, so no improvement yet. svn path=/trunk/; revision=35560 --- reactos/lib/fslib/vfatlib/check/io.c | 40 ++++++++++++++++++++++++++++ reactos/lib/fslib/vfatlib/check/io.h | 8 ++++++ reactos/lib/fslib/vfatlib/vfatlib.c | 10 +++++++ 3 files changed, 58 insertions(+) diff --git a/reactos/lib/fslib/vfatlib/check/io.c b/reactos/lib/fslib/vfatlib/check/io.c index e9cdcbb6ccf..7899134d935 100644 --- a/reactos/lib/fslib/vfatlib/check/io.c +++ b/reactos/lib/fslib/vfatlib/check/io.c @@ -72,6 +72,9 @@ void fs_open(PUNICODE_STRING DriveRoot,int rw) return; } + // If rw is specified, then the volume should be exclusively locked + if (rw) fs_lock(TRUE); + // Query geometry and partition info, to have bytes per sector, etc CurrentOffset.QuadPart = 0LL; @@ -102,6 +105,43 @@ BOOLEAN fs_isdirty() return (DirtyMask & 1); } +NTSTATUS fs_lock(BOOLEAN LockVolume) +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoSb; + + /* Check if volume is dirty */ + Status = NtFsControlFile(fd, + NULL, NULL, NULL, &IoSb, + LockVolume ? FSCTL_LOCK_VOLUME : + FSCTL_UNLOCK_VOLUME, + NULL, 0, NULL, 0); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtFsControlFile() failed with Status 0x%08x\n", Status); + } + + return Status; +} + +void fs_dismount() +{ + NTSTATUS Status; + IO_STATUS_BLOCK IoSb; + + /* Check if volume is dirty */ + Status = NtFsControlFile(fd, + NULL, NULL, NULL, &IoSb, + FSCTL_DISMOUNT_VOLUME, + NULL, 0, NULL, 0); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtFsControlFile() failed with Status 0x%08x\n", Status); + } +} + void fs_read(loff_t pos,int size,void *data) { CHANGE *walk; diff --git a/reactos/lib/fslib/vfatlib/check/io.h b/reactos/lib/fslib/vfatlib/check/io.h index 9dfce9b7574..7b23462f515 100644 --- a/reactos/lib/fslib/vfatlib/check/io.h +++ b/reactos/lib/fslib/vfatlib/check/io.h @@ -51,6 +51,14 @@ int fs_changed(void); /* Determines whether the file system has changed. See fs_close. */ +NTSTATUS fs_lock(BOOLEAN LockVolume); + +/* Lock or unlocks the volume */ + +void fs_dismount(); + +/* Dismounts the volume */ + extern unsigned device_no; /* Major number of device (0 if file) and size (in 512 byte sectors) */ diff --git a/reactos/lib/fslib/vfatlib/vfatlib.c b/reactos/lib/fslib/vfatlib/vfatlib.c index 0a096807a2c..02f1d9b1447 100755 --- a/reactos/lib/fslib/vfatlib/vfatlib.c +++ b/reactos/lib/fslib/vfatlib/vfatlib.c @@ -300,6 +300,16 @@ VfatChkdsk( VfatPrint("%wZ: %u files, %lu/%lu clusters\n", DriveRoot, FsCheckTotalFiles, fs.clusters - free_clusters, fs.clusters ); + if (FixErrors) + { + /* Dismount the volume */ + fs_dismount(); + + /* Unlock the volume */ + fs_lock(FALSE); + } + + /* Close the volume */ return fs_close(FixErrors) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL; #else return STATUS_SUCCESS;