Program Listing for File ListDevice.hpp
↰ Return to documentation for file (include/input/IPC/transmission/windows/ListDevice.hpp)
#pragma once
#include "ChildProcess.hpp"
#include "dev_path_to_name.hpp"
namespace PDJE_IPC {
struct RawDeviceData {
RID_DEVICE_INFO info{};
std::wstring deviceHIDPath;
};
static std::vector<RawDeviceData>
getRawDeviceDatas()
{
UINT num = 0;
if (GetRawInputDeviceList(nullptr, &num, sizeof(RAWINPUTDEVICELIST)) != 0 ||
num == 0)
return {};
std::vector<RAWINPUTDEVICELIST> list(num);
if (GetRawInputDeviceList(list.data(), &num, sizeof(RAWINPUTDEVICELIST)) ==
(UINT)-1)
return {};
std::vector<RawDeviceData> out;
out.reserve(num);
for (UINT i = 0; i < num; ++i) {
RawDeviceData dev;
auto h = list[i].hDevice;
UINT cbSize = dev.info.cbSize = sizeof(RID_DEVICE_INFO);
if (GetRawInputDeviceInfoW(h, RIDI_DEVICEINFO, &dev.info, &cbSize) ==
(UINT)-1)
continue;
UINT chars = 0;
GetRawInputDeviceInfoW(h, RIDI_DEVICENAME, nullptr, &chars);
if (chars > 0) {
std::wstring path(chars, L'\0');
if (GetRawInputDeviceInfoW(h, RIDI_DEVICENAME, &path[0], &chars) !=
(UINT)-1) {
if (!path.empty() && path.back() == L'\0')
path.pop_back();
}
dev.deviceHIDPath = path;
}
out.push_back(std::move(dev));
}
return out;
}
static std::string
wstring_to_utf8_nt(const std::wstring &w)
{
if (w.empty())
return {};
auto target = w;
if (target.rfind(L"\\??\\", 0) == 0) {
target.replace(0, 4, L"\\\\?\\");
}
int required = WideCharToMultiByte(CP_UTF8,
WC_ERR_INVALID_CHARS,
target.c_str(),
-1,
nullptr,
0,
nullptr,
nullptr);
if (required <= 0) {
critlog(
"pdje input module-Windows impl- WideCharToMultiByte size failed");
throw std::runtime_error("WideCharToMultiByte size failed");
}
std::string out(required, '\0');
int written = WideCharToMultiByte(CP_UTF8,
WC_ERR_INVALID_CHARS,
target.c_str(),
-1,
out.data(),
required,
nullptr,
nullptr);
if (written <= 0) {
critlog("pdje input module-Windows impl- WideCharToMultiByte convert "
"failed");
throw std::runtime_error("WideCharToMultiByte convert failed");
}
if (!out.empty() && out.back() == '\0')
out.pop_back();
return out;
}
static std::string
hid_label_from_path(const std::wstring &path)
{
auto name = GetFriendlyNameFromHidPath(path);
return wstring_to_utf8_nt(name);
}
}; // namespace PDJE_IPC