[FSUTIL]
authorPierre Schweitzer <pierre@reactos.org>
Tue, 5 Sep 2017 12:56:45 +0000 (12:56 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Tue, 5 Sep 2017 12:56:45 +0000 (12:56 +0000)
Add a skeleton for the fsutil tool.
As a proof of concept, implement fsutil dirty query.
More to follow ;-).

svn path=/trunk/; revision=75764

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

index c1f238b..9425237 100644 (file)
@@ -6,6 +6,7 @@ add_subdirectory(dbgprint)
 add_subdirectory(doskey)
 add_subdirectory(eventcreate)
 add_subdirectory(find)
+add_subdirectory(fsutil)
 add_subdirectory(help)
 add_subdirectory(hostname)
 add_subdirectory(lodctr)
diff --git a/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt b/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt
new file mode 100644 (file)
index 0000000..457915a
--- /dev/null
@@ -0,0 +1,9 @@
+list(APPEND SOURCE
+    dirty.c
+    fsutil.c
+    fsutil.h)
+add_executable(fsutil ${SOURCE} fsutil.rc)
+set_module_type(fsutil win32cui UNICODE)
+add_importlibs(fsutil msvcrt kernel32 ntdll)
+add_pch(fsutil fsutil.h SOURCE)
+add_cd_file(TARGET fsutil DESTINATION reactos/system32 FOR all)
diff --git a/reactos/base/applications/cmdutils/fsutil/dirty.c b/reactos/base/applications/cmdutils/fsutil/dirty.c
new file mode 100644 (file)
index 0000000..ead5a36
--- /dev/null
@@ -0,0 +1,126 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS FS utility tool
+ * FILE:            base/applications/cmdutils/dirty.c
+ * PURPOSE:         FSutil dirty bit handling
+ * PROGRAMMERS:     Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include "fsutil.h"
+#include <winioctl.h>
+
+/* Add handlers here for subcommands */
+static int QueryMain(int argc, const TCHAR *argv[]);
+static int SetMain(int argc, const TCHAR *argv[]);
+static HandlerItem HandlersList[] =
+{
+    /* Proc, name, help */
+    { QueryMain, _T("query"), _T("Show the dirty bit") },
+    { SetMain, _T("set"), _T("Set the dirty bit") },
+};
+
+static int
+QueryMain(int argc, const TCHAR *argv[])
+{
+    HANDLE Volume;
+    TCHAR VolumeID[PATH_MAX];
+    ULONG VolumeStatus, BytesRead;
+
+    /* We need a volume (letter or GUID) */
+    if (argc < 2)
+    {
+        _ftprintf(stderr, _T("Usage: fsutil dirty query <volume>\n"));
+        _ftprintf(stderr, _T("\tFor example: fsutil dirty query c:\n"));
+        return 1;
+    }
+
+    /* Create full name */
+    _stprintf(VolumeID, _T("\\\\.\\%s"), argv[1]);
+
+    /* Open the volume */
+    Volume = CreateFile(VolumeID, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
+                        NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (Volume == INVALID_HANDLE_VALUE)
+    {
+        _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
+        return 1;
+    }
+
+    /* And query the dirty status */
+    if (DeviceIoControl(Volume, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &VolumeStatus,
+                        sizeof(ULONG), &BytesRead, NULL) == FALSE)
+    {
+        _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
+        CloseHandle(Volume);
+        return 1;
+    }
+
+    CloseHandle(Volume);
+
+    /* Print the status */
+    _ftprintf(stdout, _T("The %s volume is %s\n"), argv[1], (VolumeStatus & VOLUME_IS_DIRTY ? _T("dirty") : _T("clean")));
+
+    return 1;
+}
+
+static int
+SetMain(int argc, const TCHAR *argv[])
+{
+    /* FIXME */
+    _ftprintf(stderr, _T("Not implemented\n"));
+    return 1;
+}
+
+static void
+PrintUsage(const TCHAR * Command)
+{
+    int i;
+
+    /* If we were given a command, print it's not supported */
+    if (Command != NULL)
+    {
+        _ftprintf(stderr, _T("Unhandled DIRTY command: %s\n"), Command);
+    }
+
+    /* And dump any available command */
+    _ftprintf(stderr, _T("---- Handled DIRTY commands ----\n\n"));
+    for (i = 0; i < (sizeof(HandlersList) / sizeof(HandlersList[0])); ++i)
+    {
+        _ftprintf(stderr, _T("%s\t%s\n"), HandlersList[i].Command, HandlersList[i].Desc);
+    }
+}
+
+int
+DirtyMain(int argc, const TCHAR *argv[])
+{
+    int i;
+    int ret;
+    const TCHAR * Command;
+
+    ret = 1;
+    Command = NULL;
+    i = (sizeof(HandlersList) / sizeof(HandlersList[0]));
+
+    /* If we have a command, does it match a known one? */
+    if (argc > 1)
+    {
+        /* Browse all the known commands finding the right one */
+        Command = argv[1];
+        for (i = 0; i < (sizeof(HandlersList) / sizeof(HandlersList[0])); ++i)
+        {
+            if (_tcsicmp(Command, HandlersList[i].Command) == 0)
+            {
+                ret = HandlersList[i].Handler(argc - 1, &argv[1]);
+                break;
+            }
+        }
+    }
+
+    /* We failed finding someone to handle the caller's needs, print out */
+    if (i == (sizeof(HandlersList) / sizeof(HandlersList[0])))
+    {
+        PrintUsage(Command);
+    }
+
+    return ret;
+}
diff --git a/reactos/base/applications/cmdutils/fsutil/fsutil.c b/reactos/base/applications/cmdutils/fsutil/fsutil.c
new file mode 100644 (file)
index 0000000..9269f0f
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS FS utility tool
+ * FILE:            base/applications/cmdutils/fsutil.c
+ * PURPOSE:         FSutil main
+ * PROGRAMMERS:     Pierre Schweitzer <pierre@reactos.org>
+ */
+
+#include "fsutil.h"
+
+/* Add handlers here for commands */
+int DirtyMain(int argc, const TCHAR *argv[]);
+static HandlerItem HandlersList[] =
+{
+    /* Proc, name, help */
+    { DirtyMain, _T("dirty"), _T("Manipulates the dirty bit") },
+};
+
+static void
+PrintUsage(const TCHAR * Command)
+{
+    int i;
+
+    /* If we were given a command, print it's not supported */
+    if (Command != NULL)
+    {
+        _ftprintf(stderr, _T("Unhandled command: %s\n"), Command);
+    }
+
+    /* And dump any available command */
+    _ftprintf(stderr, _T("---- Handled commands ----\n\n"));
+    for (i = 0; i < (sizeof(HandlersList) / sizeof(HandlersList[0])); ++i)
+    {
+        _ftprintf(stderr, _T("%s\t%s\n"), HandlersList[i].Command, HandlersList[i].Desc);
+    }
+}
+
+int
+__cdecl
+_tmain(int argc, const TCHAR *argv[])
+{
+    int i;
+    int ret;
+    const TCHAR * Command;
+
+    ret = 1;
+    Command = NULL;
+    i = (sizeof(HandlersList) / sizeof(HandlersList[0]));
+
+    /* If we have a command, does it match a known one? */
+    if (argc > 1)
+    {
+        /* Browse all the known commands finding the right one */
+        Command = argv[1];
+        for (i = 0; i < (sizeof(HandlersList) / sizeof(HandlersList[0])); ++i)
+        {
+            if (_tcsicmp(Command, HandlersList[i].Command) == 0)
+            {
+                ret = HandlersList[i].Handler(argc - 1, &argv[1]);
+                break;
+            }
+        }
+    }
+
+    /* We failed finding someone to handle the caller's needs, print out */
+    if (i == (sizeof(HandlersList) / sizeof(HandlersList[0])))
+    {
+        PrintUsage(Command);
+    }
+
+    return ret;
+}
diff --git a/reactos/base/applications/cmdutils/fsutil/fsutil.h b/reactos/base/applications/cmdutils/fsutil/fsutil.h
new file mode 100644 (file)
index 0000000..1eaaba0
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __FSUTIL_H__
+#define __FSUTIL_H__
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+
+typedef struct
+{
+    int (*Handler)(int argc, const TCHAR *argv[]);
+    const TCHAR * Command;
+    const TCHAR * Desc;
+} HandlerItem;
+
+#endif
diff --git a/reactos/base/applications/cmdutils/fsutil/fsutil.rc b/reactos/base/applications/cmdutils/fsutil/fsutil.rc
new file mode 100644 (file)
index 0000000..2120524
--- /dev/null
@@ -0,0 +1,4 @@
+#define REACTOS_STR_FILE_DESCRIPTION    "FS utility\0"
+#define REACTOS_STR_INTERNAL_NAME       "fsutil\0"
+#define REACTOS_STR_ORIGINAL_FILENAME   "fsutil.exe\0"
+#include <reactos/version.rc>