From: Pierre Schweitzer Date: Tue, 5 Sep 2017 12:56:45 +0000 (+0000) Subject: [FSUTIL] X-Git-Tag: backups/GSoC_2017/rapps@75905~4^2~42 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7f463d43dbddf406a40cf67aeffa85ff73bf9366 [FSUTIL] Add a skeleton for the fsutil tool. As a proof of concept, implement fsutil dirty query. More to follow ;-). svn path=/trunk/; revision=75764 --- diff --git a/reactos/base/applications/cmdutils/CMakeLists.txt b/reactos/base/applications/cmdutils/CMakeLists.txt index c1f238b6ca2..94252370662 100644 --- a/reactos/base/applications/cmdutils/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/CMakeLists.txt @@ -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 index 00000000000..457915a2be9 --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt @@ -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 index 00000000000..ead5a3686a5 --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/dirty.c @@ -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 + */ + +#include "fsutil.h" +#include + +/* 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 \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 index 00000000000..9269f0f2d9c --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/fsutil.c @@ -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 + */ + +#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 index 00000000000..1eaaba0e6bb --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/fsutil.h @@ -0,0 +1,15 @@ +#ifndef __FSUTIL_H__ +#define __FSUTIL_H__ + +#include +#include +#include + +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 index 00000000000..212052425e1 --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/fsutil.rc @@ -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