ReactOS  0.4.13-dev-479-gec9c8fd
chkdsk.c
Go to the documentation of this file.
1 //======================================================================
2 //
3 // Chkdskx
4 //
5 // Copyright (c) 1998 Mark Russinovich
6 // Systems Internals
7 // http://www.sysinternals.com
8 //
9 // Chkdsk clone that demonstrates the use of the FMIFS file system
10 // utility library.
11 //
12 // --------------------------------------------------------------------
13 //
14 // This software is free software; you can redistribute it and/or
15 // modify it under the terms of the GNU Library General Public License as
16 // published by the Free Software Foundation; either version 2 of the
17 // License, or (at your option) any later version.
18 //
19 // This software is distributed in the hope that it will be useful,
20 // but WITHOUT ANY WARRANTY; without even the implied warranty of
21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 // Library General Public License for more details.
23 //
24 // You should have received a copy of the GNU Library General Public
25 // License along with this software; see the file COPYING.LIB. If
26 // not, write to the Free Software Foundation, Inc., 675 Mass Ave,
27 // Cambridge, MA 02139, USA.
28 //
29 // --------------------------------------------------------------------
30 //
31 // 1999 February (Emanuele Aliberti)
32 // Adapted for ReactOS and lcc-win32.
33 //
34 // 1999 April (Emanuele Aliberti)
35 // Adapted for ReactOS and egcs.
36 //
37 // 2008 July (Aleksey Bragin)
38 // Cleanup, use ReactOS's fmifs.h
39 //
40 //======================================================================
41 
42 #include <stdio.h>
43 
44 /* PSDK/NDK Headers */
45 #define WIN32_NO_STATUS
46 #include <windef.h>
47 #include <winbase.h>
48 #include <wincon.h>
49 
50 #include <conutils.h>
51 
52 /* Resource header */
53 #include "resource.h"
54 
55 #define NTOS_MODE_USER
56 #include <ndk/ntndk.h>
57 
58 /* FMIFS Public Header */
59 #include <fmifs/fmifs.h>
60 
61 #define FMIFS_IMPORT_DLL
62 
63 //
64 // Globals
65 //
67 
68 // Switches
75 
76 #ifndef FMIFS_IMPORT_DLL
77 //
78 // Functions in FMIFS.DLL
79 //
80 PCHKDSK Chkdsk;
81 #endif
82 
83 
84 //----------------------------------------------------------------------
85 //
86 // PrintWin32Error
87 //
88 // Takes the win32 error code and prints the text version.
89 //
90 //----------------------------------------------------------------------
92 {
96  ConPuts(StdErr, L"\n");
97 }
98 
99 
100 //--------------------------------------------------------------------
101 //
102 // CtrlCIntercept
103 //
104 // Intercepts Ctrl-C's so that the program can't be quit with the
105 // disk in an inconsistent state.
106 //
107 //--------------------------------------------------------------------
108 BOOL
109 WINAPI
111 {
112  //
113  // Handle the event so that the default handler doesn't
114  //
115  return TRUE;
116 }
117 
118 
119 //----------------------------------------------------------------------
120 //
121 // Usage
122 //
123 // Tell the user how to use the program
124 //
125 //----------------------------------------------------------------------
126 static VOID
127 Usage(PWCHAR ProgramName)
128 {
129  ConResPrintf(StdOut, IDS_USAGE, ProgramName);
130 }
131 
132 
133 //----------------------------------------------------------------------
134 //
135 // ParseCommandLine
136 //
137 // Get the switches.
138 //
139 //----------------------------------------------------------------------
140 static int
142 {
143  int i;
144  BOOLEAN gotFix = FALSE;
145  BOOLEAN gotVerbose = FALSE;
146  BOOLEAN gotClean = FALSE;
147  // BOOLEAN gotScan = FALSE;
148 
149  for (i = 1; i < argc; i++)
150  {
151  switch (argv[i][0])
152  {
153  case L'-': case L'/':
154 
155  switch (argv[i][1])
156  {
157  // case L'?':
158  // Usage(argv[0]);
159  // return i;
160 
161  case L'F': case L'f':
162  {
163  if (gotFix) return i;
164  FixErrors = TRUE;
165  gotFix = TRUE;
166  break;
167  }
168 
169  case L'V': case L'v':
170  {
171  if (gotVerbose) return i;
172  Verbose = TRUE;
173  gotVerbose = TRUE;
174  break;
175  }
176 
177  case L'R': case L'r':
178  {
179  if (gotFix) return i;
180  ScanSectors = TRUE;
181  gotFix = TRUE;
182  break;
183  }
184 
185  case L'C': case L'c':
186  {
187  if (gotClean) return i;
188  SkipClean = TRUE;
189  gotClean = TRUE;
190  break;
191  }
192 
193  default:
194  return i;
195  }
196  break;
197 
198  default:
199  {
200  if (Drive) return i;
201  if (argv[i][1] != L':') return i;
202 
203  Drive = argv[i];
204  break;
205  }
206  }
207  }
208  return 0;
209 }
210 
211 
212 //----------------------------------------------------------------------
213 //
214 // ChkdskCallback
215 //
216 // The file system library will call us back with commands that we
217 // can interpret. If we wanted to halt the chkdsk we could return FALSE.
218 //
219 //----------------------------------------------------------------------
220 BOOLEAN
221 WINAPI
224  DWORD Modifier,
225  PVOID Argument)
226 {
227  BOOLEAN Ret;
228  PDWORD percent;
231 
232  //
233  // We get other types of commands,
234  // but we don't have to pay attention to them
235  //
236  Ret = TRUE;
237  switch (Command)
238  {
239  case UNKNOWN2:
240  ConPuts(StdOut, L"UNKNOWN2\r");
241  break;
242 
243  case UNKNOWN3:
244  ConPuts(StdOut, L"UNKNOWN3\n");
245  break;
246 
247  case UNKNOWN4:
248  ConPuts(StdOut, L"UNKNOWN4\n");
249  break;
250 
251  case UNKNOWN5:
252  ConPuts(StdOut, L"UNKNOWN5\n");
253  break;
254 
255  case FSNOTSUPPORTED:
256  ConPuts(StdOut, L"FSNOTSUPPORTED\n");
257  break;
258 
259  case VOLUMEINUSE:
261  Ret = FALSE;
262  break;
263 
264  case UNKNOWN9:
265  ConPuts(StdOut, L"UNKNOWN9\n");
266  break;
267 
268  case UNKNOWNA:
269  ConPuts(StdOut, L"UNKNOWNA\n");
270  break;
271 
272  case UNKNOWNC:
273  ConPuts(StdOut, L"UNKNOWNC\n");
274  break;
275 
276  case UNKNOWND:
277  ConPuts(StdOut, L"UNKNOWND\n");
278  break;
279 
280  case INSUFFICIENTRIGHTS:
281  ConPuts(StdOut, L"INSUFFICIENTRIGHTS\n");
282  break;
283 
284  case STRUCTUREPROGRESS:
285  ConPuts(StdOut, L"STRUCTUREPROGRESS\n");
286  break;
287 
288  case DONEWITHSTRUCTURE:
289  ConPuts(StdOut, L"DONEWITHSTRUCTURE\n");
290  break;
291 
292  case CLUSTERSIZETOOSMALL:
293  ConPuts(StdOut, L"CLUSTERSIZETOOSMALL\n");
294  break;
295 
296  case PROGRESS:
297  percent = (PDWORD)Argument;
299  break;
300 
301  case OUTPUT:
302  output = (PTEXTOUTPUT)Argument;
303  ConPrintf(StdOut, L"%S", output->Output);
304  break;
305 
306  case DONE:
307  status = (PBOOLEAN)Argument;
308  if (*status == FALSE)
309  {
311  Error = TRUE;
312  }
313  break;
314  }
315  return Ret;
316 }
317 
318 #ifndef FMIFS_IMPORT_DLL
319 //----------------------------------------------------------------------
320 //
321 // LoadFMIFSEntryPoints
322 //
323 // Loads FMIFS.DLL and locates the entry point(s) we are going to use
324 //
325 //----------------------------------------------------------------------
326 static BOOLEAN
327 LoadFMIFSEntryPoints(VOID)
328 {
329  HMODULE hFmifs = LoadLibraryW(L"fmifs.dll");
330  if (hFmifs == NULL)
331  return FALSE;
332 
333  Chkdsk = (PCHKDSK)GetProcAddress(hFmifs, "Chkdsk");
334  if (!Chkdsk)
335  {
336  FreeLibrary(hFmifs);
337  return FALSE;
338  }
339 
340  return TRUE;
341 }
342 #endif
343 
344 
345 //----------------------------------------------------------------------
346 //
347 // WMain
348 //
349 // Engine. Just get command line switches and fire off a chkdsk. This
350 // could also be done in a GUI like Explorer does when you select a
351 // drive and run a check on it.
352 //
353 // We do this in UNICODE because the chkdsk command expects PWCHAR
354 // arguments.
355 //
356 //----------------------------------------------------------------------
357 int
359 {
360  int badArg;
361  HANDLE volumeHandle;
362  WCHAR fileSystem[1024];
363  WCHAR volumeName[1024];
365  DWORD flags, maxComponent;
366 
367  /* Initialize the Console Standard Streams */
369 
371 
372 #ifndef FMIFS_IMPORT_DLL
373  //
374  // Get function pointers
375  //
376  if (!LoadFMIFSEntryPoints())
377  {
379  return -1;
380  }
381 #endif
382 
383  //
384  // Parse command line
385  //
386  badArg = ParseCommandLine(argc, argv);
387  if (badArg)
388  {
390  Usage(argv[0]);
391  return -1;
392  }
393 
394  //
395  // Get the drive's format
396  //
397  if (!Drive)
398  {
400  {
402  return -1;
403  }
404  }
405  else
406  {
408  }
409  CurrentDirectory[2] = L'\\';
410  CurrentDirectory[3] = L'\0';
412 
413  //
414  // Determine the drive's file system format, which we need to
415  // tell chkdsk
416  //
418  volumeName,
419  ARRAYSIZE(volumeName),
420  &serialNumber,
421  &maxComponent,
422  &flags,
423  fileSystem,
424  ARRAYSIZE(fileSystem)))
425  {
427  return -1;
428  }
429 
430  //
431  // If they want to fix, we need to have access to the drive
432  //
433  if (FixErrors)
434  {
435  swprintf(volumeName, L"\\\\.\\%C:", Drive[0]);
436  volumeHandle = CreateFileW(volumeName,
438  0,
439  NULL,
441  0,
442  0);
443  if (volumeHandle == INVALID_HANDLE_VALUE)
444  {
446  return -1;
447  }
448  CloseHandle(volumeHandle);
449 
450  //
451  // Can't let the user break out of a chkdsk that can modify the drive
452  //
454  }
455 
456  //
457  // Just do it
458  //
459  ConResPrintf(StdOut, IDS_FILE_SYSTEM, fileSystem);
460  Chkdsk(Drive,
461  fileSystem,
462  FixErrors,
463  Verbose,
464  SkipClean,
465  ScanSectors,
466  NULL,
467  NULL,
469 
470  if (Error) return -1;
471  return 0;
472 }
473 
474 /* EOF */
static int argc
Definition: ServiceArgs.c:12
#define TRUE
Definition: types.h:120
Definition: fmifs.h:71
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
#define CloseHandle
Definition: compat.h:398
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
Definition: fmifs.h:72
static const BYTE serialNumber[]
Definition: msg.c:2848
static VOID Usage(PWCHAR ProgramName)
Definition: chkdsk.c:127
BOOL Verbose
Definition: chkdsk.c:72
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
Definition: fmifs.h:70
#define IDS_NO_CURRENT_DIR
Definition: resource.h:14
static VOID PrintWin32Error(int Message, DWORD ErrorCode)
Definition: chkdsk.c:91
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:413
BOOL SkipClean
Definition: chkdsk.c:70
BOOL ScanSectors
Definition: chkdsk.c:71
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
Definition: fmifs.h:68
Definition: fmifs.h:78
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
Definition: fmifs.h:73
#define IDS_USAGE
Definition: resource.h:3
uint16_t * PWCHAR
Definition: typedefs.h:54
Definition: shell.h:41
CALLBACKCOMMAND
Definition: fmifs.h:66
#define argv
Definition: mplay32.c:18
struct TEXTOUTPUT * PTEXTOUTPUT
Definition: fmifs.h:77
#define IDS_BAD_ARGUMENT
Definition: resource.h:13
#define IDS_PERCENT_COMPL
Definition: resource.h:4
#define IDS_ABOUT
Definition: resource.h:29
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
Definition: fmifs.h:80
#define ConInitStdStreams()
Definition: stream.h:122
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2111
#define GENERIC_WRITE
Definition: nt_native.h:90
PWCHAR Drive
Definition: chkdsk.c:73
INT __cdecl ConPrintf(IN PCON_STREAM Stream, IN LPWSTR szStr,...)
Definition: outstream.c:520
unsigned char BOOLEAN
#define LoadLibraryW(x)
Definition: compat.h:404
smooth NULL
Definition: ftsmooth.c:416
#define IDS_CHKDSK_FAIL
Definition: resource.h:11
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
#define OPEN_EXISTING
Definition: compat.h:426
INT __cdecl ConResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: outstream.c:781
#define FreeLibrary(x)
Definition: compat.h:405
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL Error
Definition: chkdsk.c:66
INT ConMsgPuts(IN PCON_STREAM Stream, IN DWORD dwFlags, IN LPCVOID lpSource OPTIONAL, IN DWORD dwMessageId, IN DWORD dwLanguageId)
Definition: outstream.c:837
#define StdErr
Definition: stream.h:77
GLbitfield flags
Definition: glext.h:7161
CHAR Message[80]
Definition: alive.c:5
#define IDS_VOLUME_IN_USE
Definition: resource.h:10
INT ConResPuts(IN PCON_STREAM Stream, IN UINT uID)
Definition: outstream.c:610
char * PBOOLEAN
Definition: retypes.h:11
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
int wmain(int argc, WCHAR *argv[])
Definition: chkdsk.c:358
BOOLEAN WINAPI ChkdskCallback(CALLBACKCOMMAND Command, DWORD Modifier, PVOID Argument)
Definition: chkdsk.c:222
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
VOID NTAPI Chkdsk(IN PWCHAR DriveRoot, IN PWCHAR Format, IN BOOLEAN CorrectErrors, IN BOOLEAN Verbose, IN BOOLEAN CheckOnlyIfDirty, IN BOOLEAN ScanDrive, IN PVOID Unused2, IN PVOID Unused3, IN PFMIFSCALLBACK Callback)
Definition: chkdsk.c:18
#define IDS_NO_ENTRY_POINT
Definition: resource.h:12
#define IDS_NO_QUERY_VOL
Definition: resource.h:15
DWORD * PDWORD
Definition: pedump.c:68
INT ConPuts(IN PCON_STREAM Stream, IN LPWSTR szStr)
Definition: outstream.c:427
BOOL FixErrors
Definition: chkdsk.c:69
#define CreateFileW
Definition: compat.h:400
BOOL WINAPI CtrlCIntercept(DWORD dwCtrlType)
Definition: chkdsk.c:110
Definition: fmifs.h:81
#define StdOut
Definition: stream.h:76
static int ParseCommandLine(int argc, WCHAR *argv[])
Definition: chkdsk.c:141
#define GetProcAddress(x, y)
Definition: compat.h:410
#define DONE
Definition: rnr20lib.h:14
Definition: fmifs.h:82
#define IDS_FILE_SYSTEM
Definition: resource.h:6
static SERVICE_STATUS status
Definition: service.c:31
#define IDS_VOLUME_IN_USE_PROC
Definition: resource.h:16
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
Definition: ps.c:97