From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/dbus.c | 58 ++++++++++++++++++++++++++++++++ dlls/winebth.sys/unixlib.c | 10 ++++++ dlls/winebth.sys/unixlib.h | 10 ++++++ dlls/winebth.sys/unixlib_priv.h | 3 ++ dlls/winebth.sys/winebluetooth.c | 15 +++++++++ dlls/winebth.sys/winebth.c | 45 +++++++++++++++++++++++++ dlls/winebth.sys/winebth_priv.h | 3 ++ include/wine/winebth.h | 21 +++++++++--- 8 files changed, 160 insertions(+), 5 deletions(-)
diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c index fae5394a1e2..4a86cb4cbb4 100644 --- a/dlls/winebth.sys/dbus.c +++ b/dlls/winebth.sys/dbus.c @@ -1138,6 +1138,58 @@ NTSTATUS bluez_auth_agent_request_default( void *connection ) return STATUS_SUCCESS; }
+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 ) +{ + struct bluez_auth_agent_ctx *ctx = auth_agent; + NTSTATUS ret; + + TRACE( "auth_agent=%p device=%s negative=%d\n", auth_agent, debugstr_a( device->str ), negative ); + + pthread_mutex_lock( &ctx->lock ); + switch (ctx->status) + { + case BLUEZ_PAIRING_SESSION_PENDING_REPLY: + { + DBusMessage *reply; + if (device != ctx->device) + { + ret = STATUS_DEVICE_NOT_CONNECTED; + goto done; + } + if (numeric_or_passkey != ctx->passkey || method != ctx->method) + negative = TRUE; + + reply = negative ? p_dbus_message_new_error( ctx->auth_request, "org.bluez.Rejected", "" ) + : p_dbus_message_new_method_return( ctx->auth_request ); + if (!reply) + { + ret = STATUS_NO_MEMORY; + goto done; + } + p_dbus_connection_send_preallocated( ctx->connection, ctx->preallocate_send, reply, NULL ); + + unix_name_free( ctx->device ); + p_dbus_message_unref( ctx->auth_request ); + p_dbus_connection_unref( ctx->connection ); + ctx->status = BLUEZ_PAIRING_SESSION_NONE; + *authenticated = !negative; + ret = STATUS_SUCCESS; + break; + } + case BLUEZ_PAIRING_SESSION_CANCELLED: + ret = STATUS_CANCELLED; + break; + default: + ret = STATUS_DEVICE_NOT_READY; + break; + } +done: + pthread_mutex_unlock( &ctx->lock ); + return ret; +} + struct bluez_watcher_event { struct list entry; @@ -2052,5 +2104,11 @@ NTSTATUS bluez_adapter_stop_discovery( void *connection, const char *adapter_pat NTSTATUS bluez_auth_agent_start( void *connection, void **ctx ) { return STATUS_NOT_SUPPORTED; } NTSTATUS bluez_auth_agent_stop( void *connection, void *ctx ) { return STATUS_NOT_SUPPORTED; } NTSTATUS bluez_auth_agent_request_default( void *connection ) { return STATUS_NOT_SUPPORTED; } +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 ) +{ + return STATUS_NOT_SUPPORTED; +}
#endif /* SONAME_LIBDBUS_1 */ diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c index 7b3edaad61a..e9c4010b047 100644 --- a/dlls/winebth.sys/unixlib.c +++ b/dlls/winebth.sys/unixlib.c @@ -214,6 +214,15 @@ static NTSTATUS bluetooth_auth_agent_enable_incoming( void *args ) return bluez_auth_agent_request_default( dbus_connection ); }
+static NTSTATUS bluetooth_auth_send_response( void *args ) +{ + struct bluetooth_auth_send_response_params *params = args; + + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + return bluez_auth_agent_send_response( bluetooth_auth_agent, params->device, params->method, + params->numeric_or_passkey, params->negative, params->authenticated ); +} + static NTSTATUS bluetooth_get_event( void *args ) { struct bluetooth_get_event_params *params = args; @@ -236,6 +245,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = { bluetooth_device_free,
bluetooth_auth_agent_enable_incoming, + bluetooth_auth_send_response,
bluetooth_get_event, }; diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h index c9630fe6676..bc963f48c98 100644 --- a/dlls/winebth.sys/unixlib.h +++ b/dlls/winebth.sys/unixlib.h @@ -80,6 +80,15 @@ struct bluetooth_adapter_stop_discovery_params unix_name_t adapter; };
+struct bluetooth_auth_send_response_params +{ + unix_name_t device; + BLUETOOTH_AUTHENTICATION_METHOD method; + UINT32 numeric_or_passkey; + BOOL negative; + BOOL *authenticated; +}; + struct bluetooth_get_event_params { struct winebluetooth_event result; @@ -99,6 +108,7 @@ enum bluetoothapis_funcs unix_bluetooth_device_free,
unix_bluetooth_auth_agent_enable_incoming, + unix_bluetooth_auth_send_response,
unix_bluetooth_get_event,
diff --git a/dlls/winebth.sys/unixlib_priv.h b/dlls/winebth.sys/unixlib_priv.h index 29b789ab025..7aff1386986 100644 --- a/dlls/winebth.sys/unixlib_priv.h +++ b/dlls/winebth.sys/unixlib_priv.h @@ -57,6 +57,9 @@ extern NTSTATUS bluez_adapter_stop_discovery( void *connection, const char *adap 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 ); +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_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 0f421a87828..f9ec589e0de 100644 --- a/dlls/winebth.sys/winebluetooth.c +++ b/dlls/winebth.sys/winebluetooth.c @@ -143,6 +143,21 @@ void winebluetooth_device_properties_to_info( winebluetooth_device_props_mask_t } }
+NTSTATUS winebluetooth_auth_send_response( winebluetooth_device_t device, BLUETOOTH_AUTHENTICATION_METHOD method, + UINT32 numeric_or_passkey, BOOL negative, BOOL *authenticated ) +{ + struct bluetooth_auth_send_response_params args = {0}; + + TRACE( "device=%p method=%d negative=%d authenticated=%p\n", (void *)device.handle, method, negative, authenticated ); + + args.device = device.handle; + args.method = method; + args.numeric_or_passkey = numeric_or_passkey; + args.negative = negative; + args.authenticated = authenticated; + return UNIX_BLUETOOTH_CALL( bluetooth_auth_send_response, &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 8c885cde2fa..44d8c3f90d4 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -251,6 +251,51 @@ static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) case IOCTL_WINEBTH_RADIO_STOP_DISCOVERY: status = winebluetooth_radio_stop_discovery( ext->radio ); break; + case IOCTL_WINEBTH_RADIO_SEND_AUTH_RESPONSE: + { + struct winebth_radio_send_auth_response_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; + } + if (outsize < sizeof( *params )) + { + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + + 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->props.address.ullLong == params->address; + LeaveCriticalSection( &device->props_cs ); + if (matches) + { + BOOL authenticated = FALSE; + status = winebluetooth_auth_send_response( device->device, params->method, + params->numeric_value_or_passkey, params->negative, + &authenticated ); + params->authenticated = !!authenticated; + break; + } + } + if (!status) + irp->IoStatus.Information = sizeof( *params ); + 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 47ae3b03b15..13e234a0da8 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -210,6 +210,9 @@ void winebluetooth_device_properties_to_info( winebluetooth_device_props_mask_t const struct winebluetooth_device_properties *props, BTH_DEVICE_INFO *info );
+NTSTATUS winebluetooth_auth_send_response( winebluetooth_device_t device, BLUETOOTH_AUTHENTICATION_METHOD method, + UINT32 numeric_or_passkey, BOOL negative, BOOL *authenticated ); + enum winebluetooth_watcher_event_type { BLUETOOTH_WATCHER_EVENT_TYPE_RADIO_ADDED, diff --git a/include/wine/winebth.h b/include/wine/winebth.h index 5fa702726a7..d8ff41a6a61 100644 --- a/include/wine/winebth.h +++ b/include/wine/winebth.h @@ -24,14 +24,14 @@
/* Set the discoverability or connectable flag for a local radio. Enabling discoverability will also enable incoming * connections, while disabling incoming connections disables discoverability as well. */ -#define IOCTL_WINEBTH_RADIO_SET_FLAG CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa3, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINEBTH_RADIO_SET_FLAG CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa3, METHOD_BUFFERED, FILE_ANY_ACCESS) /* Start device inquiry for a local radio. */ -#define IOCTL_WINEBTH_RADIO_START_DISCOVERY CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa6, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINEBTH_RADIO_START_DISCOVERY CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa6, METHOD_BUFFERED, FILE_ANY_ACCESS) /* Stop device inquiry for a local radio. */ -#define IOCTL_WINEBTH_RADIO_STOP_DISCOVERY CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa7, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define IOCTL_WINEBTH_RADIO_STOP_DISCOVERY CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xa7, METHOD_BUFFERED, FILE_ANY_ACCESS) /* 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_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_GUID( GUID_WINEBTH_AUTHENTICATION_REQUEST, 0xca67235f, 0xf621, 0x4c27, 0x85, 0x65, 0xa4, 0xd5, 0x5e, 0xa1, 0x26, 0xe8 ); @@ -56,6 +56,17 @@ struct winebth_authentication_request BLUETOOTH_AUTHENTICATION_METHOD auth_method; ULONG numeric_value_or_passkey; }; + +struct winebth_radio_send_auth_response_params +{ + BTH_ADDR address; + BLUETOOTH_AUTHENTICATION_METHOD method; + UINT32 numeric_value_or_passkey; + unsigned int negative : 1; + + unsigned int authenticated : 1; +}; + #include <poppack.h>
#endif /* __WINEBTH_H__ */