From e6caff3db3178d1663af427fa04b705efcf4e4f1 Mon Sep 17 00:00:00 2001 From: Dimitriy Ryazantcev Date: Sun, 12 Mar 2023 22:29:34 +0200 Subject: [PATCH] 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. --- windows/hid.c | 58 +++++++++++++++++++++++---------------- windows/hidapi_cfgmgr32.h | 1 + 2 files changed, 35 insertions(+), 24 deletions(-) diff --git a/windows/hid.c b/windows/hid.c index 1b725b32c..5453faa15 100644 --- a/windows/hid.c +++ b/windows/hid.c @@ -409,32 +409,46 @@ static void* hid_internal_get_device_interface_property(const wchar_t* interface return property_value; } +/* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices + Request this info via dev node properties instead. + https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html +*/ static void hid_internal_get_ble_info(struct hid_device_info* dev, DEVINST dev_node) { - wchar_t *manufacturer_string, *serial_number, *product_string; - /* Manufacturer String */ - manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING); - if (manufacturer_string) { - free(dev->manufacturer_string); - dev->manufacturer_string = manufacturer_string; + if (wcslen(dev->manufacturer_string) == 0) { + /* Manufacturer Name String (UUID: 0x2A29) */ + wchar_t* manufacturer_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_Manufacturer, DEVPROP_TYPE_STRING); + if (manufacturer_string) { + free(dev->manufacturer_string); + dev->manufacturer_string = manufacturer_string; + } } - /* Serial Number String (MAC Address) */ - serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING); - if (serial_number) { - free(dev->serial_number); - dev->serial_number = serial_number; + if (wcslen(dev->serial_number) == 0) { + /* Serial Number String (UUID: 0x2A25) */ + wchar_t* serial_number = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_DeviceAddress, DEVPROP_TYPE_STRING); + if (serial_number) { + free(dev->serial_number); + dev->serial_number = serial_number; + } } - /* Get devnode grandparent to reach out Bluetooth LE device node */ - if (CM_Get_Parent(&dev_node, dev_node, 0) != CR_SUCCESS) - return; + if (wcslen(dev->product_string) == 0) { + /* Model Number String (UUID: 0x2A24) */ + wchar_t* product_string = hid_internal_get_devnode_property(dev_node, (const DEVPROPKEY*)&PKEY_DeviceInterface_Bluetooth_ModelNumber, DEVPROP_TYPE_STRING); + if (!product_string) { + DEVINST parent_dev_node = 0; + /* Fallback: Get devnode grandparent to reach out Bluetooth LE device node */ + if (CM_Get_Parent(&parent_dev_node, dev_node, 0) == CR_SUCCESS) { + /* Device Name (UUID: 0x2A00) */ + product_string = hid_internal_get_devnode_property(parent_dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING); + } + } - /* Product String */ - product_string = hid_internal_get_devnode_property(dev_node, &DEVPKEY_NAME, DEVPROP_TYPE_STRING); - if (product_string) { - free(dev->product_string); - dev->product_string = product_string; + if (product_string) { + free(dev->product_string); + dev->product_string = product_string; + } } } @@ -527,12 +541,8 @@ static void hid_internal_get_info(const wchar_t* interface_path, struct hid_devi /* Bluetooth LE devices */ if (wcsstr(compatible_id, L"BTHLEDEVICE") != NULL) { - /* HidD_GetProductString/HidD_GetManufacturerString/HidD_GetSerialNumberString is not working for BLE HID devices - Request this info via dev node properties instead. - https://docs.microsoft.com/answers/questions/401236/hidd-getproductstring-with-ble-hid-device.html */ - hid_internal_get_ble_info(dev, dev_node); - dev->bus_type = HID_API_BUS_BLUETOOTH; + hid_internal_get_ble_info(dev, dev_node); break; } diff --git a/windows/hidapi_cfgmgr32.h b/windows/hidapi_cfgmgr32.h index 720906e3d..e73b15f69 100644 --- a/windows/hidapi_cfgmgr32.h +++ b/windows/hidapi_cfgmgr32.h @@ -63,6 +63,7 @@ static DEVPROPKEY DEVPKEY_Device_ContainerId = { { 0x8c7ed206, 0x3f8a, 0x4827, { // from propkey.h static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_DeviceAddress = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 1 }; // DEVPROP_TYPE_STRING static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_Manufacturer = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 4 }; // DEVPROP_TYPE_STRING +static PROPERTYKEY PKEY_DeviceInterface_Bluetooth_ModelNumber = { { 0x2bd67d8b, 0x8beb, 0x48d5, {0x87, 0xe0, 0x6c, 0xda, 0x34, 0x28, 0x04, 0x0a} }, 5 }; // DEVPROP_TYPE_STRING #endif