ReactOS 0.4.15-dev-7934-g1dc8d80
autochk.c File Reference
#include <stdio.h>
#include <windef.h>
#include <winbase.h>
#include <ntddkbd.h>
#include <ndk/exfuncs.h>
#include <ndk/iofuncs.h>
#include <ndk/obfuncs.h>
#include <ndk/psfuncs.h>
#include <ndk/rtlfuncs.h>
#include <fmifs/fmifs.h>
#include <fslib/vfatlib.h>
#include <fslib/vfatxlib.h>
#include <fslib/ntfslib.h>
#include <fslib/btrfslib.h>
#include <fslib/ext2lib.h>
#include <fslib/cdfslib.h>
#include <debug.h>
Include dependency graph for autochk.c:

Go to the source code of this file.

Classes

struct  _FILESYSTEM_CHKDSK
 

Macros

#define WIN32_NO_STATUS
 
#define NTOS_MODE_USER
 
#define NDEBUG
 

Typedefs

typedef struct _FILESYSTEM_CHKDSK FILESYSTEM_CHKDSK
 
typedef struct _FILESYSTEM_CHKDSKPFILESYSTEM_CHKDSK
 

Functions

static INT PrintString (char *fmt,...)
 
static VOID EraseLine (IN INT LineLength)
 
static NTSTATUS OpenKeyboard (OUT PHANDLE KeyboardHandle)
 
static NTSTATUS WaitForKeyboard (IN HANDLE KeyboardHandle, IN LONG TimeOut)
 
