[VFATLIB] Make Chkdsk handle volume opening locking failures.
authorPierre Schweitzer <pierre@reactos.org>
Sat, 9 Dec 2017 20:07:09 +0000 (21:07 +0100)
committerPierre Schweitzer <pierre@reactos.org>
Sat, 9 Dec 2017 20:12:09 +0000 (21:12 +0100)
For instance, when repair is required, we can ask the caller whether we should
continue or not in case locking failed.
Also, introduced a hack for 1st stage where IopParseDevice() hack is in usage
so that broken NTSTATUS is diverted to appropriate status.
That way, usetup will properly continue even if locking failed (due to its
callback stub!)

CORE-14087

sdk/lib/fslib/vfatlib/check/io.c
sdk/lib/fslib/vfatlib/check/io.h
sdk/lib/fslib/vfatlib/vfatlib.c

index 17db7a1..2eca2ab 100644 (file)
@@ -159,7 +159,7 @@ static off_t WIN32lseek(HANDLE fd, off_t offset, int whence)
 /******************************************************************************/
 
 
-void fs_open(PUNICODE_STRING DriveRoot, int read_write)
+NTSTATUS fs_open(PUNICODE_STRING DriveRoot, int read_write)
 {
     NTSTATUS Status;
     OBJECT_ATTRIBUTES ObjectAttributes;
@@ -180,11 +180,14 @@ void fs_open(PUNICODE_STRING DriveRoot, int read_write)
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("NtOpenFile() failed with status 0x%.08x\n", Status);
-        return;
+        return Status;
     }
 
     // If read_write is specified, then the volume should be exclusively locked
-    if (read_write) fs_lock(TRUE);
+    if (read_write)
+    {
+        Status = fs_lock(TRUE);
+    }
 
     // Query geometry and partition info, to have bytes per sector, etc
 
@@ -192,6 +195,8 @@ void fs_open(PUNICODE_STRING DriveRoot, int read_write)
 
     changes = last = NULL;
     did_change = 0;
+
+    return Status;
 }
 
 BOOLEAN fs_isdirty(void)
@@ -231,6 +236,13 @@ NTSTATUS fs_lock(BOOLEAN LockVolume)
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("NtFsControlFile() failed with Status 0x%08x\n", Status);
+#if 1
+        /* FIXME: ReactOS HACK for 1stage due to IopParseDevice() hack */
+        if (Status == STATUS_INVALID_DEVICE_REQUEST)
+        {
+            Status = STATUS_ACCESS_DENIED;
+        }
+#endif
     }
 
     return Status;
index 1178cd1..23c6fd6 100644 (file)
@@ -34,7 +34,7 @@
 //#include <sys/types.h> /* for loff_t */
 // #include <fcntl.h>          /* for off_t */
 
-void fs_open(PUNICODE_STRING DriveRoot, int read_write);
+NTSTATUS fs_open(PUNICODE_STRING DriveRoot, int read_write);
 
 /* Opens the file system PATH. If RW is zero, the file system is opened
    read-only, otherwise, it is opened read-write. */
index 267d3a1..8db6e8a 100644 (file)
@@ -383,6 +383,7 @@ VfatChkdsk(IN PUNICODE_STRING DriveRoot,
     BOOLEAN salvage_files;
     ULONG free_clusters;
     DOS_FS fs;
+    NTSTATUS Status;
 
     RtlZeroMemory(&fs, sizeof(fs));
 
@@ -403,7 +404,20 @@ VfatChkdsk(IN PUNICODE_STRING DriveRoot,
     salvage_files = TRUE;
 
     /* Open filesystem and lock it */
-    fs_open(DriveRoot, FsCheckFlags & FSCHECK_READ_WRITE);
+    Status = fs_open(DriveRoot, FsCheckFlags & FSCHECK_READ_WRITE);
+    if (Status == STATUS_ACCESS_DENIED)
+    {
+        /* We failed to lock, ask the caller whether we should continue */
+        if (Callback(VOLUMEINUSE, 0, NULL))
+        {
+            Status = STATUS_SUCCESS;
+        }
+    }
+    if (!NT_SUCCESS(Status))
+    {
+        fs_close(FALSE);
+        return STATUS_DISK_CORRUPT_ERROR;
+    }
 
     if (CheckOnlyIfDirty && !fs_isdirty())
     {