How to get human readable name for RawInput HID device?
I've been having a similar problem and believe I found a potential solution.
It seems you must call CreateFile
with the name that RawInput provides from calling GetRawInputDeviceInfo
with RIDI_DEVICENAME
as the uiCommand
parameter's argument. This will give you a handle to the device with which you may call HidD_GetProductString
.
wchar_t DeviceName[126];HANDLE HIDHandle = CreateFile(RawInputDeviceName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);if(HIDHandle){ BOOLEAN Result = HidD_GetProductString(HIDHandle, DeviceName, sizeof(wchar_t) * 126); CloseHandle(HIDHandle);}
However, it seems that HidD_GetProductString
fails on a majority of the devices attached on my system and only seems to succeed for my USB keyboard and a web camera. It does not succeed for my USB mouse. I have not yet discovered why this is, but perhaps my progress will aid you.
You get a handle to the top level collection as explained here: https://msdn.microsoft.com/en-us/library/windows/hardware/ff538731%28v=vs.85%29.aspx
For HID devices you can use HidD_GetProductString
but keyboard and mouse are not avalible via HID API on Windows and exposed as separate device types: GUID_DEVINTERFACE_KEYBOARD/GUID_DEVINTERFACE_MOUSE (they cannot be directly read by user-mode app by security reasons).
You can get their device info from device interface symbolic link like this:
use
CM_Get_Device_Interface_Property
orSetupDiGetDeviceInterfaceProperty
withDEVPKEY_Device_InstanceId
to get device instance id (one device can have multiple interfaces).after you have device instance id you can use
CM_Get_DevNode_Property
orSetupDiGetDeviceProperty
withDEVPKEY_NAME
to get localized friendly name of a device (which is shown in Device Manager).
Here is example code via CM_*
API from my test repo:
bool FillDeviceInfo(const std::wstring& deviceInterfaceName){ // you need to provide deviceInterfaceName // example from my system: `\\?\HID#VID_203A&PID_FFFC&MI_01#7&2de99099&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}` DEVPROPTYPE propertyType; ULONG propertySize = 0; CONFIGRET cr = ::CM_Get_Device_Interface_PropertyW(deviceInterfaceName.c_str(), &DEVPKEY_Device_InstanceId, &propertyType, nullptr, &propertySize, 0); if (cr != CR_BUFFER_SMALL) return false; std::wstring deviceId; deviceId.resize(propertySize); cr = ::CM_Get_Device_Interface_PropertyW(deviceInterfaceName.c_str(), &DEVPKEY_Device_InstanceId, &propertyType, (PBYTE)deviceId.data(), &propertySize, 0); if (cr != CR_SUCCESS) return false; // here is deviceId will contain device instance id // example from my system: `HID\VID_203A&PID_FFFC&MI_01\7&2de99099&0&0000` DEVINST devInst; cr = ::CM_Locate_DevNodeW(&devInst, (DEVINSTID_W)deviceId.c_str(), CM_LOCATE_DEVNODE_NORMAL); if (cr != CR_SUCCESS) return false; propertySize = 0; cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propertyType, nullptr, &propertySize, 0); if (cr != CR_BUFFER_SMALL) return false; std::wstring friendlyString; friendlyString.resize(propertySize); cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_NAME, &propertyType, (PBYTE)friendlyString.data(), &propertySize, 0); // here is friendlyString will contain localized device friendly name propertySize = 0; cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_Device_Manufacturer, &propertyType, nullptr, &propertySize, 0); if (cr != CR_BUFFER_SMALL) return false; std::wstring manufacturer; manufacturer.resize(propertySize); cr = ::CM_Get_DevNode_PropertyW(devInst, &DEVPKEY_Device_Manufacturer, &propertyType, (PBYTE)manufacturer.data(), &propertySize, 0); // here is manufacturer will contain localized device "manufacturer-identifier" return true;}
Update: it turned out that HidD_GetProductString
and family is working for HID keyboard and mouse. You just need to open its device interface (path) as read-only. See https://github.com/DJm00n/RawInputDemo/blob/master/RawInputLib/RawInputDevice.cpp#L77-L86 for example.