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 HandlerProc QueryMain;
14 static HandlerProc SetMain;
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     ULONG VolumeStatus, BytesRead;
27 
28     /* We need a volume (letter or GUID) */
29     if (argc < 2)
30     {
31         _ftprintf(stderr, _T("Usage: fsutil dirty query <volume>\n"));
32         _ftprintf(stderr, _T("\tFor example: fsutil dirty query c:\n"));
33         return 1;
34     }
35 
36     /* Get a handle for the volume */
37     Volume = OpenVolume(argv[1], FALSE, FALSE);
38     if (Volume == INVALID_HANDLE_VALUE)
39     {
40         return 1;
41     }
42 
43     /* And query the dirty status */
44     if (DeviceIoControl(Volume, FSCTL_IS_VOLUME_DIRTY, NULL, 0, &VolumeStatus,
45                         sizeof(ULONG), &BytesRead, NULL) == FALSE)
46     {
47         PrintErrorMessage(GetLastError());
48         CloseHandle(Volume);
49         return 1;
50     }
51 
52     CloseHandle(Volume);
53 
54     /* Print the status */
55     _ftprintf(stdout, _T("The %s volume is %s\n"), argv[1], ((VolumeStatus & VOLUME_IS_DIRTY) ? _T("dirty") : _T("clean")));
56 
57     return 0;
58 }
59 
60 static int
61 SetMain(int argc, const TCHAR *argv[])
62 {
63     HANDLE Volume;
64     DWORD BytesRead;
65 
66     /* We need a volume (letter or GUID) */
67     if (argc < 2)
68     {
69         _ftprintf(stderr, _T("Usage: fsutil dirty set <volume>\n"));
70         _ftprintf(stderr, _T("\tFor example: fsutil dirty set c:\n"));
71         return 1;
72     }
73 
74     /* Get a handle for the volume */
75     Volume = OpenVolume(argv[1], FALSE, FALSE);
76     if (Volume == INVALID_HANDLE_VALUE)
77     {
78         return 1;
79     }
80 
81     /* And set the dirty bit */
82     if (DeviceIoControl(Volume, FSCTL_MARK_VOLUME_DIRTY, NULL, 0, NULL, 0, &BytesRead, NULL) == FALSE)
83     {
84         PrintErrorMessage(GetLastError());
85         CloseHandle(Volume);
86         return 1;
87     }
88 
89     CloseHandle(Volume);
90 
91     /* Print the status */
92     _ftprintf(stdout, _T("The %s volume is now marked as dirty\n"), argv[1]);
93 
94     return 0;
95 }
96 
97 static void
98 PrintUsage(const TCHAR * Command)
99 {
100     PrintDefaultUsage(_T(" DIRTY "), Command, (HandlerItem *)&HandlersList,
101                       (sizeof(HandlersList) / sizeof(HandlersList[0])));
102 }
103 
104 int
105 DirtyMain(int argc, const TCHAR *argv[])
106 {
107     return FindHandler(argc, argv, (HandlerItem *)&HandlersList,
108                        (sizeof(HandlersList) / sizeof(HandlersList[0])),
109                        PrintUsage);
110 }
111