[FLTLIB]
[reactos.git] / reactos / dll / win32 / fltlib / fltlib.c
1 /*
2 * PROJECT: Filesystem Filter Manager library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/fltlib/fltlib.c
5 * PURPOSE:
6 * PROGRAMMERS: Ged Murphy (ged.murphy@reactos.org)
7 */
8
9 #include <stdarg.h>
10
11 #define WIN32_NO_STATUS
12
13 #include "windef.h"
14 #include "winbase.h"
15
16 #define NTOS_MODE_USER
17 #include <ndk/iofuncs.h>
18 #include <ndk/obfuncs.h>
19 #include <ndk/rtlfuncs.h>
20 #include <fltmgr_shared.h>
21
22 #include "wine/debug.h"
23
24
25 /* DATA ****************************************************************************/
26
27 WINE_DEFAULT_DEBUG_CHANNEL(fltlib);
28
29 static
30 HRESULT
31 FilterLoadUnload(_In_z_ LPCWSTR lpFilterName,
32 _In_ BOOL Load);
33
34 static
35 DWORD
36 SendIoctl(_In_ HANDLE Handle,
37 _In_ ULONG IoControlCode,
38 _In_reads_bytes_opt_(BufferSize) LPVOID lpInBuffer,
39 _In_ DWORD BufferSize);
40
41
42 /* PUBLIC FUNCTIONS ****************************************************************/
43
44 _Must_inspect_result_
45 HRESULT
46 WINAPI
47 FilterLoad(_In_ LPCWSTR lpFilterName)
48 {
49 return FilterLoadUnload(lpFilterName, TRUE);
50 }
51
52 _Must_inspect_result_
53 HRESULT
54 WINAPI
55 FilterUnload(_In_ LPCWSTR lpFilterName)
56 {
57 return FilterLoadUnload(lpFilterName, FALSE);
58 }
59
60
61 /* PRIVATE FUNCTIONS ****************************************************************/
62
63 HRESULT
64 NtStatusToHResult(_In_ NTSTATUS Status)
65 {
66 HRESULT hr;
67 hr = RtlNtStatusToDosError(Status);
68 if (hr != ERROR_SUCCESS)
69 {
70 hr = (ULONG)hr | 0x80070000;
71 }
72 return hr;
73 }
74
75 static
76 HRESULT
77 FilterLoadUnload(_In_z_ LPCWSTR lpFilterName,
78 _In_ BOOL Load)
79 {
80 PFILTER_NAME FilterName;
81 HANDLE hFltMgr;
82 DWORD StringLength;
83 DWORD BufferLength;
84 DWORD dwError;
85
86 /* Get a handle to the filter manager */
87 hFltMgr = CreateFileW(L"\\\\.\\fltmgr",
88 GENERIC_WRITE,
89 FILE_SHARE_WRITE,
90 NULL,
91 OPEN_EXISTING,
92 FILE_ATTRIBUTE_NORMAL,
93 &hFltMgr);
94 if (hFltMgr == INVALID_HANDLE_VALUE)
95 {
96 dwError = GetLastError();
97 return HRESULT_FROM_WIN32(dwError);
98 }
99
100 /* Calc and allocate a buffer to hold our filter name */
101 StringLength = wcslen(lpFilterName) * sizeof(WCHAR);
102 BufferLength = StringLength + sizeof(FILTER_NAME);
103 FilterName = RtlAllocateHeap(GetProcessHeap(),
104 0,
105 BufferLength);
106 if (FilterName == NULL)
107 {
108 CloseHandle(hFltMgr);
109 return HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
110 }
111
112 /* Build up the filter name */
113 FilterName->Length = StringLength;
114 CopyMemory(FilterName->FilterName, lpFilterName, StringLength);
115
116 /* Tell the filter manager to load the filter for us */
117 dwError = SendIoctl(hFltMgr,
118 Load ? IOCTL_FILTER_LOAD : IOCTL_FILTER_UNLOAD,
119 FilterName,
120 BufferLength);
121
122 /* Cleanup and bail*/
123 RtlFreeHeap(GetProcessHeap(), 0, FilterName);
124 CloseHandle(hFltMgr);
125
126 return HRESULT_FROM_WIN32(dwError);
127 }
128
129 static
130 DWORD
131 SendIoctl(_In_ HANDLE Handle,
132 _In_ ULONG IoControlCode,
133 _In_reads_bytes_opt_(BufferSize) LPVOID lpInBuffer,
134 _In_ DWORD BufferSize)
135 {
136 IO_STATUS_BLOCK IoStatusBlock;
137 NTSTATUS Status;
138
139 Status = NtDeviceIoControlFile(Handle,
140 NULL,
141 NULL,
142 NULL,
143 &IoStatusBlock,
144 IoControlCode,
145 lpInBuffer,
146 BufferSize,
147 NULL,
148 0);
149 if (Status == STATUS_PENDING)
150 {
151 Status = NtWaitForSingleObject(Handle, FALSE, NULL);
152 if (NT_SUCCESS(Status))
153 {
154 Status = IoStatusBlock.Status;
155 }
156 }
157
158 return RtlNtStatusToDosError(Status);
159 }
160
161 BOOL
162 WINAPI
163 DllMain(_In_ HINSTANCE hinstDLL,
164 _In_ DWORD dwReason,
165 _In_ LPVOID lpvReserved)
166 {
167 switch (dwReason)
168 {
169 case DLL_PROCESS_ATTACH:
170 DisableThreadLibraryCalls(hinstDLL);
171 break;
172 }
173
174 return TRUE;
175 }