[PRINTING]
[reactos.git] / reactos / base / applications / fltmc / fltmc.cpp
1 /*
2 * PROJECT: ReactOS fltmc utility
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/fltmc/fltmc.c
5 * PURPOSE: Control utility for file system filter drivers
6 * PROGRAMMERS: Copyright 2016 Ged Murphy (gedmurphy@gmail.com)
7 */
8
9 //FIXME
10 #define NTDDI_VERSION NTDDI_WIN7
11
12 // Please leave this temporary hack in place
13 // it's used to keep VS2015 happy for development.
14 #ifdef __REACTOS__
15 #include <stdarg.h>
16 #include <windef.h>
17 #include <winbase.h>
18 #include <wchar.h>
19 #else
20 #include <Windows.h>
21 #endif
22 #include <fltuser.h>
23 #include <atlstr.h>
24 #include "resource.h"
25
26 EXTERN_C int wmain(int argc, WCHAR *argv[]);
27
28 void
29 LoadAndPrintString(ULONG MessageId, ...)
30 {
31 va_list args;
32
33 CAtlStringW Message;
34 if (Message.LoadStringW(MessageId))
35 {
36 va_start(args, MessageId);
37 vwprintf(Message.GetBuffer(), args);
38 va_end(args);
39 }
40 }
41
42 void
43 PrintErrorText(_In_ ULONG ErrorCode)
44 {
45 WCHAR Buffer[256];
46 if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,
47 0,
48 ErrorCode,
49 0,
50 Buffer,
51 256,
52 0))
53 {
54 wprintf(L"%s\n", Buffer);
55 }
56 }
57
58 DWORD
59 SetDriverLoadPrivilege()
60 {
61 TOKEN_PRIVILEGES TokenPrivileges;
62 HANDLE hToken;
63 LUID luid;
64 BOOL bSuccess;
65 DWORD dwError = ERROR_SUCCESS;
66
67 bSuccess = OpenProcessToken(GetCurrentProcess(),
68 TOKEN_ADJUST_PRIVILEGES,
69 &hToken);
70 if (bSuccess == FALSE)
71 return GetLastError();
72
73 if (!LookupPrivilegeValueW(NULL, SE_LOAD_DRIVER_NAME, &luid))
74 return GetLastError();
75
76 TokenPrivileges.PrivilegeCount = 1;
77 TokenPrivileges.Privileges[0].Luid = luid;
78 TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
79
80 bSuccess = AdjustTokenPrivileges(hToken,
81 FALSE,
82 &TokenPrivileges,
83 sizeof(TOKEN_PRIVILEGES),
84 NULL,
85 NULL);
86 if (bSuccess == FALSE)
87 dwError = GetLastError();
88
89 CloseHandle(hToken);
90
91 return dwError;
92 }
93
94 void
95 LoadFilter(_In_ LPWSTR FilterName)
96 {
97 DWORD dwError;
98 dwError = SetDriverLoadPrivilege();
99 if (dwError != ERROR_SUCCESS)
100 {
101 LoadAndPrintString(IDS_ERROR_PRIV, HRESULT_FROM_WIN32(dwError));
102 return;
103 }
104
105 HRESULT hr = FilterLoad(FilterName);
106 if (hr != S_OK)
107 {
108 LoadAndPrintString(IDS_ERROR_LOAD, hr);
109 PrintErrorText(hr);
110 }
111 }
112
113 void
114 UnloadFilter(_In_ LPWSTR FilterName)
115 {
116 DWORD dwError;
117 dwError = SetDriverLoadPrivilege();
118 if (dwError != ERROR_SUCCESS)
119 {
120 LoadAndPrintString(IDS_ERROR_PRIV, HRESULT_FROM_WIN32(dwError));
121 return;
122 }
123
124 HRESULT hr = FilterUnload(FilterName);
125 if (hr != S_OK)
126 {
127 LoadAndPrintString(IDS_ERROR_UNLOAD, hr);
128 PrintErrorText(hr);
129 }
130 }
131
132 void
133 PrintFilterInfo(_In_ PVOID Buffer,
134 _In_ BOOL IsNewStyle)
135 {
136 WCHAR FilterName[128] = { 0 };
137 WCHAR Altitude[64] = { 0 };
138
139 if (IsNewStyle)
140 {
141 PFILTER_AGGREGATE_STANDARD_INFORMATION FilterAggInfo;
142 FilterAggInfo = (PFILTER_AGGREGATE_STANDARD_INFORMATION)Buffer;
143
144 if (FilterAggInfo->Type.MiniFilter.FilterNameLength < 128)
145 {
146 CopyMemory(FilterName,
147 (PCHAR)FilterAggInfo + FilterAggInfo->Type.MiniFilter.FilterNameBufferOffset,
148 FilterAggInfo->Type.MiniFilter.FilterNameLength);
149 FilterName[FilterAggInfo->Type.MiniFilter.FilterNameLength] = UNICODE_NULL;
150 }
151
152 if (FilterAggInfo->Type.MiniFilter.FilterNameLength < 64)
153 {
154 CopyMemory(Altitude,
155 (PCHAR)FilterAggInfo + FilterAggInfo->Type.MiniFilter.FilterAltitudeBufferOffset,
156 FilterAggInfo->Type.MiniFilter.FilterAltitudeLength);
157 FilterName[FilterAggInfo->Type.MiniFilter.FilterAltitudeLength] = UNICODE_NULL;
158 }
159
160 wprintf(L"%-38s %-10lu %-10s %-10lu\n",
161 FilterName,
162 FilterAggInfo->Type.MiniFilter.NumberOfInstances,
163 Altitude,
164 FilterAggInfo->Type.MiniFilter.FrameID);
165 }
166 else
167 {
168 PFILTER_FULL_INFORMATION FilterInfo;
169 FilterInfo = (PFILTER_FULL_INFORMATION)Buffer;
170
171 if (FilterInfo->FilterNameLength < 128)
172 {
173 CopyMemory(FilterName,
174 FilterInfo->FilterNameBuffer,
175 FilterInfo->FilterNameLength);
176 FilterName[FilterInfo->FilterNameLength] = UNICODE_NULL;
177 }
178
179 wprintf(L"%-38s %-10lu %-10lu\n",
180 FilterName,
181 FilterInfo->NumberOfInstances,
182 FilterInfo->FrameID);
183 }
184 }
185
186 void
187 ListFilters()
188 {
189 HANDLE FindHandle;
190 BYTE Buffer[1024];
191 ULONG BytesReturned;
192 BOOL IsNewStyle = TRUE;
193 HRESULT hr;
194
195 hr = FilterFindFirst(FilterAggregateStandardInformation,
196 Buffer,
197 1024,
198 &BytesReturned,
199 &FindHandle);
200 if (!SUCCEEDED(hr))
201 {
202 IsNewStyle = FALSE;
203 hr = FilterFindFirst(FilterFullInformation,
204 Buffer,
205 1024,
206 &BytesReturned,
207 &FindHandle);
208 }
209
210 if (SUCCEEDED(hr))
211 {
212 if (IsNewStyle)
213 {
214 LoadAndPrintString(IDS_DISPLAY_FILTERS1);
215 wprintf(L"------------------------------ ------------- ------------ -----\n");
216 }
217 else
218 {
219 LoadAndPrintString(IDS_DISPLAY_FILTERS2);
220 wprintf(L"------------------------------ ------------- -----\n");
221 }
222
223 PrintFilterInfo(Buffer, IsNewStyle);
224
225 do
226 {
227 hr = FilterFindNext(FindHandle,
228 IsNewStyle ? FilterAggregateStandardInformation : FilterFullInformation,
229 Buffer,
230 1024,
231 &BytesReturned);
232 if (SUCCEEDED(hr))
233 {
234 PrintFilterInfo(Buffer, IsNewStyle);
235 }
236
237 } while (SUCCEEDED(hr));
238
239 FilterFindClose(FindHandle);
240 }
241
242 if (!SUCCEEDED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS))
243 {
244 LoadAndPrintString(IDS_ERROR_PRIV, hr);
245 PrintErrorText(hr);
246 }
247 }
248
249 int wmain(int argc, WCHAR *argv[])
250 {
251 if (argc < 2)
252 {
253 LoadAndPrintString(IDS_USAGE);
254 return 0;
255 }
256
257 wprintf(L"\n");
258
259 if (!_wcsicmp(argv[1], L"help"))
260 {
261 LoadAndPrintString(IDS_USAGE);
262 }
263 else if (!_wcsicmp(argv[1], L"load"))
264 {
265 if (argc == 3)
266 {
267 LoadFilter(argv[2]);
268 }
269 else
270 {
271 LoadAndPrintString(IDS_USAGE_LOAD);
272 wprintf(L"fltmc.exe load [name]\n\n");
273 }
274 }
275 else if (!_wcsicmp(argv[1], L"unload"))
276 {
277 if (argc == 3)
278 {
279 UnloadFilter(argv[2]);
280 }
281 else
282 {
283 LoadAndPrintString(IDS_USAGE_UNLOAD);
284 wprintf(L"fltmc.exe unload [name]\n\n");
285 }
286 }
287 else if (!_wcsicmp(argv[1], L"filters"))
288 {
289 if (argc == 2)
290 {
291 ListFilters();
292 }
293 else
294 {
295 LoadAndPrintString(IDS_USAGE_FILTERS);
296 wprintf(L"fltmc.exe filters\n\n");
297 }
298 }
299
300 return 0;
301 }