1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS FS utility tool 4 * FILE: base/applications/cmdutils/volume.c 5 * PURPOSE: FSutil volumes management 6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org> 7 */ 8 9 #include "fsutil.h" 10 11 /* Add handlers here for subcommands */ 12 static HandlerProc DismountMain; 13 static HandlerProc DiskFreeMain; 14 static HandlerItem HandlersList[] = 15 { 16 /* Proc, name, help */ 17 { DismountMain, _T("dismount"), _T("Dismounts a volume") }, 18 { DiskFreeMain, _T("diskfree"), _T("Prints free space on a volume") }, 19 }; 20 21 static int 22 LockOrUnlockVolume(HANDLE Volume, BOOLEAN Lock) 23 { 24 DWORD Operation; 25 ULONG BytesRead; 26 27 Operation = (Lock ? FSCTL_LOCK_VOLUME : FSCTL_UNLOCK_VOLUME); 28 if (DeviceIoControl(Volume, Operation, NULL, 0, NULL, 0, 29 &BytesRead, NULL) == FALSE) 30 { 31 PrintErrorMessage(GetLastError()); 32 return 1; 33 } 34 35 return 0; 36 } 37 38 static int 39 DismountMain(int argc, const TCHAR *argv[]) 40 { 41 HANDLE Volume; 42 ULONG BytesRead; 43 44 /* We need a volume (letter or GUID) */ 45 if (argc < 2) 46 { 47 _ftprintf(stderr, _T("Usage: fsutil volume dismount <volume>\n")); 48 _ftprintf(stderr, _T("\tFor example: fsutil volume dismount d:\n")); 49 return 1; 50 } 51 52 /* Get a handle for the volume */ 53 Volume = OpenVolume(argv[1], FALSE, FALSE); 54 if (Volume == INVALID_HANDLE_VALUE) 55 { 56 return 1; 57 } 58 59 /* Attempt to lock the volume */ 60 if (LockOrUnlockVolume(Volume, TRUE)) 61 { 62 CloseHandle(Volume); 63 return 1; 64 } 65 66 /* Issue the dismount command */ 67 if (DeviceIoControl(Volume, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 68 0, &BytesRead, NULL) == FALSE) 69 { 70 PrintErrorMessage(GetLastError()); 71 LockOrUnlockVolume(Volume, FALSE); 72 CloseHandle(Volume); 73 return 1; 74 } 75 76 /* Unlock and quit */ 77 LockOrUnlockVolume(Volume, FALSE); 78 CloseHandle(Volume); 79 80 _ftprintf(stdout, _T("The %s volume has been dismounted\n"), argv[1]); 81 82 return 0; 83 } 84 85 static int 86 DiskFreeMain(int argc, const TCHAR *argv[]) 87 { 88 ULARGE_INTEGER FreeAvail, TotalNumber, TotalNumberFree; 89 90 /* We need a path */ 91 if (argc < 2) 92 { 93 _ftprintf(stderr, _T("Usage: fsutil volume diskfree <volume path>\n")); 94 _ftprintf(stderr, _T("\tFor example: fsutil volume diskfree c:\n")); 95 return 1; 96 } 97 98 if (!GetDiskFreeSpaceEx(argv[1], &FreeAvail, &TotalNumber, &TotalNumberFree)) 99 { 100 PrintErrorMessage(GetLastError()); 101 return 1; 102 } 103 104 _ftprintf(stdout, _T("Total free bytes\t\t: %I64i\n"), TotalNumberFree.QuadPart); 105 _ftprintf(stdout, _T("Total bytes\t\t\t: %I64i\n"), TotalNumber.QuadPart); 106 _ftprintf(stdout, _T("Total free available bytes\t: %I64i\n"), FreeAvail.QuadPart); 107 108 return 0; 109 } 110 111 static void 112 PrintUsage(const TCHAR * Command) 113 { 114 PrintDefaultUsage(_T(" VOLUME "), Command, (HandlerItem *)&HandlersList, 115 (sizeof(HandlersList) / sizeof(HandlersList[0]))); 116 } 117 118 int 119 VolumeMain(int argc, const TCHAR *argv[]) 120 { 121 return FindHandler(argc, argv, (HandlerItem *)&HandlersList, 122 (sizeof(HandlersList) / sizeof(HandlersList[0])), 123 PrintUsage); 124 } 125