From 3978e1eb2cb0a25ff5c9d2a6bf47999f8843330d Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Thu, 2 Oct 2025 04:11:27 -0500 Subject: [PATCH] WindowsDevice: Add some utility functions for getting device properties using CfgMgr32. --- Source/Core/Common/WindowsDevice.cpp | 49 ++++++++++++++++++++++++++++ Source/Core/Common/WindowsDevice.h | 8 +++++ 2 files changed, 57 insertions(+) diff --git a/Source/Core/Common/WindowsDevice.cpp b/Source/Core/Common/WindowsDevice.cpp index 8ecc346187..770aa3861a 100644 --- a/Source/Core/Common/WindowsDevice.cpp +++ b/Source/Core/Common/WindowsDevice.cpp @@ -7,7 +7,10 @@ #include +#include "Hidclass.h" + #include "Common/CommonFuncs.h" +#include "Common/Logging/Log.h" namespace Common { @@ -33,6 +36,52 @@ std::wstring GetDeviceProperty(const HDEVINFO& device_info, const PSP_DEVINFO_DA return std::wstring(unicode_buffer.data()); } + +std::optional GetPropertyHelper(auto function, auto dev, + const DEVPROPKEY* requested_property, + DEVPROPTYPE expected_type) +{ + DEVPROPTYPE type{}; + ULONG buffer_size{}; + + if (const auto result = function(dev, requested_property, &type, nullptr, &buffer_size, 0); + result != CR_SUCCESS && result != CR_BUFFER_SMALL) + { + WARN_LOG_FMT(COMMON, "CM_Get_DevNode_Property returned: {}", result); + return std::nullopt; + } + if (type != expected_type) + { + WARN_LOG_FMT(COMMON, "CM_Get_DevNode_Property unexpected type: 0x{:x}", type); + return std::nullopt; + } + + std::optional property; + // FYI: It's legal to write the null terminator at data()[size()] of std::basic_string. + property.emplace(buffer_size / sizeof(WCHAR) - 1, L'\0'); + if (const auto result = function(dev, requested_property, &type, + reinterpret_cast(property->data()), &buffer_size, 0); + result != CR_SUCCESS) + { + ERROR_LOG_FMT(COMMON, "CM_Get_DevNode_Property returned: {}", result); + return std::nullopt; + } + return property; +} + +std::optional GetDevNodeStringProperty(DEVINST dev, + const DEVPROPKEY* requested_property) +{ + return GetPropertyHelper(CM_Get_DevNode_Property, dev, requested_property, DEVPROP_TYPE_STRING); +} + +std::optional GetDeviceInterfaceStringProperty(LPCWSTR iface, + const DEVPROPKEY* requested_property) +{ + return GetPropertyHelper(CM_Get_Device_Interface_Property, iface, requested_property, + DEVPROP_TYPE_STRING); +} + } // namespace Common #endif diff --git a/Source/Core/Common/WindowsDevice.h b/Source/Core/Common/WindowsDevice.h index c79e9b0d7a..463c6299b4 100644 --- a/Source/Core/Common/WindowsDevice.h +++ b/Source/Core/Common/WindowsDevice.h @@ -5,6 +5,7 @@ #ifdef _WIN32 +#include #include #ifndef WIN32_LEAN_AND_MEAN @@ -24,6 +25,13 @@ namespace Common // Obtains a device property and returns it as a wide string. std::wstring GetDeviceProperty(const HANDLE& device_info, const PSP_DEVINFO_DATA device_data, const DEVPROPKEY* requested_property); + +std::optional GetDevNodeStringProperty(DEVINST device, + const DEVPROPKEY* requested_property); + +std::optional GetDeviceInterfaceStringProperty(LPCWSTR iface, + const DEVPROPKEY* requested_property); + } // namespace Common #endif