summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-01-30 01:23:34 -0500
committera1xd <[email protected]>2021-01-30 01:23:34 -0500
commitf64c40346dab580220101b0aacb4a6ff5484d86a (patch)
treee6103ccb3a0a4adde6cab99a6293a63dbc90738e
parentbump version (diff)
downloadrawaccel-f64c40346dab580220101b0aacb4a6ff5484d86a.tar.xz
rawaccel-f64c40346dab580220101b0aacb4a6ff5484d86a.zip
fix device id not working with g305
this uses w32 apis for enumerating dev info instead of ManagementObjectSearcher, which upper-cases dev ids, differing from kernel/cfgmgr32 this also breaks showing dev name alongside id, as the name seems inaccessible from cfgmgr32 given an interface supplied by rawinput not a big deal considering the names are too generic to be useful anyway
-rw-r--r--common/utility-rawinput.hpp78
-rw-r--r--grapher/Models/Devices/DeviceIDItem.cs2
-rw-r--r--grapher/Models/Devices/DeviceIDManager.cs22
-rw-r--r--grapher/grapher.csproj1
-rw-r--r--wrapper/wrapper.cpp48
5 files changed, 97 insertions, 54 deletions
diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp
index 3c44068..c43084b 100644
--- a/common/utility-rawinput.hpp
+++ b/common/utility-rawinput.hpp
@@ -2,7 +2,6 @@
#pragma comment(lib, "cfgmgr32.lib")
-#include <iostream>
#include <string>
#include <system_error>
#include <vector>
@@ -12,9 +11,40 @@
#include <initguid.h> // needed for devpkey.h to parse properly
#include <devpkey.h>
-// returns device handles corresponding to a "device id"
-// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids
-std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& dev_id, DWORD input_type = RIM_TYPEMOUSE) {
+std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key) {
+ ULONG size = 0;
+ DEVPROPTYPE type;
+ CONFIGRET cm_res;
+
+ cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
+ &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) + ')');
+ }
+
+ std::wstring prop((size + 1) / 2, L'\0');
+
+ cm_res = CM_Get_Device_Interface_PropertyW(interface_name, key,
+ &type, reinterpret_cast<PBYTE>(&prop[0]), &size, 0);
+
+ if (cm_res != CR_SUCCESS) {
+ throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
+ std::to_string(cm_res) + ')');
+ }
+
+ return prop;
+}
+
+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;
+}
+
+template <typename Func>
+void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) {
const UINT RI_ERROR = -1;
UINT num_devs = 0;
@@ -28,8 +58,6 @@ std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& dev_id, DWO
if (GetRawInputDeviceList(&devs[0], &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) {
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed");
}
-
- std::vector<HANDLE> handles;
for (auto&& dev : devs) {
if (dev.dwType != input_type) continue;
@@ -41,34 +69,20 @@ std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& dev_id, DWO
throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceInfoW failed");
}
- ULONG id_size = 0;
- DEVPROPTYPE type;
- CONFIGRET cm_res;
-
- cm_res = CM_Get_Device_Interface_PropertyW(name, &DEVPKEY_Device_InstanceId,
- &type, NULL, &id_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) + ')');
- }
-
- std::wstring id((static_cast<size_t>(id_size) + 1) / 2, '\0');
-
- cm_res = CM_Get_Device_Interface_PropertyW(name, &DEVPKEY_Device_InstanceId,
- &type, reinterpret_cast<PBYTE>(&id[0]), &id_size, 0);
-
- if (cm_res != CR_SUCCESS) {
- throw std::runtime_error("CM_Get_Device_Interface_PropertyW failed (" +
- std::to_string(cm_res) + ')');
- }
+ fn(dev, name);
+ }
+}
- // remove instance id
- id.resize(id.find_last_of('\\'));
+// returns device handles corresponding to a "device id"
+// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids
+std::vector<HANDLE> rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE) {
+ std::vector<HANDLE> handles;
- if (id == dev_id) handles.push_back(dev.hDevice);
- }
+ rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
+ if (device_id == dev_id_from_interface(name)) {
+ handles.push_back(dev.hDevice);
+ }
+ }, input_type);
return handles;
}
-
diff --git a/grapher/Models/Devices/DeviceIDItem.cs b/grapher/Models/Devices/DeviceIDItem.cs
index 63c2761..8f1587b 100644
--- a/grapher/Models/Devices/DeviceIDItem.cs
+++ b/grapher/Models/Devices/DeviceIDItem.cs
@@ -40,7 +40,7 @@ namespace grapher.Models.Devices
DeviceIDMenuItem.Checked = false;
}
- private string MenuItemText() => string.IsNullOrEmpty(ID) ? $"{Name}" : $"{Name}: {ID}";
+ private string MenuItemText() => string.IsNullOrEmpty(ID) ? $"{Name}" : ID.Replace("&", "&&");
private string DisconnectedText() => $"Disconnected: {ID}";
diff --git a/grapher/Models/Devices/DeviceIDManager.cs b/grapher/Models/Devices/DeviceIDManager.cs
index c50cda8..8592763 100644
--- a/grapher/Models/Devices/DeviceIDManager.cs
+++ b/grapher/Models/Devices/DeviceIDManager.cs
@@ -25,24 +25,6 @@ namespace grapher.Models.Devices
public Dictionary<string, DeviceIDItem> DeviceIDs { get; private set; }
- public static IEnumerable<(string, string)> GetDeviceIDs(string PNPClass = "Mouse")
- {
- ManagementObjectSearcher searcher = new ManagementObjectSearcher(new SelectQuery("Win32_PnPEntity"));
-
- foreach (ManagementObject obj in searcher.Get())
- {
- if (obj["PNPClass"] != null && obj["PNPClass"].ToString().Equals(PNPClass) && obj["DeviceID"] != null)
- {
- string name = obj["Name"].ToString();
-
- string devInstanceID = obj["DeviceID"].ToString();
- string devID = devInstanceID.Remove(devInstanceID.LastIndexOf('\\'));
-
- yield return (name, devID);
- }
- }
- }
-
public void SetActive(DeviceIDItem deviceIDItem)
{
if (SelectedDeviceID != null)
@@ -64,9 +46,9 @@ namespace grapher.Models.Devices
if (found) SetActive(anyDevice);
- foreach (var device in GetDeviceIDs().Distinct())
+ foreach (var (name, id) in RawInputInterop.GetDeviceIDs())
{
- var deviceItem = new DeviceIDItem(device.Item1, device.Item2, this);
+ var deviceItem = new DeviceIDItem(name, id, this);
if (!found && deviceItem.ID.Equals(devID))
{
SetActive(deviceItem);
diff --git a/grapher/grapher.csproj b/grapher/grapher.csproj
index 8673325..1160ba8 100644
--- a/grapher/grapher.csproj
+++ b/grapher/grapher.csproj
@@ -59,7 +59,6 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
- <Reference Include="System.Management" />
<Reference Include="System.Windows.Forms.DataVisualization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp
index f5672a1..71a8cf6 100644
--- a/wrapper/wrapper.cpp
+++ b/wrapper/wrapper.cpp
@@ -1,5 +1,6 @@
#pragma once
+#include <algorithm>
#include <type_traits>
#include <msclr\marshal_cppstd.h>
@@ -276,6 +277,30 @@ public:
}
};
+struct device_info {
+ std::wstring name;
+ std::wstring id;
+};
+
+std::vector<device_info> get_unique_device_info() {
+ std::vector<device_info> info;
+
+ rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
+ info.push_back({
+ L"", // get_property_wstr(name, &DEVPKEY_Device_FriendlyName), /* doesn't work */
+ dev_id_from_interface(name)
+ });
+ });
+
+ std::sort(info.begin(), info.end(),
+ [](auto&& l, auto&& r) { return l.id < r.id; });
+ auto last = std::unique(info.begin(), info.end(),
+ [](auto&& l, auto&& r) { return l.id == r.id; });
+ info.erase(last, info.end());
+
+ return info;
+}
+
public ref struct RawInputInterop
{
static void AddHandlesFromID(String^ deviceID, List<IntPtr>^ rawInputHandles)
@@ -292,6 +317,29 @@ public ref struct RawInputInterop
throw gcnew System::Exception(gcnew String(e.what()));
}
}
+
+ static List<ValueTuple<String^, String^>>^ GetDeviceIDs()
+ {
+ try
+ {
+ auto managed = gcnew List<ValueTuple<String^, String^>>();
+
+ for (auto&& [name, id] : get_unique_device_info())
+ {
+ managed->Add(
+ ValueTuple<String^, String^>(
+ msclr::interop::marshal_as<String^>(name),
+ msclr::interop::marshal_as<String^>(id)));
+ }
+
+ return managed;
+ }
+ catch (const std::exception& e)
+ {
+ throw gcnew System::Exception(gcnew String(e.what()));
+ }
+ }
+
};
public ref struct DriverInterop