static NTSTATUS GetFileSystem (IN PUNICODE_STRING VolumePathU, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
static BOOLEAN NTAPI ChkdskCallback (IN CALLBACKCOMMAND Command, IN ULONG Modifier, IN PVOID Argument)
 
static NTSTATUS CheckVolume (IN PCWSTR VolumePath, IN LONG TimeOut, IN BOOLEAN CheckOnlyIfDirty)
 
static VOID QueryTimeout (IN OUT PLONG TimeOut)
 
INT __cdecl _main (IN INT argc, IN PCHAR argv[], IN PCHAR envp[], IN ULONG DebugFlag)
 

Variables

FILESYSTEM_CHKDSK FileSystems []
 
HANDLE KeyboardHandle = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 36 of file autochk.c.

◆ NTOS_MODE_USER

#define NTOS_MODE_USER

Definition at line 21 of file autochk.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 16 of file autochk.c.

Typedef Documentation

◆ FILESYSTEM_CHKDSK

◆ PFILESYSTEM_CHKDSK

Function Documentation

◆ _main()

INT __cdecl _main ( IN INT  argc,
IN PCHAR  argv[],
IN PCHAR  envp[],
IN ULONG  DebugFlag 
)

Definition at line 524 of file autochk.c.

529{
531 LONG TimeOut;
532 ULONG i;
533 BOOLEAN CheckAllVolumes = FALSE;
534 BOOLEAN CheckOnlyIfDirty = TRUE;
536 PCHAR SkipDrives = NULL;
537 ANSI_STRING VolumePathA;
538 UNICODE_STRING VolumePathU;
539 WCHAR VolumePath[128] = L"";
540
541 /*
542 * Parse the command-line: optional command switches,
543 * then the NT volume name (or drive letter) to be analysed.
544 * If "*" is passed this means that we check all the volumes.
545 */
546 if (argc <= 1)
547 {
548 /* Only one parameter (the program name), bail out */
549 return 1;
550 }
551 for (i = 1; i < argc; ++i)
552 {
553 if (argv[i][0] == '/' || argv[i][0] == '-')
554 {
555 DPRINT("Parameter %d: %s\n", i, argv[i]);
556 switch (toupper(argv[i][1]))
557 {
558 case 'K': /* List of drive letters to skip */
559 {
560 /* Check for the separator */
561 if (argv[i][2] != ':')
562 goto Default;
563
564 SkipDrives = &argv[i][3];
565 break;
566 }
567
568 case 'R': /* Repair the errors, implies /P */
569 case 'P': /* Check even if not dirty */
570 {
571 if (argv[i][2] != ANSI_NULL)
572 goto Default;
573
574 CheckOnlyIfDirty = FALSE;
575 break;
576 }
577
578 default: Default:
579 DPRINT1("Unknown switch %d: %s\n", i, argv[i]);
580 break;
581 }
582 }
583 else
584 {
585 DPRINT("Parameter %d - Volume specification: %s\n", i, argv[i]);
586 if (strcmp(argv[i], "*") == 0)
587 {
588 CheckAllVolumes = TRUE;
589 }
590 else
591 {
592 RtlInitEmptyUnicodeString(&VolumePathU,
593 VolumePath,
594 sizeof(VolumePath));
595 RtlInitAnsiString(&VolumePathA, argv[i]);
597 &VolumePathA,
598 FALSE);
599 }
600
601 /* Stop the parsing now */
602 break;
603 }
604 }
605
606 /*
607 * FIXME: We should probably use here the mount manager to be
608 * able to check volumes which don't have a drive letter.
609 */
612 &DeviceMap.Query,
613 sizeof(DeviceMap.Query),
614 NULL);
615 if (!NT_SUCCESS(Status))
616 {
617 DPRINT1("NtQueryInformationProcess() failed, Status 0x%08lx\n", Status);
618 return 1;
619 }
620
621 /* Filter out the skipped drives from the map */
622 if (SkipDrives && *SkipDrives)
623 {
624 DPRINT1("Skipping drives:");
625 while (*SkipDrives)
626 {
627#if DBG
628 DbgPrint(" %c:", *SkipDrives);
629#endif
630 /* Retrieve the index and filter the drive out */
631 i = toupper(*SkipDrives) - 'A';
632 if (0 <= i && i <= 'Z'-'A')
633 DeviceMap.Query.DriveMap &= ~(1 << i);
634
635 /* Go to the next drive letter */
636 ++SkipDrives;
637 }
638 DbgPrint("\n");
639 }
640
641 /* Query the timeout */
642 TimeOut = 3;
643 QueryTimeout(&TimeOut);
644
645 /* Open the keyboard */
647 if (!NT_SUCCESS(Status))
648 {
649 DPRINT1("OpenKeyboard() failed, Status 0x%08lx\n", Status);
650 /* Ignore keyboard interaction */
651 }
652
653 if (CheckAllVolumes)
654 {
655 /* Enumerate and check each of the available volumes */
656 for (i = 0; i <= 'Z'-'A'; i++)
657 {
658 if ((DeviceMap.Query.DriveMap & (1 << i)) &&
659 (DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED))
660 {
661 swprintf(VolumePath, L"\\??\\%c:", L'A' + i);
662 CheckVolume(VolumePath, TimeOut, CheckOnlyIfDirty);
663 }
664 }
665 }
666 else
667 {
668 /* Retrieve our index and analyse the volume */
669 if (wcslen(VolumePath) == 6 &&
670 VolumePath[0] == L'\\' &&
671 VolumePath[1] == L'?' &&
672 VolumePath[2] == L'?' &&
673 VolumePath[3] == L'\\' &&
674 VolumePath[5] == L':')
675 {
676 i = toupper(VolumePath[4]) - 'A';
677 if ((DeviceMap.Query.DriveMap & (1 << i)) &&
678 (DeviceMap.Query.DriveType[i] == DOSDEVICE_DRIVE_FIXED))
679 {
680 CheckVolume(VolumePath, TimeOut, CheckOnlyIfDirty);
681 }
682 }
683 else
684 {
685 /* Just perform the check on the specified volume */
686 // TODO: Check volume type using NtQueryVolumeInformationFile(FileFsDeviceInformation)
687 CheckVolume(VolumePath, TimeOut, CheckOnlyIfDirty);
688 }
689 }
690
691 /* Close the keyboard */
692 if (KeyboardHandle)
694
695 // PrintString("Done\r\n\r\n");
696 return 0;
697}
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int toupper(int c)
Definition: utclib.c:881
static NTSTATUS CheckVolume(IN PCWSTR VolumePath, IN LONG TimeOut, IN BOOLEAN CheckOnlyIfDirty)
Definition: autochk.c:391
HANDLE KeyboardHandle
Definition: autochk.c:60
static VOID QueryTimeout(IN OUT PLONG TimeOut)
Definition: autochk.c:507
static NTSTATUS OpenKeyboard(OUT PHANDLE KeyboardHandle)
Definition: autochk.c:126
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define swprintf
Definition: precomp.h:40
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
@ ProcessDeviceMap
Definition: winternl.h:879
#define argv
Definition: mplay32.c:18
@ Default
Definition: stdole2.idl:392
#define DOSDEVICE_DRIVE_FIXED
Definition: obtypes.h:166
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define ANSI_NULL
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define DPRINT
Definition: sndvol32.h:71
struct _PROCESS_DEVICEMAP_INFORMATION::@4175::@4177 Query
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ CheckVolume()

