From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/unixlib.c | 30 +++++++++++++++++ dlls/winebth.sys/unixlib.h | 9 +++++ dlls/winebth.sys/winebluetooth.c | 17 ++++++++++ dlls/winebth.sys/winebth.c | 57 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 2 ++ 5 files changed, 115 insertions(+)
diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c index dc3ff2a56d6..955702e2f44 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -107,6 +107,35 @@ static NTSTATUS bluetooth_shutdown( void *params ) return STATUS_SUCCESS; }
+static NTSTATUS get_unique_name( const struct unix_name *name, char *buf, SIZE_T *buf_size ) +{ + SIZE_T path_len, i; + + path_len = strlen( name->str ); + if (*buf_size <= (path_len * sizeof(char))) + { + *buf_size = (path_len + 1) * sizeof(char); + return STATUS_BUFFER_TOO_SMALL; + } + + for (i = 0; i < path_len; i++) + { + if (name->str[i] == '/') buf[i] = '_'; + else + buf[i] = name->str[i]; + } + buf[path_len] = '\0'; + return STATUS_SUCCESS; +} + +static NTSTATUS bluetooth_adapter_get_unique_name( void *args ) +{ + struct bluetooth_adapter_get_unique_name_params *params = args; + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + + return get_unique_name( params->adapter, params->buf, ¶ms->buf_size ); +} + static NTSTATUS bluetooth_adapter_free( void *args ) { struct bluetooth_adapter_free_params *params = args; @@ -127,6 +156,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { bluetooth_init, bluetooth_shutdown,
+ bluetooth_adapter_get_unique_name, bluetooth_adapter_free,
bluetooth_get_event, diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h index a2a1bff98c6..b88b749c8cc 100644 --- a/dlls/winebth.sys/unixlib.h +++ b/dlls/winebth.sys/unixlib.h @@ -47,6 +47,14 @@ struct bluetooth_adapter_free_params unix_name_t adapter; };
+struct bluetooth_adapter_get_unique_name_params +{ + unix_name_t adapter; + + char *buf; + SIZE_T buf_size; +}; + struct bluetooth_get_event_params { struct winebluetooth_event result; @@ -57,6 +65,7 @@ enum bluetoothapis_funcs unix_bluetooth_init, unix_bluetooth_shutdown,
+ unix_bluetooth_adapter_get_unique_name, unix_bluetooth_adapter_free,
unix_bluetooth_get_event, diff --git a/dlls/winebth.sys/winebluetooth.c b/dlls/winebth.sys/winebluetooth.c index c0088577d13..08e1b998520 100644 --- a/dlls/winebth.sys/winebluetooth.c +++ b/dlls/winebth.sys/winebluetooth.c @@ -36,6 +36,23 @@
WINE_DEFAULT_DEBUG_CHANNEL( winebth );
+NTSTATUS winebluetooth_radio_get_unique_name( winebluetooth_radio_t radio, char *name, + SIZE_T *size ) +{ + struct bluetooth_adapter_get_unique_name_params params = {0}; + NTSTATUS status; + + TRACE( "(%p, %p, %p)\n", (void *)radio.handle, name, size ); + + params.adapter = radio.handle; + params.buf = name; + params.buf_size = *size; + status = UNIX_BLUETOOTH_CALL( bluetooth_adapter_get_unique_name, ¶ms ); + if (status == STATUS_BUFFER_TOO_SMALL) + *size = params.buf_size; + return status; +} + void winebluetooth_radio_free( winebluetooth_radio_t radio ) { struct bluetooth_adapter_free_params args = { 0 }; diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 434604b4dad..45c5ba9d6d3 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -66,6 +66,7 @@ struct bluetooth_radio
DEVICE_OBJECT *device_obj; winebluetooth_radio_t radio; + WCHAR *hw_name; };
void WINAPIV append_id( struct string_buffer *buffer, const WCHAR *format, ... ) @@ -98,7 +99,45 @@ void WINAPIV append_id( struct string_buffer *buffer, const WCHAR *format, ... )
static HANDLE event_loop_thread; +static NTSTATUS radio_get_hw_name_w( winebluetooth_radio_t radio, WCHAR **name ) +{ + char *name_a; + SIZE_T size = sizeof( char ) * 256; + NTSTATUS status; + + name_a = malloc( size ); + if (!name_a) + return STATUS_NO_MEMORY; + + status = winebluetooth_radio_get_unique_name( radio, name_a, &size ); + if (status == STATUS_BUFFER_TOO_SMALL) + { + void *ptr = realloc( name_a, size ); + if (!ptr) + { + free( name_a ); + return STATUS_NO_MEMORY; + } + name_a = ptr; + status = winebluetooth_radio_get_unique_name( radio, name_a, &size ); + } + if (status != STATUS_SUCCESS) + { + free( name_a ); + return status; + }
+ *name = malloc( (mbstowcs( NULL, name_a, 0 ) + 1) * sizeof( WCHAR )); + if (!*name) + { + free( name_a ); + return status; + } + + mbstowcs( *name, name_a, strlen( name_a ) + 1 ); + free( name_a ); + return STATUS_SUCCESS; +} static void add_bluetooth_radio( struct winebluetooth_watcher_event_radio_added event ) { struct bluetooth_radio *device; @@ -106,11 +145,19 @@ static void add_bluetooth_radio( struct winebluetooth_watcher_event_radio_added UNICODE_STRING string; NTSTATUS status; WCHAR name[256]; + WCHAR *hw_name; static unsigned int radio_index;
swprintf( name, ARRAY_SIZE( name ), L"\Device\WINEBTH-RADIO-%d", radio_index++ ); TRACE( "Adding new bluetooth radio %p: %s\n", (void *)event.radio.handle, debugstr_w( name ) );
+ status = radio_get_hw_name_w( event.radio, &hw_name ); + if (status) + { + ERR( "Failed to get hardware name for radio %p, status %#lx\n", (void *)event.radio.handle, status ); + return; + } + RtlInitUnicodeString( &string, name ); status = IoCreateDevice( driver_obj, sizeof( *device ), &string, FILE_DEVICE_BLUETOOTH, 0, FALSE, &device_obj ); @@ -124,6 +171,7 @@ static void add_bluetooth_radio( struct winebluetooth_watcher_event_radio_added device->device_obj = device_obj; device->radio = event.radio; device->removed = FALSE; + device->hw_name = hw_name;
EnterCriticalSection( &device_list_cs ); list_add_tail( &device_list, &device->entry ); @@ -257,6 +305,14 @@ static NTSTATUS query_id(const struct bluetooth_radio *ext, IRP *irp, BUS_QUERY_ TRACE( "(%p, %p, %s)\n", ext, irp, debugstr_BUS_QUERY_ID_TYPE( type ) ); switch (type) { + case BusQueryDeviceID: + append_id( &buf, L"WINEBTH\RADIO" ); + break; + case BusQueryInstanceID: + append_id( &buf, L"%s", ext->hw_name ); + break; + case BusQueryHardwareIDs: + append_id( &buf, L"WINEBTH\%s", ext->hw_name ); case BusQueryCompatibleIDs: append_id( &buf, L"" ); break; @@ -297,6 +353,7 @@ static NTSTATUS WINAPI pdo_pnp( DEVICE_OBJECT *device_obj, IRP *irp ) break; case IRP_MN_REMOVE_DEVICE: assert( device->removed ); + free( device->hw_name ); winebluetooth_radio_free( device->radio ); IoDeleteDevice( device->device_obj ); ret = STATUS_SUCCESS; diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index fd676896d8c..a875654d461 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -104,6 +104,8 @@ struct winebluetooth_bluetooth_version UCHAR minor; };
+NTSTATUS winebluetooth_radio_get_unique_name( winebluetooth_radio_t radio, char *name, + SIZE_T *size ); void winebluetooth_radio_free( winebluetooth_radio_t radio );
enum winebluetooth_watcher_event_type