From: Vibhav Pant vibhavp@gmail.com
On receiving a BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED event from Unix, broadcast a GUID_BLUETOOTH_RADIO_IN_RANGE PnP event, containing the old and newly updated properties for the remote device. --- dlls/winebth.sys/winebth.c | 46 +++++++++++++++++++++++++++++++++++++- include/bthdef.h | 10 +++++++++ 2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 44d8c3f90d4..c4923902691 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -557,7 +557,10 @@ static void bluetooth_radio_remove_remote_device( struct winebluetooth_watcher_e
static void bluetooth_radio_update_device_props( struct winebluetooth_watcher_event_device_props_changed event ) { + BTH_DEVICE_INFO device_new_info = {0}; + DEVICE_OBJECT *radio_obj = NULL; /* The radio PDO the remote device exists on. */ struct bluetooth_radio *radio; + ULONG device_old_flags = 0;
EnterCriticalSection( &device_list_cs ); LIST_FOR_EACH_ENTRY( radio, &device_list, struct bluetooth_radio, entry ) @@ -569,7 +572,13 @@ static void bluetooth_radio_update_device_props( struct winebluetooth_watcher_ev { if (winebluetooth_device_equal( event.device, device->device )) { + BTH_DEVICE_INFO old_info = {0}; + + radio_obj = radio->device_obj; + EnterCriticalSection( &device->props_cs ); + winebluetooth_device_properties_to_info( device->props_mask, &device->props, &old_info ); + device->props_mask |= event.changed_props_mask; device->props_mask &= ~event.invalid_props_mask; if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_NAME) @@ -586,16 +595,51 @@ static void bluetooth_radio_update_device_props( struct winebluetooth_watcher_ev device->props.trusted = event.props.trusted; if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_CLASS) device->props.class = event.props.class; + winebluetooth_device_properties_to_info( device->props_mask, &device->props, &device_new_info ); LeaveCriticalSection( &device->props_cs ); LeaveCriticalSection( &radio->remote_devices_cs ); + + device_old_flags = old_info.flags; goto done; } } LeaveCriticalSection( &radio->remote_devices_cs ); } done: - LeaveCriticalSection( &device_list_cs ); winebluetooth_device_free( event.device ); + + if (radio_obj) + { + TARGET_DEVICE_CUSTOM_NOTIFICATION *notification; + BTH_RADIO_IN_RANGE *device; + SIZE_T notif_size; + NTSTATUS ret; + + notif_size = offsetof( TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer[sizeof( *device )]); + notification = ExAllocatePool( PagedPool, notif_size ); + if (!notification) + { + LeaveCriticalSection( &device_list_cs ); + return; + } + + notification->Version = 1; + notification->Size = notif_size; + notification->Event = GUID_BLUETOOTH_RADIO_IN_RANGE; + notification->FileObject = NULL; + notification->NameBufferOffset = -1; + device = (BTH_RADIO_IN_RANGE *)notification->CustomDataBuffer; + memset( device, 0, sizeof( *device ) ); + device->previousDeviceFlags = device_old_flags; + device->deviceInfo = device_new_info; + + ret = IoReportTargetDeviceChange( radio_obj, notification ); + if (ret) + ERR("IoReportTargetDeviceChange failed: %#lx\n", ret ); + ExFreePool( notification ); + } + + LeaveCriticalSection( &device_list_cs ); }
static void bluetooth_radio_report_auth_event( struct winebluetooth_auth_event event ) diff --git a/include/bthdef.h b/include/bthdef.h index d71b2e005e7..d3b9387f8cc 100644 --- a/include/bthdef.h +++ b/include/bthdef.h @@ -29,6 +29,9 @@ DEFINE_GUID( GUID_BTHPORT_DEVICE_INTERFACE, 0x850302a, 0xb344, 0x4fda, 0x9b, 0xe DEFINE_GUID( GUID_BLUETOOTH_RADIO_INTERFACE, 0x92383b0e, 0xf90e, 0x4ac9, 0x8d, 0x44, 0x8c, 0x2d, 0x0d, 0x0e, 0xbd, 0xa2 );
+DEFINE_GUID( GUID_BLUETOOTH_RADIO_IN_RANGE, 0xea3b5b82, 0x26ee, 0x450e, 0xb0, 0xd8, 0xd2, 0x6f, + 0xe3, 0x0a, 0x38, 0x69 ); + typedef ULONG BTH_COD;
#define BTH_MAX_NAME_SIZE (248) @@ -52,6 +55,13 @@ typedef struct _BTH_DEVICE_INFO CHAR name[BTH_MAX_NAME_SIZE]; } BTH_DEVICE_INFO, *PBTH_DEVICE_INFO;
+/* Buffer for GUID_BLUETOOTH_RADIO_IN_RANGE events. */ +typedef struct _BTH_RADIO_IN_RANGE +{ + BTH_DEVICE_INFO deviceInfo; + ULONG previousDeviceFlags; +} BTH_RADIO_IN_RANGE, *PBTH_RADIO_IN_RANGE; + #ifdef __cplusplus } #endif