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 or SetupDiGetDeviceInterfaceProperty with DEVPKEY_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 or SetupDiGetDeviceProperty with DEVPKEY_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.