static NTSTATUS CheckVolume ( IN PCWSTR  VolumePath,
IN LONG  TimeOut,
IN BOOLEAN  CheckOnlyIfDirty 
)
static

Definition at line 391 of file autochk.c.

395{
398 PCWSTR DisplayName;
399 UNICODE_STRING VolumePathU;
400 ULONG Count;
401 WCHAR FileSystem[128];
402
403 RtlInitUnicodeString(&VolumePathU, VolumePath);
404
405 /* Get a drive string for display purposes only */
406 if (wcslen(VolumePath) == 6 &&
407 VolumePath[0] == L'\\' &&
408 VolumePath[1] == L'?' &&
409 VolumePath[2] == L'?' &&
410 VolumePath[3] == L'\\' &&
411 VolumePath[5] == L':')
412 {
413 /* DOS drive */
414 DisplayName = &VolumePath[4];
415 }
416 else
417 {
418 DisplayName = VolumePath;
419 }
420
421 DPRINT1("AUTOCHK: Checking %wZ\n", &VolumePathU);
422 PrintString("Verifying the file system on %S\r\n", DisplayName);
423
424 /* Get the file system */
425 Status = GetFileSystem(&VolumePathU,
427 sizeof(FileSystem));
428 if (!NT_SUCCESS(Status))
429 {
430 DPRINT1("GetFileSystem() failed, Status 0x%08lx\n", Status);
431 PrintString(" Unable to detect the file system of volume %S\r\n", DisplayName);
432 goto Quit;
433 }
434
435 PrintString(" The file system type is %S.\r\n\r\n", FileSystem);
436
437 /* Find a suitable file system provider */
438 for (Count = 0; Count < RTL_NUMBER_OF(FileSystems); ++Count)
439 {
441 break;
442 }
444 {
445 DPRINT1("File system %S not supported\n", FileSystem);
446 PrintString(" Unable to verify the volume. The %S file system is not supported.\r\n", FileSystem);
448 goto Quit;
449 }
450
451 /* Check whether the volume is dirty */
453 Success = FileSystems[Count].ChkdskFunc(&VolumePathU,
455 FALSE, // FixErrors
456 TRUE, // Verbose
457 TRUE, // CheckOnlyIfDirty
458 FALSE, // ScanDrive
459 NULL,
460 NULL,
461 NULL,
462 NULL,
463 (PULONG)&Status);
464
465 /* Perform the check either when the volume is dirty or a check is forced */
466 if (Success && ((Status == STATUS_DISK_CORRUPT_ERROR) || !CheckOnlyIfDirty))
467 {
468 /* Let the user decide whether to repair */
470 {
471 PrintString("The file system on volume %S needs to be checked for problems.\r\n", DisplayName);
472 PrintString("You may cancel this check, but it is recommended that you continue.\r\n");
473 }
474 else
475 {
476 PrintString("A volume check has been scheduled.\r\n");
477 }
478
480 {
481 PrintString("The system will now check the file system.\r\n\r\n");
483 Success = FileSystems[Count].ChkdskFunc(&VolumePathU,
485 TRUE, // FixErrors
486 TRUE, // Verbose
487 CheckOnlyIfDirty,
488 FALSE, // ScanDrive
489 NULL,
490 NULL,
491 NULL,
492 NULL,
493 (PULONG)&Status);
494 }
495 else
496 {
497 PrintString("The file system check has been skipped.\r\n");
498 }
499 }
500
501Quit:
502 PrintString("\r\n\r\n");
503 return Status;
504}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
static NTSTATUS GetFileSystem(IN PUNICODE_STRING VolumePathU, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: autochk.c:228
static INT PrintString(char *fmt,...)
Definition: autochk.c:69
FILESYSTEM_CHKDSK FileSystems[]
Definition: autochk.c:47
static NTSTATUS WaitForKeyboard(IN HANDLE KeyboardHandle, IN LONG TimeOut)
Definition: autochk.c:148
PWCHAR FileSystem
Definition: format.c:72
@ Success
Definition: eventcreate.c:712
int Count
Definition: noreturn.cpp:7
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:545
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define STATUS_SUCCESS
Definition: shellext.h:65
PULIB_CHKDSK ChkdskFunc
Definition: autochk.c:44
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
PFMIFSCALLBACK ChkdskCallback
Definition: vfatlib.c:43

Referenced by _main().

◆ ChkdskCallback()

static BOOLEAN NTAPI ChkdskCallback ( IN CALLBACKCOMMAND  Command,
IN ULONG  Modifier,
IN PVOID  Argument 
)
static

Definition at line 297 of file autochk.c.

301{
302 PDWORD Percent;
305
306 //
307 // We get other types of commands,
308 // but we don't have to pay attention to them
309 //
310 switch(Command)
311 {
312 case UNKNOWN2:
313 DPRINT("UNKNOWN2\n");
314 break;
315
316 case UNKNOWN3:
317 DPRINT("UNKNOWN3\n");
318 break;
319
320 case UNKNOWN4:
321 DPRINT("UNKNOWN4\n");
322 break;
323
324 case UNKNOWN5:
325 DPRINT("UNKNOWN5\n");
326 break;
327
328 case UNKNOWN9:
329 DPRINT("UNKNOWN9\n");
330 break;
331
332 case UNKNOWNA:
333 DPRINT("UNKNOWNA\n");
334 break;
335
336 case UNKNOWNC:
337 DPRINT("UNKNOWNC\n");
338 break;
339
340 case UNKNOWND:
341 DPRINT("UNKNOWND\n");
342 break;
343
345 DPRINT("INSUFFICIENTRIGHTS\n");
346 break;
347
348 case FSNOTSUPPORTED:
349 DPRINT("FSNOTSUPPORTED\n");
350 break;
351
352 case VOLUMEINUSE:
353 DPRINT("VOLUMEINUSE\n");
354 break;
355
357 DPRINT("STRUCTUREPROGRESS\n");
358 break;
359
361 DPRINT("DONEWITHSTRUCTURE\n");
362 break;
363
365 DPRINT("CLUSTERSIZETOOSMALL\n");
366 break;
367
368 case PROGRESS:
369 Percent = (PDWORD) Argument;
370 PrintString("%d percent completed.\r", *Percent);
371 break;
372
373 case OUTPUT:
374 Output = (PTEXTOUTPUT) Argument;
375 PrintString("%s", Output->Output);
376 break;
377
378 case DONE:
379 Status = (PBOOLEAN)Argument;
380 if (*Status == FALSE)
381 {
382 PrintString("The file system check was unable to complete successfully.\r\n\r\n");
383 // Error = TRUE;
384 }
385 break;
386 }
387 return TRUE;
388}
struct TEXTOUTPUT * PTEXTOUTPUT
@ UNKNOWN9
Definition: fmifs.h:77
@ OUTPUT
Definition: fmifs.h:82
@ FSNOTSUPPORTED
Definition: fmifs.h:75
@ UNKNOWND
Definition: fmifs.h:81
@ VOLUMEINUSE
Definition: fmifs.h:76
@ UNKNOWN4
Definition: fmifs.h:72
@ UNKNOWNA
Definition: fmifs.h:78
@ STRUCTUREPROGRESS
Definition: fmifs.h:83
@ CLUSTERSIZETOOSMALL
Definition: fmifs.h:84
@ DONEWITHSTRUCTURE
Definition: fmifs.h:69
@ INSUFFICIENTRIGHTS
Definition: fmifs.h:74
@ PROGRESS
Definition: fmifs.h:68
@ UNKNOWN5
Definition: fmifs.h:73
@ UNKNOWN2
Definition: fmifs.h:70
@ UNKNOWN3
Definition: fmifs.h:71
@ UNKNOWNC
Definition: fmifs.h:80
DWORD * PDWORD
Definition: pedump.c:68
#define DONE
Definition: rnr20lib.h:14
@ Output
Definition: arc.h:85
Definition: shell.h:41
unsigned char * PBOOLEAN
Definition: typedefs.h:53

◆ EraseLine()

static VOID EraseLine ( IN INT  LineLength)
static

Definition at line 92 of file autochk.c.

94{
95 INT Len;
97 WCHAR buffer[512];
98
99 if (LineLength <= 0)
100 return;
101
102 /* Go to the beginning of the line */
105
106 /* Fill the buffer chunk with spaces */
107 Len = min(LineLength, ARRAYSIZE(buffer));
108 while (Len > 0) buffer[--Len] = L' ';
109
110 RtlInitEmptyUnicodeString(&UnicodeString, buffer, sizeof(buffer));
111 while (LineLength > 0)
112 {
113 /* Display the buffer */
114 Len = min(LineLength, ARRAYSIZE(buffer));
115 LineLength -= Len;
116 UnicodeString.Length = Len * sizeof(WCHAR);
118 }
119
120 /* Go to the beginning of the line */
123}
#define Len
Definition: deflate.h:82
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
GLuint buffer
Definition: glext.h:5915
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String)
int32_t INT
Definition: typedefs.h:58

