[FSUTIL]
[reactos.git] / reactos / base / applications / cmdutils / fsutil / dirty.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS FS utility tool
4 * FILE: base/applications/cmdutils/dirty.c
5 * PURPOSE: FSutil dirty bit handling
6 * PROGRAMMERS: Pierre Schweitzer <pierre@reactos.org>
7 */
8
9 #include "fsutil.h"
10 #include <winioctl.h>
11
12 /* Add handlers here for subcommands */
13 static int QueryMain(int argc, const TCHAR *argv[]);
14 static int SetMain(int argc, const TCHAR *argv[]);
15 static HandlerItem HandlersList[] =
16 {
17 /* Proc, name, help */
18 { QueryMain, _T("query"), _T("Show the dirty bit") },
19 { SetMain, _T("set"), _T("Set the dirty bit") },
20 };
21
22 static int
23 QueryMain(int argc, const TCHAR *argv[])
24 {
25 HANDLE Volume;
26 TCHAR VolumeID[PATH_MAX];
27 ULONG VolumeStatus, BytesRead;
28
29 /* We need a volume (letter or GUID) */
30 if (argc < 2)
31 {
32 _ftprintf(stderr, _T("Usage: fsutil dirty query <volume>\n"));
33 _ftprintf(stderr, _T("\tFor example: fsutil dirty query c:\n"));
34 return 1;
35 }
36
37 /* Create full name */
38 _stprintf(VolumeID, _T("\\\\.\\%s"), argv[1]);
39
40 /* Open the volume */
41 Volume = CreateFile(VolumeID, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
42 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
43 if (Volume == INVALID_HANDLE_VALUE)
44 {
45 _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
46 return 1;
47 }
48
49 /* And query the dirty status */
50 if (DeviceIoControl(Volume, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &VolumeStatus,
51 sizeof(ULONG), &BytesRead, NULL) == FALSE)
52 {
53 _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
54 CloseHandle(Volume);
55 return 1;
56 }
57
58 CloseHandle(Volume);
59
60 /* Print the status */
61 _ftprintf(stdout, _T("The %s volume is %s\n"), argv[1], (VolumeStatus & VOLUME_IS_DIRTY ? _T("dirty") : _T("clean")));
62
63 return 0;
64 }
65
66 static int
67 SetMain(int argc, const TCHAR *argv[])
68 {
69 HANDLE Volume;
70 DWORD BytesRead;
71 TCHAR VolumeID[PATH_MAX];
72
73 /* We need a volume (letter or GUID) */
74 if (argc < 2)
75 {
76 _ftprintf(stderr, _T("Usage: fsutil dirty set <volume>\n"));
77 _ftprintf(stderr, _T("\tFor example: fsutil dirty set c:\n"));
78 return 1;
79 }
80
81 /* Create full name */
82 _stprintf(VolumeID, _T("\\\\.\\%s"), argv[1]);
83
84 /* Open the volume */
85 Volume = CreateFile(VolumeID, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
86 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
87 if (Volume == INVALID_HANDLE_VALUE)
88 {
89 _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
90 return 1;
91 }
92
93 /* And set the dirty bit */
94 if (DeviceIoControl(Volume, FSCTL_MARK_VOLUME_DIRTY, NULL, 0, NULL, 0, &BytesRead, NULL) == FALSE)
95 {
96 _ftprintf(stderr, _T("Error: %d\n"), GetLastError());
97 CloseHandle(Volume);
98 return 1;
99 }
100
101 CloseHandle(Volume);
102
103 /* Print the status */
104 _ftprintf(stdout, _T("The %s volume is now marked as dirty\n"), argv[1]);
105
106 return 0;
107 }
108
109 static void
110 PrintUsage(const TCHAR * Command)
111 {
112 PrintDefaultUsage(_T(" DIRTY "), Command, (HandlerItem *)&HandlersList,
113 (sizeof(HandlersList) / sizeof(HandlersList[0])));
114 }
115
116 int
117 DirtyMain(int argc, const TCHAR *argv[])
118 {
119 return FindHandler(argc, argv, (HandlerItem *)&HandlersList,
120 (sizeof(HandlersList) / sizeof(HandlersList[0])),
121 PrintUsage);
122 }