From 84fd9647d350c6bceaf88d202069eccad47ced0d Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 20 Sep 2017 08:15:10 +0000 Subject: [PATCH] [FSUTIL] Implement fsutil volume dismount CORE-13805 svn path=/trunk/; revision=75910 --- .../cmdutils/fsutil/CMakeLists.txt | 1 + .../applications/cmdutils/fsutil/fsutil.c | 2 + .../applications/cmdutils/fsutil/volume.c | 96 +++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 reactos/base/applications/cmdutils/fsutil/volume.c diff --git a/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt b/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt index 2b1f8e4cf6c..56556c68bb0 100644 --- a/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt +++ b/reactos/base/applications/cmdutils/fsutil/CMakeLists.txt @@ -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) diff --git a/reactos/base/applications/cmdutils/fsutil/fsutil.c b/reactos/base/applications/cmdutils/fsutil/fsutil.c index 77d1cf23cd0..afb16d97da6 100644 --- a/reactos/base/applications/cmdutils/fsutil/fsutil.c +++ b/reactos/base/applications/cmdutils/fsutil/fsutil.c @@ -12,12 +12,14 @@ 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 index 00000000000..379797f3702 --- /dev/null +++ b/reactos/base/applications/cmdutils/fsutil/volume.c @@ -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 + */ + +#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 \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); +}