From 046c6bbef0a2a5f208c80f0d4666411ce991ef4a Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:44:45 -0400 Subject: ignore cfgmgr errors when retrieving device id --- common/utility-rawinput.hpp | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index c43084b..5506109 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -11,35 +11,33 @@ #include // needed for devpkey.h to parse properly #include -std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key) { +// Returns an empty string on failure +// +// interface names from GetRawInputDeviceInfo are not guaranteed to be valid; +// CM_Get_Device_Interface_PropertyW can return CR_NO_SUCH_DEVICE_INTERFACE +std::wstring dev_id_from_interface(const WCHAR* interface_name) { ULONG size = 0; DEVPROPTYPE type; CONFIGRET cm_res; - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key, + cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, &type, NULL, &size, 0); - if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) { - throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" + - std::to_string(cm_res) + ')'); - } + if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) return {}; - std::wstring prop((size + 1) / 2, L'\0'); + std::wstring id((size + 1) / 2, L'\0'); - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key, - &type, reinterpret_cast(&prop[0]), &size, 0); + cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, + &type, reinterpret_cast(&id[0]), &size, 0); - if (cm_res != CR_SUCCESS) { - throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" + - std::to_string(cm_res) + ')'); - } + if (cm_res != CR_SUCCESS) return {}; - return prop; -} + auto instance_delim_pos = id.find_last_of('\\'); + + if (instance_delim_pos != std::string::npos) { + id.resize(instance_delim_pos); + } -std::wstring dev_id_from_interface(const WCHAR* interface_name) { - auto id = dev_prop_wstr_from_interface(interface_name, &DEVPKEY_Device_InstanceId); - id.resize(id.find_last_of('\\')); return id; } @@ -79,7 +77,8 @@ std::vector rawinput_handles_from_dev_id(const std::wstring& device_id, std::vector handles; rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) { - if (device_id == dev_id_from_interface(name)) { + auto id = dev_id_from_interface(name); + if (!id.empty() && id == device_id) { handles.push_back(dev.hDevice); } }, input_type); -- cgit v1.2.3 From b24311e3ae47f6e68b63dcb5c9122a22cbce7757 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sun, 25 Apr 2021 21:50:57 -0400 Subject: bugfix - rawinput GetRawInputDeviceInfo requires character length to be passed, not byte count --- common/utility-rawinput.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index 5506109..26e558f 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -61,9 +61,9 @@ void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) if (dev.dwType != input_type) continue; WCHAR name[256] = {}; - UINT name_size = sizeof(name); + UINT len = 256; - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, name, &name_size) == RI_ERROR) { + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, name, &len) == RI_ERROR) { throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceInfoW failed"); } -- cgit v1.2.3 From 5c63222dce051bd4a2e79e736887d15ef9d3d377 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Sun, 25 Apr 2021 22:19:27 -0400 Subject: ignore GetRawInputDeviceInfo errors --- common/utility-rawinput.hpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index 26e558f..1167891 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -57,17 +57,24 @@ void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed"); } + std::wstring name; + UINT len; + for (auto&& dev : devs) { if (dev.dwType != input_type) continue; - WCHAR name[256] = {}; - UINT len = 256; + // get required length + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &len) == RI_ERROR) { + continue; + } + + name.resize(len); - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, name, &len) == RI_ERROR) { - throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceInfoW failed"); + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &len) == RI_ERROR) { + continue; } - fn(dev, name); + fn(dev, &name[0]); } } -- cgit v1.2.3 From 8de054735f51c6b933f4fadf7e7aa63c11971a68 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:00:51 -0400 Subject: refactor rawinput util some generalizations here don't make sense now that we're ignoring errors --- common/utility-rawinput.hpp | 103 ++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index 1167891..f20d594 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -2,6 +2,7 @@ #pragma comment(lib, "cfgmgr32.lib") +#include #include #include #include @@ -11,40 +12,12 @@ #include // needed for devpkey.h to parse properly #include -// Returns an empty string on failure -// -// interface names from GetRawInputDeviceInfo are not guaranteed to be valid; -// CM_Get_Device_Interface_PropertyW can return CR_NO_SUCH_DEVICE_INTERFACE -std::wstring dev_id_from_interface(const WCHAR* interface_name) { - ULONG size = 0; - DEVPROPTYPE type; - CONFIGRET cm_res; - - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, - &type, NULL, &size, 0); - - if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) return {}; - - std::wstring id((size + 1) / 2, L'\0'); - - cm_res = CM_Get_Device_Interface_PropertyW(interface_name, &DEVPKEY_Device_InstanceId, - &type, reinterpret_cast(&id[0]), &size, 0); - - if (cm_res != CR_SUCCESS) return {}; - - auto instance_delim_pos = id.find_last_of('\\'); - - if (instance_delim_pos != std::string::npos) { - id.resize(instance_delim_pos); - } - - return id; -} - template -void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) { +void rawinput_foreach_dev_with_id(Func fn, bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ const UINT RI_ERROR = -1; - + UINT num_devs = 0; if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) { @@ -58,37 +31,73 @@ void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) } std::wstring name; - UINT len; + std::wstring id; + DEVPROPTYPE type; + CONFIGRET cm_res; for (auto&& dev : devs) { if (dev.dwType != input_type) continue; - // get required length - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &len) == RI_ERROR) { + // get interface name length + UINT name_len = 0; + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &name_len) == RI_ERROR) { continue; } - name.resize(len); + name.resize(name_len); - if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &len) == RI_ERROR) { + if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &name_len) == RI_ERROR) { continue; } - fn(dev, &name[0]); + // get sizeof dev instance id + ULONG id_size = 0; + cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId, + &type, NULL, &id_size, 0); + + if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) continue; + + id.resize((id_size + 1) / 2); + + cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId, + &type, reinterpret_cast(&id[0]), &id_size, 0); + + if (cm_res != CR_SUCCESS) continue; + + if (!with_instance_id) { + auto instance_delim_pos = id.find_last_of('\\'); + if(instance_delim_pos != std::string::npos) id.resize(instance_delim_pos); + } + + fn(dev, id); } } -// returns device handles corresponding to a "device id" -// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids -std::vector rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE) { +inline +std::vector rawinput_handles_from_dev_id(const std::wstring& device_id, + bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ std::vector handles; - rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) { - auto id = dev_id_from_interface(name); - if (!id.empty() && id == device_id) { - handles.push_back(dev.hDevice); - } - }, input_type); + rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) { + if (id == device_id) handles.push_back(dev.hDevice); + }, with_instance_id, input_type); return handles; } + +inline +std::vector rawinput_dev_id_list(bool with_instance_id = false, + DWORD input_type = RIM_TYPEMOUSE) +{ + std::vector ids; + + rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) { + ids.push_back(id); + }, with_instance_id, input_type); + + std::sort(ids.begin(), ids.end()); + ids.erase(std::unique(ids.begin(), ids.end()), ids.end()); + return ids; +} -- cgit v1.2.3 From 630760dc3106b8fd4b0622510d4e2af769a04df5 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:06:28 -0400 Subject: match error handling in MS raw input docs --- common/utility-rawinput.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index f20d594..80d305b 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -18,9 +18,9 @@ void rawinput_foreach_dev_with_id(Func fn, bool with_instance_id = false, { const UINT RI_ERROR = -1; + // get number of devices UINT num_devs = 0; - - if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) { + if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) != 0) { throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed"); } -- cgit v1.2.3 From 5d0fec5592641aff4b8a4ce5da269fa38edf7219 Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:14:00 -0400 Subject: ignore errors when trying to retrieve dev list might be a good idea to add logging here, not much else we can do if this fails --- common/utility-rawinput.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp index 80d305b..c3a4576 100644 --- a/common/utility-rawinput.hpp +++ b/common/utility-rawinput.hpp @@ -27,7 +27,7 @@ void rawinput_foreach_dev_with_id(Func fn, bool with_instance_id = false, auto devs = std::vector(num_devs); if (GetRawInputDeviceList(&devs[0], &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) { - throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed"); + return; } std::wstring name; -- cgit v1.2.3 From f218e44194845da4b25ffb0a8f298e9729d9bfbc Mon Sep 17 00:00:00 2001 From: a1xd <68629610+a1xd@users.noreply.github.com> Date: Mon, 26 Apr 2021 22:14:29 -0400 Subject: bump version --- common/rawaccel-version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common') diff --git a/common/rawaccel-version.h b/common/rawaccel-version.h index 40ff2d2..ce53b30 100644 --- a/common/rawaccel-version.h +++ b/common/rawaccel-version.h @@ -2,7 +2,7 @@ #define RA_VER_MAJOR 1 #define RA_VER_MINOR 4 -#define RA_VER_PATCH 3 +#define RA_VER_PATCH 4 #define RA_OS "Win7+" -- cgit v1.2.3