ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

format.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.