Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenformat.c
Go to the documentation of this file.
00001 // Copyright (c) 1998 Mark Russinovich 00002 // Systems Internals 00003 // http://www.sysinternals.com 00004 #include <stdio.h> 00005 #include <stdlib.h> 00006 #include <string.h> 00007 #include <windows.h> 00008 #include <winternl.h> 00009 #include <fmifs/fmifs.h> 00010 #include <tchar.h> 00011 #include "resource.h" 00012 00013 // Globals 00014 BOOL Error = FALSE; 00015 00016 // switches 00017 BOOL QuickFormat = FALSE; 00018 DWORD ClusterSize = 0; 00019 BOOL CompressDrive = FALSE; 00020 BOOL GotALabel = FALSE; 00021 LPTSTR Label = _T(""); 00022 LPTSTR Drive = NULL; 00023 LPTSTR Format = _T("FAT"); 00024 00025 TCHAR RootDirectory[MAX_PATH]; 00026 TCHAR LabelString[12]; 00027 00028 // 00029 // Size array 00030 // 00031 typedef struct { 00032 TCHAR SizeString[16]; 00033 DWORD ClusterSize; 00034 } SIZEDEFINITION, *PSIZEDEFINITION; 00035 00036 SIZEDEFINITION LegalSizes[] = { 00037 { _T("512"), 512 }, 00038 { _T("1024"), 1024 }, 00039 { _T("2048"), 2048 }, 00040 { _T("4096"), 4096 }, 00041 { _T("8192"), 8192 }, 00042 { _T("16K"), 16384 }, 00043 { _T("32K"), 32768 }, 00044 { _T("64K"), 65536 }, 00045 { _T("128K"), 65536 * 2 }, 00046 { _T("256K"), 65536 * 4 }, 00047 { _T(""), 0 }, 00048 }; 00049 00050 00051 int LoadStringAndOem(HINSTANCE hInst, 00052 UINT uID, 00053 LPTSTR szStr, 00054 int Siz 00055 ) 00056 { 00057 TCHAR szTmp[RC_STRING_MAX_SIZE]; 00058 int res = LoadString(hInst, uID, szTmp, sizeof(szTmp)); 00059 CharToOem(szTmp, szStr); 00060 return(res); 00061 } 00062 00063 00064 //---------------------------------------------------------------------- 00065 // 00066 // PrintWin32Error 00067 // 00068 // Takes the win32 error code and prints the text version. 00069 // 00070 //---------------------------------------------------------------------- 00071 static VOID PrintWin32Error( LPTSTR Message, DWORD ErrorCode ) 00072 { 00073 LPTSTR lpMsgBuf; 00074 00075 FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 00076 NULL, ErrorCode, 00077 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00078 (LPTSTR)&lpMsgBuf, 0, NULL ); 00079 00080 _tprintf(_T("%s: %s\n"), Message, lpMsgBuf ); 00081 LocalFree( lpMsgBuf ); 00082 } 00083 00084 00085 //---------------------------------------------------------------------- 00086 // 00087 // ParseCommandLine 00088 // 00089 // Get the switches. 00090 // 00091 //---------------------------------------------------------------------- 00092 static int ParseCommandLine( int argc, TCHAR *argv[] ) 00093 { 00094 int i, j; 00095 BOOLEAN gotFormat = FALSE; 00096 BOOLEAN gotQuick = FALSE; 00097 BOOLEAN gotSize = FALSE; 00098 BOOLEAN gotLabel = FALSE; 00099 BOOLEAN gotCompressed = FALSE; 00100 00101 00102 for( i = 1; i < argc; i++ ) { 00103 00104 switch( argv[i][0] ) { 00105 00106 case '-': 00107 case '/': 00108 00109 if( !_tcsnicmp( &argv[i][1], _T("FS:"), 3 )) { 00110 00111 if( gotFormat) return -1; 00112 Format = &argv[i][4]; 00113 gotFormat = TRUE; 00114 00115 00116 } else if( !_tcsnicmp( &argv[i][1], _T("A:"), 2 )) { 00117 00118 if( gotSize ) return -1; 00119 j = 0; 00120 while( LegalSizes[j].ClusterSize && 00121 _tcsicmp( LegalSizes[j].SizeString, &argv[i][3] )) j++; 00122 00123 if( !LegalSizes[j].ClusterSize ) return i; 00124 ClusterSize = LegalSizes[j].ClusterSize; 00125 gotSize = TRUE; 00126 00127 } else if( ! _tcsnicmp( &argv[i][1], _T("V:"), 2 )) { 00128 00129 if( gotLabel ) return -1; 00130 Label = &argv[i][3]; 00131 gotLabel = TRUE; 00132 GotALabel = TRUE; 00133 00134 } else if( !_tcsicmp( &argv[i][1], _T("Q") )) { 00135 00136 if( gotQuick ) return -1; 00137 QuickFormat = TRUE; 00138 gotQuick = TRUE; 00139 00140 } else if( !_tcsicmp( &argv[i][1], _T("C") )) { 00141 00142 if( gotCompressed ) return -1; 00143 CompressDrive = TRUE; 00144 gotCompressed = TRUE; 00145 00146 } else return i; 00147 break; 00148 00149 default: 00150 00151 if( Drive ) return i; 00152 if( argv[i][1] != _T(':') ) return i; 00153 00154 Drive = argv[i]; 00155 break; 00156 } 00157 } 00158 return 0; 00159 } 00160 00161 //---------------------------------------------------------------------- 00162 // 00163 // FormatExCallback 00164 // 00165 // The file system library will call us back with commands that we 00166 // can interpret. If we wanted to halt the chkdsk we could return FALSE. 00167 // 00168 //---------------------------------------------------------------------- 00169 BOOLEAN WINAPI 00170 FormatExCallback ( 00171 CALLBACKCOMMAND Command, 00172 ULONG Modifier, 00173 PVOID Argument) 00174 { 00175 PDWORD percent; 00176 PTEXTOUTPUT output; 00177 PBOOLEAN status; 00178 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00179 00180 // 00181 // We get other types of commands, but we don't have to pay attention to them 00182 // 00183 switch( Command ) { 00184 00185 case PROGRESS: 00186 percent = (PDWORD) Argument; 00187 LoadStringAndOem( GetModuleHandle(NULL), STRING_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00188 _tprintf(szMsg, *percent); 00189 break; 00190 00191 case OUTPUT: 00192 output = (PTEXTOUTPUT) Argument; 00193 fprintf(stdout, "%s", output->Output); 00194 break; 00195 00196 case DONE: 00197 status = (PBOOLEAN) Argument; 00198 if( *status == FALSE ) { 00199 00200 LoadStringAndOem( GetModuleHandle(NULL), STRING_FORMAT_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00201 _tprintf("%s", szMsg); 00202 Error = TRUE; 00203 } 00204 break; 00205 case DONEWITHSTRUCTURE: 00206 case UNKNOWN2: 00207 case UNKNOWN3: 00208 case UNKNOWN4: 00209 case UNKNOWN5: 00210 case INSUFFICIENTRIGHTS: 00211 case FSNOTSUPPORTED: 00212 case VOLUMEINUSE: 00213 case UNKNOWN9: 00214 case UNKNOWNA: 00215 case UNKNOWNC: 00216 case UNKNOWND: 00217 case STRUCTUREPROGRESS: 00218 case CLUSTERSIZETOOSMALL: 00219 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_SUPPORT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00220 _tprintf("%s", szMsg); 00221 return FALSE; 00222 } 00223 return TRUE; 00224 } 00225 00226 00227 //---------------------------------------------------------------------- 00228 // 00229 // LoadFMIFSEntryPoints 00230 // 00231 // Loads FMIFS.DLL and locates the entry point(s) we are going to use 00232 // 00233 //---------------------------------------------------------------------- 00234 BOOLEAN LoadFMIFSEntryPoints() 00235 { 00236 HMODULE hFmifs = LoadLibrary( _T("fmifs.dll") ); 00237 if( !(void*) GetProcAddress( hFmifs, "FormatEx" ) ) { 00238 00239 return FALSE; 00240 } 00241 00242 if( !((void *) GetProcAddress( hFmifs, 00243 "EnableVolumeCompression" )) ) { 00244 00245 return FALSE; 00246 } 00247 00248 if( !((void *) GetProcAddress( hFmifs, 00249 "QueryAvailableFileSystemFormat" )) ) { 00250 00251 return FALSE; 00252 } 00253 00254 return TRUE; 00255 } 00256 00257 00258 //---------------------------------------------------------------------- 00259 // 00260 // Usage 00261 // 00262 // Tell the user how to use the program 00263 // 00264 //---------------------------------------------------------------------- 00265 static VOID Usage( LPTSTR ProgramName ) 00266 { 00267 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00268 TCHAR szFormats[MAX_PATH]; 00269 #ifndef UNICODE 00270 TCHAR szFormatA[MAX_PATH]; 00271 #endif 00272 WCHAR szFormatW[MAX_PATH]; 00273 DWORD Index = 0; 00274 BYTE dummy; 00275 BOOLEAN lastestVersion; 00276 00277 LoadStringAndOem( GetModuleHandle(NULL), STRING_HELP, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00278 if (!LoadFMIFSEntryPoints()) 00279 { 00280 _tprintf(szMsg, ProgramName, _T("")); 00281 return; 00282 } 00283 00284 szFormats[0] = 0; 00285 while (QueryAvailableFileSystemFormat(Index++, szFormatW, &dummy, &dummy, &lastestVersion)) 00286 { 00287 if (!lastestVersion) 00288 continue; 00289 if (szFormats[0]) 00290 _tcscat(szFormats, _T(", ")); 00291 #ifdef UNICODE 00292 _tcscat(szFormats, szFormatW); 00293 #else 00294 if (0 != WideCharToMultiByte(CP_ACP, 0, szFormatW, -1, szFormatA, sizeof(szFormatA), NULL, NULL)) 00295 _tcscat(szFormats, szFormatA); 00296 #endif 00297 } 00298 _tprintf(szMsg, ProgramName, szFormats); 00299 } 00300 00301 00302 //---------------------------------------------------------------------- 00303 // 00304 // WMain 00305 // 00306 // Engine. Just get command line switches and fire off a format. This 00307 // could also be done in a GUI like Explorer does when you select a 00308 // drive and run a check on it. 00309 // 00310 // We do this in UNICODE because the chkdsk command expects PWCHAR 00311 // arguments. 00312 // 00313 //---------------------------------------------------------------------- 00314 int 00315 _tmain(int argc, TCHAR *argv[]) 00316 { 00317 int badArg; 00318 DWORD media = FMIFS_HARDDISK; 00319 DWORD driveType; 00320 TCHAR fileSystem[1024]; 00321 TCHAR volumeName[1024]; 00322 TCHAR input[1024]; 00323 DWORD serialNumber; 00324 DWORD flags, maxComponent; 00325 ULARGE_INTEGER freeBytesAvailableToCaller, totalNumberOfBytes, totalNumberOfFreeBytes; 00326 #ifndef UNICODE 00327 WCHAR RootDirectoryW[MAX_PATH], FormatW[MAX_PATH], LabelW[MAX_PATH]; 00328 #endif 00329 TCHAR szMsg[RC_STRING_MAX_SIZE]; 00330 00331 // 00332 // Get function pointers 00333 // 00334 if( !LoadFMIFSEntryPoints()) { 00335 LoadStringAndOem( GetModuleHandle(NULL), STRING_FMIFS_FAIL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00336 _tprintf("%s", szMsg); 00337 return -1; 00338 } 00339 00340 // 00341 // Parse command line 00342 // 00343 if( (badArg = ParseCommandLine( argc, argv ))) { 00344 00345 LoadStringAndOem( GetModuleHandle(NULL), STRING_UNKNOW_ARG, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00346 _tprintf(szMsg, argv[badArg] ); 00347 00348 Usage(argv[0]); 00349 return -1; 00350 } 00351 00352 // 00353 // Get the drive's format 00354 // 00355 if( !Drive ) { 00356 00357 LoadStringAndOem( GetModuleHandle(NULL), STRING_DRIVE_PARM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00358 _tprintf(szMsg); 00359 Usage( argv[0] ); 00360 return -1; 00361 00362 } else { 00363 00364 _tcscpy( RootDirectory, Drive ); 00365 } 00366 RootDirectory[2] = _T('\\'); 00367 RootDirectory[3] = _T('\0'); 00368 00369 // 00370 // See if the drive is removable or not 00371 // 00372 driveType = GetDriveType( RootDirectory ); 00373 00374 if( driveType == 0 ) { 00375 LoadStringAndOem( GetModuleHandle(NULL), STRING_ERROR_DRIVE_TYPE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00376 PrintWin32Error( szMsg, GetLastError()); 00377 return -1; 00378 } 00379 else if ( driveType == 1 ) 00380 { 00381 LoadString( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00382 PrintWin32Error( szMsg, GetLastError()); 00383 return -1; 00384 } 00385 00386 if( driveType != DRIVE_FIXED ) { 00387 LoadStringAndOem( GetModuleHandle(NULL), STRING_INSERT_DISK, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00388 _tprintf(szMsg, RootDirectory[0] ); 00389 _fgetts( input, sizeof(input)/2, stdin ); 00390 00391 media = FMIFS_FLOPPY; 00392 } 00393 00394 // 00395 // Determine the drive's file system format 00396 // 00397 if( !GetVolumeInformation( RootDirectory, 00398 volumeName, sizeof(volumeName)/2, 00399 &serialNumber, &maxComponent, &flags, 00400 fileSystem, sizeof(fileSystem)/2)) { 00401 00402 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00403 PrintWin32Error( szMsg, GetLastError()); 00404 return -1; 00405 } 00406 00407 if( !GetDiskFreeSpaceEx( RootDirectory, 00408 &freeBytesAvailableToCaller, 00409 &totalNumberOfBytes, 00410 &totalNumberOfFreeBytes )) { 00411 00412 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00413 PrintWin32Error( szMsg, GetLastError()); 00414 return -1; 00415 } 00416 LoadStringAndOem( GetModuleHandle(NULL), STRING_FILESYSTEM, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00417 _tprintf(szMsg, fileSystem ); 00418 00419 // 00420 // Make sure they want to do this 00421 // 00422 if( driveType == DRIVE_FIXED ) { 00423 00424 if( volumeName[0] ) { 00425 00426 while(1 ) { 00427 00428 LoadStringAndOem( GetModuleHandle(NULL), STRING_LABEL_NAME_EDIT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00429 _tprintf(szMsg, RootDirectory[0] ); 00430 _fgetts( input, sizeof(input)/2, stdin ); 00431 input[ _tcslen( input ) - 1] = 0; 00432 00433 if( !_tcsicmp( input, volumeName )) { 00434 00435 break; 00436 } 00437 LoadStringAndOem( GetModuleHandle(NULL), STRING_ERROR_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00438 _tprintf("%s", szMsg); 00439 } 00440 } 00441 00442 LoadStringAndOem( GetModuleHandle(NULL), STRING_YN_FORMAT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00443 _tprintf(szMsg, RootDirectory[0] ); 00444 00445 LoadStringAndOem( GetModuleHandle(NULL), STRING_YES_NO_FAQ, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00446 00447 while( 1 ) { 00448 _fgetts( input, sizeof(input)/2, stdin ); 00449 if(_strnicmp(&input[0],&szMsg[0],1) == 0) break; 00450 if(_strnicmp(&input[0],&szMsg[1],1) == 0) { 00451 _tprintf(_T("\n")); 00452 return 0; 00453 } 00454 } 00455 media = FMIFS_HARDDISK; 00456 } 00457 00458 // 00459 // Tell the user we're doing a long format if appropriate 00460 // 00461 if( !QuickFormat ) { 00462 00463 LoadString( GetModuleHandle(NULL), STRING_VERIFYING, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00464 00465 if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) { 00466 00467 _tprintf(_T("%s %luM\n"),szMsg, (DWORD) (totalNumberOfBytes.QuadPart/(1024*1024))); 00468 00469 } else { 00470 00471 _tprintf(_T("%s %.1fM\n"),szMsg, 00472 ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); 00473 } 00474 } else { 00475 00476 LoadStringAndOem( GetModuleHandle(NULL), STRING_FAST_FMT, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00477 if( totalNumberOfBytes.QuadPart > 1024*1024*10 ) { 00478 00479 _tprintf(_T("%s %luM\n"),szMsg, (DWORD) (totalNumberOfBytes.QuadPart/(1024*1024))); 00480 00481 } else { 00482 00483 _tprintf(_T("%s %.2fM\n"),szMsg, 00484 ((float)(LONGLONG)totalNumberOfBytes.QuadPart)/(float)(1024.0*1024.0)); 00485 } 00486 LoadStringAndOem( GetModuleHandle(NULL), STRING_CREATE_FSYS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00487 _tprintf("%s", szMsg); 00488 } 00489 00490 // 00491 // Format away! 00492 // 00493 #ifndef UNICODE 00494 MultiByteToWideChar(CP_ACP, 0, RootDirectory, -1, RootDirectoryW, MAX_PATH); 00495 MultiByteToWideChar(CP_ACP, 0, Format, -1, FormatW, MAX_PATH); 00496 MultiByteToWideChar(CP_ACP, 0, Label, -1, LabelW, MAX_PATH); 00497 FormatEx( RootDirectoryW, media, FormatW, LabelW, QuickFormat, 00498 ClusterSize, FormatExCallback ); 00499 #else 00500 FormatEx( RootDirectory, media, Format, Label, QuickFormat, 00501 ClusterSize, FormatExCallback ); 00502 #endif 00503 if( Error ) return -1; 00504 LoadStringAndOem( GetModuleHandle(NULL), STRING_FMT_COMPLETE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00505 _tprintf("%s", szMsg); 00506 00507 // 00508 // Enable compression if desired 00509 // 00510 if( CompressDrive ) { 00511 00512 #ifndef UNICODE 00513 MultiByteToWideChar(CP_ACP, 0, RootDirectory, -1, RootDirectoryW, MAX_PATH); 00514 if( !EnableVolumeCompression( RootDirectoryW, TRUE )) { 00515 #else 00516 if( !EnableVolumeCompression( RootDirectory, TRUE )) { 00517 #endif 00518 00519 LoadStringAndOem( GetModuleHandle(NULL), STRING_VOL_COMPRESS, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00520 _tprintf("%s", szMsg); 00521 } 00522 } 00523 00524 // 00525 // Get the label if we don't have it 00526 // 00527 if( !GotALabel ) { 00528 00529 LoadString( GetModuleHandle(NULL), STRING_ENTER_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00530 _tprintf("%s", szMsg); 00531 _fgetts( input, sizeof(LabelString)/2, stdin ); 00532 00533 input[ _tcslen(input)-1] = 0; 00534 if( !SetVolumeLabel( RootDirectory, input )) { 00535 00536 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_LABEL, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00537 PrintWin32Error(szMsg, GetLastError()); 00538 return -1; 00539 } 00540 } 00541 00542 if( !GetVolumeInformation( RootDirectory, 00543 volumeName, sizeof(volumeName)/2, 00544 &serialNumber, &maxComponent, &flags, 00545 fileSystem, sizeof(fileSystem)/2)) { 00546 00547 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00548 PrintWin32Error( szMsg, GetLastError()); 00549 return -1; 00550 } 00551 00552 // 00553 // Print out some stuff including the formatted size 00554 // 00555 if( !GetDiskFreeSpaceEx( RootDirectory, 00556 &freeBytesAvailableToCaller, 00557 &totalNumberOfBytes, 00558 &totalNumberOfFreeBytes )) { 00559 00560 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME_SIZE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00561 PrintWin32Error(szMsg, GetLastError()); 00562 return -1; 00563 } 00564 00565 LoadStringAndOem( GetModuleHandle(NULL), STRING_FREE_SPACE, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00566 _tprintf(szMsg, totalNumberOfBytes.QuadPart, totalNumberOfFreeBytes.QuadPart ); 00567 00568 // 00569 // Get the drive's serial number 00570 // 00571 if( !GetVolumeInformation( RootDirectory, 00572 volumeName, sizeof(volumeName)/2, 00573 &serialNumber, &maxComponent, &flags, 00574 fileSystem, sizeof(fileSystem)/2)) { 00575 00576 LoadStringAndOem( GetModuleHandle(NULL), STRING_NO_VOLUME, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00577 PrintWin32Error( szMsg, GetLastError()); 00578 return -1; 00579 } 00580 LoadStringAndOem( GetModuleHandle(NULL), STRING_SERIAL_NUMBER, (LPTSTR) szMsg,RC_STRING_MAX_SIZE); 00581 _tprintf(szMsg, (unsigned int)(serialNumber >> 16), 00582 (unsigned int)(serialNumber & 0xFFFF) ); 00583 00584 return 0; 00585 } 00586 Generated on Mon May 28 2012 04:17:50 for ReactOS by
1.7.6.1
|