diff --git a/HidHide.sln.DotSettings b/HidHide.sln.DotSettings
index 8a86275..0c97bbd 100644
--- a/HidHide.sln.DotSettings
+++ b/HidHide.sln.DotSettings
@@ -1,7 +1,11 @@
+ True
True
+ True
True
True
True
True
- True
\ No newline at end of file
+ True
+ True
+ True
\ No newline at end of file
diff --git a/Watchdog/App.cpp b/Watchdog/App.cpp
index 84cca10..4e1f3cc 100644
--- a/Watchdog/App.cpp
+++ b/Watchdog/App.cpp
@@ -1,8 +1,14 @@
#include "App.hpp"
-#include "Util.h"
#include
#include
+#include
+#include
+#include
+
+#include
+#include
+
#pragma warning(disable: 26800)
#include
#include
@@ -27,67 +33,6 @@ class WatchdogTask : public Poco::Task
{
bool _isInteractive;
- static DWORD CheckServiceStatus(const std::wstring& serviceName, unsigned long& serviceState)
- {
- SC_HANDLE sch = nullptr;
- SC_HANDLE svc = nullptr;
- DWORD error = ERROR_SUCCESS;
-
- __try
- {
- sch = OpenSCManager(
- nullptr,
- nullptr,
- SC_MANAGER_ALL_ACCESS
- );
- if (sch == nullptr)
- {
- error = GetLastError();
- __leave;
- }
-
- svc = OpenService(
- sch,
- serviceName.c_str(),
- SC_MANAGER_ALL_ACCESS
- );
- if (svc == nullptr)
- {
- error = GetLastError();
- __leave;
- }
-
- SERVICE_STATUS_PROCESS stat;
- DWORD needed = 0;
- BOOL ret = QueryServiceStatusEx(
- svc,
- SC_STATUS_PROCESS_INFO,
- (BYTE*)&stat,
- sizeof stat,
- &needed
- );
- if (ret == 0)
- {
- error = GetLastError();
- __leave;
- }
-
- serviceState = stat.dwCurrentState;
-
- error = ERROR_SUCCESS;
- __leave;
- }
- __finally
- {
- if (svc)
- CloseServiceHandle(svc);
- if (sch)
- CloseServiceHandle(sch);
- }
-
- return error;
- }
-
public:
explicit WatchdogTask(const std::string& name, const bool isInteractive)
: Task(name)
@@ -105,71 +50,95 @@ class WatchdogTask : public Poco::Task
do
{
- const auto serviceName = L"HidHide";
- unsigned long winError = 0, serviceStatus = 0;
+ const std::wstring serviceName = L"HidHide";
+
+ const auto serviceStatus = nefarius::winapi::services::GetServiceStatus(serviceName);
// check if driver service is healthy
- if ((winError = CheckServiceStatus(serviceName, serviceStatus)) != ERROR_SUCCESS)
+ if (!serviceStatus)
{
- spdlog::error("Failed to query service status, error {}", winError);
+ logger->error("Failed to query service status, error {}", serviceStatus.error().getErrorMessageA());
continue;
}
// expecting service to be running as an indicator that driver is loaded
- if (serviceStatus != SERVICE_RUNNING)
+ if (serviceStatus.value().dwCurrentState != SERVICE_RUNNING)
{
- spdlog::error("Driver service not detected running, removing filter entries");
+ logger->error("Driver service not detected running, removing filter entries");
//
// Prevents bricked HID devices
//
- RemoveDeviceClassFilter(&GUID_DEVCLASS_HIDCLASS,
- serviceName, util::DeviceClassFilterPosition::Upper);
- RemoveDeviceClassFilter(&GUID_DEVCLASS_XNACOMPOSITE,
- serviceName, util::DeviceClassFilterPosition::Upper);
- RemoveDeviceClassFilter(&GUID_DEVCLASS_XBOXCOMPOSITE,
- serviceName, util::DeviceClassFilterPosition::Upper);
+ auto removeResult = RemoveDeviceClassFilter(&GUID_DEVCLASS_HIDCLASS,
+ serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper);
+
+ if (!removeResult)
+ {
+ logger->error("Removal from GUID_DEVCLASS_HIDCLASS failed with {}",
+ removeResult.error().getErrorMessageA());
+ }
+
+ removeResult = RemoveDeviceClassFilter(&GUID_DEVCLASS_XNACOMPOSITE,
+ serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper);
+
+ if (!removeResult)
+ {
+ logger->error("Removal from GUID_DEVCLASS_XNACOMPOSITE failed with {}",
+ removeResult.error().getErrorMessageA());
+ }
+
+ removeResult = RemoveDeviceClassFilter(&GUID_DEVCLASS_XBOXCOMPOSITE,
+ serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper);
+
+ if (!removeResult)
+ {
+ logger->error("Removal from GUID_DEVCLASS_XBOXCOMPOSITE failed with {}",
+ removeResult.error().getErrorMessageA());
+ }
continue;
}
// filter value or entry not present
- if (bool found = false; !HasDeviceClassFilter(&GUID_DEVCLASS_HIDCLASS, serviceName,
- util::DeviceClassFilterPosition::Upper, found) || !found)
+ if (!HasDeviceClassFilter(&GUID_DEVCLASS_HIDCLASS, serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper).value_or(false))
{
- spdlog::warn("Filter missing for HIDClass, adding");
+ logger->warn("Filter missing for HIDClass, adding");
if (!AddDeviceClassFilter(&GUID_DEVCLASS_HIDCLASS, serviceName,
- util::DeviceClassFilterPosition::Upper))
+ nefarius::devcon::DeviceClassFilterPosition::Upper))
{
- spdlog::error("Failed to add upper filters entry for HIDClass");
+ logger->error("Failed to add upper filters entry for HIDClass");
}
}
// filter value or entry not present
- if (bool found = false; !HasDeviceClassFilter(&GUID_DEVCLASS_XNACOMPOSITE, serviceName,
- util::DeviceClassFilterPosition::Upper, found) || !found)
+ if (!HasDeviceClassFilter(&GUID_DEVCLASS_XNACOMPOSITE, serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper).value_or(false))
{
- spdlog::warn("Filter missing for XnaComposite, adding");
+ logger->warn("Filter missing for XnaComposite, adding");
if (!AddDeviceClassFilter(&GUID_DEVCLASS_XNACOMPOSITE, serviceName,
- util::DeviceClassFilterPosition::Upper))
+ nefarius::devcon::DeviceClassFilterPosition::Upper))
{
- spdlog::error("Failed to add upper filters entry for XnaComposite");
+ logger->error("Failed to add upper filters entry for XnaComposite");
}
}
// filter value or entry not present
- if (bool found = false; !HasDeviceClassFilter(&GUID_DEVCLASS_XBOXCOMPOSITE, serviceName,
- util::DeviceClassFilterPosition::Upper, found) || !found)
+ if (!HasDeviceClassFilter(&GUID_DEVCLASS_XBOXCOMPOSITE, serviceName,
+ nefarius::devcon::DeviceClassFilterPosition::Upper).value_or(false))
{
- spdlog::warn("Filter missing for XboxComposite, adding");
+ logger->warn("Filter missing for XboxComposite, adding");
if (!AddDeviceClassFilter(&GUID_DEVCLASS_XBOXCOMPOSITE, serviceName,
- util::DeviceClassFilterPosition::Upper))
+ nefarius::devcon::DeviceClassFilterPosition::Upper))
{
- spdlog::error("Failed to add upper filters entry for XboxComposite");
+ logger->error("Failed to add upper filters entry for XboxComposite");
}
}
}
@@ -211,9 +180,11 @@ int App::main(const std::vector& args)
console->info("Application started");
- const bool isAdmin = util::IsAdmin();
+#if !defined(_DEBUG)
+ const auto isAdmin = nefarius::winapi::security::IsAppRunningAsAdminMode();
- if (isAdmin)
+ if (isAdmin.value_or(false))
+#endif
{
Poco::TaskManager tm;
tm.start(new WatchdogTask("HidHideWatchdog", this->isInteractive()));
@@ -221,12 +192,18 @@ int App::main(const std::vector& args)
tm.cancelAll();
tm.joinAll();
}
+#if !defined(_DEBUG)
else
{
errLogger->error("App need administrative permissions to run");
}
+#endif
console->info("Exiting application");
+#if !defined(_DEBUG)
return isAdmin ? EXIT_OK : EXIT_TEMPFAIL;
+#else
+ return EXIT_OK;
+#endif
}
diff --git a/Watchdog/AppIcon.rc b/Watchdog/AppIcon.rc
new file mode 100644
index 0000000..6b75efe
Binary files /dev/null and b/Watchdog/AppIcon.rc differ
diff --git a/Watchdog/Util.cpp b/Watchdog/Util.cpp
deleted file mode 100644
index 134d3b5..0000000
--- a/Watchdog/Util.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-#include "Util.h"
-#define WIN32_LEAN_AND_MEAN
-#include
-#include
-#include
-#include
-#include
-
-
-bool util::AddDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position)
-{
- auto key = SetupDiOpenClassRegKey(classGuid, KEY_ALL_ACCESS);
-
- if (INVALID_HANDLE_VALUE == key)
- {
- spdlog::error("SetupDiOpenClassRegKey failed with error code {}", GetLastError());
- return false;
- }
-
- LPCWSTR filterValue = (position == DeviceClassFilterPosition::Lower) ? L"LowerFilters" : L"UpperFilters";
- DWORD type, size;
- std::vector filters;
-
- auto status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- nullptr,
- &size
- );
-
- //
- // Value exists already, read it with returned buffer size
- //
- if (status == ERROR_SUCCESS)
- {
- std::vector temp(size / sizeof(wchar_t));
-
- status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- reinterpret_cast(&temp[0]),
- &size
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegQueryValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- size_t index = 0;
- size_t len = wcslen(&temp[0]);
- while (len > 0)
- {
- filters.emplace_back(&temp[index]);
- index += len + 1;
- len = wcslen(&temp[index]);
- }
-
- //
- // Filter not there yet, add
- //
- if (std::ranges::find(filters, filterName) == filters.end())
- {
- filters.emplace_back(filterName);
- }
-
- const std::vector multiString = winreg::winreg_internal::BuildMultiString(filters);
-
- const auto& dataSize = multiString.size() * sizeof(wchar_t);
-
- status = RegSetValueExW(
- key,
- filterValue,
- 0, // reserved
- REG_MULTI_SZ,
- reinterpret_cast(&multiString[0]),
- static_cast(dataSize)
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegSetValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- RegCloseKey(key);
- return true;
- }
- //
- // Value doesn't exist, create and populate
- //
- if (status == ERROR_FILE_NOT_FOUND)
- {
- filters.emplace_back(filterName);
-
- const std::vector multiString = winreg::winreg_internal::BuildMultiString(filters);
-
- const auto dataSize = multiString.size() * sizeof(wchar_t);
-
- status = RegSetValueExW(
- key,
- filterValue,
- 0, // reserved
- REG_MULTI_SZ,
- reinterpret_cast(&multiString[0]),
- // ReSharper disable once CppRedundantCastExpression
- static_cast(dataSize)
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegSetValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- RegCloseKey(key);
- return true;
- }
-
- RegCloseKey(key);
- return false;
-}
-
-bool util::RemoveDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position)
-{
- auto key = SetupDiOpenClassRegKey(classGuid, KEY_ALL_ACCESS);
-
- if (INVALID_HANDLE_VALUE == key)
- {
- spdlog::error("SetupDiOpenClassRegKey failed with error code {}", GetLastError());
- return false;
- }
-
- LPCWSTR filterValue = (position == DeviceClassFilterPosition::Lower) ? L"LowerFilters" : L"UpperFilters";
- DWORD type, size;
- std::vector filters;
-
- auto status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- nullptr,
- &size
- );
-
- //
- // Value exists already, read it with returned buffer size
- //
- if (status == ERROR_SUCCESS)
- {
- std::vector temp(size / sizeof(wchar_t));
-
- status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- reinterpret_cast(&temp[0]),
- &size
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegQueryValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- //
- // Remove value, if found
- //
- size_t index = 0;
- size_t len = wcslen(&temp[0]);
- while (len > 0)
- {
- if (filterName != &temp[index])
- {
- filters.emplace_back(&temp[index]);
- }
- index += len + 1;
- len = wcslen(&temp[index]);
- }
-
- const std::vector multiString = winreg::winreg_internal::BuildMultiString(filters);
-
- const auto dataSize = multiString.size() * sizeof(wchar_t);
-
- status = RegSetValueExW(
- key,
- filterValue,
- 0, // reserved
- REG_MULTI_SZ,
- reinterpret_cast(&multiString[0]),
- // ReSharper disable once CppRedundantCastExpression
- static_cast(dataSize)
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegSetValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- RegCloseKey(key);
- return true;
- }
- //
- // Value doesn't exist, return
- //
- if (status == ERROR_FILE_NOT_FOUND)
- {
- RegCloseKey(key);
- return true;
- }
-
- RegCloseKey(key);
- return false;
-}
-
-bool util::HasDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position, bool& found)
-{
- const auto key = SetupDiOpenClassRegKey(classGuid, KEY_READ);
-
- if (INVALID_HANDLE_VALUE == key)
- {
- spdlog::error("SetupDiOpenClassRegKey failed with error code {}", GetLastError());
- return false;
- }
-
- LPCWSTR filterValue = (position == DeviceClassFilterPosition::Lower) ? L"LowerFilters" : L"UpperFilters";
- DWORD type, size;
- std::vector filters;
-
- auto status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- nullptr,
- &size
- );
-
- //
- // Value exists already, read it with returned buffer size
- //
- if (status == ERROR_SUCCESS)
- {
- std::vector temp(size / sizeof(wchar_t));
-
- status = RegQueryValueExW(
- key,
- filterValue,
- nullptr,
- &type,
- reinterpret_cast(&temp[0]),
- &size
- );
-
- if (status != ERROR_SUCCESS)
- {
- spdlog::error("RegQueryValueExW failed with status {}", status);
- RegCloseKey(key);
- SetLastError(status);
- return false;
- }
-
- //
- // Enumerate values
- //
- size_t index = 0;
- size_t len = wcslen(&temp[0]);
- while (len > 0)
- {
- if (filterName == &temp[index])
- {
- found = true;
- break;
- }
- index += len + 1;
- len = wcslen(&temp[index]);
- }
-
- RegCloseKey(key);
- return true;
- }
- //
- // Value doesn't exist, return
- //
- if (status == ERROR_FILE_NOT_FOUND)
- {
- RegCloseKey(key);
- return true;
- }
-
- RegCloseKey(key);
- return false;
-}
-
-unsigned long util::IsAdminMode(bool& is_admin)
-{
- DWORD dwError = ERROR_SUCCESS;
- PSID pAdministratorsGroup = nullptr;
- BOOL IsAdmin = 0;
-
- // Allocate and initialize a SID of the administrators group.
- SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
- if (!AllocateAndInitializeSid(
- &NtAuthority,
- 2,
- SECURITY_BUILTIN_DOMAIN_RID,
- DOMAIN_ALIAS_RID_ADMINS,
- 0, 0, 0, 0, 0, 0,
- &pAdministratorsGroup))
- {
- dwError = GetLastError();
- goto Cleanup;
- }
-
- // Determine whether the SID of administrators group is enabled in
- // the primary access token of the process.
- if (!CheckTokenMembership(nullptr, pAdministratorsGroup, &IsAdmin))
- {
- dwError = GetLastError();
- }
-
- is_admin = IsAdmin > 0;
-
-Cleanup:
- // Centralized cleanup for all allocated resources.
- if (pAdministratorsGroup)
- {
- FreeSid(pAdministratorsGroup);
- pAdministratorsGroup = nullptr;
- }
-
- return dwError;
-}
-
-bool util::IsAdmin()
-{
- bool isAdmin = false;
-
- if (IsAdminMode(isAdmin) != ERROR_SUCCESS)
- {
- return false;
- }
-
- if (!isAdmin)
- {
- return false;
- }
-
- return true;
-}
diff --git a/Watchdog/Util.h b/Watchdog/Util.h
deleted file mode 100644
index 7d7a31f..0000000
--- a/Watchdog/Util.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include
-#include
-
-namespace util
-{
- struct DeviceClassFilterPosition
- {
- enum Value
- {
- Upper,
- Lower
- };
- };
-
- bool AddDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position);
-
- bool RemoveDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position);
-
- bool HasDeviceClassFilter(const GUID* classGuid, const std::wstring& filterName,
- DeviceClassFilterPosition::Value position, bool& found);
-
- unsigned long IsAdminMode(bool& is_admin);
-
- bool IsAdmin();
-};
diff --git a/Watchdog/Watchdog.vcxproj b/Watchdog/Watchdog.vcxproj
index 954bbf0..073b38b 100644
--- a/Watchdog/Watchdog.vcxproj
+++ b/Watchdog/Watchdog.vcxproj
@@ -98,7 +98,7 @@
true
- true
+ true
true
@@ -119,7 +119,8 @@
WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
true
MultiThreadedDebug
- stdcpp20
+ stdcpplatest
+ /utf-8 %(AdditionalOptions)
Console
@@ -136,7 +137,8 @@
WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
true
MultiThreaded
- stdcpp20
+ stdcpplatest
+ /utf-8 %(AdditionalOptions)
Console
@@ -154,7 +156,8 @@
_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
true
MultiThreadedDebug
- stdcpp20
+ stdcpplatest
+ /utf-8 %(AdditionalOptions)
Console
@@ -180,7 +183,8 @@
NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
true
MultiThreaded
- stdcpp20
+ stdcpplatest
+ /utf-8 %(AdditionalOptions)
Console
@@ -201,22 +205,26 @@
-
-
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Watchdog/Watchdog.vcxproj.filters b/Watchdog/Watchdog.vcxproj.filters
index 9374a80..569c4d2 100644
--- a/Watchdog/Watchdog.vcxproj.filters
+++ b/Watchdog/Watchdog.vcxproj.filters
@@ -21,9 +21,6 @@
Source Files
-
- Source Files
-
@@ -32,7 +29,7 @@
Header Files
-
+
Header Files
@@ -40,10 +37,19 @@
+
Resource Files
+
+ Resource Files
+
+
+
+
+ Resource Files
+
\ No newline at end of file
diff --git a/Watchdog/favicon.ico b/Watchdog/favicon.ico
index 58bc7d4..9d5d585 100644
Binary files a/Watchdog/favicon.ico and b/Watchdog/favicon.ico differ
diff --git a/Watchdog/resource1.h b/Watchdog/resource1.h
new file mode 100644
index 0000000..13d7ded
--- /dev/null
+++ b/Watchdog/resource1.h
@@ -0,0 +1,16 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by AppIcon.rc
+//
+#define IDI_ICON1 101
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Watchdog/vcpkg-configuration.json b/Watchdog/vcpkg-configuration.json
new file mode 100644
index 0000000..ad3204c
--- /dev/null
+++ b/Watchdog/vcpkg-configuration.json
@@ -0,0 +1,15 @@
+{
+ "registries": [
+ {
+ "kind": "git",
+ "repository": "https://github.com/nefarius/nefarius-vcpkg-registry.git",
+ "baseline": "b82fe0af4c127713acb1d1433e0796199080adce",
+ "packages": [ "neflib" ]
+ }
+ ],
+ "default-registry": {
+ "kind": "git",
+ "repository": "https://github.com/microsoft/vcpkg",
+ "baseline": "3508985146f1b1d248c67ead13f8f54be5b4f5da"
+ }
+}
diff --git a/Watchdog/vcpkg.json b/Watchdog/vcpkg.json
index ab25a09..e0c2ac3 100644
--- a/Watchdog/vcpkg.json
+++ b/Watchdog/vcpkg.json
@@ -7,6 +7,7 @@
"dependencies": [
"poco",
"spdlog",
- "winreg"
+ "winreg",
+ "neflib"
]
}
diff --git a/appveyor.yml b/appveyor.yml
index 87c2ca6..6ab0b79 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,6 +2,9 @@ version: 1.5.{build}.0
build_cloud: WIN-LKR467JS4GL
image: Windows
configuration: Release
+branches:
+ only:
+ - master
skip_commits:
files:
- '**/*.md'
@@ -9,8 +12,8 @@ test: off
platform:
- x64
install:
-# manifest mode takes forever to build each commit so use global copy instead
-- cmd: vcpkg install poco:%PLATFORM%-windows-static spdlog:%PLATFORM%-windows-static winreg:%PLATFORM%-windows-static
+# this junction points to a RAM disk on the CI server significantly speeding up building dependencies
+- cmd: mklink /J "%APPVEYOR_BUILD_FOLDER%\Watchdog\vcpkg_installed" "C:\tools\build-cache\HidHide\Watchdog\vcpkg_installed\%PLATFORM%"
- ps: Setup-VS2022
build:
project: $(APPVEYOR_BUILD_FOLDER)\$(APPVEYOR_PROJECT_NAME).sln