ReactOS  0.4.15-dev-3439-g2693a26
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]);
596  Status = RtlAnsiStringToUnicodeString(&VolumePathU,
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 }
signed char * PCHAR
Definition: retypes.h:7
static int argc
Definition: ServiceArgs.c:12
#define DbgPrint
Definition: hal.h:12
#define TRUE
Definition: types.h:120
HANDLE KeyboardHandle
Definition: autochk.c:60
LONG NTSTATUS
Definition: precomp.h:26
#define swprintf
Definition: precomp.h:40
#define argv
Definition: mplay32.c:18
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
#define ANSI_NULL
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
static VOID QueryTimeout(IN OUT PLONG TimeOut)
Definition: autochk.c:507
#define NtCurrentProcess()
Definition: nt_native.h:1657
Status
Definition: gdiplustypes.h:24
int toupper(int c)
Definition: utclib.c:881
#define DOSDEVICE_DRIVE_FIXED
Definition: obtypes.h:166
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
struct _PROCESS_DEVICEMAP_INFORMATION::@3922::@3924 Query
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
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
static NTSTATUS OpenKeyboard(OUT PHANDLE KeyboardHandle)
Definition: autochk.c:126
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_ PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:59
static NTSTATUS CheckVolume(IN PCWSTR VolumePath, IN LONG TimeOut, IN BOOLEAN CheckOnlyIfDirty)
Definition: autochk.c:391

◆ 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,
426  FileSystem,
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  {
440  if (wcscmp(FileSystem, FileSystems[Count].Name) == 0)
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 
501 Quit:
502  PrintString("\r\n\r\n");
503  return Status;
504 }
const uint16_t * PCWSTR
Definition: typedefs.h:57
static NTSTATUS WaitForKeyboard(IN HANDLE KeyboardHandle, IN LONG TimeOut)
Definition: autochk.c:148
PWCHAR FileSystem
Definition: format.c:72
#define TRUE
Definition: types.h:120
HANDLE KeyboardHandle
Definition: autochk.c:60
LONG NTSTATUS
Definition: precomp.h:26
static INT PrintString(char *fmt,...)
Definition: autochk.c:69
static BOOLEAN NTAPI ChkdskCallback(IN CALLBACKCOMMAND Command, IN ULONG Modifier, IN PVOID Argument)
Definition: autochk.c:297
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define L(x)
Definition: ntvdm.h:50
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
Status
Definition: gdiplustypes.h:24
PULIB_CHKDSK ChkdskFunc
Definition: autochk.c:44
int Count
Definition: noreturn.cpp:7
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static NTSTATUS GetFileSystem(IN PUNICODE_STRING VolumePathU, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: autochk.c:228
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
FILESYSTEM_CHKDSK FileSystems[]
Definition: autochk.c:47
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:545
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define DPRINT1
Definition: precomp.h:8
#define STATUS_DISK_CORRUPT_ERROR
Definition: udferr_usr.h:147
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_SUCCESS
Definition: shellext.h:65

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 
344  case INSUFFICIENTRIGHTS:
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 
356  case STRUCTUREPROGRESS:
357  DPRINT("STRUCTUREPROGRESS\n");
358  break;
359 
360  case DONEWITHSTRUCTURE:
361  DPRINT("DONEWITHSTRUCTURE\n");
362  break;
363 
364  case CLUSTERSIZETOOSMALL:
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 }
Definition: fmifs.h:71
Definition: fmifs.h:72
Definition: fmifs.h:70
#define TRUE
Definition: types.h:120
static INT PrintString(char *fmt,...)
Definition: autochk.c:69
Definition: fmifs.h:68
Definition: fmifs.h:78
Definition: fmifs.h:73
Definition: shell.h:41
struct TEXTOUTPUT * PTEXTOUTPUT
Definition: fmifs.h:77
Definition: fmifs.h:80
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
char * PBOOLEAN
Definition: retypes.h:11
Definition: arc.h:85
DWORD * PDWORD
Definition: pedump.c:68
Definition: fmifs.h:81
#define DONE
Definition: rnr20lib.h:14
Definition: fmifs.h:82
#define DPRINT
Definition: sndvol32.h:71

Referenced by CheckVolume().

◆ 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 ARRAYSIZE(array)
Definition: filtermapper.c:47
GLuint buffer
Definition: glext.h:5915
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
int32_t INT
Definition: typedefs.h:58
#define L(x)
Definition: ntvdm.h:50
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define Len
Definition: deflate.h:82
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String)
#define min(a, b)
Definition: monoChain.cc:55
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

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 
251  &IoStatusBlock,
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 
267  &IoStatusBlock,
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 }
#define FILE_GENERIC_READ
Definition: nt_native.h:653
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
#define FILE_SHARE_READ
Definition: compat.h:136
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
HANDLE FileHandle
Definition: stats.c:38
#define UNICODE_NULL
Definition: bufpool.h:45
Status
Definition: gdiplustypes.h:24
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)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
struct _FILE_FS_ATTRIBUTE_INFORMATION * PFILE_FS_ATTRIBUTE_INFORMATION
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3398
unsigned char UCHAR
Definition: xmlstorage.h:181
#define FILE_OPEN
Definition: from_kernel.h:54
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65

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);
139  return NtOpenFile(KeyboardHandle,
142  &IoStatusBlock,
143  FILE_OPEN,
144  0);
145 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_ALL_ACCESS
Definition: nt_native.h:651
HANDLE KeyboardHandle
Definition: autochk.c:60
#define L(x)
Definition: ntvdm.h:50
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:3951
#define FILE_OPEN
Definition: from_kernel.h:54
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#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);
78  Len = vsprintf(buffer, fmt, ap);
79  va_end(ap);
80 
83  &AnsiString,
84  TRUE);
87 
88  return Len;
89 }
#define TRUE
Definition: types.h:120
GLuint buffer
Definition: glext.h:5915
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
int32_t INT
Definition: typedefs.h:58
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define va_end(ap)
Definition: acmsvcex.h:90
char * va_list
Definition: acmsvcex.h:78
#define Len
Definition: deflate.h:82
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
va_start(ap, x)
NTSTATUS NTAPI NtDisplayString(PUNICODE_STRING String)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
Definition: dsound.c:943

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 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
#define max(a, b)
Definition: svc.c:63
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
#define L(x)
Definition: ntvdm.h:50
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

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,
170  &IoStatusBlock,
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 }
HANDLE KeyboardHandle
Definition: autochk.c:60
LONG NTSTATUS
Definition: precomp.h:26
static INT PrintString(char *fmt,...)
Definition: autochk.c:69
#define KEY_BREAK
Definition: ntddkbd.h:71
int32_t INT
Definition: typedefs.h:58
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
static VOID EraseLine(IN INT LineLength)
Definition: autochk.c:92
#define Len
Definition: deflate.h:82
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
static ULONG Timeout
Definition: ping.c:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI NtCancelIoFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock)
Definition: file.c:4018
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)
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)

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 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 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
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
#define L(x)
Definition: ntvdm.h:50
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 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 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

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().