- Integrate chkdsk into our build system.
- Whitespace fixes.

svn path=/trunk/; revision=70868
This commit is contained in:
Hermès Bélusca-Maïto 2016-03-02 22:05:19 +00:00
parent 4dc68af961
commit 9723b5e974
3 changed files with 310 additions and 314 deletions

View file

@ -1,7 +1,7 @@
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/fmifs)
add_executable(chkdsk chkdsk.c chkdsk.rc) add_executable(chkdsk chkdsk.c chkdsk.rc)
include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/fmifs)
set_module_type(chkdsk win32cui UNICODE) set_module_type(chkdsk win32cui UNICODE)
target_link_libraries(chkdsk win32err)
add_importlibs(chkdsk fmifs msvcrt kernel32 ntdll) add_importlibs(chkdsk fmifs msvcrt kernel32 ntdll)
add_cd_file(TARGET chkdsk DESTINATION reactos/system32 FOR all) add_cd_file(TARGET chkdsk DESTINATION reactos/system32 FOR all)

View file

@ -3,8 +3,11 @@
// Chkdskx // Chkdskx
// //
// Copyright (c) 1998 Mark Russinovich // Copyright (c) 1998 Mark Russinovich
// Systems Internals // Systems Internals
// http://www.sysinternals.com/ // http://www.sysinternals.com/
//
// Chkdsk clone that demonstrates the use of the FMIFS file system
// utility library.
// //
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// //
@ -25,51 +28,71 @@
// //
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// //
// Chkdsk clone that demonstrates the use of the FMIFS file system
// utility library.
//
// 1999 February (Emanuele Aliberti) // 1999 February (Emanuele Aliberti)
// Adapted for ReactOS and lcc-win32. // Adapted for ReactOS and lcc-win32.
// //
// 1999 April (Emanuele Aliberti) // 1999 April (Emanuele Aliberti)
// Adapted for ReactOS and egcs. // Adapted for ReactOS and egcs.
// //
// 2008 July (Aleksey Bragin) // 2008 July (Aleksey Bragin)
// Cleanup, use ReactOS's fmifs.h // Cleanup, use ReactOS's fmifs.h
// //
//====================================================================== //======================================================================
#define WIN32_NO_STATUS
#define NTOS_MODE_USER
#include <windows.h>
#include <stdio.h> #include <stdio.h>
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/ntndk.h> #include <ndk/ntndk.h>
#include <fmifs/fmifs.h> #include <fmifs/fmifs.h>
#define _UNICODE 1
#include <tchar.h> #define FMIFS_IMPORT_DLL
#include "../config.h"
#include "../win32err.h"
// //
// Globals // Globals
// //
BOOL Error = FALSE; BOOL Error = FALSE;
// switches // switches
BOOL FixErrors = FALSE; BOOL FixErrors = FALSE;
BOOL SkipClean = FALSE; BOOL SkipClean = FALSE;
BOOL ScanSectors = FALSE; BOOL ScanSectors = FALSE;
BOOL Verbose = FALSE; BOOL Verbose = FALSE;
PWCHAR Drive = NULL; PWCHAR Drive = NULL;
WCHAR CurrentDirectory[1024]; WCHAR CurrentDirectory[1024];
#ifndef FMIFS_IMPORT_DLL #ifndef FMIFS_IMPORT_DLL
// //
// FMIFS function // FMIFS function
// //
//PCHKDSK Chkdsk; // PCHKDSK Chkdsk;
#endif /* ndef FMIFS_IMPORT_DLL */ #endif /* ndef FMIFS_IMPORT_DLL */
//----------------------------------------------------------------------
//
// PrintWin32Error
//
// Takes the win32 error code and prints the text version.
//
//----------------------------------------------------------------------
static VOID PrintWin32Error(LPWSTR Message, DWORD ErrorCode)
{
LPWSTR lpMsgBuf;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&lpMsgBuf, 0, NULL);
wprintf(L"%s: %s\n", Message, lpMsgBuf);
LocalFree(lpMsgBuf);
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// //
// CtrlCIntercept // CtrlCIntercept
@ -80,12 +103,12 @@ WCHAR CurrentDirectory[1024];
//-------------------------------------------------------------------- //--------------------------------------------------------------------
BOOL BOOL
WINAPI WINAPI
CtrlCIntercept( DWORD dwCtrlType ) CtrlCIntercept(DWORD dwCtrlType)
{ {
// //
// Handle the event so that the default handler doesn't // Handle the event so that the default handler doesn't
// //
return TRUE; return TRUE;
} }
@ -98,18 +121,15 @@ CtrlCIntercept( DWORD dwCtrlType )
// 19990216 EA Missing printf %s argument // 19990216 EA Missing printf %s argument
//---------------------------------------------------------------------- //----------------------------------------------------------------------
VOID VOID
Usage( PWCHAR ProgramName ) Usage(PWCHAR ProgramName)
{ {
_tprintf( wprintf(L"Usage: %s [drive:] [-F] [-V] [-R] [-C]\n\n"
L"\ L"[drive:] Specifies the drive to check.\n"
Usage: %s [drive:] [-F] [-V] [-R] [-C]\n\n\ L"-F Fixes errors on the disk.\n"
[drive:] Specifies the drive to check.\n\ L"-V Displays the full path of every file on the disk.\n"
-F Fixes errors on the disk.\n\ L"-R Locates bad sectors and recovers readable information.\n"
-V Displays the full path of every file on the disk.\n\ L"-C Checks the drive only if it is dirty.\n\n",
-R Locates bad sectors and recovers readable information.\n\ ProgramName);
-C Checks the drive only if it is dirty.\n\n",
ProgramName
);
} }
@ -122,75 +142,76 @@ Usage: %s [drive:] [-F] [-V] [-R] [-C]\n\n\
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int int
ParseCommandLine( ParseCommandLine(
int argc, int argc,
WCHAR *argv [] WCHAR *argv[]
) )
{ {
int i; int i;
BOOLEAN gotFix = FALSE; BOOLEAN gotFix = FALSE;
BOOLEAN gotVerbose = FALSE; BOOLEAN gotVerbose = FALSE;
BOOLEAN gotClean = FALSE; BOOLEAN gotClean = FALSE;
/*BOOLEAN gotScan = FALSE;*/ // BOOLEAN gotScan = FALSE;
for (i = 1; i < argc; i++)
{
switch (argv[i][0])
{
case L'-': case L'/':
for ( i = 1; switch (argv[i][1])
(i < argc); {
i++ case L'?':
) { Usage(argv[0]);
switch( argv[i][0] ) break;
{
case L'-':
case L'/':
switch( argv[i][1] ) case L'F': case L'f':
{ {
case L'F': if (gotFix) return i;
case L'f': FixErrors = TRUE;
gotFix = TRUE;
break;
}
if( gotFix ) return i; case L'V': case L'v':
FixErrors = TRUE; {
gotFix = TRUE; if (gotVerbose) return i;
break; Verbose = TRUE;
gotVerbose = TRUE;
break;
}
case L'V': case L'R': case L'r':
case L'v': {
if (gotFix) return i;
ScanSectors = TRUE;
gotFix = TRUE;
break;
}
if( gotVerbose) return i; case L'C': case L'c':
Verbose = TRUE; {
gotVerbose = TRUE; if (gotClean) return i;
break; SkipClean = TRUE;
gotClean = TRUE;
break;
}
case L'R': default:
case L'r': return i;
}
break;
if( gotFix ) return i; default:
ScanSectors = TRUE; {
gotFix = TRUE; if (Drive) return i;
break; if (argv[i][1] != L':') return i;
case L'C': Drive = argv[i];
case L'c': break;
}
if( gotClean ) return i; }
SkipClean = TRUE; }
gotClean = TRUE; return 0;
break;
default:
return i;
}
break;
default:
if( Drive ) return i;
if( argv[i][1] != L':' ) return i;
Drive = argv[i];
break;
}
}
return 0;
} }
@ -205,97 +226,97 @@ ParseCommandLine(
BOOLEAN BOOLEAN
WINAPI WINAPI
ChkdskCallback( ChkdskCallback(
CALLBACKCOMMAND Command, CALLBACKCOMMAND Command,
DWORD Modifier, DWORD Modifier,
PVOID Argument PVOID Argument
) )
{ {
PDWORD percent; PDWORD percent;
PBOOLEAN status; PBOOLEAN status;
PTEXTOUTPUT output; PTEXTOUTPUT output;
// //
// We get other types of commands, // We get other types of commands,
// but we don't have to pay attention to them // but we don't have to pay attention to them
// //
switch( Command ) switch (Command)
{ {
case UNKNOWN2: case UNKNOWN2:
wprintf(L"UNKNOWN2\r"); wprintf(L"UNKNOWN2\r");
break; break;
case UNKNOWN3: case UNKNOWN3:
wprintf(L"UNKNOWN3\r"); wprintf(L"UNKNOWN3\n");
break; break;
case UNKNOWN4: case UNKNOWN4:
wprintf(L"UNKNOWN4\r"); wprintf(L"UNKNOWN4\n");
break; break;
case UNKNOWN5: case UNKNOWN5:
wprintf(L"UNKNOWN5\r"); wprintf(L"UNKNOWN5\n");
break; break;
case FSNOTSUPPORTED: case FSNOTSUPPORTED:
wprintf(L"FSNOTSUPPORTED\r"); wprintf(L"FSNOTSUPPORTED\n");
break; break;
case VOLUMEINUSE: case VOLUMEINUSE:
wprintf(L"VOLUMEINUSE\r"); wprintf(L"VOLUMEINUSE\n");
break; break;
case UNKNOWN9: case UNKNOWN9:
wprintf(L"UNKNOWN9\r"); wprintf(L"UNKNOWN9\n");
break; break;
case UNKNOWNA: case UNKNOWNA:
wprintf(L"UNKNOWNA\r"); wprintf(L"UNKNOWNA\n");
break; break;
case UNKNOWNC: case UNKNOWNC:
wprintf(L"UNKNOWNC\r"); wprintf(L"UNKNOWNC\n");
break; break;
case UNKNOWND: case UNKNOWND:
wprintf(L"UNKNOWND\r"); wprintf(L"UNKNOWND\n");
break; break;
case INSUFFICIENTRIGHTS: case INSUFFICIENTRIGHTS:
wprintf(L"INSUFFICIENTRIGHTS\r"); wprintf(L"INSUFFICIENTRIGHTS\n");
break; break;
case STRUCTUREPROGRESS: case STRUCTUREPROGRESS:
wprintf(L"STRUCTUREPROGRESS\r"); wprintf(L"STRUCTUREPROGRESS\n");
break; break;
case DONEWITHSTRUCTURE: case DONEWITHSTRUCTURE:
wprintf(L"DONEWITHSTRUCTURE\r"); wprintf(L"DONEWITHSTRUCTURE\n");
break; break;
case CLUSTERSIZETOOSMALL: case CLUSTERSIZETOOSMALL:
wprintf(L"CLUSTERSIZETOOSMALL\r"); wprintf(L"CLUSTERSIZETOOSMALL\n");
break; break;
case PROGRESS: case PROGRESS:
percent = (PDWORD) Argument; percent = (PDWORD)Argument;
wprintf(L"%d percent completed.\r", *percent); wprintf(L"%d percent completed.\r", *percent);
break; break;
case OUTPUT: case OUTPUT:
output = (PTEXTOUTPUT) Argument; output = (PTEXTOUTPUT)Argument;
fwprintf(stdout, L"%s", output->Output); wprintf(L"%S", output->Output);
break; break;
case DONE: case DONE:
status = (PBOOLEAN) Argument; status = (PBOOLEAN)Argument;
if ( *status == TRUE ) if (*status == TRUE)
{ {
wprintf(L"Chkdsk was unable to complete successfully.\n\n"); wprintf(L"Chkdsk was unable to complete successfully.\n\n");
Error = TRUE; Error = TRUE;
} }
break; break;
} }
return TRUE; return TRUE;
} }
#ifndef FMIFS_IMPORT_DLL #ifndef FMIFS_IMPORT_DLL
@ -311,17 +332,19 @@ ChkdskCallback(
BOOLEAN BOOLEAN
LoadFMIFSEntryPoints(VOID) LoadFMIFSEntryPoints(VOID)
{ {
LoadLibraryW( L"fmifs.dll" ); HMODULE hFmifs = LoadLibraryW(L"fmifs.dll");
if (hFmifs == NULL)
return FALSE;
if( !(Chkdsk = Chkdsk = (PCHKDSK)GetProcAddress(hFmifs, "Chkdsk");
(void *) GetProcAddress(
GetModuleHandleW(L"fmifs.dll"), if (!Chkdsk)
"Chkdsk" )) {
) FreeLibrary(hFmifs);
{ return FALSE;
return FALSE; }
}
return TRUE; return TRUE;
} }
#endif /* ndef FMIFS_IMPORT_DLL */ #endif /* ndef FMIFS_IMPORT_DLL */
@ -339,147 +362,120 @@ LoadFMIFSEntryPoints(VOID)
// //
//---------------------------------------------------------------------- //----------------------------------------------------------------------
int int
wmain( int argc, WCHAR *argv[] ) wmain(int argc, WCHAR *argv[])
{ {
int badArg; int badArg;
HANDLE volumeHandle; HANDLE volumeHandle;
WCHAR fileSystem [1024]; WCHAR fileSystem[1024];
WCHAR volumeName [1024]; WCHAR volumeName[1024];
DWORD serialNumber; DWORD serialNumber;
DWORD flags, DWORD flags, maxComponent;
maxComponent;
wprintf( wprintf(L"\n\
L"\n\
Chkdskx v1.0.1 by Mark Russinovich\n\ Chkdskx v1.0.1 by Mark Russinovich\n\
Systems Internals - http://www.sysinternals.com/\n\ Systems Internals - http://www.sysinternals.com/\n\
ReactOS adaptation 1999 by Emanuele Aliberti\n\n" ReactOS adaptation 1999 by Emanuele Aliberti\n\n");
);
#ifndef FMIFS_IMPORT_DLL #ifndef FMIFS_IMPORT_DLL
// //
// Get function pointers // Get function pointers
// //
if( !LoadFMIFSEntryPoints()) if (!LoadFMIFSEntryPoints())
{ {
wprintf(L"Could not located FMIFS entry points.\n\n"); wprintf(L"Could not located FMIFS entry points.\n\n");
return -1; return -1;
} }
#endif /* ndef FMIFS_IMPORT_DLL */ #endif /* ndef FMIFS_IMPORT_DLL */
//
// Parse command line
//
if( (badArg = ParseCommandLine( argc, argv )))
{
wprintf(
L"Unknown argument: %s\n",
argv[badArg]
);
Usage(argv[0]); //
return -1; // Parse command line
} //
badArg = ParseCommandLine(argc, argv);
if (badArg)
{
wprintf(L"Unknown argument: %s\n", argv[badArg]);
Usage(argv[0]);
return -1;
}
// //
// Get the drive's format // Get the drive's format
// //
if( !Drive ) if (!Drive)
{ {
if( !GetCurrentDirectoryW( if (!GetCurrentDirectoryW(ARRAYSIZE(CurrentDirectory), CurrentDirectory))
sizeof(CurrentDirectory), {
CurrentDirectory PrintWin32Error(L"Could not get current directory", GetLastError());
) return -1;
) { }
}
else
{
wcscpy(CurrentDirectory, Drive);
}
CurrentDirectory[2] = L'\\';
CurrentDirectory[3] = L'\0';
Drive = CurrentDirectory;
PrintWin32Error( //
L"Could not get current directory", // Determine the drive's file system format, which we need to
GetLastError() // tell chkdsk
); //
return -1; if (!GetVolumeInformationW(Drive,
} volumeName,
ARRAYSIZE(volumeName),
&serialNumber,
&maxComponent,
&flags,
fileSystem,
ARRAYSIZE(fileSystem)))
{
PrintWin32Error(L"Could not query volume", GetLastError());
return -1;
}
} else { //
// If they want to fix, we need to have access to the drive
//
if (FixErrors)
{
swprintf(volumeName, L"\\\\.\\%C:", Drive[0]);
volumeHandle = CreateFileW(volumeName,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
0);
if (volumeHandle == INVALID_HANDLE_VALUE)
{
wprintf(L"Chdskx cannot run because the volume is in use by another process.\n\n");
return -1;
}
CloseHandle(volumeHandle);
wcscpy( CurrentDirectory, Drive ); //
} // Can't let the user break out of a chkdsk that can modify the drive
CurrentDirectory[2] = L'\\'; //
CurrentDirectory[3] = L'\0'; SetConsoleCtrlHandler(CtrlCIntercept, TRUE);
Drive = CurrentDirectory; }
// //
// Determine the drive's file system format, which we need to // Just do it
// tell chkdsk //
// wprintf(L"The type of file system is %s.\n", fileSystem);
if( !GetVolumeInformationW( Chkdsk(Drive,
Drive, fileSystem,
volumeName, FixErrors,
sizeof volumeName, Verbose,
& serialNumber, SkipClean,
& maxComponent, ScanSectors,
& flags, NULL,
fileSystem, NULL,
sizeof fileSystem ChkdskCallback);
)
) {
PrintWin32Error(
L"Could not query volume",
GetLastError()
);
return -1;
}
// if (Error) return -1;
// If they want to fix, we need to have access to the drive return 0;
//
if ( FixErrors )
{
swprintf(
volumeName,
L"\\\\.\\%C:",
Drive[0]
);
volumeHandle = CreateFileW(
volumeName,
GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
0
);
if( volumeHandle == INVALID_HANDLE_VALUE )
{
wprintf(L"Chdskx cannot run because the volume is in use by another process.\n\n");
return -1;
}
CloseHandle( volumeHandle );
//
// Can't let the user break out of a chkdsk that can modify the drive
//
SetConsoleCtrlHandler( CtrlCIntercept, TRUE );
}
//
// Just do it
//
wprintf(
L"The type of file system is %s.\n",
fileSystem
);
Chkdsk(
Drive,
fileSystem,
FixErrors,
Verbose,
SkipClean,
ScanSectors,
NULL,
NULL,
ChkdskCallback
);
if ( Error ) return -1;
return 0;
} }
/* EOF */ /* EOF */

View file

@ -1,6 +1,6 @@
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Disk Checking Utility\0" #define REACTOS_STR_FILE_DESCRIPTION "ReactOS Disk Checking Utility"
#define REACTOS_STR_INTERNAL_NAME "chkdsk\0" #define REACTOS_STR_INTERNAL_NAME "chkdsk"
#define REACTOS_STR_ORIGINAL_FILENAME "chkdsk.exe\0" #define REACTOS_STR_ORIGINAL_FILENAME "chkdsk.exe"
#define REACTOS_STR_ORIGINAL_COPYRIGHT "1998 Mark Russinovich\0" #define REACTOS_STR_ORIGINAL_COPYRIGHT "1998 Mark Russinovich"
#include <reactos/version.rc> #include <reactos/version.rc>