1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS FS utility tool
4  * FILE:            base/applications/cmdutils/common.c
5  * PURPOSE:         FSutil common functions
6  * PROGRAMMERS:     Pierre Schweitzer <pierre@reactos.org>
7  */
8 
9 #include "fsutil.h"
10 
11 int FindHandler(int argc,
12                 const TCHAR *argv[],
13                 HandlerItem * HandlersList,
14                 int HandlerListCount,
15                 void (*UsageHelper)(const TCHAR *))
16 {
17     int i;
18     int ret;
19     const TCHAR * Command;
20 
21     ret = 1;
22     Command = NULL;
23     i = HandlerListCount;
24 
25     /* If we have a command, does it match a known one? */
26     if (argc > 1)
27     {
28         /* Browse all the known commands finding the right one */
29         Command = argv[1];
30         for (i = 0; i < HandlerListCount; ++i)
31         {
32             if (_tcsicmp(Command, HandlersList[i].Command) == 0)
33             {
34                 ret = HandlersList[i].Handler(argc - 1, &argv[1]);
35                 break;
36             }
37         }
38     }
39 
40     /* We failed finding someone to handle the caller's needs, print out */
41     if (i == HandlerListCount)
42     {
43         UsageHelper(Command);
44     }
45 
46     return ret;
47 }
48 
49 HANDLE OpenVolume(const TCHAR * Volume,
50                   BOOLEAN AllowRemote,
51                   BOOLEAN NtfsOnly)
52 {
53     UINT Type;
54     HANDLE hVolume;
55     TCHAR VolumeID[PATH_MAX];
56 
57     /* Get volume type */
58     if (!AllowRemote && Volume[1] == L':')
59     {
60         Type = GetDriveType(Volume);
61         if (Type == DRIVE_REMOTE)
62         {
63             _ftprintf(stderr, _T("FSUTIL needs a local device\n"));
64             return INVALID_HANDLE_VALUE;
65         }
66     }
67 
68     /* Get filesystem type */
69     if (NtfsOnly)
70     {
71         TCHAR FileSystem[MAX_PATH + 1];
72 
73         _stprintf(VolumeID, _T("\\\\.\\%s\\"), Volume);
74         if (!GetVolumeInformation(VolumeID, NULL,  0, NULL, NULL, NULL, FileSystem, MAX_PATH + 1))
75         {
76             PrintErrorMessage(GetLastError());
77             return INVALID_HANDLE_VALUE;
78         }
79 
80         if (_tcscmp(FileSystem, _T("NTFS")) != 0)
81         {
82             _ftprintf(stderr, _T("FSUTIL needs a NTFS device\n"));
83             return INVALID_HANDLE_VALUE;
84         }
85     }
86 
87     /* Create full name */
88     _stprintf(VolumeID, _T("\\\\.\\%s"), Volume);
89 
90     /* Open the volume */
91     hVolume = CreateFile(VolumeID, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
92                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
93     if (hVolume == INVALID_HANDLE_VALUE)
94     {
95         PrintErrorMessage(GetLastError());
96         return INVALID_HANDLE_VALUE;
97     }
98 
99     return hVolume;
100 }
101 
102 void PrintDefaultUsage(const TCHAR * Command,
103                        const TCHAR * SubCommand,
104                        HandlerItem * HandlersList,
105                        int HandlerListCount)
106 {
107     int i;
108 
109     /* If we were given a command, print it's not supported */
110     if (SubCommand != NULL)
111     {
112         _ftprintf(stderr, _T("Unhandled%scommand: %s\n"), Command, SubCommand);
113     }
114 
115     /* And dump any available command */
116     _ftprintf(stderr, _T("---- Handled%scommands ----\n\n"), Command);
117     for (i = 0; i < HandlerListCount; ++i)
118     {
119         _ftprintf(stderr, _T("%s\t%s\n"), HandlersList[i].Command, HandlersList[i].Desc);
120     }
121 }
122 
123 int PrintErrorMessage(DWORD Error)
124 {
125     TCHAR * String;
126 
127     /* Try to get textual error */
128     if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
129                        NULL, Error, 0, (TCHAR *)&String, 0, NULL) != 0)
130     {
131         /* And print it */
132         _ftprintf(stderr, _T("Error: %s\n"), String);
133         LocalFree(String);
134     }
135     else
136     {
137         /* Otherwise, just print the error number */
138         _ftprintf(stderr, _T("Error: %d\n"), Error);
139     }
140 
141     return Error;
142 }
143