https://git.reactos.org/?p=reactos.git;a=commitdiff;h=79975ede2692aa36b1112…
commit 79975ede2692aa36b1112b44698561a7a4a31bbf
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Tue Jun 5 19:33:36 2018 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Tue Jun 5 19:34:47 2018 +0200
[AUTOCHK] Allow users to skip disk checking if dirty
CORE-14692
---
base/system/autochk/autochk.c | 109 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 107 insertions(+), 2 deletions(-)
diff --git a/base/system/autochk/autochk.c b/base/system/autochk/autochk.c
index 36dfdae849..918d709878 100644
--- a/base/system/autochk/autochk.c
+++ b/base/system/autochk/autochk.c
@@ -15,6 +15,7 @@
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
+#include <ntddkbd.h>
#define NTOS_MODE_USER
#include <ndk/exfuncs.h>
#include <ndk/iofuncs.h>
@@ -59,6 +60,8 @@ FILESYSTEM_CHKDSK FileSystems[10] =
{ L"CDFS", CdfsChkdsk },
};
+HANDLE KeyboardHandle;
+
/* FUNCTIONS ****************************************************************/
//
// FMIFS function
@@ -135,6 +138,66 @@ OpenDirectory(
return hFile;
}
+static NTSTATUS
+OpenKeyboard(VOID)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING KeyboardName =
RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
+
+ /* Just open the class driver */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyboardName,
+ 0,
+ NULL,
+ NULL);
+ return NtOpenFile(&KeyboardHandle,
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_OPEN,
+ 0);
+}
+
+static NTSTATUS
+WaitForKeyboard(VOID)
+{
+ NTSTATUS Status;
+ IO_STATUS_BLOCK IoStatusBlock;
+ LARGE_INTEGER Offset, Timeout;
+ KEYBOARD_INPUT_DATA InputData;
+
+ /* Attempt to read from the keyboard */
+ Offset.QuadPart = 0;
+ Status = NtReadFile(KeyboardHandle,
+ NULL,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ &InputData,
+ sizeof(KEYBOARD_INPUT_DATA),
+ &Offset,
+ NULL);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait 3s */
+ Timeout.QuadPart = (LONG)-3*1000*1000*10;
+ Status = NtWaitForSingleObject(KeyboardHandle, FALSE, &Timeout);
+ /* The user didn't enter anything, cancel the read */
+ if (Status == STATUS_TIMEOUT)
+ {
+ NtCancelIoFile(KeyboardHandle, &IoStatusBlock);
+ }
+ /* Else, return some status */
+ else
+ {
+ Status = IoStatusBlock.Status;
+ }
+ }
+
+ return Status;
+}
+
static NTSTATUS
GetFileSystem(
IN LPCWSTR Drive,
@@ -283,6 +346,8 @@ CheckVolume(
NTSTATUS Status;
DWORD Count;
+ PrintString(" Verifying volume %S\r\n", DrivePath);
+
/* Get the file system */
Status = GetFileSystem(DrivePath,
FileSystem,
@@ -294,6 +359,8 @@ CheckVolume(
return Status;
}
+ PrintString(" Its filesystem type is %S\r\n", FileSystem);
+
/* Call provider */
for (Count = 0; Count < sizeof(FileSystems) / sizeof(FileSystems[0]); ++Count)
{
@@ -302,19 +369,45 @@ CheckVolume(
continue;
}
- // PrintString(" Verifying volume %S\r\n", DrivePath);
swprintf(NtDrivePath, L"\\??\\");
wcscat(NtDrivePath, DrivePath);
NtDrivePath[wcslen(NtDrivePath)-1] = 0;
RtlInitUnicodeString(&DrivePathU, NtDrivePath);
DPRINT1("AUTOCHK: Checking %wZ\n", &DrivePathU);
+ /* First, check whether the volume is dirty */
Status = FileSystems[Count].ChkdskFunc(&DrivePathU,
- TRUE, // FixErrors
+ FALSE, // FixErrors
TRUE, // Verbose
TRUE, // CheckOnlyIfDirty
FALSE,// ScanDrive
ChkdskCallback);
+ /* It is */
+ if (Status == STATUS_DISK_CORRUPT_ERROR)
+ {
+ NTSTATUS WaitStatus;
+
+ /* Let the user decide whether to repair */
+ PrintString(" %S needs to be checked\r\n", DrivePath);
+ PrintString(" You can skip it, but be advised it is not
recommanded\r\n");
+ PrintString(" To skip disk checking press any key in 3
seconds\r\n", DrivePath);
+
+ /* Timeout == fix it! */
+ WaitStatus = WaitForKeyboard();
+ if (WaitStatus == STATUS_TIMEOUT)
+ {
+ Status = FileSystems[Count].ChkdskFunc(&DrivePathU,
+ TRUE, // FixErrors
+ TRUE, // Verbose
+ TRUE, // CheckOnlyIfDirty
+ FALSE,// ScanDrive
+ ChkdskCallback);
+ }
+ else
+ {
+ PrintString(" %S checking has been skipped\r\n", DrivePath);
+ }
+ }
break;
}
@@ -364,6 +457,14 @@ _main(int argc,
return 1;
}
+ /* Open keyboard */
+ Status = OpenKeyboard();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("OpenKeyboard() failed with status 0x%08lx\n", Status);
+ return 1;
+ }
+
for (i = 0; i < 26; i++)
{
if ((DeviceMap.Query.DriveMap & (1 << i))
@@ -373,6 +474,10 @@ _main(int argc,
CheckVolume(DrivePath);
}
}
+
+ /* Close keyboard */
+ NtClose(KeyboardHandle);
+
// PrintString(" Done\r\n\r\n");
return 0;
}