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 /* DATA ****************************************************************************/ 23 24 static 25 HRESULT 26 FilterLoadUnload(_In_z_ LPCWSTR lpFilterName, 27 _In_ BOOL Load); 28 29 static 30 DWORD 31 SendIoctl(_In_ HANDLE Handle, 32 _In_ ULONG IoControlCode, 33 _In_reads_bytes_opt_(BufferSize) LPVOID lpInBuffer, 34 _In_ DWORD BufferSize); 35 36 37 /* PUBLIC FUNCTIONS ****************************************************************/ 38 39 _Must_inspect_result_ 40 HRESULT 41 WINAPI 42 FilterLoad(_In_ LPCWSTR lpFilterName) 43 { 44 return FilterLoadUnload(lpFilterName, TRUE); 45 } 46 47 _Must_inspect_result_ 48 HRESULT 49 WINAPI 50 FilterUnload(_In_ LPCWSTR lpFilterName) 51 { 52 return FilterLoadUnload(lpFilterName, FALSE); 53 } 54 55 56 /* PRIVATE FUNCTIONS ****************************************************************/ 57 58 HRESULT 59 NtStatusToHResult(_In_ NTSTATUS Status) 60 { 61 HRESULT hr; 62 hr = RtlNtStatusToDosError(Status); 63 if (hr != ERROR_SUCCESS) 64 { 65 hr = (ULONG)hr | 0x80070000; 66 } 67 return hr; 68 } 69 70 static 71 HRESULT 72 FilterLoadUnload(_In_z_ LPCWSTR lpFilterName, 73 _In_ BOOL Load) 74 { 75 PFILTER_NAME FilterName; 76 HANDLE hFltMgr; 77 SIZE_T StringLength; 78 SIZE_T BufferLength; 79 DWORD dwError; 80 81 /* Get a handle to the filter manager */ 82 hFltMgr = CreateFileW(L"\\\\.\\fltmgr", 83 GENERIC_WRITE, 84 FILE_SHARE_WRITE, 85 NULL, 86 OPEN_EXISTING, 87 FILE_ATTRIBUTE_NORMAL, 88 &hFltMgr); 89 if (hFltMgr == INVALID_HANDLE_VALUE) 90 { 91 dwError = GetLastError(); 92 return HRESULT_FROM_WIN32(dwError); 93 } 94 95 /* Calc and allocate a buffer to hold our filter name */ 96 StringLength = wcslen(lpFilterName) * sizeof(WCHAR); 97 BufferLength = StringLength + sizeof(FILTER_NAME); 98 FilterName = RtlAllocateHeap(GetProcessHeap(), 99 0, 100 BufferLength); 101 if (FilterName == NULL) 102 { 103 CloseHandle(hFltMgr); 104 return HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY); 105 } 106 107 /* Build up the filter name */ 108 FilterName->Length = StringLength; 109 CopyMemory(FilterName->FilterName, lpFilterName, StringLength); 110 111 /* Tell the filter manager to load the filter for us */ 112 dwError = SendIoctl(hFltMgr, 113 Load ? IOCTL_FILTER_LOAD : IOCTL_FILTER_UNLOAD, 114 FilterName, 115 BufferLength); 116 117 /* Cleanup and bail*/ 118 RtlFreeHeap(GetProcessHeap(), 0, FilterName); 119 CloseHandle(hFltMgr); 120 121 return HRESULT_FROM_WIN32(dwError); 122 } 123 124 static 125 DWORD 126 SendIoctl(_In_ HANDLE Handle, 127 _In_ ULONG IoControlCode, 128 _In_reads_bytes_opt_(BufferSize) LPVOID lpInBuffer, 129 _In_ DWORD BufferSize) 130 { 131 IO_STATUS_BLOCK IoStatusBlock; 132 NTSTATUS Status; 133 134 Status = NtDeviceIoControlFile(Handle, 135 NULL, 136 NULL, 137 NULL, 138 &IoStatusBlock, 139 IoControlCode, 140 lpInBuffer, 141 BufferSize, 142 NULL, 143 0); 144 if (Status == STATUS_PENDING) 145 { 146 Status = NtWaitForSingleObject(Handle, FALSE, NULL); 147 if (NT_SUCCESS(Status)) 148 { 149 Status = IoStatusBlock.Status; 150 } 151 } 152 153 return RtlNtStatusToDosError(Status); 154 } 155 156 BOOL 157 WINAPI 158 DllMain(_In_ HINSTANCE hinstDLL, 159 _In_ DWORD dwReason, 160 _In_ LPVOID lpvReserved) 161 { 162 switch (dwReason) 163 { 164 case DLL_PROCESS_ATTACH: 165 DisableThreadLibraryCalls(hinstDLL); 166 break; 167 } 168 169 return TRUE; 170 }