From: Vibhav Pant <vibhavp@gmail.com> --- dlls/winebth.sys/winebth.c | 56 ++++++++++++++++++++++++++------------ include/ddk/bthguid.h | 5 ++++ 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index fccac50bdef..dea7af365c0 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -102,8 +102,12 @@ struct bluetooth_remote_device BOOL started; /* Whether the device has been started. Guarded by props_cs */ BOOL removed; - BOOL le; /* Guarded by props_cs */ + /* Whether the device supports LE. Set when support is either indicated by unix + * (WINEBLUETOOTH_DEVICE_PROPERTY_BEARER_LE) or manually detected when a GATT service for this device is found. + * Guarded by props_cs */ + BOOL le; UNICODE_STRING bthle_symlink_name; /* Guarded by props_cs */ + UNICODE_STRING bredr_symlink_name; /* Guarded by props_cs */ struct list gatt_services; /* Guarded by props_cs */ }; @@ -334,6 +338,18 @@ static NTSTATUS bluetooth_gatt_service_dispatch( DEVICE_OBJECT *device, struct b return status; } +/* Returns whether the remote device supports BR/EDR. Caller should hold device->props_cs. */ +static BOOL bluetooth_remote_device_has_bredr( const struct bluetooth_remote_device *device ) +{ + return !!(device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_BEARER_BREDR); +} + +/* Returns whether the remote device supports LE. Caller should hold device->props_cs. */ +static BOOL bluetooth_remote_device_has_le( const struct bluetooth_remote_device *device ) +{ + return device->le; +} + static NTSTATUS bluetooth_remote_device_dispatch( DEVICE_OBJECT *device, struct bluetooth_remote_device *ext, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); @@ -1044,7 +1060,7 @@ static void bluetooth_radio_add_remote_device( struct winebluetooth_watcher_even ext->remote_device.removed = FALSE; ext->remote_device.started = FALSE; - ext->remote_device.le = FALSE; + ext->remote_device.le = !!(event.known_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_BEARER_LE); list_init( &ext->remote_device.gatt_services ); if (!event.init_entry) @@ -1297,17 +1313,15 @@ static void complete_irp( IRP *irp, NTSTATUS result ) /* Enables the low energy interface for this device if it hasn't been already. Caller should hold device->props_cs. */ static void bluetooth_device_enable_le_iface( struct bluetooth_remote_device *device ) { - /* The device hasn't been started by the PnP manager yet. Set le, and let remote_device_pdo_pnp enable the - * interface. */ - if (!device->started) - device->le = TRUE; - else if (!device->le) - { - device->le = TRUE; - if (!IoRegisterDeviceInterface( device->device_obj, &GUID_BLUETOOTHLE_DEVICE_INTERFACE, NULL, - &device->bthle_symlink_name )) + if (bluetooth_remote_device_has_le( device )) return; + + device->le = TRUE; + /* If the device hasn't been started by the PnP manager, do nothing as remote_device_pdo_pnp enables the interface. */ + if (!device->started) return; + /* Otherwise, do it manually. */ + if (!IoRegisterDeviceInterface( device->device_obj, &GUID_BLUETOOTHLE_DEVICE_INTERFACE, NULL, + &device->bthle_symlink_name )) IoSetDeviceInterfaceState( &device->bthle_symlink_name, TRUE ); - } } static void bluetooth_device_add_gatt_service( struct winebluetooth_watcher_event_gatt_service_added event ) @@ -1397,7 +1411,7 @@ static void bluetooth_gatt_service_remove( winebluetooth_gatt_service_t service struct bluetooth_gatt_service *svc; EnterCriticalSection( &device->props_cs ); - if (!device->le) + if (!bluetooth_remote_device_has_le( device )) { LeaveCriticalSection( &device->props_cs ); continue; @@ -1437,7 +1451,7 @@ bluetooth_gatt_service_add_characteristic( struct winebluetooth_watcher_event_ga struct bluetooth_gatt_service *svc; EnterCriticalSection( &device->props_cs ); - if (!device->le) + if (!bluetooth_remote_device_has_le( device )) { LeaveCriticalSection( &device->props_cs ); continue; @@ -1514,7 +1528,7 @@ static void bluetooth_gatt_characteristic_remove( winebluetooth_gatt_characteris struct bluetooth_gatt_service *svc; EnterCriticalSection( &device->props_cs ); - if (!device->le) + if (!bluetooth_remote_device_has_le( device )) { LeaveCriticalSection( &device->props_cs ); continue; @@ -1564,7 +1578,7 @@ static void bluetooth_gatt_characteristic_value_update( struct winebluetooth_wat struct bluetooth_gatt_service *svc; EnterCriticalSection( &device->props_cs ); - if (!device->le) + if (!bluetooth_remote_device_has_le( device )) { LeaveCriticalSection( &device->props_cs ); continue; @@ -2061,6 +2075,11 @@ static void remote_device_destroy( struct bluetooth_remote_device *ext ) IoSetDeviceInterfaceState( &ext->bthle_symlink_name, FALSE ); RtlFreeUnicodeString( &ext->bthle_symlink_name ); } + if (ext->bredr_symlink_name.Buffer) + { + IoSetDeviceInterfaceState( &ext->bredr_symlink_name, FALSE ); + RtlFreeUnicodeString( &ext->bredr_symlink_name ); + } ext->props_cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &ext->props_cs ); winebluetooth_device_free( ext->device ); @@ -2128,10 +2147,13 @@ static NTSTATUS WINAPI remote_device_pdo_pnp( DEVICE_OBJECT *device_obj, struct LeaveCriticalSection( &device_list_cs ); EnterCriticalSection( &ext->props_cs ); - if (ext->le && + if (bluetooth_remote_device_has_le( ext ) && !IoRegisterDeviceInterface( device_obj, &GUID_BLUETOOTHLE_DEVICE_INTERFACE, NULL, &ext->bthle_symlink_name )) IoSetDeviceInterfaceState( &ext->bthle_symlink_name, TRUE ); + if (bluetooth_remote_device_has_bredr( ext ) && + !IoRegisterDeviceInterface( device_obj, &GUID_BTH_DEVICE_INTERFACE, NULL, &ext->bredr_symlink_name )) + IoSetDeviceInterfaceState( &ext->bredr_symlink_name, TRUE ); ext->started = TRUE; bluetooth_device_set_properties( ext, adapter_addr.rgBytes, &ext->props, ext->props_mask ); LeaveCriticalSection( &ext->props_cs ); diff --git a/include/ddk/bthguid.h b/include/ddk/bthguid.h index 2b850969972..ca902dd94a6 100644 --- a/include/ddk/bthguid.h +++ b/include/ddk/bthguid.h @@ -19,9 +19,14 @@ #ifndef __DDK_BTHGUID_H__ #define __DDK_BTHGUID_H__ +/* Interface for BR/EDR (Bluetooth Classic) devices. */ +DEFINE_GUID( GUID_BTH_DEVICE_INTERFACE, 0x00f40965,0xe89d,0x4487,0x98,0x90,0x87,0xc3,0xab,0xb2,0x11,0xf4 ); + /* DEVPROP_TYPE_STRING */ DEFINE_DEVPROPKEY( DEVPKEY_Bluetooth_DeviceAddress, 0x2bd67d8b,0x8beb,0x48d5,0x87,0xe0,0x6c,0xda,0x34,0x28,0x04,0x0a,1 ); /* DEVPROP_TYPE_UINT32 */ +DEFINE_DEVPROPKEY( DEVPKEY_Bluetooth_DeviceFlags, 0x2bd67d8b,0x8beb,0x48d5,0x87,0xe0,0x6c,0xda,0x34,0x28,0x04,0x0a,3 ); +/* DEVPROP_TYPE_UINT32 */ DEFINE_DEVPROPKEY( DEVPKEY_Bluetooth_ClassOfDevice, 0x2bd67d8b,0x8beb,0x48d5,0x87,0xe0,0x6c,0xda,0x34,0x28,0x04,0x0a,10 ); /* DEVPROP_TYPE_FILETIME */ DEFINE_DEVPROPKEY( DEVPKEY_Bluetooth_LastConnectedTime, 0x2bd67d8b,0x8beb,0x48d5,0x87,0xe0,0x6c,0xda,0x34,0x28,0x04,0x0a,11 ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11084