summaryrefslogtreecommitdiff
path: root/common/utility-rawinput.hpp
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-01-12 17:01:18 -0500
committera1xd <[email protected]>2021-01-12 17:01:18 -0500
commit0e60e22b73dd0693b349cbb63cf9a390c01fd5dd (patch)
tree493bfaeb2b59b7db452c52e9ec9713e8b8296510 /common/utility-rawinput.hpp
parentSmall behavior improvements (diff)
downloadrawaccel-0e60e22b73dd0693b349cbb63cf9a390c01fd5dd.tar.xz
rawaccel-0e60e22b73dd0693b349cbb63cf9a390c01fd5dd.zip
filter raw input based on id
use device id (from device instance) over first hardware id use buffered method for all ioctls update gui/DeviceIDManager to match driver behavior respond to device change events desync MouseData and PointData accessors
Diffstat (limited to 'common/utility-rawinput.hpp')
-rw-r--r--common/utility-rawinput.hpp74
1 files changed, 74 insertions, 0 deletions
diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp
new file mode 100644
index 0000000..3c44068
--- /dev/null
+++ b/common/utility-rawinput.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#pragma comment(lib, "cfgmgr32.lib")
+
+#include <iostream>
+#include <string>
+#include <system_error>
+#include <vector>
+
+#include <Windows.h>
+#include <cfgmgr32.h>
+#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) {
+ const UINT RI_ERROR = -1;
+
+ UINT num_devs = 0;
+
+ if (GetRawInputDeviceList(NULL, &num_devs, sizeof(RAWINPUTDEVICELIST)) == RI_ERROR) {
+ throw std::system_error(GetLastError(), std::system_category(), "GetRawInputDeviceList failed");
+ }
+
+ auto devs = std::vector<RAWINPUTDEVICELIST>(num_devs);
+
+ 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;
+
+ WCHAR name[256] = {};
+ UINT name_size = sizeof(name);
+
+ if (GetRawInputDeviceInfoW(dev.hDevice, RIDI_DEVICENAME, name, &name_size) == RI_ERROR) {
+ 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) + ')');
+ }
+
+ // remove instance id
+ id.resize(id.find_last_of('\\'));
+
+ if (id == dev_id) handles.push_back(dev.hDevice);
+ }
+
+ return handles;
+}
+