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 | 10 +++++++++ dlls/winebth.sys/winebth.c | 35 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 2 +- include/wine/winebth.h | 7 +++++++ 8 files changed, 102 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index 9a4aa89bbee..0cf5f7b5387 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -1266,6 +1266,39 @@ NTSTATUS bluez_device_disconnect( void *connection, const char *device_path ) return STATUS_SUCCESS; }
+NTSTATUS bluez_device_start_pairing( void *connection, struct unix_name *device ) +{ + DBusMessage *request, *reply = NULL; + DBusError error; + NTSTATUS status; + + TRACE( "(%p, %s)\n", connection, debugstr_a( device->str ) ); + + request = p_dbus_message_new_method_call( BLUEZ_DEST, device->str, BLUEZ_INTERFACE_DEVICE, "Pair" ); + 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 initiate pairing with device %s: %s: %s\n", debugstr_a( device->str ), 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 249137dd502..08ec229dbb2 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -240,6 +240,14 @@ static NTSTATUS bluetooth_device_disconnect( void *args ) return bluez_device_disconnect( dbus_connection, params->device->str ); }
+static NTSTATUS bluetooth_device_start_pairing( void *args ) +{ + struct bluetooth_device_start_pairing_params *params = args; + + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + return bluez_device_start_pairing( dbus_connection, params->device ); +} + static NTSTATUS bluetooth_get_event( void *args ) { struct bluetooth_get_event_params *params = args; @@ -262,6 +270,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = {
bluetooth_device_free, bluetooth_device_disconnect, + bluetooth_device_start_pairing,
bluetooth_auth_agent_enable_incoming, bluetooth_auth_send_response, diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h index 7357f777804..53a8467a057 100644 --- a/dlls/winebth.sys/unixlib.h +++ b/dlls/winebth.sys/unixlib.h @@ -100,6 +100,11 @@ struct bluetooth_auth_send_response_params BOOL *authenticated; };
+struct bluetooth_device_start_pairing_params +{ + unix_name_t device; +}; + struct bluetooth_get_event_params { struct winebluetooth_event result; @@ -119,6 +124,7 @@ enum bluetoothapis_funcs
unix_bluetooth_device_free, unix_bluetooth_device_disconnect, + unix_bluetooth_device_start_pairing,
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 a9c1bc0f080..73b287665f9 100644 --- a/dlls/winebth.sys/unixlib_priv.h +++ b/dlls/winebth.sys/unixlib_priv.h @@ -62,6 +62,7 @@ extern NTSTATUS bluez_auth_agent_send_response( void *auth_agent, struct unix_na 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_device_start_pairing( void *dbus_connection, struct unix_name *device ); 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 ca234b98f4b..6f1d9444bb1 100644 --- a/dlls/winebth.sys/winebluetooth.c +++ b/dlls/winebth.sys/winebluetooth.c @@ -177,6 +177,16 @@ NTSTATUS winebluetooth_auth_send_response( winebluetooth_device_t device, BLUETO return UNIX_BLUETOOTH_CALL( bluetooth_auth_send_response, &args ); }
+NTSTATUS winebluetooth_device_start_pairing( winebluetooth_device_t device ) +{ + struct bluetooth_device_start_pairing_params args = {0}; + + TRACE( "(%p)\n", (void *)device.handle ); + + args.device = device.handle; + return UNIX_BLUETOOTH_CALL( bluetooth_device_start_pairing, &args ); +} + NTSTATUS winebluetooth_get_event( struct winebluetooth_event *result ) { struct bluetooth_get_event_params params = {0}; diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 694c9f1d629..8a22d274175 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_START_AUTH: + { + const struct winebth_radio_start_auth_params *params = irp->AssociatedIrp.SystemBuffer; + struct bluetooth_remote_device *device; + + if (!params) + { + status = STATUS_INVALID_PARAMETER; + break; + } + if (insize < sizeof( *params )) + { + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + + status = STATUS_DEVICE_DOES_NOT_EXIST; + EnterCriticalSection( &ext->remote_devices_cs ); + LIST_FOR_EACH_ENTRY( device, &ext->remote_devices, struct bluetooth_remote_device, entry ) + { + BOOL matches, already_auth; + EnterCriticalSection( &device->props_cs ); + matches = device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_ADDRESS && + device->props.address.ullLong == params->address; + already_auth = matches && device->props_mask & WINEBLUETOOTH_DEVICE_PROPERTY_PAIRED && device->props.paired; + LeaveCriticalSection( &device->props_cs ); + if (matches) + { + status = already_auth ? STATUS_NO_MORE_ENTRIES : winebluetooth_device_start_pairing( device->device ); + break; + } + } + LeaveCriticalSection( &ext->remote_devices_cs ); + break; + } case IOCTL_WINEBTH_RADIO_REMOVE_DEVICE: { const BTH_ADDR *param = irp->AssociatedIrp.SystemBuffer; diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index 5456acdd7a3..5d2a7159c74 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -214,7 +214,7 @@ 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 ); - +NTSTATUS winebluetooth_device_start_pairing( winebluetooth_device_t device ); enum winebluetooth_watcher_event_type { BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_ADDED, diff --git a/include/wine/winebth.h b/include/wine/winebth.h index df75684c8b1..2214a9ccd41 100644 --- a/include/wine/winebth.h +++ b/include/wine/winebth.h @@ -32,6 +32,8 @@ /* 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) +/* Initiate the authentication procedure with a remote device. */ +#define IOCTL_WINEBTH_RADIO_START_AUTH CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xaa, 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, @@ -68,6 +70,11 @@ struct winebth_radio_send_auth_response_params unsigned int authenticated : 1; };
+struct winebth_radio_start_auth_params +{ + BTH_ADDR address; +}; + #include <poppack.h>
#endif /* __WINEBTH_H__ */