⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chkdsk.c

📁 chkdskx and formatx
💻 C
字号:
//======================================================================
//
// Chkdskx
//
// By Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//
// Chkdsk clone that demonstrates the use of the FMIFS file system
// utility library.
//
//======================================================================
#include <windows.h>
#include <stdio.h>
#include "..\fmifs.h"
#define _UNICODE 1
#include "tchar.h"

//
// Globals
//
BOOL	Error = FALSE;

// switches
BOOL	FixErrors = FALSE;
BOOL	SkipClean = FALSE;
BOOL	ScanSectors = FALSE;
BOOL	Verbose = FALSE;
PWCHAR  Drive = NULL;
WCHAR	  CurrentDirectory[1024];

//
// FMIFS function
//
PCHKDSK   Chkdsk;


//----------------------------------------------------------------------
//
// PrintWin32Error
//
// Takes the win32 error code and prints the text version.
//
//----------------------------------------------------------------------
void PrintWin32Error( PWCHAR Message, DWORD ErrorCode )
{
	LPVOID lpMsgBuf;
 
	FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
					NULL, ErrorCode, 
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
					(PWCHAR) &lpMsgBuf, 0, NULL );
	_tprintf(L"%s: %s\n", Message, lpMsgBuf );
	LocalFree( lpMsgBuf );
}

//--------------------------------------------------------------------
//
// CtrlCIntercept
//
// Intercepts Ctrl-C's so that the program can't be quit with the
// disk in an inconsistent state.
//
//--------------------------------------------------------------------
BOOL WINAPI CtrlCIntercept( DWORD dwCtrlType )
{
	//
	// Handle the event so that the default handler doesn't
	//
	return TRUE;
}


//----------------------------------------------------------------------
// 
// Usage
//
// Tell the user how to use the program
//
//----------------------------------------------------------------------
VOID Usage( PWCHAR ProgramName )
{
	_tprintf(L"Usage: %s [drive:] [-F] [-V] [-R] [-C]\n\n");
	_tprintf(L"  [drive:]    Specifies the drive to check.\n");
	_tprintf(L"  -F          Fixes errors on the disk.\n");
	_tprintf(L"  -V          Displays the full path of every file on the disk.\n");
	_tprintf(L"  -R          Locates bad sectors and recovers readable information.\n");
	_tprintf(L"  -C          Checks the drive only if it is dirty.\n");
	_tprintf(L"\n");
}


//----------------------------------------------------------------------
//
// ParseCommandLine
//
// Get the switches.
//
//----------------------------------------------------------------------
int ParseCommandLine( int argc, WCHAR *argv[] )
{
	int i;
	BOOLEAN gotFix = FALSE;
	BOOLEAN gotVerbose = FALSE;
	BOOLEAN gotClean = FALSE;
	BOOLEAN gotScan = FALSE;


	for( i = 1; i < argc; i++ ) {

		switch( argv[i][0] ) {

		case '-':
		case '/':

			switch( argv[i][1] ) {

			case L'F':
			case L'f':

				if( gotFix ) return i;
				FixErrors = TRUE;
				gotFix = TRUE;
				break;

			case L'V':
			case L'v':

				if( gotVerbose) return i;
				Verbose = TRUE;
				gotVerbose = TRUE;
				break;

			case L'R':
			case L'r':

				if( gotFix ) return i;
				ScanSectors = TRUE;
				gotFix = TRUE;
				break;

			case L'C':
			case L'c':

				if( gotClean ) return i;
				SkipClean = TRUE;
				gotClean = TRUE;
				break;

			default:
				return i;
			}
			break;

		default:

			if( Drive ) return i;
			if( argv[i][1] != L':' ) return i;

			Drive = argv[i];
			break;
		}
	}
	return 0;
}


//----------------------------------------------------------------------
//
// ChkdskCallback
//
// The file system library will call us back with commands that we
// can interpret. If we wanted to halt the chkdsk we could return FALSE.
//
//----------------------------------------------------------------------
BOOLEAN __stdcall ChkdskCallback( CALLBACKCOMMAND Command, DWORD Modifier, PVOID Argument )
{
	PDWORD percent;
	PBOOLEAN status;
	PTEXTOUTPUT output;

	// 
	// We get other types of commands, but we don't have to pay attention to them
	//
	switch( Command ) {

	case PROGRESS:
		percent = (PDWORD) Argument;
		_tprintf(L"%d percent completed.\r", *percent);
		break;

	case OUTPUT:
		output = (PTEXTOUTPUT) Argument;
		fprintf(stdout, "%s", output->Output);
		break;

	case DONE:
		status = (PBOOLEAN) Argument;
		if( *status == TRUE ) {

			_tprintf(L"Chkdsk was unable to complete successfully.\n\n");
			Error = TRUE;
		}
		break;
	}
	return TRUE;
}


//----------------------------------------------------------------------
//
// LoadFMIFSEntryPoints
//
// Loads FMIFS.DLL and locates the entry point(s) we are going to use
//
//----------------------------------------------------------------------
BOOLEAN LoadFMIFSEntryPoints()
{
	LoadLibrary( "fmifs.dll" );

	if( !(Chkdsk = (void *) GetProcAddress( GetModuleHandle( "fmifs.dll"),
			"Chkdsk" )) ) {

		return FALSE;
	}
	return TRUE;
}


//----------------------------------------------------------------------
// 
// WMain
//
// Engine. Just get command line switches and fire off a chkdsk. This 
// could also be done in a GUI like Explorer does when you select a 
// drive and run a check on it.
//
// We do this in UNICODE because the chkdsk command expects PWCHAR
// arguments.
//
//----------------------------------------------------------------------
int wmain( int argc, WCHAR *argv[] )
{
	int badArg;
	HANDLE volumeHandle;
	WCHAR fileSystem[1024];
	WCHAR volumeName[1024];
	DWORD serialNumber;
	DWORD flags, maxComponent;

	_tprintf(L"\nChkdskx v1.0 by Mark Russinovich\n");
	_tprintf(L"Systems Internals - http://www.sysinternals.com\n\n");

	//
	// Get function pointers
	//
	if( !LoadFMIFSEntryPoints()) {

		_tprintf(L"Could not located FMIFS entry points.\n\n");
		return -1;
	}

	//
	// Parse command line
	//
	if( (badArg = ParseCommandLine( argc, argv ))) {

		_tprintf(L"Unknown argument: %s\n", argv[badArg] );

		Usage(argv[0]);
		return -1;
	}

	// 
	// Get the drive's format
	//
	if( !Drive ) {

		if( !GetCurrentDirectoryW( sizeof(CurrentDirectory), CurrentDirectory )) {

			PrintWin32Error( L"Could not get current directory", GetLastError());
			return -1;
		}

	} else {

		wcscpy( CurrentDirectory, Drive );
	}
	CurrentDirectory[2] = L'\\';
	CurrentDirectory[3] = (WCHAR) 0;
	Drive = CurrentDirectory;

	//
	// Determine the drive's file system format, which we need to 
	// tell chkdsk
	//
	if( !GetVolumeInformationW( Drive, 
						volumeName, sizeof(volumeName), 
						&serialNumber, &maxComponent, &flags, 
						fileSystem, sizeof(fileSystem))) {

		PrintWin32Error( L"Could not query volume", GetLastError());
		return -1;
	}

	//
	// 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 ) {

			_tprintf(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
	//
	_tprintf(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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -