mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 22:56:00 +00:00
Correctly implement autochk, which now calls the ChkdskEx function in u{FS}.dll.
svn path=/trunk/; revision=23962
This commit is contained in:
parent
611b577fd6
commit
0d173915ac
1 changed files with 118 additions and 89 deletions
|
@ -1,10 +1,10 @@
|
||||||
/* $Id$
|
/* PROJECT: ReactOS Kernel
|
||||||
* PROJECT: ReactOS Kernel
|
|
||||||
* LICENSE: GPL - See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* FILE: base/system/autochk/autochk.c
|
* FILE: base/system/autochk/autochk.c
|
||||||
* PURPOSE: Filesystem checker
|
* PURPOSE: Filesystem checker
|
||||||
* PROGRAMMERS: Aleksey Bragin
|
* PROGRAMMERS: Aleksey Bragin
|
||||||
* Eric Kohl
|
* Eric Kohl
|
||||||
|
* Hervé Poussineau
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -28,30 +28,8 @@
|
||||||
//
|
//
|
||||||
// FMIFS function
|
// FMIFS function
|
||||||
//
|
//
|
||||||
typedef
|
|
||||||
VOID
|
|
||||||
(STDCALL *PCHKDSK)(PWCHAR DriveRoot,
|
|
||||||
PWCHAR Format,
|
|
||||||
BOOLEAN CorrectErrors,
|
|
||||||
BOOLEAN Verbose,
|
|
||||||
BOOLEAN CheckOnlyIfDirty,
|
|
||||||
BOOLEAN ScanDrive,
|
|
||||||
PVOID Unused2,
|
|
||||||
PVOID Unused3,
|
|
||||||
PFMIFSCALLBACK Callback);
|
|
||||||
|
|
||||||
PCHKDSK ChkdskFunc = NULL;
|
static VOID
|
||||||
|
|
||||||
void
|
|
||||||
DisplayString(LPCWSTR lpwString)
|
|
||||||
{
|
|
||||||
UNICODE_STRING us;
|
|
||||||
|
|
||||||
RtlInitUnicodeString(&us, lpwString);
|
|
||||||
NtDisplayString(&us);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
PrintString(char* fmt,...)
|
PrintString(char* fmt,...)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
|
@ -72,9 +50,10 @@ PrintString(char* fmt,...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this func is taken from kernel32/file/volume.c
|
// this func is taken from kernel32/file/volume.c
|
||||||
HANDLE
|
static HANDLE
|
||||||
OpenDirectory(LPCWSTR DirName,
|
OpenDirectory(
|
||||||
BOOLEAN Write)
|
IN LPCWSTR DirName,
|
||||||
|
IN BOOLEAN Write)
|
||||||
{
|
{
|
||||||
UNICODE_STRING NtPathU;
|
UNICODE_STRING NtPathU;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -121,10 +100,11 @@ OpenDirectory(LPCWSTR DirName,
|
||||||
return hFile;
|
return hFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
static NTSTATUS
|
||||||
GetFileSystem(LPCWSTR Drive,
|
GetFileSystem(
|
||||||
LPWSTR FileSystemName,
|
IN LPCWSTR Drive,
|
||||||
ULONG FileSystemNameSize)
|
IN OUT LPWSTR FileSystemName,
|
||||||
|
IN SIZE_T FileSystemNameSize)
|
||||||
{
|
{
|
||||||
HANDLE FileHandle;
|
HANDLE FileHandle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -149,7 +129,7 @@ GetFileSystem(LPCWSTR Drive,
|
||||||
{
|
{
|
||||||
if (FileSystemNameSize * sizeof(WCHAR) >= FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
|
if (FileSystemNameSize * sizeof(WCHAR) >= FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
|
||||||
{
|
{
|
||||||
memcpy(FileSystemName,
|
CopyMemory(FileSystemName,
|
||||||
FileFsAttribute->FileSystemName,
|
FileFsAttribute->FileSystemName,
|
||||||
FileFsAttribute->FileSystemNameLength);
|
FileFsAttribute->FileSystemNameLength);
|
||||||
FileSystemName[FileFsAttribute->FileSystemNameLength / sizeof(WCHAR)] = 0;
|
FileSystemName[FileFsAttribute->FileSystemNameLength / sizeof(WCHAR)] = 0;
|
||||||
|
@ -164,11 +144,11 @@ GetFileSystem(LPCWSTR Drive,
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is based on SysInternal's ChkDsk app
|
// This is based on SysInternal's ChkDsk app
|
||||||
BOOLEAN
|
static BOOLEAN CALLBACK
|
||||||
STDCALL
|
ChkdskCallback(
|
||||||
ChkdskCallback(CALLBACKCOMMAND Command,
|
IN CALLBACKCOMMAND Command,
|
||||||
DWORD Modifier,
|
IN DWORD Modifier,
|
||||||
PVOID Argument)
|
IN PVOID Argument)
|
||||||
{
|
{
|
||||||
PDWORD Percent;
|
PDWORD Percent;
|
||||||
PBOOLEAN Status;
|
PBOOLEAN Status;
|
||||||
|
@ -254,6 +234,86 @@ ChkdskCallback(CALLBACKCOMMAND Command,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load the provider associated with this file system */
|
||||||
|
static PVOID
|
||||||
|
LoadProvider(
|
||||||
|
IN PWCHAR FileSystem)
|
||||||
|
{
|
||||||
|
UNICODE_STRING ProviderDll = RTL_CONSTANT_STRING(L"ufat.dll");
|
||||||
|
PVOID BaseAddress;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* FIXME: add more providers here */
|
||||||
|
|
||||||
|
if (wcscmp(FileSystem, L"FAT") != 0
|
||||||
|
&& wcscmp(FileSystem, L"FAT32") != 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = LdrLoadDll(NULL, NULL, &ProviderDll, &BaseAddress);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return NULL;
|
||||||
|
return BaseAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
CheckVolume(
|
||||||
|
IN PWCHAR DrivePath)
|
||||||
|
{
|
||||||
|
WCHAR FileSystem[128];
|
||||||
|
ANSI_STRING ChkdskFunctionName = RTL_CONSTANT_STRING("ChkdskEx");
|
||||||
|
PVOID Provider;
|
||||||
|
CHKDSKEX ChkdskFunc;
|
||||||
|
UNICODE_STRING DrivePathU;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Get the file system */
|
||||||
|
Status = GetFileSystem(DrivePath,
|
||||||
|
FileSystem,
|
||||||
|
sizeof(FileSystem) / sizeof(FileSystem[0]));
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("GetFileSystem() failed with status 0x%08lx\n", Status);
|
||||||
|
PrintString(" Unable to get file system of %S\n", DrivePath);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the provider which will do the chkdsk */
|
||||||
|
Provider = LoadProvider(FileSystem);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("LoadProvider() failed\n");
|
||||||
|
PrintString(" Unable to verify a %S volume\n", FileSystem);
|
||||||
|
return STATUS_DLL_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the Chkdsk function address */
|
||||||
|
Status = LdrGetProcedureAddress(Provider,
|
||||||
|
&ChkdskFunctionName,
|
||||||
|
0,
|
||||||
|
(PVOID*)&ChkdskFunc);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("LdrGetProcedureAddress() failed with status 0x%08lx\n", Status);
|
||||||
|
PrintString(" Unable to verify a %S volume\n", FileSystem);
|
||||||
|
LdrUnloadDll(Provider);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call provider */
|
||||||
|
PrintString(" Verifying volume %S\n", DrivePath);
|
||||||
|
RtlInitUnicodeString(&DrivePathU, DrivePath);
|
||||||
|
Status = ChkdskFunc(&DrivePathU,
|
||||||
|
TRUE, // FixErrors
|
||||||
|
TRUE, // Verbose
|
||||||
|
FALSE, // CheckOnlyIfDirty
|
||||||
|
FALSE,// ScanDrive
|
||||||
|
ChkdskCallback);
|
||||||
|
|
||||||
|
LdrUnloadDll(Provider);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/* Native image's entry point */
|
/* Native image's entry point */
|
||||||
int
|
int
|
||||||
|
@ -266,11 +326,8 @@ _main(int argc,
|
||||||
PROCESS_DEVICEMAP_INFORMATION DeviceMap;
|
PROCESS_DEVICEMAP_INFORMATION DeviceMap;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
WCHAR FileSystem[128];
|
|
||||||
WCHAR DrivePath[128];
|
WCHAR DrivePath[128];
|
||||||
|
|
||||||
PrintString("Autochk 0.0.2\n");
|
|
||||||
|
|
||||||
// Win2003 passes the only param - "*". Probably means to check all drives
|
// Win2003 passes the only param - "*". Probably means to check all drives
|
||||||
/*
|
/*
|
||||||
DPRINT("Got %d params\n", argc);
|
DPRINT("Got %d params\n", argc);
|
||||||
|
@ -278,61 +335,33 @@ _main(int argc,
|
||||||
DPRINT("Param %d: %s\n", i, argv[i]);
|
DPRINT("Param %d: %s\n", i, argv[i]);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* FIXME: We should probably use here the mount manager to be
|
||||||
|
* able to check volumes which don't have a drive letter.
|
||||||
|
*/
|
||||||
|
|
||||||
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
Status = NtQueryInformationProcess(NtCurrentProcess(),
|
||||||
ProcessDeviceMap,
|
ProcessDeviceMap,
|
||||||
&DeviceMap.Query,
|
&DeviceMap.Query,
|
||||||
sizeof(DeviceMap.Query),
|
sizeof(DeviceMap.Query),
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if(NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
for (i = 0; i < 26; i++)
|
|
||||||
{
|
|
||||||
if ((DeviceMap.Query.DriveMap & (1 << i)) &&
|
|
||||||
(DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED))
|
|
||||||
{
|
|
||||||
swprintf(DrivePath, L"%c:\\", 'A'+i);
|
|
||||||
Status = GetFileSystem(DrivePath,
|
|
||||||
FileSystem,
|
|
||||||
sizeof(FileSystem));
|
|
||||||
PrintString(" Checking drive %c: \n", 'A'+i);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Error getting FS information, Status=0x%08X\n",
|
DPRINT1("NtQueryInformationProcess() failed with status 0x%08lx\n",
|
||||||
Status);
|
Status);
|
||||||
// skip to the next volume
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FS type known, show it to user and then call chkdsk routine
|
|
||||||
PrintString(" Filesystem type ");
|
|
||||||
DisplayString(FileSystem);
|
|
||||||
PrintString("\n");
|
|
||||||
|
|
||||||
/*ChkdskFunc(DrivePath,
|
|
||||||
FileSystem,
|
|
||||||
TRUE, // FixErrors
|
|
||||||
TRUE, // Verbose
|
|
||||||
FALSE, // SkipClean
|
|
||||||
FALSE,// ScanSectors
|
|
||||||
NULL,
|
|
||||||
NULL,
|
|
||||||
ChkdskCallback);*/
|
|
||||||
|
|
||||||
PrintString(" OK\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PrintString("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DPRINT1("NtQueryInformationProcess() failed with status=0x%08X\n",
|
|
||||||
Status);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 26; i++)
|
||||||
|
{
|
||||||
|
if ((DeviceMap.Query.DriveMap & (1 << i))
|
||||||
|
&& (DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED))
|
||||||
|
{
|
||||||
|
swprintf(DrivePath, L"%c:\\", 'A'+i);
|
||||||
|
CheckVolume(DrivePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrintString(" Done\n\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue