Skip to content

Commit e6caff3

Browse files
authored
windows: Get Bluetooth device Model Number String instead of Device Name into product string (#500)
Use `Device Name` only if `Model Number String` is not available. This should better match what we have in `USB_DEVICE_DESCRIPTOR.iProduct` See [Bluetooth Device Information Service](https://www.bluetooth.com/specifications/specs/device-information-service-1-1/) spec for more info.
1 parent 19f71a5 commit e6caff3

2 files changed

Lines changed: 35 additions & 24 deletions

File tree

windows/hid.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -409,32 +409,46 @@ static void* hid_internal_get_device_interface_property(const wchar_t* interface
409409
return property_value;
410410
}
411411

412+
/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices
413+
Request this info via dev node properties instead.
414+
https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html
415+
*/
412416
static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node)
413417
{
414-
wchar_t *manufacturer_string, *serial_number, *product_string;
415-
/* Manufacturer String */
416-
manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING);
417-
if (manufacturer_string) {
418-
free(dev->manufacturer_string);
419-
dev->manufacturer_string = manufacturer_string;
418+
if (wcslen(dev->manufacturer_string) == 0) {
419+
/* Manufacturer Name String (UUID: 0x2A29) */
420+
wchar_t* manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING);
421+
if (manufacturer_string) {
422+
free(dev->manufacturer_string);
423+
dev->manufacturer_string = manufacturer_string;
424+
}
420425
}
421426

422-
/* Serial Number String (MAC Address) */
423-
serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING);
424-
if (serial_number) {
425-
free(dev->serial_number);
426-
dev->serial_number = serial_number;
427+
if (wcslen(dev->serial_number) == 0) {
428+
/* Serial Number String (UUID: 0x2A25) */
429+
wchar_t* serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING);
430+
if (serial_number) {
431+
free(dev->serial_number);
432+
dev->serial_number = serial_number;
433+
}
427434
}
428435

429-
/* Get devnode grandparent to reach out Bluetooth LE device node */
430-
if (CM_Get_Parent(&dev_node, dev_node, 0) != CR_SUCCESS)
431-
return;
436+
if (wcslen(dev->product_string) == 0) {
437+
/* Model Number String (UUID: 0x2A24) */
438+
wchar_t* product_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_ModelNumber, DEVPROP_TYPE_STRING);
439+
if (!product_string) {
440+
DEVINST parent_dev_node = 0;
441+
/* Fallback: Get devnode grandparent to reach out Bluetooth LE device node */
442+
if (CM_Get_Parent(&parent_dev_node, dev_node, 0) == CR_SUCCESS) {
443+
/* Device Name (UUID: 0x2A00) */
444+
product_string = hid_internal_get_devnode_property(parent_dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING);
445+
}
446+
}
432447

433-
/* Product String */
434-
product_string = hid_internal_get_devnode_property(dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING);
435-
if (product_string) {
436-
free(dev->product_string);
437-
dev->product_string = product_string;
448+
if (product_string) {
449+
free(dev->product_string);
450+
dev->product_string = product_string;
451+
}
438452
}
439453
}
440454

@@ -527,12 +541,8 @@ static void hid_internal_get_info(const wchar_t* interface_path, struct hid_devi
527541

528542
/* Bluetooth LE devices */
529543
if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) {
530-
/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices
531-
Request this info via dev node properties instead.
532-
https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html */
533-
hid_internal_get_ble_info(dev, dev_node);
534-
535544
dev->bus_type = HID_API_BUS_BLUETOOTH;
545+
hid_internal_get_ble_info(dev, dev_node);
536546
break;
537547
}
538548

windows/hidapi_cfgmgr32.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, {
6363
// from propkey.h
6464
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 1 }; // DEVPROP_TYPE_STRING
6565
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 4 }; // DEVPROP_TYPE_STRING
66+
static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_ModelNumber = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 5 }; // DEVPROP_TYPE_STRING
6667

6768
#endif
6869

0 commit comments

Comments
 (0)