Skip to content

Commit c13f066

Browse files
authored
Merge pull request RawAccelOfficial#86 from a1xd/fix-input
Suppress id/rawinput related errors
2 parents 11b62cf + f218e44 commit c13f066

File tree

4 files changed

+72
-85
lines changed

4 files changed

+72
-85
lines changed

common/rawaccel-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#define RA_VER_MAJOR 1
44
#define RA_VER_MINOR 4
5-
#define RA_VER_PATCH 3
5+
#define RA_VER_PATCH 4
66

77
#define RA_OS "Win7+"
88

common/utility-rawinput.hpp

+65-50
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#pragma comment(lib, "cfgmgr32.lib")
44

5+
#include <algorithm>
56
#include <string>
67
#include <system_error>
78
#include <vector>
@@ -11,78 +12,92 @@
1112
#include <initguid.h> // needed for devpkey.h to parse properly
1213
#include <devpkey.h>
1314

14-
std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key) {
15-
ULONG size = 0;
16-
DEVPROPTYPE type;
17-
CONFIGRET cm_res;
18-
19-
cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
20-
&type, NULL, &size, 0);
21-
22-
if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) {
23-
throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
24-
std::to_string(cm_res) + ')');
25-
}
26-
27-
std::wstring prop((size + 1) / 2, L'\0');
28-
29-
cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
30-
&type, reinterpret_cast<PBYTE>(&prop[0]), &size, 0);
31-
32-
if (cm_res != CR_SUCCESS) {
33-
throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
34-
std::to_string(cm_res) + ')');
35-
}
36-
37-
return prop;
38-
}
39-
40-
std::wstring dev_id_from_interface(const WCHAR* interface_name) {
41-
auto id = dev_prop_wstr_from_interface(interface_name, &DEVPKEY_Device_InstanceId);
42-
id.resize(id.find_last_of('\\'));
43-
return id;
44-
}
45-
4615
template <typename Func>
47-
void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) {
16+
void rawinput_foreach_dev_with_id(Func fn, bool with_instance_id = false,
17+
DWORD input_type = RIM_TYPEMOUSE)
18+
{
4819
const UINT RI_ERROR = -1;
49-
20+
21+
// get number of devices
5022
UINT num_devs = 0;
51-
52-
if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) {
23+
if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) != 0) {
5324
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed");
5425
}
5526

5627
auto devs = std::vector<RAWINPUTDEVICELIST>(num_devs);
5728

5829
if (GetRawInputDeviceList(&devs[0], &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) {
59-
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed");
30+
return;
6031
}
6132

33+
std::wstring name;
34+
std::wstring id;
35+
DEVPROPTYPE type;
36+
CONFIGRET cm_res;
37+
6238
for (auto&& dev : devs) {
6339
if (dev.dwType != input_type) continue;
6440

65-
WCHAR name[256] = {};
66-
UINT name_size = sizeof(name);
41+
// get interface name length
42+
UINT name_len = 0;
43+
if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, NULL, &name_len) == RI_ERROR) {
44+
continue;
45+
}
46+
47+
name.resize(name_len);
48+
49+
if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, &name[0], &name_len) == RI_ERROR) {
50+
continue;
51+
}
52+
53+
// get sizeof dev instance id
54+
ULONG id_size = 0;
55+
cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId,
56+
&type, NULL, &id_size, 0);
57+
58+
if (cm_res != CR_BUFFER_SMALL && cm_res != CR_SUCCESS) continue;
59+
60+
id.resize((id_size + 1) / 2);
61+
62+
cm_res = CM_Get_Device_Interface_PropertyW(&name[0], &DEVPKEY_Device_InstanceId,
63+
&type, reinterpret_cast<PBYTE>(&id[0]), &id_size, 0);
6764

68-
if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, name, &name_size) == RI_ERROR) {
69-
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceInfoW failed");
65+
if (cm_res != CR_SUCCESS) continue;
66+
67+
if (!with_instance_id) {
68+
auto instance_delim_pos = id.find_last_of('\\');
69+
if(instance_delim_pos != std::string::npos) id.resize(instance_delim_pos);
7070
}
7171

72-
fn(dev, name);
72+
fn(dev, id);
7373
}
7474
}
7575