Referenced by WaitForKeyboard().

◆ GetFileSystem()

static NTSTATUS GetFileSystem ( IN PUNICODE_STRING  VolumePathU,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)
static

Definition at line 228 of file autochk.c.

232{
237 PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute;
239
240 FileFsAttribute = (PFILE_FS_ATTRIBUTE_INFORMATION)Buffer;
241
243 VolumePathU,
245 NULL,
246 NULL);
247
252 NULL,
253 0,
255 FILE_OPEN,
256 0,
257 NULL,
258 0);
259 if (!NT_SUCCESS(Status))
260 {
261 DPRINT1("Could not open volume '%wZ' to obtain its file system, Status 0x%08lx\n",
262 VolumePathU, Status);
263 return Status;
264 }
265
268 FileFsAttribute,
269 sizeof(Buffer),
272
273 if (!NT_SUCCESS(Status))
274 {
275 DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
276 return Status;
277 }
278
279 if (FileSystemNameSize >= FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
280 {
281 RtlCopyMemory(FileSystemName,
282 FileFsAttribute->FileSystemName,
283 FileFsAttribute->FileSystemNameLength);
284 FileSystemName[FileFsAttribute->FileSystemNameLength / sizeof(WCHAR)] = UNICODE_NULL;
285 }
286 else
287 {
289 }
290
291 return STATUS_SUCCESS;
292}
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define MAX_PATH
Definition: compat.h:34
#define FILE_SHARE_READ
Definition: compat.h:136
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_OPEN
Definition: from_kernel.h:54
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
@ FileFsAttributeInformation
Definition: from_kernel.h:223
struct _FILE_FS_ATTRIBUTE_INFORMATION * PFILE_FS_ATTRIBUTE_INFORMATION
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define UNICODE_NULL
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by CheckVolume().

