ReactOS 0.4.15-dev-6069-g56a4501
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//
80PCHKDSK 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//--------------------------------------------------------------------
108BOOL
109WINAPI
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//----------------------------------------------------------------------
126static VOID
127Usage(PWCHAR ProgramName)
128{
129 ConResPrintf(StdOut, IDS_USAGE, ProgramName);
130}
131
132
133//----------------------------------------------------------------------
134//
135// ParseCommandLine
136//
137// Get the switches.
138//
139//----------------------------------------------------------------------
140static 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;
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//----------------------------------------------------------------------
221WINAPI
224 DWORD Modifier,
225 PVOID Argument)
226{
227 BOOLEAN Ret;
228 PDWORD percent;
230 PTEXTOUTPUT output;
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
281 ConPuts(StdOut, L"INSUFFICIENTRIGHTS\n");
282 break;
283
285 ConPuts(StdOut, L"STRUCTUREPROGRESS\n");
286 break;
287
289 ConPuts(StdOut, L"DONEWITHSTRUCTURE\n");
290 break;
291
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//----------------------------------------------------------------------
326static BOOLEAN
327LoadFMIFSEntryPoints(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//----------------------------------------------------------------------
357int
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),
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);
461 fileSystem,
462 FixErrors,
463 Verbose,
464 SkipClean,
466 NULL,
467 NULL,
469
470 if (Error) return -1;
471 return 0;
472}
473
474/* EOF */
unsigned char BOOLEAN
static int argc
Definition: ServiceArgs.c:12
#define IDS_ABOUT
Definition: resource.h:29
#define IDS_USAGE
Definition: resource.h:3
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: fc.c:16
#define ConInitStdStreams()
Definition: fc.c:13
void ConPrintf(FILE *fp, LPCWSTR psz,...)
Definition: fc.c:20
#define StdOut
Definition: fc.c:14
void ConResPrintf(FILE *fp, UINT nID,...)
Definition: fc.c:33
#define StdErr
Definition: fc.c:15
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
BOOL FixErrors
Definition: chkdsk.c:69
BOOL Error
Definition: chkdsk.c:66
PWCHAR Drive
Definition: chkdsk.c:73
static VOID PrintWin32Error(int Message, DWORD ErrorCode)
Definition: chkdsk.c:91
BOOL Verbose
Definition: chkdsk.c:72
static int ParseCommandLine(int argc, WCHAR *argv[])
Definition: chkdsk.c:141
BOOL WINAPI CtrlCIntercept(DWORD dwCtrlType)
Definition: chkdsk.c:110
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
BOOL SkipClean
Definition: chkdsk.c:70
BOOL ScanSectors
Definition: chkdsk.c:71
#define IDS_PERCENT_COMPL
Definition: resource.h:4
#define IDS_NO_ENTRY_POINT
Definition: resource.h:12
#define IDS_CHKDSK_FAIL
Definition: resource.h:11
#define IDS_BAD_ARGUMENT
Definition: resource.h:13
#define IDS_NO_QUERY_VOL
Definition: resource.h:15
#define IDS_FILE_SYSTEM
Definition: resource.h:6
#define IDS_VOLUME_IN_USE_PROC
Definition: resource.h:16
#define IDS_NO_CURRENT_DIR
Definition: resource.h:14
#define IDS_VOLUME_IN_USE
Definition: resource.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define OPEN_EXISTING
Definition: compat.h:775
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define FreeLibrary(x)
Definition: compat.h:748
#define CreateFileW
Definition: compat.h:741
#define LoadLibraryW(x)
Definition: compat.h:747
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
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
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
#define swprintf
Definition: precomp.h:40
static const WCHAR Message[]
Definition: register.c:74
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
struct TEXTOUTPUT * PTEXTOUTPUT
CALLBACKCOMMAND
Definition: fmifs.h:67
@ 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
GLbitfield flags
Definition: glext.h:7161
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
_Must_inspect_result_ _In_ USAGE _In_ USHORT _In_ USAGE Usage
Definition: hidpi.h:384
static const BYTE serialNumber[]
Definition: msg.c:2848
#define argv
Definition: mplay32.c:18
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define GENERIC_WRITE
Definition: nt_native.h:90
#define L(x)
Definition: ntvdm.h:50
INT ConMsgPuts(IN PCON_STREAM Stream, IN DWORD dwFlags, IN LPCVOID lpSource OPTIONAL, IN DWORD dwMessageId, IN DWORD dwLanguageId)
Definition: outstream.c:837
DWORD * PDWORD
Definition: pedump.c:68
int wmain()
#define DONE
Definition: rnr20lib.h:14
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
Definition: shell.h:41
PCHAR Output
Definition: fmifs.h:33
Definition: ps.c:97
#define LANG_USER_DEFAULT
Definition: tnerror.cpp:50
unsigned char * PBOOLEAN
Definition: typedefs.h:53
uint16_t * PWCHAR
Definition: typedefs.h:56
PFMIFSCALLBACK ChkdskCallback
Definition: vfatlib.c:43
DWORD WINAPI GetLastError(void)
Definition: except.c:1040
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180