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;