From: Vibhav Pant vibhavp@gmail.com
--- configure | 2 + dlls/winebth.sys/Makefile.in | 7 +- dlls/winebth.sys/dbus.c | 129 +++++++++++++++++++++++++++++++ dlls/winebth.sys/dbus.h | 113 +++++++++++++++++++++++++++ dlls/winebth.sys/unixlib.c | 62 +++++++++++++++ dlls/winebth.sys/unixlib.h | 38 +++++++++ dlls/winebth.sys/unixlib_priv.h | 38 +++++++++ dlls/winebth.sys/winebluetooth.c | 51 ++++++++++++ dlls/winebth.sys/winebth.c | 13 +++- dlls/winebth.sys/winebth_priv.h | 9 +++ 10 files changed, 458 insertions(+), 4 deletions(-) create mode 100644 dlls/winebth.sys/dbus.c create mode 100644 dlls/winebth.sys/dbus.h create mode 100644 dlls/winebth.sys/unixlib.c create mode 100644 dlls/winebth.sys/unixlib.h create mode 100644 dlls/winebth.sys/unixlib_priv.h create mode 100644 dlls/winebth.sys/winebluetooth.c
diff --git a/configure b/configure index a74bdc797ed..71d44388a66 100755 --- a/configure +++ b/configure @@ -1509,6 +1509,7 @@ enable_windowscodecs enable_windowscodecsext enable_winealsa_drv enable_wineandroid_drv +enable_winebth_sys enable_winebus_sys enable_winecoreaudio_drv enable_winecrt0 @@ -22662,6 +22663,7 @@ wine_fn_config_makefile dlls/windowscodecsext enable_windowscodecsext wine_fn_config_makefile dlls/windowscodecsext/tests enable_tests wine_fn_config_makefile dlls/winealsa.drv enable_winealsa_drv wine_fn_config_makefile dlls/wineandroid.drv enable_wineandroid_drv +wine_fn_config_makefile dlls/winebth.sys enable_winebth_sys wine_fn_config_makefile dlls/winebus.sys enable_winebus_sys wine_fn_config_makefile dlls/winecoreaudio.drv enable_winecoreaudio_drv wine_fn_config_makefile dlls/winecrt0 enable_winecrt0 diff --git a/dlls/winebth.sys/Makefile.in b/dlls/winebth.sys/Makefile.in index 19f754cb487..12d1b4ddcc9 100644 --- a/dlls/winebth.sys/Makefile.in +++ b/dlls/winebth.sys/Makefile.in @@ -1,8 +1,13 @@ MODULE = winebth.sys -IMPORTS = ntoskrnl +IMPORTS = ntoskrnl uuid +UNIXLIB = winebth.so +UNIX_CFLAGS = $(DBUS_CFLAGS)
EXTRADLLFLAGS = -Wl,--subsystem,native
SOURCES = \ + dbus.c \ + unixlib.c \ + winebluetooth.c \ winebth.c \ winebth.rc diff --git a/dlls/winebth.sys/dbus.c b/dlls/winebth.sys/dbus.c new file mode 100644 index 00000000000..7840bba161d --- /dev/null +++ b/dlls/winebth.sys/dbus.c @@ -0,0 +1,129 @@ +/* + * Support for communicating with BlueZ over DBus. + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <stdlib.h> +#include <dlfcn.h> + +#ifdef SONAME_LIBDBUS_1 +#include <dbus/dbus.h> +#endif + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <windef.h> +#include <winternl.h> +#include <winbase.h> + +#include <wine/debug.h> + +#include "unixlib.h" +#include "unixlib_priv.h" +#include "dbus.h" + +WINE_DEFAULT_DEBUG_CHANNEL( winebth ); +WINE_DECLARE_DEBUG_CHANNEL( dbus ); + +#ifdef SONAME_LIBDBUS_1 + +const int bluez_timeout = -1; + +#define BLUEZ_DEST "org.bluez" +#define BLUEZ_INTERFACE_ADAPTER "org.bluez.Adapter1" + +#define DO_FUNC( f ) typeof( f ) (*p_##f) +DBUS_FUNCS; +#undef DO_FUNC + +static BOOL load_dbus_functions( void ) +{ + void *handle = dlopen( SONAME_LIBDBUS_1, RTLD_NOW ); + + if (handle == NULL) goto failed; + +#define DO_FUNC( f ) \ + if (!( p_##f = dlsym( handle, #f ) )) \ + { \ + ERR( "failed to load symbol %s: %s\n", #f, dlerror() ); \ + goto failed; \ + } + DBUS_FUNCS; +#undef DO_FUNC + return TRUE; + +failed: + WARN( "failed to load DBus support: %s\n", dlerror() ); + return FALSE; +} + +static inline const char *dbgstr_dbus_connection( DBusConnection *connection ) +{ + return wine_dbg_sprintf( "{%p connected=%d}", connection, + p_dbus_connection_get_is_connected( connection ) ); +} + +void *bluez_dbus_init( void ) +{ + DBusError error; + DBusConnection *connection; + + if (!load_dbus_functions()) return NULL; + + p_dbus_threads_init_default(); + p_dbus_error_init ( &error ); + + connection = p_dbus_bus_get_private ( DBUS_BUS_SYSTEM, &error ); + if (!connection) + { + ERR( "Failed to get system dbus connection: %s: %s\n", debugstr_a( error.name ), debugstr_a( error.message ) ); + p_dbus_error_free( &error ); + return NULL; + } + + return connection; +} + +void bluez_dbus_close( void *connection ) +{ + TRACE_(dbus)( "(%s)\n", dbgstr_dbus_connection( connection ) ); + + p_dbus_connection_flush( connection ); + p_dbus_connection_close( connection ); +} + +void bluez_dbus_free( void *connection ) +{ + TRACE_(dbus)( "(%s)\n", dbgstr_dbus_connection( connection ) ); + + p_dbus_connection_unref( connection ); +} +#else + +void *bluez_dbus_init( void ) { return NULL; } +void bluez_dbus_close( void *connection ) {} +void bluez_dbus_free( void *connection ) {} + +#endif /* SONAME_LIBDBUS_1 */ diff --git a/dlls/winebth.sys/dbus.h b/dlls/winebth.sys/dbus.h new file mode 100644 index 00000000000..025d2c6fd2c --- /dev/null +++ b/dlls/winebth.sys/dbus.h @@ -0,0 +1,113 @@ +/* + * DBus declarations. + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_BLUETOOTHAPIS_UNIXLIB_DBUS_H +#define __WINE_BLUETOOTHAPIS_UNIXLIB_DBUS_H + +#include "config.h" + +#ifdef SONAME_LIBDBUS_1 +#include <dbus/dbus.h> +#endif + +#ifdef SONAME_LIBDBUS_1 + +#define DBUS_FUNCS \ + DO_FUNC(dbus_bus_add_match); \ + DO_FUNC(dbus_bus_get); \ + DO_FUNC(dbus_bus_get_id); \ + DO_FUNC(dbus_bus_get_private); \ + DO_FUNC(dbus_bus_remove_match); \ + DO_FUNC(dbus_connection_add_filter); \ + DO_FUNC(dbus_connection_close); \ + DO_FUNC(dbus_connection_flush); \ + DO_FUNC(dbus_connection_free_preallocated_send); \ + DO_FUNC(dbus_connection_get_is_anonymous); \ + DO_FUNC(dbus_connection_get_is_authenticated); \ + DO_FUNC(dbus_connection_get_is_connected); \ + DO_FUNC(dbus_connection_get_server_id); \ + DO_FUNC(dbus_connection_get_unix_process_id); \ + DO_FUNC(dbus_connection_get_unix_fd); \ + DO_FUNC(dbus_connection_get_unix_user); \ + DO_FUNC(dbus_connection_preallocate_send); \ + DO_FUNC(dbus_connection_read_write_dispatch); \ + DO_FUNC(dbus_connection_remove_filter); \ + DO_FUNC(dbus_connection_ref); \ + DO_FUNC(dbus_connection_send); \ + DO_FUNC(dbus_connection_send_preallocated); \ + DO_FUNC(dbus_connection_send_with_reply); \ + DO_FUNC(dbus_connection_send_with_reply_and_block); \ + DO_FUNC(dbus_connection_try_register_object_path); \ + DO_FUNC(dbus_connection_unref); \ + DO_FUNC(dbus_connection_unregister_object_path); \ + DO_FUNC(dbus_error_free); \ + DO_FUNC(dbus_error_has_name) ; \ + DO_FUNC(dbus_error_init); \ + DO_FUNC(dbus_error_is_set); \ + DO_FUNC(dbus_free); \ + DO_FUNC(dbus_free_string_array); \ + DO_FUNC(dbus_message_append_args); \ + DO_FUNC(dbus_message_get_args); \ + DO_FUNC(dbus_message_iter_get_element_count); \ + DO_FUNC(dbus_message_get_interface); \ + DO_FUNC(dbus_message_get_member); \ + DO_FUNC(dbus_message_get_path); \ + DO_FUNC(dbus_message_get_sender); \ + DO_FUNC(dbus_message_get_serial); \ + DO_FUNC(dbus_message_get_signature); \ + DO_FUNC(dbus_message_get_type); \ + DO_FUNC(dbus_message_has_signature); \ + DO_FUNC(dbus_message_iter_has_next); \ + DO_FUNC(dbus_message_is_error); \ + DO_FUNC(dbus_message_is_method_call); \ + DO_FUNC(dbus_message_is_signal); \ + DO_FUNC(dbus_message_iter_append_basic); \ + DO_FUNC(dbus_message_iter_close_container); \ + DO_FUNC(dbus_message_iter_get_arg_type); \ + DO_FUNC(dbus_message_iter_get_element_type); \ + DO_FUNC(dbus_message_iter_get_basic); \ + DO_FUNC(dbus_message_iter_get_fixed_array); \ + DO_FUNC(dbus_message_iter_get_signature); \ + DO_FUNC(dbus_message_iter_init); \ + DO_FUNC(dbus_message_iter_init_append); \ + DO_FUNC(dbus_message_iter_next); \ + DO_FUNC(dbus_message_iter_open_container); \ + DO_FUNC(dbus_message_iter_recurse); \ + DO_FUNC(dbus_message_new_error); \ + DO_FUNC(dbus_message_new_error_printf); \ + DO_FUNC(dbus_message_new_method_return); \ + DO_FUNC(dbus_message_new_method_call); \ + DO_FUNC(dbus_message_ref); \ + DO_FUNC(dbus_message_unref); \ + DO_FUNC(dbus_pending_call_block); \ + DO_FUNC(dbus_pending_call_cancel); \ + DO_FUNC(dbus_pending_call_get_completed); \ + DO_FUNC(dbus_pending_call_set_notify); \ + DO_FUNC(dbus_pending_call_steal_reply); \ + DO_FUNC(dbus_pending_call_unref); \ + DO_FUNC(dbus_set_error_from_message); \ + DO_FUNC(dbus_threads_init_default); + +#define DO_FUNC( f ) extern typeof( f ) *p_##f +DBUS_FUNCS; +#undef DO_FUNC + +#endif /* SONAME_LIBDBUS_1 */ +#endif /* __WINE_BLUETOOTHAPIS_UNIXLIB_DBUS_H */ diff --git a/dlls/winebth.sys/unixlib.c b/dlls/winebth.sys/unixlib.c new file mode 100644 index 00000000000..c289a690659 --- /dev/null +++ b/dlls/winebth.sys/unixlib.c @@ -0,0 +1,62 @@ +/* + * winebluetooth Unix interface + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#if 0 +#pragma makedep unix +#endif + +#include <config.h> + +#include <stdarg.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <wine/debug.h> + +#include "unixlib.h" +#include "unixlib_priv.h" + +WINE_DEFAULT_DEBUG_CHANNEL( winebth ); + +static void *dbus_connection; + +static NTSTATUS bluetooth_init ( void *params ) +{ + dbus_connection = bluez_dbus_init(); + TRACE("dbus_connection=%p\n", dbus_connection); + + return dbus_connection ? STATUS_SUCCESS : STATUS_INTERNAL_ERROR; +} + +static NTSTATUS bluetooth_shutdown( void *params ) +{ + if (!dbus_connection) return STATUS_NOT_SUPPORTED; + + bluez_dbus_close( dbus_connection ); + bluez_dbus_free( dbus_connection ); + return STATUS_SUCCESS; +} + +const unixlib_entry_t __wine_unix_call_funcs[] = { + bluetooth_init, + bluetooth_shutdown, +}; + +C_ASSERT( ARRAYSIZE( __wine_unix_call_funcs ) == unix_funcs_count ); diff --git a/dlls/winebth.sys/unixlib.h b/dlls/winebth.sys/unixlib.h new file mode 100644 index 00000000000..e79a2c4745a --- /dev/null +++ b/dlls/winebth.sys/unixlib.h @@ -0,0 +1,38 @@ +/* + * Unix interface definitions + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINEBTH_UNIXLIB_H +#define __WINE_WINEBTH_UNIXLIB_H + +#include <stdarg.h> + +#include <wine/unixlib.h> + +enum bluetoothapis_funcs +{ + unix_bluetooth_init, + unix_bluetooth_shutdown, + + unix_funcs_count +}; + +#define UNIX_BLUETOOTH_CALL( func, params ) WINE_UNIX_CALL( unix_##func, params ) + +#endif /* __WINE_WINEBTH_UNIXLIB_H */ diff --git a/dlls/winebth.sys/unixlib_priv.h b/dlls/winebth.sys/unixlib_priv.h new file mode 100644 index 00000000000..e1215f3590a --- /dev/null +++ b/dlls/winebth.sys/unixlib_priv.h @@ -0,0 +1,38 @@ +/* + * Bluetoothapis Unix interface + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINE_WINEBTH_UNIXLIB_PRIV_H +#define __WINE_WINEBTH_UNIXLIB_PRIV_H + +#include <config.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS +#include <windef.h> + +#include <wine/list.h> +#include <wine/rbtree.h> + +#include "unixlib.h" + +extern void *bluez_dbus_init( void ); +extern void bluez_dbus_close( void *connection ); +extern void bluez_dbus_free( void *connection ); +#endif /* __WINE_WINEBTH_UNIXLIB_PRIV_H */ diff --git a/dlls/winebth.sys/winebluetooth.c b/dlls/winebth.sys/winebluetooth.c new file mode 100644 index 00000000000..0895311d569 --- /dev/null +++ b/dlls/winebth.sys/winebluetooth.c @@ -0,0 +1,51 @@ +/* + * Wine bluetooth APIs + * + * Copyright 2024 Vibhav Pant + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include <stdarg.h> + +#include <ntstatus.h> +#define WIN32_NO_STATUS + +#include <windef.h> +#include <winbase.h> + +#include <wine/debug.h> +#include <wine/heap.h> +#include <wine/unixlib.h> + +#include "winebth_priv.h" +#include "unixlib.h" + +NTSTATUS winebluetooth_init( void ) +{ + NTSTATUS status; + + status = __wine_init_unix_call(); + if (status != STATUS_SUCCESS) + return status; + + return UNIX_BLUETOOTH_CALL( bluetooth_init, NULL ); +} + +NTSTATUS winebluetooth_shutdown( void ) +{ + return UNIX_BLUETOOTH_CALL( bluetooth_shutdown, NULL ); +} diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 27808483e02..afcd39466e9 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -27,6 +27,8 @@ #include <windef.h> #include <winbase.h> #include <winternl.h> +#include <initguid.h> +#include <devpkey.h> #include <winioctl.h> #include <ddk/wdm.h>
@@ -58,6 +60,7 @@ static NTSTATUS WINAPI fdo_pnp( DEVICE_OBJECT *device_obj, IRP *irp ) case IRP_MN_REMOVE_DEVICE: { NTSTATUS ret; + winebluetooth_shutdown(); IoSkipCurrentIrpStackLocation( irp ); ret = IoCallDriver( bus_pdo, irp ); IoDetachDevice( bus_pdo ); @@ -137,13 +140,17 @@ static void WINAPI driver_unload( DRIVER_OBJECT *driver ) {}
NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) { + NTSTATUS status; TRACE( "(%p, %s)\n", driver, debugstr_w( path->Buffer ) );
- driver->DriverExtension->AddDevice = driver_add_device; + status = winebluetooth_init(); + if (status != STATUS_SUCCESS) + return status; + driver_obj = driver;
- driver->MajorFunction[IRP_MJ_PNP] = bluetooth_pnp; + driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload; - + driver->MajorFunction[IRP_MJ_PNP] = bluetooth_pnp; return STATUS_SUCCESS; } diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h index 25d69dd2386..362502fa655 100644 --- a/dlls/winebth.sys/winebth_priv.h +++ b/dlls/winebth.sys/winebth_priv.h @@ -21,6 +21,8 @@ #ifndef __WINE_WINEBTH_WINEBTH_H_ #define __WINE_WINEBTH_WINEBTH_H_
+#include <ddk/wdm.h> + #ifdef __ASM_USE_FASTCALL_WRAPPER extern void * WINAPI wrap_fastcall_func1(void *func, const void *a); __ASM_STDCALL_FUNC(wrap_fastcall_func1, 8, @@ -32,6 +34,11 @@ __ASM_STDCALL_FUNC(wrap_fastcall_func1, 8, #else #define call_fastcall_func1(func,a) func(a) #endif +struct string_buffer +{ + WCHAR *string; + size_t len; +};
#define XX(i) case (i): return #i
@@ -70,5 +77,7 @@ static inline const char *debugstr_minor_function_code( UCHAR code ) } #undef XX
+NTSTATUS winebluetooth_init( void ); +NTSTATUS winebluetooth_shutdown( void );
#endif /* __WINE_WINEBTH_WINEBTH_H_ */