From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 33 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/unixlib.c | 9 +++++++++ dlls/winebth.sys/unixlib.h | 6 ++++++ dlls/winebth.sys/unixlib_priv.h | 1 + dlls/winebth.sys/winebluetooth.c | 9 +++++++++ dlls/winebth.sys/winebth.c | 33 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 1 + include/bthioctl.h | 5 +++-- 8 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index b390828d231..a7ba4994402 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -1194,6 +1194,39 @@ done: return ret; }
+NTSTATUS bluez_device_disconnect( void *connection, const char *device_path ) +{ + DBusMessage *request, *reply = NULL; + NTSTATUS status; + DBusError error; + + TRACE( "(%p, %s)\n", connection, debugstr_a( device_path ) ); + + request = p_dbus_message_new_method_call( BLUEZ_DEST, device_path, BLUEZ_INTERFACE_DEVICE, "Disconnect" ); + if (!request) + return STATUS_NO_MEMORY; + + p_dbus_error_init( &error ); + status = bluez_dbus_send_and_wait_for_reply( connection, request, &reply, &error ); + if (status) + { + p_dbus_error_free( &error ); + return status; + } + if (!reply) + { + ERR( "Failed to disconnect device %s: %s: %s\n", debugstr_a( device_path ), debugstr_a( error.name ), + debugstr_a( error.message ) ); + status = bluez_dbus_error_to_ntstatus( &error ); + p_dbus_error_free( &error ); + return status; + } + p_dbus_message_unref( reply ); + p_dbus_error_free( &error ); + + return STATUS_SUCCESS; +} + struct bluez_watcher_event { struct list entry; diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c index e9c4010b047..7a9b80487c2 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -223,6 +223,14 @@ static NTSTATUS bluetooth_auth_send_response( void *args ) params->numeric_or_passkey, params->negative, params->authenticated ); }
+static NTSTATUS bluetooth_device_disconnect( void *args ) +{ + struct bluetooth_device_disconnect_params *params = args; + + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + return bluez_device_disconnect( dbus_connection, params->device->str ); +} + static NTSTATUS bluetooth_get_event( void *args ) { struct bluetooth_get_event_params *params = args; @@ -243,6 +251,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { bluetooth_adapter_free,
bluetooth_device_free, + bluetooth_device_disconnect,
bluetooth_auth_agent_enable_incoming, bluetooth_auth_send_response, diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h index bc963f48c98..c10964b5bc7 100644 --- a/dlls/winebth.sys/unixlib.h +++ b/dlls/winebth.sys/unixlib.h @@ -54,6 +54,11 @@ struct bluetooth_device_free_params unix_name_t device; };
+struct bluetooth_device_disconnect_params +{ + unix_name_t device; +}; + struct bluetooth_adapter_get_unique_name_params { unix_name_t adapter; @@ -106,6 +111,7 @@ enum bluetoothapis_funcs unix_bluetooth_adapter_free,
unix_bluetooth_device_free, + unix_bluetooth_device_disconnect,
unix_bluetooth_auth_agent_enable_incoming, unix_bluetooth_auth_send_response, diff --git a/dlls/winebth.sys/unixlib_priv.h b/dlls/winebth.sys/unixlib_priv.h index 7aff1386986..8853adec1a3 100644 --- a/dlls/winebth.sys/unixlib_priv.h +++ b/dlls/winebth.sys/unixlib_priv.h @@ -60,6 +60,7 @@ extern NTSTATUS bluez_auth_agent_stop( void *connection, void *ctx ); extern NTSTATUS bluez_auth_agent_send_response( void *auth_agent, struct unix_name *device, BLUETOOTH_AUTHENTICATION_METHOD method, UINT32 numeric_or_passkey, BOOL negative, BOOL *authenticated ); +extern NTSTATUS bluez_device_disconnect( void *connection, const char *device_path ); extern NTSTATUS bluez_watcher_init( void *connection, void **ctx ); extern void bluez_watcher_close( void *connection, void *ctx ); #endif /* __WINE_WINEBTH_UNIXLIB_PRIV_H */ diff --git a/dlls/winebth.sys/winebluetooth.c b/dlls/winebth.sys/winebluetooth.c index f9ec589e0de..f3a16adf951 100644 --- a/dlls/winebth.sys/winebluetooth.c +++ b/dlls/winebth.sys/winebluetooth.c @@ -110,6 +110,15 @@ void winebluetooth_device_free( winebluetooth_device_t device ) UNIX_BLUETOOTH_CALL( bluetooth_device_free, &args ); }
+NTSTATUS winebluetooth_device_disconnect( winebluetooth_device_t device ) +{ + struct bluetooth_device_disconnect_params args = {0}; + TRACE( "(%p)\n", (void *)device.handle ); + + args.device = device.handle; + return UNIX_BLUETOOTH_CALL( bluetooth_device_disconnect, &args ); +} + void winebluetooth_device_properties_to_info( winebluetooth_device_props_mask_t props_mask, const struct winebluetooth_device_properties *props, BTH_DEVICE_INFO *info ) diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 4293f0d4610..8bace437a18 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -225,6 +225,39 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) status = STATUS_INVALID_BUFFER_SIZE; break; } + case IOCTL_BTH_DISCONNECT_DEVICE: + { + const BTH_ADDR *param = irp->AssociatedIrp.SystemBuffer; + BTH_ADDR device_addr; + struct bluetooth_remote_device *device; + + if (!param || insize < sizeof( *param )) + { + status = STATUS_INVALID_USER_BUFFER; + break; + } + + device_addr = RtlUlonglongByteSwap( *param ) >> 16; + status = STATUS_DEVICE_NOT_CONNECTED; + + EnterCriticalSection( &ext->remote_devices_cs ); + LIST_FOR_EACH_ENTRY( device, &ext->remote_devices, struct bluetooth_remote_device, entry ) + { + BOOL matches; + + EnterCriticalSection( &device->props_cs ); + matches = device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS && + device_addr == device->props.address.ullLong; + LeaveCriticalSection( &device->props_cs ); + if (matches) + { + status = winebluetooth_device_disconnect( device->device ); + break; + } + } + LeaveCriticalSection( &ext->remote_devices_cs ); + break; + } case IOCTL_WINEBTH_RADIO_SET_FLAG: { const struct winebth_radio_set_flag_params *params = irp->AssociatedIrp.SystemBuffer; diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index e47491b6956..e37ac20f140 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -209,6 +209,7 @@ static inline BOOL winebluetooth_device_equal( winebluetooth_device_t d1, winebl void winebluetooth_device_properties_to_info( winebluetooth_device_props_mask_t props_mask, const struct winebluetooth_device_properties *props, BTH_DEVICE_INFO *info ); +NTSTATUS winebluetooth_device_disconnect( winebluetooth_device_t device );
NTSTATUS winebluetooth_auth_send_response( winebluetooth_device_t device, BLUETOOTH_AUTHENTICATION_METHOD method, UINT32 numeric_or_passkey, BOOL negative, BOOL *authenticated ); diff --git a/include/bthioctl.h b/include/bthioctl.h index 56a665e9f41..d08d002aaaa 100644 --- a/include/bthioctl.h +++ b/include/bthioctl.h @@ -22,8 +22,9 @@ #ifndef __BTHIOCTL_H__ #define __BTHIOCTL_H__
-#define IOCTL_BTH_GET_LOCAL_INFO CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS) -#define IOCTL_BTH_GET_DEVICE_INFO CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_BTH_GET_LOCAL_INFO CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_BTH_GET_DEVICE_INFO CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_BTH_DISCONNECT_DEVICE CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS)
#include <pshpack1.h>
From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 39 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/unixlib.c | 10 ++++++++ dlls/winebth.sys/unixlib.h | 7 ++++++ dlls/winebth.sys/unixlib_priv.h | 1 + dlls/winebth.sys/winebluetooth.c | 10 ++++++++ dlls/winebth.sys/winebth.c | 35 ++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 1 + include/wine/winebth.h | 1 + 8 files changed, 104 insertions(+)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index a7ba4994402..b3b8408c5f8 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -491,6 +491,45 @@ NTSTATUS bluez_adapter_stop_discovery( void *connection, const char *adapter_pat return STATUS_SUCCESS; }
+NTSTATUS bluez_adapter_remove_device( void *connection, const char *adapter_path, const char *device_path ) +{ + DBusMessage *request, *reply = NULL; + DBusError error; + NTSTATUS status; + + TRACE( "(%p, %s, %s)\n", connection, debugstr_a( adapter_path ), debugstr_a( device_path ) ); + + request = p_dbus_message_new_method_call( BLUEZ_DEST, adapter_path, BLUEZ_INTERFACE_ADAPTER, "RemoveDevice" ); + if (!request) + return STATUS_NO_MEMORY; + + if (!p_dbus_message_append_args( request, DBUS_TYPE_OBJECT_PATH, &device_path, DBUS_TYPE_INVALID )) + { + p_dbus_message_unref( request ); + return STATUS_NO_MEMORY; + } + + p_dbus_error_init( &error ); + status = bluez_dbus_send_and_wait_for_reply( connection, request, &reply, &error ); + if (status) + { + p_dbus_error_free( &error ); + return status; + } + if (!reply) + { + ERR( "Failed to remove device %s on adapter %s: %s: %s\n", debugstr_a( device_path ), + debugstr_a( adapter_path ), debugstr_a( error.name ), debugstr_a( error.message ) ); + status = bluez_dbus_error_to_ntstatus( &error ); + p_dbus_error_free( &error ); + return status; + } + p_dbus_message_unref( reply ); + p_dbus_error_free( &error ); + + return STATUS_SUCCESS; +} + NTSTATUS bluez_adapter_set_prop( void *connection, struct bluetooth_adapter_set_prop_params *params ) { DBusMessage *request, *reply; diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c index 7a9b80487c2..249137dd502 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -208,6 +208,15 @@ static NTSTATUS bluetooth_adapter_stop_discovery( void *args ) return bluez_adapter_stop_discovery( dbus_connection, params->adapter->str ); }
+ +static NTSTATUS bluetooth_adapter_remove_device( void *args ) +{ + struct bluetooth_adapter_remove_device_params *params = args; + + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + return bluez_adapter_remove_device( dbus_connection, params->adapter->str, params->device->str ); +} + static NTSTATUS bluetooth_auth_agent_enable_incoming( void *args ) { if (!dbus_connection) return STATUS_NOT_SUPPORTED; @@ -248,6 +257,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { bluetooth_adapter_get_unique_name, bluetooth_adapter_start_discovery, bluetooth_adapter_stop_discovery, + bluetooth_adapter_remove_device, bluetooth_adapter_free,
bluetooth_device_free, diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h index c10964b5bc7..7357f777804 100644 --- a/dlls/winebth.sys/unixlib.h +++ b/dlls/winebth.sys/unixlib.h @@ -85,6 +85,12 @@ struct bluetooth_adapter_stop_discovery_params unix_name_t adapter; };
+struct bluetooth_adapter_remove_device_params +{ + unix_name_t adapter; + unix_name_t device; +}; + struct bluetooth_auth_send_response_params { unix_name_t device; @@ -108,6 +114,7 @@ enum bluetoothapis_funcs unix_bluetooth_adapter_get_unique_name, unix_bluetooth_adapter_start_discovery, unix_bluetooth_adapter_stop_discovery, + unix_bluetooth_adapter_remove_device, unix_bluetooth_adapter_free,
unix_bluetooth_device_free, diff --git a/dlls/winebth.sys/unixlib_priv.h b/dlls/winebth.sys/unixlib_priv.h index 8853adec1a3..a9c1bc0f080 100644 --- a/dlls/winebth.sys/unixlib_priv.h +++ b/dlls/winebth.sys/unixlib_priv.h @@ -54,6 +54,7 @@ extern NTSTATUS bluez_adapter_set_prop( void *connection, struct bluetooth_adapter_set_prop_params *params ); extern NTSTATUS bluez_adapter_start_discovery( void *connection, const char *adapter_path ); extern NTSTATUS bluez_adapter_stop_discovery( void *connection, const char *adapter_path ); +extern NTSTATUS bluez_adapter_remove_device( void *connection, const char *adapter_path, const char *device_path); extern NTSTATUS bluez_auth_agent_request_default( void *connection ); extern NTSTATUS bluez_auth_agent_start( void *connection, void **ctx ); extern NTSTATUS bluez_auth_agent_stop( void *connection, void *ctx ); diff --git a/dlls/winebth.sys/winebluetooth.c b/dlls/winebth.sys/winebluetooth.c index f3a16adf951..ca234b98f4b 100644 --- a/dlls/winebth.sys/winebluetooth.c +++ b/dlls/winebth.sys/winebluetooth.c @@ -87,6 +87,16 @@ NTSTATUS winebluetooth_radio_stop_discovery( winebluetooth_radio_t radio ) return UNIX_BLUETOOTH_CALL(bluetooth_adapter_stop_discovery, ¶ms); }
+NTSTATUS winebluetooth_radio_remove_device( winebluetooth_radio_t radio, winebluetooth_device_t device ) +{ + struct bluetooth_adapter_remove_device_params params = {0}; + + TRACE( "(%p, %p)\n", (void *)radio.handle, (void *)device.handle ); + params.adapter = radio.handle; + params.device = device.handle; + return UNIX_BLUETOOTH_CALL( bluetooth_adapter_remove_device, ¶ms ); +} + NTSTATUS winebluetooth_auth_agent_enable_incoming( void ) { return UNIX_BLUETOOTH_CALL( bluetooth_auth_agent_enable_incoming, NULL ); diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 8bace437a18..694c9f1d629 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -329,6 +329,41 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) LeaveCriticalSection( &ext->remote_devices_cs ); break; } + case IOCTL_WINEBTH_RADIO_REMOVE_DEVICE: + { + const BTH_ADDR *param = irp->AssociatedIrp.SystemBuffer; + struct bluetooth_remote_device *device; + + if (!param) + { + status = STATUS_INVALID_PARAMETER; + break; + } + if (insize < sizeof( *param )) + { + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + + status = STATUS_NOT_FOUND; + EnterCriticalSection( &ext->remote_devices_cs ); + LIST_FOR_EACH_ENTRY( device, &ext->remote_devices, struct bluetooth_remote_device, entry ) + { + BOOL matches; + EnterCriticalSection( &device->props_cs ); + matches = device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS && + device->props.address.ullLong == *param && device->props.paired; + LeaveCriticalSection( &device->props_cs ); + + if (matches) + { + status = winebluetooth_radio_remove_device( ext->radio, device->device ); + break; + } + } + LeaveCriticalSection( &ext->remote_devices_cs ); + break; + } default: FIXME( "Unimplemented IOCTL code: %#lx\n", code ); break; diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index e37ac20f140..5456acdd7a3 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -199,6 +199,7 @@ NTSTATUS winebluetooth_radio_set_property( winebluetooth_radio_t radio, union winebluetooth_property *property ); NTSTATUS winebluetooth_radio_start_discovery( winebluetooth_radio_t radio ); NTSTATUS winebluetooth_radio_stop_discovery( winebluetooth_radio_t radio ); +NTSTATUS winebluetooth_radio_remove_device( winebluetooth_radio_t radio, winebluetooth_device_t device ); NTSTATUS winebluetooth_auth_agent_enable_incoming( void );
void winebluetooth_device_free( winebluetooth_device_t device ); diff --git a/include/wine/winebth.h b/include/wine/winebth.h index d8ff41a6a61..df75684c8b1 100644 --- a/include/wine/winebth.h +++ b/include/wine/winebth.h @@ -32,6 +32,7 @@ /* Ask the system's Bluetooth service to send all incoming authentication requests to Wine. */ #define IOCTL_WINEBTH_AUTH_REGISTER CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa8, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WINEBTH_RADIO_SEND_AUTH_RESPONSE CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa9, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINEBTH_RADIO_REMOVE_DEVICE CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xab, METHOD_BUFFERED, FILE_ANY_ACCESS)
DEFINE_GUID( GUID_WINEBTH_AUTHENTICATION_REQUEST, 0xca67235f, 0xf621, 0x4c27, 0x85, 0x65, 0xa4, 0xd5, 0x5e, 0xa1, 0x26, 0xe8 );
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/bluetoothapis.spec | 2 +- dlls/bluetoothapis/main.c | 6 ++++++ dlls/bthprops.cpl/bthprops.cpl.spec | 2 +- dlls/irprops.cpl/irprops.cpl.spec | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/bluetoothapis/bluetoothapis.spec b/dlls/bluetoothapis/bluetoothapis.spec index b028c29146f..46b1903a7a7 100644 --- a/dlls/bluetoothapis/bluetoothapis.spec +++ b/dlls/bluetoothapis/bluetoothapis.spec @@ -52,7 +52,7 @@ @ stub BluetoothIsVersionAvailable @ stub BluetoothRegisterForAuthentication @ stdcall BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) -@ stub BluetoothRemoveDevice +@ stdcall BluetoothRemoveDevice(ptr) @ stdcall BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stdcall BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall BluetoothSdpGetContainerElementData(ptr long ptr ptr) diff --git a/dlls/bluetoothapis/main.c b/dlls/bluetoothapis/main.c index 5341db0d295..c6c8f42279c 100644 --- a/dlls/bluetoothapis/main.c +++ b/dlls/bluetoothapis/main.c @@ -947,3 +947,9 @@ DWORD WINAPI BluetoothSendAuthenticationResponseEx( HANDLE handle_radio, BLUETOO ReleaseSRWLockShared( &bluetooth_auth_lock ); return ret; } + +DWORD WINAPI BluetoothRemoveDevice( BLUETOOTH_ADDRESS *addr ) +{ + FIXME( "(%s): stub!\n", debugstr_addr( (BYTE *)addr ) ); + return ERROR_CALL_NOT_IMPLEMENTED; +} diff --git a/dlls/bthprops.cpl/bthprops.cpl.spec b/dlls/bthprops.cpl/bthprops.cpl.spec index 4c6ad724792..c7606604821 100644 --- a/dlls/bthprops.cpl/bthprops.cpl.spec +++ b/dlls/bthprops.cpl/bthprops.cpl.spec @@ -43,7 +43,7 @@ @ stub BluetoothMapClassOfDeviceToString @ stub BluetoothRegisterForAuthentication @ stdcall -import BluetoothRegisterForAuthenticationEx(ptr ptr ptr ptr) -@ stub BluetoothRemoveDevice +@ stdcall -import BluetoothRemoveDevice(ptr) @ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr) diff --git a/dlls/irprops.cpl/irprops.cpl.spec b/dlls/irprops.cpl/irprops.cpl.spec index 483ae4e288e..507c40dd1ce 100644 --- a/dlls/irprops.cpl/irprops.cpl.spec +++ b/dlls/irprops.cpl/irprops.cpl.spec @@ -37,7 +37,7 @@ @ stub BluetoothMapClassOfDeviceToImageIndex @ stub BluetoothMapClassOfDeviceToString @ stub BluetoothRegisterForAuthentication -@ stub BluetoothRemoveDevice +@ stdcall -import BluetoothRemoveDevice(ptr) @ stdcall -import BluetoothSdpEnumAttributes(ptr long ptr ptr) @ stdcall -import BluetoothSdpGetAttributeValue(ptr long long ptr) @ stdcall -import BluetoothSdpGetContainerElementData(ptr long ptr ptr)
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/main.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/dlls/bluetoothapis/main.c b/dlls/bluetoothapis/main.c index c6c8f42279c..d24a40fd1de 100644 --- a/dlls/bluetoothapis/main.c +++ b/dlls/bluetoothapis/main.c @@ -950,6 +950,32 @@ DWORD WINAPI BluetoothSendAuthenticationResponseEx( HANDLE handle_radio, BLUETOO
DWORD WINAPI BluetoothRemoveDevice( BLUETOOTH_ADDRESS *addr ) { - FIXME( "(%s): stub!\n", debugstr_addr( (BYTE *)addr ) ); - return ERROR_CALL_NOT_IMPLEMENTED; + BLUETOOTH_FIND_RADIO_PARAMS find_params = {0}; + HBLUETOOTH_RADIO_FIND radio_find; + const static BYTE addr_zero[6]; + BOOL success = FALSE; + HANDLE radio; + DWORD ret; + + TRACE( "(%s)\n", debugstr_addr( (BYTE *)addr ) ); + + if (!memcmp( addr_zero, &addr->rgBytes, sizeof( addr_zero ) )) + return ERROR_NOT_FOUND; + + find_params.dwSize = sizeof( find_params ); + radio_find = BluetoothFindFirstRadio( &find_params, &radio ); + if (!radio_find) + { + ret = GetLastError(); + return ret == ERROR_NO_MORE_ITEMS ? ERROR_NOT_FOUND : ret; + } + + do { + DWORD bytes; + success |= DeviceIoControl( radio, IOCTL_WINEBTH_RADIO_REMOVE_DEVICE, addr, sizeof( *addr ), NULL, 0, &bytes, NULL ); + CloseHandle( radio ); + } while (BluetoothFindNextRadio( radio_find, &radio )); + + BluetoothFindRadioClose( radio_find ); + return success ? ERROR_SUCCESS : ERROR_NOT_FOUND; }
From: Vibhav Pant vibhavp@gmail.com
--- dlls/bluetoothapis/tests/device.c | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/dlls/bluetoothapis/tests/device.c b/dlls/bluetoothapis/tests/device.c index 75684de2436..9e6d34ac6ac 100644 --- a/dlls/bluetoothapis/tests/device.c +++ b/dlls/bluetoothapis/tests/device.c @@ -363,6 +363,58 @@ static void test_BluetoothSendAuthenticationResponseEx( void ) test_for_all_radios( __FILE__, __LINE__, test_radio_BluetoothSendAuthenticationResponseEx, NULL ); }
+static void test_radio_BluetoothRemoveDevice( HANDLE radio, void *data ) +{ + BLUETOOTH_DEVICE_SEARCH_PARAMS search_params = {0}; + BLUETOOTH_DEVICE_INFO device_info = {0}; + HBLUETOOTH_DEVICE_FIND find; + DWORD err; + + device_info.dwSize = sizeof( device_info ); + search_params.dwSize = sizeof( search_params ); + search_params.fReturnAuthenticated = TRUE; + search_params.fReturnRemembered = TRUE; + search_params.fReturnUnknown = TRUE; + search_params.fReturnConnected = TRUE; + search_params.hRadio = radio; + + find = BluetoothFindFirstDevice( &search_params, &device_info ); + err = GetLastError(); + ok( find || err == ERROR_NO_MORE_ITEMS, "BluetoothFindFirstDevice failed: %lu\n", err ); + if (!find) + { + skip( "No devices found.\n" ); + return; + } + + do { + DWORD exp; + winetest_push_context( "%s (%s)", debugstr_w( device_info.szName ), + debugstr_bluetooth_address( device_info.Address.rgBytes ) ); + err = BluetoothRemoveDevice( &device_info.Address ); + exp = device_info.fRemembered ? ERROR_SUCCESS : ERROR_NOT_FOUND; + todo_wine ok( err == exp, "%lu != %lu\n", err, exp ); + err = BluetoothGetDeviceInfo( radio, &device_info ); + ok( !err || err == ERROR_NOT_FOUND, "BluetoothGetDeviceInfo failed: %lu\n", err ); + if (!err) + todo_wine ok( !device_info.fRemembered, "%d != %d\n", device_info.fRemembered, 0 ); + winetest_pop_context(); + } while (BluetoothFindNextDevice( find, &device_info )); + + BluetoothFindDeviceClose( find ); +} + +static void test_BluetoothRemoveDevice( void ) +{ + DWORD err; + BLUETOOTH_ADDRESS addr_zeros = {0}; + + err = BluetoothRemoveDevice( &addr_zeros ); + todo_wine ok( err == ERROR_NOT_FOUND, "%lu != %d\n", err, ERROR_NOT_FOUND ); + + test_for_all_radios( __FILE__, __LINE__, test_radio_BluetoothRemoveDevice, NULL ); +} + START_TEST( device ) { test_BluetoothFindFirstDevice(); @@ -372,4 +424,5 @@ START_TEST( device ) if (winetest_interactive) test_BluetoothRegisterForAuthenticationEx(); test_BluetoothSendAuthenticationResponseEx(); + test_BluetoothRemoveDevice(); }