◆ OpenKeyboard()

static NTSTATUS OpenKeyboard ( OUT PHANDLE  KeyboardHandle)
static

Definition at line 126 of file autochk.c.

128{
131 UNICODE_STRING KeyboardName = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
132
133 /* Just open the class driver */
135 &KeyboardName,
136 0,
137 NULL,
138 NULL);
143 FILE_OPEN,
144 0);
145}
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by _main().

◆ PrintString()

static INT PrintString ( char fmt,
  ... 
)
static

Definition at line 69 of file autochk.c.

70{
71 INT Len;
72 char buffer[512];
73 va_list ap;
76
77 va_start(ap, fmt);
79 va_end(ap);
80
84 TRUE);
87
88 return Len;
89}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
@ AnsiString
Definition: dnslib.h:19
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
Definition: dsound.c:943
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36

Referenced by CheckVolume(), ChkdskCallback(), and WaitForKeyboard().

◆ QueryTimeout()

static VOID QueryTimeout ( IN OUT PLONG  TimeOut)
static

Definition at line 507 of file autochk.c.

509{
511
514 QueryTable[0].Name = L"AutoChkTimeOut";
515 QueryTable[0].EntryContext = TimeOut;
516
518 /* See: https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/autochk */
519 *TimeOut = min(max(*TimeOut, 0), 259200);
520}
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4208
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define max(a, b)
Definition: svc.c:63
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by _main().