76-
// returns device handles corresponding to a "device id"
77-
// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids
78-
std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE) {
76+
inline
77+
std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& device_id,
78+
bool with_instance_id = false,
79+
DWORD input_type = RIM_TYPEMOUSE)
80+
{
7981
std::vector<HANDLE> handles;
8082

81-
rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
82-
if (device_id == dev_id_from_interface(name)) {
83-
handles.push_back(dev.hDevice);
84-
}
85-
}, input_type);
83+
rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) {
84+
if (id == device_id) handles.push_back(dev.hDevice);
85+
}, with_instance_id, input_type);
8686

8787
return handles;
8888
}
89+
90+
inline
91+
std::vector<std::wstring> rawinput_dev_id_list(bool with_instance_id = false,
92+
DWORD input_type = RIM_TYPEMOUSE)
93+
{
94+
std::vector<std::wstring> ids;
95+
96+
rawinput_foreach_dev_with_id([&](const auto& dev, const std::wstring& id) {
97+
ids.push_back(id);
98+
}, with_instance_id, input_type);
99+
100+
std::sort(ids.begin(), ids.end());
101+
ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
102+
return ids;
103+
}

grapher/Models/Devices/DeviceIDManager.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ public void Update(string devID)
4646

4747
if (found) SetActive(anyDevice);
4848

49-
foreach (var (name, id) in RawInputInterop.GetDeviceIDs())
49+
foreach (string id in RawInputInterop.GetDeviceIDs())
5050
{
51-
var deviceItem = new DeviceIDItem(name, id, this);
51+
var deviceItem = new DeviceIDItem(string.Empty, id, this);
5252
if (!found && deviceItem.ID.Equals(devID))
5353
{
5454
SetActive(deviceItem);

wrapper/wrapper.cpp

+4-32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#pragma once
22

3-
#include <algorithm>
43
#include <type_traits>
54
#include <msclr\marshal_cppstd.h>
65

@@ -277,30 +276,6 @@ public ref class SettingsErrors
277276
}
278277
};
279278

280-
struct device_info {
281-
std::wstring name;
282-
std::wstring id;
283-
};
284-
285-
std::vector<device_info> get_unique_device_info() {
286-
std::vector<device_info> info;
287-
288-
rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
289-
info.push_back({
290-
L"", // get_property_wstr(name, &DEVPKEY_Device_FriendlyName), /* doesn't work */
291-
dev_id_from_interface(name)
292-
});
293-
});
294-
295-
std::sort(info.begin(), info.end(),
296-
[](auto&& l, auto&& r) { return l.id < r.id; });
297-
auto last = std::unique(info.begin(), info.end(),
298-
[](auto&& l, auto&& r) { return l.id == r.id; });
299-
info.erase(last, info.end());
300-
301-
return info;
302-
}
303-
304279
public ref struct RawInputInterop
305280
{
306281
static void AddHandlesFromID(String^ deviceID, List<IntPtr>^ rawInputHandles)
@@ -318,18 +293,15 @@ public ref struct RawInputInterop
318293
}
319294
}
320295

321-
static List<ValueTuple<String^, String^>>^ GetDeviceIDs()
296+
static List<String^>^ GetDeviceIDs()
322297
{
323298
try
324299
{
325-
auto managed = gcnew List<ValueTuple<String^, String^>>();
300+
auto managed = gcnew List<String^>();
326301

327-
for (auto&& [name, id] : get_unique_device_info())
302+
for (auto&& id : rawinput_dev_id_list())
328303
{
329-
managed->Add(
330-
ValueTuple<String^, String^>(
331-
msclr::interop::marshal_as<String^>(name),
332-
msclr::interop::marshal_as<String^>(id)));
304+
managed->Add(msclr::interop::marshal_as<String^>(id));
333305
}
334306

335307
return managed;

0 commit comments

Comments
 (0)