[FSUTIL]
authorPierre Schweitzer <pierre@reactos.org>
Wed, 20 Sep 2017 08:15:10 +0000 (08:15 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Wed, 20 Sep 2017 08:15:10 +0000 (08:15 +0000)
Implement fsutil volume dismount

CORE-13805

svn path=/trunk/; revision=75910

reactos/base/applications/cmdutils/fsutil/CMakeLists.txt
reactos/base/applications/cmdutils/fsutil/fsutil.c
reactos/base/applications/cmdutils/fsutil/volume.c [new file with mode: 0644]

index 2b1f8e4..56556c6 100644 (file)
@@ -4,6 +4,7 @@ list(APPEND SOURCE
     fsinfo.c
     fsutil.c
     hardlink.c
+    volume.c
     fsutil.h)
 add_executable(fsutil ${SOURCE} fsutil.rc)
 set_module_type(fsutil win32cui UNICODE)
index 77d1cf2..afb16d9 100644 (file)
 HandlerProc DirtyMain;
 HandlerProc FsInfoMain;
 HandlerProc HardLinkMain;
+HandlerProc VolumeMain;
 static HandlerItem HandlersList[] =
 {
     /* Proc, name, help */
     { DirtyMain, _T("dirty"), _T("Manipulates the dirty bit") },
     { FsInfoMain, _T("fsinfo"), _T("Gathers informations about file systems") },
     { HardLinkMain, _T("hardlink"), _T("Handles hard links") },
+    { VolumeMain, _T("volume"), _T("Manages volumes") },
 };
 
 static void
diff --git a/reactos/base/applications/cmdutils/fsutil/volume.c b/reactos/base/applications/cmdutils/fsutil/volume.c
new file mode 100644 (file)
index 0000000..379797f
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS FS utility tool
+ * FILE:            base/applications/cmdutils/volume.c
+ * PURPOSE:         FSutil volumes management
+ * PROGRAMMERS:     Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include "fsutil.h"
+
+/* Add handlers here for subcommands */
+static HandlerProc DismountMain;
+static HandlerItem HandlersList[] =
+{
+    /* Proc, name, help */
+    { DismountMain, _T("dismount"), _T("Dismounts a volume") },
+};
+
+static int
+LockOrUnlockVolume(HANDLE Volume, BOOLEAN Lock)
+{
+    DWORD Operation;
+    ULONG BytesRead;
+
+    Operation = (Lock ? FSCTL_LOCK_VOLUME : FSCTL_UNLOCK_VOLUME);
+    if (DeviceIoControl(Volume, Operation, NULL, 0, NULL, 0,
+                        &BytesRead, NULL) == FALSE)
+    {
+        PrintErrorMessage(GetLastError());
+        return 1;
+    }
+
+    return 0;
+}
+
+static int
+DismountMain(int argc, const TCHAR *argv[])
+{
+    HANDLE Volume;
+    ULONG BytesRead;
+
+    /* We need a volume (letter or GUID) */
+    if (argc < 2)
+    {
+        _ftprintf(stderr, _T("Usage: fsutil volume dismount <volume>\n"));
+        _ftprintf(stderr, _T("\tFor example: fsutil volume dismount d:\n"));
+        return 1;
+    }
+
+    /* Get a handle for the volume */
+    Volume = OpenVolume(argv[1], FALSE);
+    if (Volume == INVALID_HANDLE_VALUE)
+    {
+        return 1;
+    }
+
+    /* Attempt to lock the volume */
+    if (LockOrUnlockVolume(Volume, TRUE))
+    {
+        CloseHandle(Volume);
+        return 1;
+    }
+
+    /* Issue the dismount command */
+    if (DeviceIoControl(Volume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL,
+                        0, &BytesRead, NULL) == FALSE)
+    {
+        PrintErrorMessage(GetLastError());
+        LockOrUnlockVolume(Volume, FALSE);
+        CloseHandle(Volume);
+        return 1;
+    }
+
+    /* Unlock and quit */
+    LockOrUnlockVolume(Volume, FALSE);
+    CloseHandle(Volume);
+
+    _ftprintf(stdout, _T("The %s volume has been dismounted\n"), argv[1]);
+
+    return 0;
+}
+
+static void
+PrintUsage(const TCHAR * Command)
+{
+    PrintDefaultUsage(_T(" VOLUME "), Command, (HandlerItem *)&HandlersList,
+                      (sizeof(HandlersList) / sizeof(HandlersList[0])));
+}
+
+int
+VolumeMain(int argc, const TCHAR *argv[])
+{
+    return FindHandler(argc, argv, (HandlerItem *)&HandlersList,
+                       (sizeof(HandlersList) / sizeof(HandlersList[0])),
+                       PrintUsage);
+}