1 //======================================================================
7 // Copyright (c) 1998 Mark Russinovich
9 // http://www.sysinternals.com/
11 // --------------------------------------------------------------------
13 // This software is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Library General Public License as
15 // published by the Free Software Foundation; either version 2 of the
16 // License, or (at your option) any later version.
18 // This software is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Library General Public License for more details.
23 // You should have received a copy of the GNU Library General Public
24 // License along with this software; see the file COPYING.LIB. If
25 // not, write to the Free Software Foundation, Inc., 675 Mass Ave,
26 // Cambridge, MA 02139, USA.
28 // --------------------------------------------------------------------
30 // Chkdsk clone that demonstrates the use of the FMIFS file system
33 // 1999 February (Emanuele Aliberti)
34 // Adapted for ReactOS and lcc-win32.
36 // 1999 April (Emanuele Aliberti)
37 // Adapted for ReactOS and egcs.
39 // 2008 July (Aleksey Bragin)
40 // Cleanup, use ReactOS's fmifs.h
42 //======================================================================
43 #define WIN32_NO_STATUS
44 #define NTOS_MODE_USER
47 #include <ndk/ntndk.h>
48 #include <fmifs/fmifs.h>
60 BOOL FixErrors
= FALSE
;
61 BOOL SkipClean
= FALSE
;
62 BOOL ScanSectors
= FALSE
;
65 WCHAR CurrentDirectory
[1024];
67 #ifndef FMIFS_IMPORT_DLL
72 #endif /* ndef FMIFS_IMPORT_DLL */
75 //--------------------------------------------------------------------
79 // Intercepts Ctrl-C's so that the program can't be quit with the
80 // disk in an inconsistent state.
82 //--------------------------------------------------------------------
85 CtrlCIntercept( DWORD dwCtrlType
)
88 // Handle the event so that the default handler doesn't
94 //----------------------------------------------------------------------
98 // Tell the user how to use the program
100 // 19990216 EA Missing printf %s argument
101 //----------------------------------------------------------------------
103 Usage( PWCHAR ProgramName
)
107 Usage: %s [drive:] [-F] [-V] [-R] [-C]\n\n\
108 [drive:] Specifies the drive to check.\n\
109 -F Fixes errors on the disk.\n\
110 -V Displays the full path of every file on the disk.\n\
111 -R Locates bad sectors and recovers readable information.\n\
112 -C Checks the drive only if it is dirty.\n\n",
118 //----------------------------------------------------------------------
124 //----------------------------------------------------------------------
132 BOOLEAN gotFix
= FALSE
;
133 BOOLEAN gotVerbose
= FALSE
;
134 BOOLEAN gotClean
= FALSE
;
135 /*BOOLEAN gotScan = FALSE;*/
152 if( gotFix
) return i
;
160 if( gotVerbose
) return i
;
168 if( gotFix
) return i
;
176 if( gotClean
) return i
;
188 if( Drive
) return i
;
189 if( argv
[i
][1] != L
':' ) return i
;
199 //----------------------------------------------------------------------
203 // The file system library will call us back with commands that we
204 // can interpret. If we wanted to halt the chkdsk we could return FALSE.
206 //----------------------------------------------------------------------
210 CALLBACKCOMMAND Command
,
220 // We get other types of commands,
221 // but we don't have to pay attention to them
226 wprintf(L
"UNKNOWN2\r");
230 wprintf(L
"UNKNOWN3\r");
234 wprintf(L
"UNKNOWN4\r");
238 wprintf(L
"UNKNOWN5\r");
242 wprintf(L
"FSNOTSUPPORTED\r");
246 wprintf(L
"VOLUMEINUSE\r");
250 wprintf(L
"UNKNOWN9\r");
254 wprintf(L
"UNKNOWNA\r");
258 wprintf(L
"UNKNOWNC\r");
262 wprintf(L
"UNKNOWND\r");
265 case INSUFFICIENTRIGHTS
:
266 wprintf(L
"INSUFFICIENTRIGHTS\r");
269 case STRUCTUREPROGRESS
:
270 wprintf(L
"STRUCTUREPROGRESS\r");
273 case DONEWITHSTRUCTURE
:
274 wprintf(L
"DONEWITHSTRUCTURE\r");
277 case CLUSTERSIZETOOSMALL
:
278 wprintf(L
"CLUSTERSIZETOOSMALL\r");
282 percent
= (PDWORD
) Argument
;
283 wprintf(L
"%d percent completed.\r", *percent
);
287 output
= (PTEXTOUTPUT
) Argument
;
288 fwprintf(stdout
, L
"%s", output
->Output
);
292 status
= (PBOOLEAN
) Argument
;
293 if ( *status
== TRUE
)
295 wprintf(L
"Chkdsk was unable to complete successfully.\n\n");
303 #ifndef FMIFS_IMPORT_DLL
304 //----------------------------------------------------------------------
306 // LoadFMIFSEntryPoints
308 // Loads FMIFS.DLL and locates the entry point(s) we are going to use
310 // 19990216 EA Used wide functions
312 //----------------------------------------------------------------------
314 LoadFMIFSEntryPoints(VOID
)
316 LoadLibraryW( L
"fmifs.dll" );
319 (void *) GetProcAddress(
320 GetModuleHandleW(L
"fmifs.dll"),
328 #endif /* ndef FMIFS_IMPORT_DLL */
331 //----------------------------------------------------------------------
335 // Engine. Just get command line switches and fire off a chkdsk. This
336 // could also be done in a GUI like Explorer does when you select a
337 // drive and run a check on it.
339 // We do this in UNICODE because the chkdsk command expects PWCHAR
342 //----------------------------------------------------------------------
344 wmain( int argc
, WCHAR
*argv
[] )
348 WCHAR fileSystem
[1024];
349 WCHAR volumeName
[1024];
356 Chkdskx v1.0.1 by Mark Russinovich\n\
357 Systems Internals - http://www.sysinternals.com/\n\
358 ReactOS adaptation 1999 by Emanuele Aliberti\n\n"
360 #ifndef FMIFS_IMPORT_DLL
362 // Get function pointers
364 if( !LoadFMIFSEntryPoints())
366 wprintf(L
"Could not located FMIFS entry points.\n\n");
369 #endif /* ndef FMIFS_IMPORT_DLL */
371 // Parse command line
373 if( (badArg
= ParseCommandLine( argc
, argv
)))
376 L
"Unknown argument: %s\n",
385 // Get the drive's format
389 if( !GetCurrentDirectoryW(
390 sizeof(CurrentDirectory
),
396 L
"Could not get current directory",
404 wcscpy( CurrentDirectory
, Drive
);
406 CurrentDirectory
[2] = L
'\\';
407 CurrentDirectory
[3] = L
'\0';
408 Drive
= CurrentDirectory
;
411 // Determine the drive's file system format, which we need to
414 if( !GetVolumeInformationW(
426 L
"Could not query volume",
433 // If they want to fix, we need to have access to the drive
442 volumeHandle
= CreateFileW(
451 if( volumeHandle
== INVALID_HANDLE_VALUE
)
453 wprintf(L
"Chdskx cannot run because the volume is in use by another process.\n\n");
456 CloseHandle( volumeHandle
);
459 // Can't let the user break out of a chkdsk that can modify the drive
461 SetConsoleCtrlHandler( CtrlCIntercept
, TRUE
);
468 L
"The type of file system is %s.\n",
483 if ( Error
) return -1;