This fadds to the basic infrastructure needed for device inquiry/scanning.
Also, fixes radio properties being incorrectly updated.
-- v3: winebth.sys: Set the device class for remote devices from BlueZ's "Class" property. winebth.sys: Use the "Trusted" property from BlueZ device objects to set BDIF_PERSONAL. winebth.sys: Use the "Name" property of a BlueZ adapter for the local radio name. winebth.sys: Don't iterate over the remaining radios once a local device has been removed. winebth.sys: Initially set numOfDevices to 0 in IOCTL_BTH_GET_DEVICE_INFO. winebth.sys: Use the correct DBus property name in IOCTL_WINEBTH_RADIO_SET_FLAG. winebth.sys: Update properties for tracked remote devices on receiving PropertiesChanged for org.bluez.Device1 objects from BlueZ.
From: Vibhav Pant vibhavp@gmail.com
A PropertiesChanged signal only contains the updated properties for the object, so the PE driver should only modify the properties which have their corresponding mask bit set. Additionally, unset the mask bits for invalidated properties. --- dlls/winebth.sys/winebth.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 28cc67c123c..39e5a7cd988 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -399,8 +399,6 @@ static void update_bluetooth_radio_properties( struct winebluetooth_watcher_even { struct bluetooth_radio *device; winebluetooth_radio_t radio = event.radio; - winebluetooth_radio_props_mask_t mask = event.changed_props_mask; - struct winebluetooth_radio_properties props = event.props;
EnterCriticalSection( &device_list_cs ); LIST_FOR_EACH_ENTRY( device, &device_list, struct bluetooth_radio, entry ) @@ -408,8 +406,27 @@ static void update_bluetooth_radio_properties( struct winebluetooth_watcher_even if (winebluetooth_radio_equal( radio, device->radio ) && !device->removed) { EnterCriticalSection( &device->props_cs ); - device->props_mask = mask; - device->props = props; + device->props_mask |= event.changed_props_mask; + device->props_mask &= ~event.invalid_props_mask; + + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_NAME) + memcpy( device->props.name, event.props.name, sizeof( event.props.name )); + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_ADDRESS) + device->props.address.ullLong = RtlUlonglongByteSwap( event.props.address.ullLong ); + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_DISCOVERABLE) + device->props.discoverable = event.props.discoverable; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_CONNECTABLE) + device->props.connectable = event.props.connectable; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_CLASS) + device->props.class = event.props.class; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_MANUFACTURER) + device->props.manufacturer = event.props.manufacturer; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_VERSION) + device->props.version = event.props.version; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_DISCOVERING) + device->props.discovering = event.props.discovering; + if (event.changed_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_PAIRABLE) + device->props.pairable = event.props.pairable; bluetooth_radio_set_properties( device->device_obj, device->props_mask, &device->props ); LeaveCriticalSection( &device->props_cs );
From: Vibhav Pant vibhavp@gmail.com
When the unix bluez watcher receives a PropertiesChanged signal for a org.bluez.Device1 object, queue a BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED event, containing the changed and invalidated properties for the associated remote device. --- dlls/winebth.sys/dbus.c | 141 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth.c | 46 +++++++++++ dlls/winebth.sys/winebth_priv.h | 13 ++- 3 files changed, 199 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 13e4bbe29e5..5de6ab5916c 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -579,6 +579,29 @@ static NTSTATUS bluez_adapter_get_props_async( void *connection, const char *rad return STATUS_SUCCESS; }
+static NTSTATUS bluez_device_get_props_by_path_async( DBusConnection *connection, + const char *device_path, + DBusPendingCall **pending_call ) +{ + DBusMessage *request; + static const char *adapter_iface = BLUEZ_INTERFACE_DEVICE; + dbus_bool_t ret; + + request = p_dbus_message_new_method_call( BLUEZ_DEST, device_path, + DBUS_INTERFACE_PROPERTIES, "GetAll" ); + if (!request) return STATUS_NO_MEMORY; + + p_dbus_message_append_args( request, DBUS_TYPE_STRING, &adapter_iface, DBUS_TYPE_INVALID ); + ret = p_dbus_connection_send_with_reply( connection, request, pending_call, bluez_timeout ); + p_dbus_message_unref( request ); + if (!ret) + return STATUS_NO_MEMORY; + if (!*pending_call) + return STATUS_INTERNAL_ERROR; + + return STATUS_SUCCESS; +} + struct bluez_watcher_ctx { void *init_device_list_call; @@ -715,6 +738,42 @@ static void bluez_filter_radio_props_changed_callback( DBusPendingCall *call, vo p_dbus_message_unref( reply ); }
+static void bluez_filter_device_props_changed_callback( DBusPendingCall *call, void *user_data ) +{ + union winebluetooth_watcher_event_data *event = user_data; + struct winebluetooth_watcher_event_device_props_changed *changed = &event->device_props_changed; + const struct unix_name *device = (struct unix_name *)event->device_props_changed.device.handle; + DBusMessage *reply; + DBusMessageIter dict, prop_iter, variant; + const char *prop_name; + DBusError error; + + TRACE( "call %p, device %s\n", call, debugstr_a( device->str ) ); + + reply = p_dbus_pending_call_steal_reply( call ); + p_dbus_error_init( &error ); + if (p_dbus_set_error_from_message( &error, reply )) + { + ERR( "Failed to get device properties for %s: %s: %s\n", debugstr_a( device->str ), debugstr_a( error.name ), + debugstr_a( error.message ) ); + p_dbus_error_free( &error ); + p_dbus_message_unref( reply ); + return; + } + p_dbus_error_free( &error ); + + p_dbus_message_iter_init( reply, &dict ); + p_dbus_message_iter_recurse( &dict, &prop_iter ); + while((prop_name = bluez_next_dict_entry( &prop_iter, &variant ))) + { + bluez_device_prop_from_dict_entry( prop_name, &variant, &changed->props, + &changed->changed_props_mask, + changed->invalid_props_mask ); + } + changed->invalid_props_mask &= ~changed->changed_props_mask; + p_dbus_message_unref( reply ); +} + struct bluez_object_property_masks { const char *prop_name; @@ -1022,6 +1081,85 @@ static DBusHandlerResult bluez_filter( DBusConnection *conn, DBusMessage *msg, v } } } + else if (strcmp( iface, BLUEZ_INTERFACE_DEVICE ) == 0) + { + struct winebluetooth_watcher_event_device_props_changed props_changed = {0}; + struct unix_name *device; + const char *prop_name, *object_path; + union winebluetooth_watcher_event_data event; + DBusMessageIter changed_props_iter, invalid_props_iter, variant; + const static struct bluez_object_property_masks device_prop_masks[] = { + { "Name", WINEBLUETOOTH_DEVICE_PROPERTY_NAME }, + { "Address", WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS }, + { "Connected", WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED }, + { "Paired", WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED }, + { "LegacyPairing", WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING }, + { "Trusted", WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED }, + { "Class", WINEBLUETOOTH_DEVICE_PROPERTY_CLASS } + }; + + p_dbus_message_iter_next( &iter ); + p_dbus_message_iter_recurse( &iter, &changed_props_iter ); + while ((prop_name = bluez_next_dict_entry( &changed_props_iter, &variant ))) + { + bluez_device_prop_from_dict_entry( prop_name, &variant, &props_changed.props, + &props_changed.changed_props_mask, + WINEBLUETOOTH_DEVICE_ALL_PROPERTIES ); + } + p_dbus_message_iter_next( &iter ); + p_dbus_message_iter_recurse( &iter, &invalid_props_iter ); + props_changed.invalid_props_mask = bluez_dbus_get_invalidated_properties_from_iter( + &invalid_props_iter, device_prop_masks, ARRAY_SIZE( device_prop_masks ) ); + /* No properties that we're interested in have changed or been invalidated. */ + if (!props_changed.changed_props_mask && !props_changed.invalid_props_mask) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + object_path = p_dbus_message_get_path( msg ); + TRACE( "Properties changed for device %s, changed %#x, invalidated %#x\n", debugstr_a( object_path ), + props_changed.changed_props_mask, props_changed.invalid_props_mask ); + + device = unix_name_get_or_create( object_path ); + if (!device) + { + ERR( "Failed to allocate memory for device path %s\n", object_path ); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + props_changed.device.handle = (UINT_PTR)device; + event.device_props_changed = props_changed; + + if (props_changed.invalid_props_mask != 0) + { + DBusPendingCall *pending_call = NULL; + NTSTATUS status; + + status = bluez_device_get_props_by_path_async( conn, device->str, &pending_call ); + if (status) + { + ERR( "Failed to create async call to get device properties: %#x\n", (int)status ); + unix_name_free( device ); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (!bluez_event_list_queue_new_event_with_call( event_list, + BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED, + event, pending_call, + bluez_filter_device_props_changed_callback )) + { + unix_name_free( device ); + p_dbus_pending_call_cancel( pending_call ); + p_dbus_pending_call_unref( pending_call ); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } + else if (!bluez_event_list_queue_new_event( event_list, + BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED, + event )) + { + + unix_name_free( device ); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + } }
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1078,6 +1216,9 @@ static void bluez_watcher_free( struct bluez_watcher_ctx *watcher ) case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_REMOVED: unix_name_free( (struct unix_name *)event1->event.device_removed.device.handle ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED: + unix_name_free( (struct unix_name *)event1->event.device_props_changed.device.handle ); + break; } free( event1 ); } diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 39e5a7cd988..08e92ed74cd 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -497,6 +497,49 @@ static void bluetooth_radio_remove_remote_device( struct winebluetooth_watcher_e winebluetooth_device_free( event.device ); }
+static void bluetooth_radio_update_device_props( struct winebluetooth_watcher_event_device_props_changed event ) +{ + struct bluetooth_radio *radio; + + EnterCriticalSection( &device_list_cs ); + LIST_FOR_EACH_ENTRY( radio, &device_list, struct bluetooth_radio, entry ) + { + struct bluetooth_remote_device *device; + + EnterCriticalSection( &radio->remote_devices_cs ); + LIST_FOR_EACH_ENTRY( device, &radio->remote_devices, struct bluetooth_remote_device, entry ) + { + if (winebluetooth_device_equal( event.device, device->device )) + { + EnterCriticalSection( &device->props_cs ); + device->props_mask |= event.changed_props_mask; + device->props_mask &= ~event.invalid_props_mask; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_NAME) + memcpy( device->props.name, event.props.name, sizeof( event.props.name )); + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS) + device->props.address = event.props.address; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED) + device->props.connected = event.props.connected; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED) + device->props.paired = event.props.paired; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING) + device->props.legacy_pairing = event.props.legacy_pairing; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED) + device->props.trusted = event.props.trusted; + if (event.changed_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_CLASS) + device->props.class = event.props.class; + LeaveCriticalSection( &device->props_cs ); + LeaveCriticalSection( &radio->remote_devices_cs ); + goto done; + } + } + LeaveCriticalSection( &radio->remote_devices_cs ); + } +done: + LeaveCriticalSection( &device_list_cs ); + winebluetooth_device_free( event.device ); +} + static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) { NTSTATUS status; @@ -529,6 +572,9 @@ static DWORD CALLBACK bluetooth_event_loop_thread_proc( void *arg ) case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_REMOVED: bluetooth_radio_remove_remote_device( event->event_data.device_removed ); break; + case BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED: + bluetooth_radio_update_device_props( event->event_data.device_props_changed); + break; default: FIXME( "Unknown bluetooth watcher event code: %#x\n", event->event_type ); } diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index 72dcf4bf130..b3975a48c11 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -204,7 +204,8 @@ enum winebluetooth_watcher_event_type BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_REMOVED, BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_PROPERTIES_CHANGED, BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_ADDED, - BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_REMOVED + BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_REMOVED, + BLUETOOTH_WATCHER_EVENT_TYPE_DEVICE_PROPERTIES_CHANGED };
struct winebluetooth_watcher_event_radio_added @@ -231,6 +232,15 @@ struct winebluetooth_watcher_event_device_added winebluetooth_radio_t radio; };
+struct winebluetooth_watcher_event_device_props_changed +{ + winebluetooth_device_props_mask_t changed_props_mask; + struct winebluetooth_device_properties props; + + winebluetooth_device_props_mask_t invalid_props_mask; + winebluetooth_device_t device; +}; + struct winebluetooth_watcher_event_device_removed { winebluetooth_device_t device; @@ -243,6 +253,7 @@ union winebluetooth_watcher_event_data struct winebluetooth_watcher_event_radio_props_changed radio_props_changed; struct winebluetooth_watcher_event_device_added device_added; struct winebluetooth_watcher_event_device_removed device_removed; + struct winebluetooth_watcher_event_device_props_changed device_props_changed; };
struct winebluetooth_watcher_event
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 5de6ab5916c..6b63bb1e06b 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -345,12 +345,12 @@ NTSTATUS bluez_adapter_set_prop( void *connection, struct bluetooth_adapter_set_ switch (params->prop_flag) { case LOCAL_RADIO_CONNECTABLE: - prop_name = "Discoverable"; + prop_name = "Connectable"; val.bool_val = params->prop->boolean; val_type = DBUS_TYPE_BOOLEAN; break; case LOCAL_RADIO_DISCOVERABLE: - prop_name = "Connectable"; + prop_name = "Discoverable"; val.bool_val = params->prop->boolean; val_type = DBUS_TYPE_BOOLEAN; break;
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/winebth.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 08e92ed74cd..273abdc24f0 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -168,6 +168,7 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) rem_devices = (outsize - sizeof( *list ))/sizeof(BTH_DEVICE_INFO) + 1; status = STATUS_SUCCESS; irp->IoStatus.Information = 0; + list->numOfDevices = 0;
EnterCriticalSection( &ext->remote_devices_cs ); LIST_FOR_EACH_ENTRY( device, &ext->remote_devices, struct bluetooth_remote_device, entry )
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/winebth.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 273abdc24f0..5b8d9e06211 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -489,7 +489,11 @@ static void bluetooth_radio_remove_remote_device( struct winebluetooth_watcher_e winebluetooth_device_free( device->device ); DeleteCriticalSection( &device->props_cs ); free( device ); - break; + + LeaveCriticalSection( &radio->remote_devices_cs ); + LeaveCriticalSection( &device_list_cs ); + winebluetooth_device_free( event.device ); + return; } } LeaveCriticalSection( &radio->remote_devices_cs );
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 6b63bb1e06b..3c4b2eb4fa1 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -420,6 +420,18 @@ static void bluez_radio_prop_from_dict_entry( const char *prop_name, DBusMessage TRACE_(dbus)( "(%s, %p, %p, %p, %#x)\n", debugstr_a( prop_name ), variant, props, props_mask, wanted_props_mask );
+ if (wanted_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_NAME && + !strcmp( prop_name, "Name" ) && + p_dbus_message_iter_get_arg_type( variant )) + { + const char *name_str; + SIZE_T len; + p_dbus_message_iter_get_basic( variant, &name_str ); + len = strlen( name_str ); + memcpy( props->name, name_str, min( len + 1, ARRAYSIZE( props->name ))); + props->name[ARRAYSIZE( props->name ) - 1] = '\0'; + *props_mask |= WINEBLUETOOTH_RADIO_PROPERTY_NAME; + } if (wanted_props_mask & WINEBLUETOOTH_RADIO_PROPERTY_ADDRESS && !strcmp( prop_name, "Address" ) && p_dbus_message_iter_get_arg_type( variant ) == DBUS_TYPE_STRING)
From: Vibhav Pant vibhavp@gmail.com
On BlueZ, "Trusted" devices are saved to the local cache, which makes them equivalent to Win32 devices with the BDIF_PERSONAL flag set. --- dlls/winebth.sys/dbus.c | 10 ++++++++++ dlls/winebth.sys/winebth.c | 3 +++ dlls/winebth.sys/winebth_priv.h | 4 +++- 3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 3c4b2eb4fa1..7dfde34d3d8 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -566,6 +566,16 @@ static void bluez_device_prop_from_dict_entry( const char *prop_name, DBusMessag props->legacy_pairing = !!legacy; *props_mask |= WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING; } + else if (wanted_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED && + !strcmp( prop_name, "Trusted" ) && + p_dbus_message_iter_get_arg_type( variant ) == DBUS_TYPE_BOOLEAN) + { + dbus_bool_t trusted; + + p_dbus_message_iter_get_basic( variant, &trusted ); + props->trusted = !!trusted; + *props_mask |= WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED; + } }
static NTSTATUS bluez_adapter_get_props_async( void *connection, const char *radio_object_path, diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 5b8d9e06211..c214156d8b2 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -206,6 +206,9 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) device->props.paired) info->flags |= BDIF_SSP_PAIRED; } + if (device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED && + device->props.trusted) + info->flags |= BDIF_PERSONAL; LeaveCriticalSection( &device->props_cs );
irp->IoStatus.Information += sizeof( *info ); diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index b3975a48c11..8e8fd1c543e 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -145,11 +145,12 @@ typedef UINT16 winebluetooth_device_props_mask_t; #define WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED (1 << 2) #define WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED (1 << 3) #define WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING (1 << 4) +#define WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED (1 << 5)
#define WINEBLUETOOTH_DEVICE_ALL_PROPERTIES \ (WINEBLUETOOTH_DEVICE_PROPERTY_NAME | WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS | \ WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED | WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED | \ - WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING) + WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING | WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED)
union winebluetooth_property { @@ -179,6 +180,7 @@ struct winebluetooth_device_properties BOOL connected; BOOL paired; BOOL legacy_pairing; + BOOL trusted; };
NTSTATUS winebluetooth_radio_get_unique_name( winebluetooth_radio_t radio, char *name,
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 7 +++++++ dlls/winebth.sys/winebth.c | 5 +++++ dlls/winebth.sys/winebth_priv.h | 11 +++++++---- 3 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 7dfde34d3d8..153c4e60ad1 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -576,6 +576,13 @@ static void bluez_device_prop_from_dict_entry( const char *prop_name, DBusMessag props->trusted = !!trusted; *props_mask |= WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED; } + else if (wanted_props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_CLASS && + !strcmp( prop_name, "Class" ) && + p_dbus_message_iter_get_arg_type( variant ) == DBUS_TYPE_UINT32) + { + p_dbus_message_iter_get_basic( variant, &props->class ); + *props_mask |= WINEBLUETOOTH_DEVICE_PROPERTY_CLASS; + } }
static NTSTATUS bluez_adapter_get_props_async( void *connection, const char *radio_object_path, diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index c214156d8b2..b47806de077 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -209,6 +209,11 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) if (device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED && device->props.trusted) info->flags |= BDIF_PERSONAL; + if (device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_CLASS) + { + info->classOfDevice = device->props.class; + info->flags |= BDIF_COD; + } LeaveCriticalSection( &device->props_cs );
irp->IoStatus.Information += sizeof( *info ); diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index 8e8fd1c543e..b50935c091c 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -146,11 +146,13 @@ typedef UINT16 winebluetooth_device_props_mask_t; #define WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED (1 << 3) #define WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING (1 << 4) #define WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED (1 << 5) +#define WINEBLUETOOTH_DEVICE_PROPERTY_CLASS (1 << 6)
-#define WINEBLUETOOTH_DEVICE_ALL_PROPERTIES \ - (WINEBLUETOOTH_DEVICE_PROPERTY_NAME | WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS | \ - WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED | WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED | \ - WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING | WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED) +#define WINEBLUETOOTH_DEVICE_ALL_PROPERTIES \ + (WINEBLUETOOTH_DEVICE_PROPERTY_NAME | WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS | \ + WINEBLUETOOTH_DEVICE_PROPERTY_CONNECTED | WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED | \ + WINEBLUETOOTH_DEVICE_PROPERTY_LEGACY_PAIRING | WINEBLUETOOTH_DEVICE_PROPERTY_TRUSTED | \ + WINEBLUETOOTH_DEVICE_PROPERTY_CLASS)
union winebluetooth_property { @@ -181,6 +183,7 @@ struct winebluetooth_device_properties BOOL paired; BOOL legacy_pairing; BOOL trusted; + UINT32 class; };
NTSTATUS winebluetooth_radio_get_unique_name( winebluetooth_radio_t radio, char *name,
Apologies for so many commits, but only #1 and #2 introduce substantial changes. The rest are one-liners that either add mapings for other DBus properties or fix issues with existing code.