Reactos
at master 289 lines 7.5 kB view raw
1/* 2 * PROJECT: ReactOS DiskPart 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: base/system/diskpart/format.c 5 * PURPOSE: Manages all the partitions of the OS in an interactive way. 6 * PROGRAMMERS: Lee Schroeder 7 */ 8 9#include "diskpart.h" 10 11#include <fmifs/fmifs.h> 12 13#define NDEBUG 14#include <debug.h> 15 16static 17BOOL 18GetFsModule( 19 _In_ PWSTR pszFileSystem, 20 _Out_ HMODULE *phModule) 21{ 22 WCHAR szDllNameBuffer[32]; 23 HKEY hKey; 24 DWORD dwLength, dwErr; 25 26 *phModule = NULL; 27 28 dwErr = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 29 L"SOFTWARE\\ReactOS\\ReactOS\\CurrentVersion\\IFS", 30 0, 31 KEY_READ, 32 &hKey); 33 if (dwErr != ERROR_SUCCESS) 34 { 35 DPRINT1("Failed to open!\n"); 36 return FALSE; 37 } 38 39 dwLength = sizeof(szDllNameBuffer); 40 dwErr = RegQueryValueExW(hKey, 41 pszFileSystem, 42 NULL, 43 NULL, 44 (PBYTE)szDllNameBuffer, 45 &dwLength); 46 47 RegCloseKey(hKey); 48 49 if (dwErr != ERROR_SUCCESS) 50 { 51 DPRINT1("Failed to query!\n"); 52 return FALSE; 53 } 54 55 *phModule = LoadLibraryW(szDllNameBuffer); 56 if (*phModule == NULL) 57 { 58 DPRINT1("Failed to load!\n"); 59 return FALSE; 60 } 61 62 return TRUE; 63} 64 65 66BOOLEAN 67WINAPI 68FormatCallback( 69 CALLBACKCOMMAND Command, 70 ULONG Size, 71 PVOID Argument) 72{ 73 PDWORD percent; 74 75 switch (Command) 76 { 77 case PROGRESS: 78 percent = (PDWORD)Argument; 79 ConResPrintf(StdOut, IDS_FORMAT_PROGRESS, *percent); 80 break; 81 82 case DONE: 83 break; 84 85 default: 86 DPRINT1("Callback (%u %lu %p)\n", Command, Size, Argument); 87 break; 88 } 89 90 return TRUE; 91} 92 93 94EXIT_CODE 95format_main( 96 _In_ INT argc, 97 _In_ PWSTR *argv) 98{ 99 UNICODE_STRING usDriveRoot; 100 UNICODE_STRING LabelString; 101 PWSTR pszSuffix = NULL; 102 PWSTR pszFileSystem = NULL; 103 PWSTR pszLabel = NULL; 104 BOOLEAN bQuickFormat = FALSE; 105 ULONG ulClusterSize = 0; 106 HMODULE hModule = NULL; 107 PULIB_FORMAT pFormat = NULL; 108// FMIFS_MEDIA_FLAG MediaType = FMIFS_HARDDISK; 109 INT i; 110 BOOLEAN Success = FALSE; 111 112 113 if (CurrentVolume == NULL) 114 { 115 ConResPuts(StdOut, IDS_SELECT_NO_VOLUME); 116 return EXIT_SUCCESS; 117 } 118 119 for (i = 1; i < argc; i++) 120 { 121 if (_wcsicmp(argv[i], L"noerr") == 0) 122 { 123 /* noerr */ 124 DPRINT("NoErr\n", pszSuffix); 125 ConPuts(StdOut, L"The NOERR option is not supported yet!\n"); 126#if 0 127 bNoErr = TRUE; 128#endif 129 } 130 } 131 132 for (i = 1; i < argc; i++) 133 { 134 ConPrintf(StdOut, L"%s\n", argv[i]); 135 136 if (HasPrefix(argv[i], L"fs=", &pszSuffix)) 137 { 138 /* fs=<fs> */ 139 pszFileSystem = pszSuffix; 140 } 141 else if (HasPrefix(argv[i], L"revision=", &pszSuffix)) 142 { 143 /* revision=<X.XX> */ 144 ConPuts(StdOut, L"The REVISION option is not supported yet!\n"); 145 } 146 else if (HasPrefix(argv[i], L"label=", &pszSuffix)) 147 { 148 /* label=<"label"> */ 149 pszLabel = pszSuffix; 150 } 151 else if (HasPrefix(argv[i], L"unit=", &pszSuffix)) 152 { 153 /* unit=<N> */ 154 ulClusterSize = wcstoul(pszSuffix, NULL, 0); 155 if ((ulClusterSize == 0) && (errno == ERANGE)) 156 { 157 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 158 goto done; 159 } 160 } 161 else if (_wcsicmp(argv[i], L"recommended") == 0) 162 { 163 /* recommended */ 164 ConPuts(StdOut, L"The RECOMMENDED option is not supported yet!\n"); 165 } 166 else if (_wcsicmp(argv[i], L"quick") == 0) 167 { 168 /* quick */ 169 bQuickFormat = TRUE; 170 } 171 else if (_wcsicmp(argv[i], L"compress") == 0) 172 { 173 /* compress */ 174 ConPuts(StdOut, L"The COMPRESS option is not supported yet!\n"); 175 } 176 else if (_wcsicmp(argv[i], L"override") == 0) 177 { 178 /* override */ 179 ConPuts(StdOut, L"The OVERRIDE option is not supported yet!\n"); 180 } 181 else if (_wcsicmp(argv[i], L"duplicate") == 0) 182 { 183 /* duplicate */ 184 ConPuts(StdOut, L"The DUPLICATE option is not supported yet!\n"); 185 } 186 else if (_wcsicmp(argv[i], L"nowait") == 0) 187 { 188 /* nowait */ 189 ConPuts(StdOut, L"The NOWAIT option is not supported yet!\n"); 190 } 191 else if (_wcsicmp(argv[i], L"noerr") == 0) 192 { 193 /* noerr - Already handled above */ 194 } 195 else 196 { 197 ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS); 198 return EXIT_SUCCESS; 199 } 200 } 201 202 DPRINT("VolumeName : %S\n", CurrentVolume->VolumeName); 203 DPRINT("DeviceName : %S\n", CurrentVolume->DeviceName); 204 DPRINT("DriveLetter : %C\n", CurrentVolume->DriveLetter); 205#if 0 206 switch (CurrentVolume->VolumeType) 207 { 208 case VOLUME_TYPE_CDROM: 209 MediaType = FMIFS_REMOVABLE; // ??? 210 break; 211 212 case VOLUME_TYPE_PARTITION: 213 MediaType = FMIFS_HARDDISK; 214 break; 215 216 case VOLUME_TYPE_REMOVABLE: 217 MediaType = FMIFS_REMOVABLE; // ??? 218 break; 219 220 case VOLUME_TYPE_UNKNOWN: 221 default: 222 MediaType = FMIFS_REMOVABLE; // ??? 223 break; 224 } 225#endif 226 227 DPRINT("FileSystem: %S\n", pszFileSystem); 228 DPRINT("Label: %S\n", pszLabel); 229 DPRINT("Quick: %d\n", bQuickFormat); 230 DPRINT("ClusterSize: %lu\n", ulClusterSize); 231 232 RtlDosPathNameToNtPathName_U(CurrentVolume->VolumeName, &usDriveRoot, NULL, NULL); 233 234 /* Remove trailing backslash */ 235 if (usDriveRoot.Buffer[(usDriveRoot.Length / sizeof(WCHAR)) - 1] == L'\\') 236 { 237 usDriveRoot.Buffer[(usDriveRoot.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL; 238 usDriveRoot.Length -= sizeof(WCHAR); 239 } 240 241 DPRINT("DriveRoot: %wZ\n", &usDriveRoot); 242 243 /* Use the FAT filesystem as default */ 244 if (pszFileSystem == NULL) 245 pszFileSystem = L"FAT"; 246 247 BOOLEAN bBackwardCompatible = FALSE; // Default to latest FS versions. 248 if (_wcsicmp(pszFileSystem, L"FAT") == 0) 249 bBackwardCompatible = TRUE; 250 // else if (wcsicmp(pszFileSystem, L"FAT32") == 0) 251 // bBackwardCompatible = FALSE; 252 253 if (pszLabel == NULL) 254 pszLabel = L""; 255 256 RtlInitUnicodeString(&LabelString, pszLabel); 257 258 if (!GetFsModule(pszFileSystem, &hModule)) 259 { 260 DPRINT1("GetFsModule() failed\n"); 261 goto done; 262 } 263 264 pFormat = (PULIB_FORMAT)GetProcAddress(hModule, "Format"); 265 if (pFormat) 266 { 267 Success = (pFormat)(&usDriveRoot, 268 FormatCallback, 269 bQuickFormat, 270 bBackwardCompatible, 271 FMIFS_HARDDISK, //MediaType, 272 &LabelString, 273 ulClusterSize); 274 } 275 276done: 277 ConPuts(StdOut, L"\n"); 278 if (Success) 279 ConResPrintf(StdOut, IDS_FORMAT_SUCCESS); 280 else 281 ConResPrintf(StdOut, IDS_FORMAT_FAIL); 282 283 if (hModule) 284 FreeLibrary(hModule); 285 286 RtlFreeUnicodeString(&usDriveRoot); 287 288 return EXIT_SUCCESS; 289}