From 0b589c107d19989788d17c044c16e048304deda7 Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 9 Aug 2016 21:33:53 +0000 Subject: [PATCH] [FLTMC] - Start to implement fltMC - It currently supports loading, unloading and listing loaded filter driver. svn path=/trunk/; revision=72174 --- .../base/applications/fltmc/CMakeLists.txt | 9 + reactos/base/applications/fltmc/fltmc.cpp | 301 ++++++++++++++++++ reactos/base/applications/fltmc/fltmc.rc | 60 ++++ reactos/base/applications/fltmc/lang/en-US.rc | 27 ++ reactos/base/applications/fltmc/resource.h | 14 + 5 files changed, 411 insertions(+) create mode 100644 reactos/base/applications/fltmc/CMakeLists.txt create mode 100644 reactos/base/applications/fltmc/fltmc.cpp create mode 100644 reactos/base/applications/fltmc/fltmc.rc create mode 100644 reactos/base/applications/fltmc/lang/en-US.rc create mode 100644 reactos/base/applications/fltmc/resource.h diff --git a/reactos/base/applications/fltmc/CMakeLists.txt b/reactos/base/applications/fltmc/CMakeLists.txt new file mode 100644 index 00000000000..0ac7538164b --- /dev/null +++ b/reactos/base/applications/fltmc/CMakeLists.txt @@ -0,0 +1,9 @@ + +set_cpp(WITH_RUNTIME WITH_EXCEPTIONS) + +include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/atl) + +add_executable(fltmc fltmc.cpp fltmc.rc) +set_module_type(fltmc win32cui UNICODE) +add_importlibs(fltmc fltlib msvcrt kernel32 advapi32) +add_cd_file(TARGET fltmc DESTINATION reactos/system32 FOR all) diff --git a/reactos/base/applications/fltmc/fltmc.cpp b/reactos/base/applications/fltmc/fltmc.cpp new file mode 100644 index 00000000000..f8f3cdf49ae --- /dev/null +++ b/reactos/base/applications/fltmc/fltmc.cpp @@ -0,0 +1,301 @@ +/* +* PROJECT: ReactOS fltmc utility +* LICENSE: GPL - See COPYING in the top level directory +* FILE: base/applications/fltmc/fltmc.c +* PURPOSE: Control utility for file system filter drivers +* PROGRAMMERS: Copyright 2016 Ged Murphy (gedmurphy@gmail.com) +*/ + +//FIXME +#define NTDDI_VERSION NTDDI_WIN7 + +// Please leave this temporary hack in place +// it's used to keep VS2015 happy for development. +#ifdef __REACTOS__ +#include +#include +#include +#include +#else +#include +#endif +#include +#include +#include "resource.h" + +EXTERN_C int wmain(int argc, WCHAR *argv[]); + +void +LoadAndPrintString(ULONG MessageId, ...) +{ + va_list args; + + CAtlStringW Message; + if (Message.LoadStringW(MessageId)) + { + va_start(args, MessageId); + vwprintf(Message.GetBuffer(), args); + va_end(args); + } +} + +void +PrintErrorText(_In_ ULONG ErrorCode) +{ + WCHAR Buffer[256]; + if (FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, + 0, + ErrorCode, + 0, + Buffer, + 256, + 0)) + { + wprintf(L"%s\n", Buffer); + } +} + +DWORD +SetDriverLoadPrivilege() +{ + TOKEN_PRIVILEGES TokenPrivileges; + HANDLE hToken; + LUID luid; + BOOL bSuccess; + DWORD dwError = ERROR_SUCCESS; + + bSuccess = OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &hToken); + if (bSuccess == FALSE) + return GetLastError(); + + if (!LookupPrivilegeValueW(NULL, SE_LOAD_DRIVER_NAME, &luid)) + return GetLastError(); + + TokenPrivileges.PrivilegeCount = 1; + TokenPrivileges.Privileges[0].Luid = luid; + TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + bSuccess = AdjustTokenPrivileges(hToken, + FALSE, + &TokenPrivileges, + sizeof(TOKEN_PRIVILEGES), + NULL, + NULL); + if (bSuccess == FALSE) + dwError = GetLastError(); + + CloseHandle(hToken); + + return dwError; +} + +void +LoadFilter(_In_ LPWSTR FilterName) +{ + DWORD dwError; + dwError = SetDriverLoadPrivilege(); + if (dwError != ERROR_SUCCESS) + { + LoadAndPrintString(IDS_ERROR_PRIV, HRESULT_FROM_WIN32(dwError)); + return; + } + + HRESULT hr = FilterLoad(FilterName); + if (hr != S_OK) + { + LoadAndPrintString(IDS_ERROR_LOAD, hr); + PrintErrorText(hr); + } +} + +void +UnloadFilter(_In_ LPWSTR FilterName) +{ + DWORD dwError; + dwError = SetDriverLoadPrivilege(); + if (dwError != ERROR_SUCCESS) + { + LoadAndPrintString(IDS_ERROR_PRIV, HRESULT_FROM_WIN32(dwError)); + return; + } + + HRESULT hr = FilterUnload(FilterName); + if (hr != S_OK) + { + LoadAndPrintString(IDS_ERROR_UNLOAD, hr); + PrintErrorText(hr); + } +} + +void +PrintFilterInfo(_In_ PVOID Buffer, + _In_ BOOL IsNewStyle) +{ + WCHAR FilterName[128] = { 0 }; + WCHAR Altitude[64] = { 0 }; + + if (IsNewStyle) + { + PFILTER_AGGREGATE_STANDARD_INFORMATION FilterAggInfo; + FilterAggInfo = (PFILTER_AGGREGATE_STANDARD_INFORMATION)Buffer; + + if (FilterAggInfo->Type.MiniFilter.FilterNameLength < 128) + { + CopyMemory(FilterName, + (PCHAR)FilterAggInfo + FilterAggInfo->Type.MiniFilter.FilterNameBufferOffset, + FilterAggInfo->Type.MiniFilter.FilterNameLength); + FilterName[FilterAggInfo->Type.MiniFilter.FilterNameLength] = UNICODE_NULL; + } + + if (FilterAggInfo->Type.MiniFilter.FilterNameLength < 64) + { + CopyMemory(Altitude, + (PCHAR)FilterAggInfo + FilterAggInfo->Type.MiniFilter.FilterAltitudeBufferOffset, + FilterAggInfo->Type.MiniFilter.FilterAltitudeLength); + FilterName[FilterAggInfo->Type.MiniFilter.FilterAltitudeLength] = UNICODE_NULL; + } + + wprintf(L"%-38s %-10lu %-10s %-10lu\n", + FilterName, + FilterAggInfo->Type.MiniFilter.NumberOfInstances, + Altitude, + FilterAggInfo->Type.MiniFilter.FrameID); + } + else + { + PFILTER_FULL_INFORMATION FilterInfo; + FilterInfo = (PFILTER_FULL_INFORMATION)Buffer; + + if (FilterInfo->FilterNameLength < 128) + { + CopyMemory(FilterName, + FilterInfo->FilterNameBuffer, + FilterInfo->FilterNameLength); + FilterName[FilterInfo->FilterNameLength] = UNICODE_NULL; + } + + wprintf(L"%-38s %-10lu %-10lu\n", + FilterName, + FilterInfo->NumberOfInstances, + FilterInfo->FrameID); + } +} + +void +ListFilters() +{ + HANDLE FindHandle; + BYTE Buffer[1024]; + ULONG BytesReturned; + BOOL IsNewStyle = TRUE; + HRESULT hr; + + hr = FilterFindFirst(FilterAggregateStandardInformation, + Buffer, + 1024, + &BytesReturned, + &FindHandle); + if (!SUCCEEDED(hr)) + { + IsNewStyle = FALSE; + hr = FilterFindFirst(FilterFullInformation, + Buffer, + 1024, + &BytesReturned, + &FindHandle); + } + + if (SUCCEEDED(hr)) + { + if (IsNewStyle) + { + LoadAndPrintString(IDS_DISPLAY_FILTERS1); + wprintf(L"------------------------------ ------------- ------------ -----\n"); + } + else + { + LoadAndPrintString(IDS_DISPLAY_FILTERS2); + wprintf(L"------------------------------ ------------- -----\n"); + } + + PrintFilterInfo(Buffer, IsNewStyle); + + do + { + hr = FilterFindNext(FindHandle, + IsNewStyle ? FilterAggregateStandardInformation : FilterFullInformation, + Buffer, + 1024, + &BytesReturned); + if (SUCCEEDED(hr)) + { + PrintFilterInfo(Buffer, IsNewStyle); + } + + } while (SUCCEEDED(hr)); + + FilterFindClose(FindHandle); + } + + if (!SUCCEEDED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) + { + LoadAndPrintString(IDS_ERROR_PRIV, hr); + PrintErrorText(hr); + } +} + +int wmain(int argc, WCHAR *argv[]) +{ + if (argc < 2) + { + LoadAndPrintString(IDS_USAGE); + return 0; + } + + wprintf(L"\n"); + + if (!_wcsicmp(argv[1], L"help")) + { + LoadAndPrintString(IDS_USAGE); + } + else if (!_wcsicmp(argv[1], L"load")) + { + if (argc == 3) + { + LoadFilter(argv[2]); + } + else + { + LoadAndPrintString(IDS_USAGE_LOAD); + wprintf(L"fltmc.exe load [name]\n\n"); + } + } + else if (!_wcsicmp(argv[1], L"unload")) + { + if (argc == 3) + { + UnloadFilter(argv[2]); + } + else + { + LoadAndPrintString(IDS_USAGE_UNLOAD); + wprintf(L"fltmc.exe unload [name]\n\n"); + } + } + else if (!_wcsicmp(argv[1], L"filters")) + { + if (argc == 2) + { + ListFilters(); + } + else + { + LoadAndPrintString(IDS_USAGE_FILTERS); + wprintf(L"fltmc.exe filters\n\n"); + } + } + + return 0; +} diff --git a/reactos/base/applications/fltmc/fltmc.rc b/reactos/base/applications/fltmc/fltmc.rc new file mode 100644 index 00000000000..984e6487500 --- /dev/null +++ b/reactos/base/applications/fltmc/fltmc.rc @@ -0,0 +1,60 @@ +#include + +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Filter Manager Control Program" +#define REACTOS_STR_INTERNAL_NAME "fltmc" +#define REACTOS_STR_ORIGINAL_FILENAME "fltmc.exe" +//#include + +/* UTF-8 */ +#pragma code_page(65001) + +//#ifdef LANGUAGE_BG_BG +// #include "lang/bg-BG.rc" +//#endif +//#ifdef LANGUAGE_CS_CZ +// #include "lang/cs-CZ.rc" +//#endif +//#ifdef LANGUAGE_DE_DE +// #include "lang/de-DE.rc" +//#endif +//#ifdef LANGUAGE_EN_US + #include "lang/en-US.rc" +//#endif +//#ifdef LANGUAGE_ES_ES +// #include "lang/es-ES.rc" +//#endif +//#ifdef LANGUAGE_FR_FR +// #include "lang/fr-FR.rc" +//#endif +//#ifdef LANGUAGE_IT_IT +// #include "lang/it-IT.rc" +//#endif +//#ifdef LANGUAGE_PL_PL +// #include "lang/pl-PL.rc" +//#endif +//#ifdef LANGUAGE_RO_RO +// #include "lang/ro-RO.rc" +//#endif +//#ifdef LANGUAGE_RU_RU +// #include "lang/ru-RU.rc" +//#endif +//#ifdef LANGUAGE_SV_SE +// #include "lang/sv-SE.rc" +//#endif +//#ifdef LANGUAGE_SQ_AL +// #include "lang/sq-AL.rc" +//#endif +//#ifdef LANGUAGE_TR_TR +// #include "lang/tr-TR.rc" +//#endif +//#ifdef LANGUAGE_UK_UA +// #include "lang/uk-UA.rc" +//#endif +//#ifdef LANGUAGE_ZH_CN +// #include "lang/zh-CN.rc" +//#endif +//#ifdef LANGUAGE_ZH_TW +// #include "lang/zh-TW.rc" +//#endif \ No newline at end of file diff --git a/reactos/base/applications/fltmc/lang/en-US.rc b/reactos/base/applications/fltmc/lang/en-US.rc new file mode 100644 index 00000000000..8b22f2fa55a --- /dev/null +++ b/reactos/base/applications/fltmc/lang/en-US.rc @@ -0,0 +1,27 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE +BEGIN + IDS_USAGE "\nValid commands :\n\ + load Loads a Filter driver\n\ + unload Unloads a Filter driver\n\ + filters Lists the Filters currently registered in the system\n\n\0" + + IDS_USAGE_LOAD "Loads a filter driver\n\0" + IDS_USAGE_UNLOAD "Unloads a filter driver\n\0" + IDS_USAGE_FILTERS "Lists all registered filters\n\0" +END + +STRINGTABLE +BEGIN + IDS_DISPLAY_FILTERS1 "Filter Name Num Instances Altitude Frame\n\0" + IDS_DISPLAY_FILTERS2 "Filter Name Num Instances Frame\n\0" +END + +STRINGTABLE +BEGIN + IDS_ERROR_PRIV "Failed to set the driver load privilige (0x%X)\n\0" + IDS_ERROR_FILTERS "Failed to list the filters (0x%X)\n\0" + IDS_ERROR_LOAD "Failed to load the filter (0x%X)\n\0" + IDS_ERROR_UNLOAD "Failed to unload the filter (0x%X)\n\0" +END diff --git a/reactos/base/applications/fltmc/resource.h b/reactos/base/applications/fltmc/resource.h new file mode 100644 index 00000000000..366b6bd6e45 --- /dev/null +++ b/reactos/base/applications/fltmc/resource.h @@ -0,0 +1,14 @@ +#pragma once + +#define IDS_USAGE 0 +#define IDS_USAGE_LOAD 1 +#define IDS_USAGE_UNLOAD 2 +#define IDS_USAGE_FILTERS 3 + +#define IDS_DISPLAY_FILTERS1 10 +#define IDS_DISPLAY_FILTERS2 11 + +#define IDS_ERROR_PRIV 20 +#define IDS_ERROR_FILTERS 21 +#define IDS_ERROR_LOAD 22 +#define IDS_ERROR_UNLOAD 23 -- 2.17.1