◆ WaitForKeyboard()

static NTSTATUS WaitForKeyboard ( IN HANDLE  KeyboardHandle,
IN LONG  TimeOut 
)
static

Definition at line 148 of file autochk.c.

151{
155 KEYBOARD_INPUT_DATA InputData;
156 INT Len = 0;
157
158 /* Skip the wait if there is no timeout */
159 if (TimeOut <= 0)
160 return STATUS_TIMEOUT;
161
162 /* Attempt to read a down key-press from the keyboard */
163 do
164 {
165 Offset.QuadPart = 0;
167 NULL,
168 NULL,
169 NULL,
171 &InputData,
172 sizeof(KEYBOARD_INPUT_DATA),
173 &Offset,
174 NULL);
175 if (!NT_SUCCESS(Status))
176 {
177 /* Something failed, bail out */
178 return Status;
179 }
180 if ((Status != STATUS_PENDING) && !(InputData.Flags & KEY_BREAK))
181 {
182 /* We have a down key-press, return */
183 return Status;
184 }
185 } while (Status != STATUS_PENDING);
186
187 /* Perform the countdown of TimeOut seconds */
189 while (TimeOut > 0)
190 {
191 /*
192 * Display the countdown string.
193 * Note that we only do a carriage return to go back to the
194 * beginning of the line to possibly erase it. Note also that
195 * we display a trailing space to erase any last character
196 * when the string length decreases.
197 */
198 Len = PrintString("Press any key within %d second(s) to cancel and resume startup. \r", TimeOut);
199
200 /* Decrease the countdown */
201 --TimeOut;
202
203 /* Wait one second for a key press */
204 Timeout.QuadPart = -10000000;
206 if (Status != STATUS_TIMEOUT)
207 break;
208 }
209
210 /* Erase the countdown string */
211 EraseLine(Len);
212
213 if (Status == STATUS_TIMEOUT)
214 {
215 /* The user did not press any key, cancel the read */
217 }
218 else
219 {
220 /* Otherwise, return some status */
222 }
223
224 return Status;
225}
static VOID EraseLine(IN INT LineLength)
Definition: autochk.c:92
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define KEY_BREAK
Definition: ntddkbd.h:71
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS NTAPI NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: file.c:4019
#define STATUS_PENDING
Definition: ntstatus.h:82
static ULONG Timeout
Definition: ping.c:61
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)

Referenced by CheckVolume().

Variable Documentation

◆ FileSystems

FILESYSTEM_CHKDSK FileSystems[]
Initial value:
=
{
{ L"FAT", VfatChkdsk },
{ L"FAT32", VfatChkdsk },
{ L"FATX" , VfatxChkdsk },
{ L"NTFS", NtfsChkdsk },
{ L"BTRFS", BtrfsChkdsk },
{ L"EXT2", Ext2Chkdsk },
{ L"EXT3", Ext2Chkdsk },
{ L"EXT4", Ext2Chkdsk },
{ L"CDFS", CdfsChkdsk },
}
BOOLEAN NTAPI BtrfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
BOOLEAN NTAPI CdfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: cdfslib.c:32
BOOLEAN NTAPI Ext2Chkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: Mke2fs.c:1007
BOOLEAN NTAPI VfatChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: vfatlib.c:374
BOOLEAN NTAPI VfatxChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: vfatxlib.c:162
BOOLEAN NTAPI NtfsChkdsk(IN PUNICODE_STRING DriveRoot, IN PFMIFSCALLBACK Callback, IN BOOLEAN FixErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID pUnknown1, IN PVOID pUnknown2, IN PVOID pUnknown3, IN PVOID pUnknown4, IN PULONG ExitStatus)
Definition: ntfslib.c:33

Definition at line 47 of file autochk.c.

Referenced by CheckVolume(), and GetFileSystemByName().

◆ KeyboardHandle

HANDLE KeyboardHandle = NULL

Definition at line 60 of file autochk.c.

Referenced by _main(), CheckVolume(), OpenKeyboard(), and WaitForKeyboard().