diff --git a/MAINTAINERS b/MAINTAINERS index 6d22ae52d49..c50c5d235c9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -49,6 +49,11 @@ F: dlls/x3daudio*/ F: dlls/xapofx*/ F: dlls/xaudio*/ +Bluetooth support +M: Vibhav Pant +F: dlls/winebth.sys/ +F: dlls/bluetoothapis/sdp.c + Common Controls Library P: Nikolay Sivov P: Zhiyi Zhang diff --git a/configure b/configure index 983eb81d27f..932307d024d 100755 --- a/configure +++ b/configure @@ -1511,6 +1511,7 @@ enable_windowscodecs enable_windowscodecsext enable_winealsa_drv enable_wineandroid_drv +enable_winebth_sys enable_winebus_sys enable_winecoreaudio_drv enable_winecrt0 @@ -22854,6 +22855,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/configure.ac b/configure.ac index 94260d7ae7b..4e3311d877d 100644 --- a/configure.ac +++ b/configure.ac @@ -3252,6 +3252,7 @@ WINE_CONFIG_MAKEFILE(dlls/windowscodecsext) WINE_CONFIG_MAKEFILE(dlls/windowscodecsext/tests) WINE_CONFIG_MAKEFILE(dlls/winealsa.drv) WINE_CONFIG_MAKEFILE(dlls/wineandroid.drv) +WINE_CONFIG_MAKEFILE(dlls/winebth.sys) WINE_CONFIG_MAKEFILE(dlls/winebus.sys) WINE_CONFIG_MAKEFILE(dlls/winecoreaudio.drv) WINE_CONFIG_MAKEFILE(dlls/winecrt0) diff --git a/dlls/winebth.sys/Makefile.in b/dlls/winebth.sys/Makefile.in new file mode 100644 index 00000000000..19f754cb487 --- /dev/null +++ b/dlls/winebth.sys/Makefile.in @@ -0,0 +1,8 @@ +MODULE = winebth.sys +IMPORTS = ntoskrnl + +EXTRADLLFLAGS = -Wl,--subsystem,native + +SOURCES = \ + winebth.c \ + winebth.rc diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c new file mode 100644 index 00000000000..27808483e02 --- /dev/null +++ b/dlls/winebth.sys/winebth.c @@ -0,0 +1,149 @@ +/* + * Bluetooth bus driver + * + * 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 +#include +#include + +#include +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include + +#include +#include + +#include "winebth_priv.h" + +WINE_DEFAULT_DEBUG_CHANNEL( winebth ); + +static DRIVER_OBJECT *driver_obj; + +static DEVICE_OBJECT *bus_fdo, *bus_pdo; + +static NTSTATUS WINAPI fdo_pnp( DEVICE_OBJECT *device_obj, IRP *irp ) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + + TRACE( "irp %p, minor function %s.\n", irp, debugstr_minor_function_code( stack->MinorFunction ) ); + + switch (stack->MinorFunction) + { + case IRP_MN_START_DEVICE: + irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IRP_MN_SURPRISE_REMOVAL: + irp->IoStatus.Status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + { + NTSTATUS ret; + IoSkipCurrentIrpStackLocation( irp ); + ret = IoCallDriver( bus_pdo, irp ); + IoDetachDevice( bus_pdo ); + IoDeleteDevice( bus_fdo ); + return ret; + } + default: + FIXME( "Unhandled minor function %s.\n", debugstr_minor_function_code( stack->MinorFunction ) ); + } + + IoSkipCurrentIrpStackLocation( irp ); + return IoCallDriver( bus_pdo, irp ); +} + +static NTSTATUS WINAPI pdo_pnp( DEVICE_OBJECT *device_obj, IRP *irp ) +{ + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); + NTSTATUS ret = irp->IoStatus.Status; + + TRACE( "device_obj %p, irp %p, minor function %s\n", device_obj, irp, debugstr_minor_function_code( stack->MinorFunction ) ); + switch (stack->MinorFunction) + { + case IRP_MN_QUERY_CAPABILITIES: + { + DEVICE_CAPABILITIES *caps = stack->Parameters.DeviceCapabilities.Capabilities; + caps->Removable = TRUE; + caps->SurpriseRemovalOK = TRUE; + caps->RawDeviceOK = TRUE; + ret = STATUS_SUCCESS; + break; + } + case IRP_MN_START_DEVICE: + ret = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + IoDeleteDevice( device_obj ); + case IRP_MN_SURPRISE_REMOVAL: + irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return STATUS_SUCCESS; + default: + FIXME( "Unhandled minor function %s.\n", debugstr_minor_function_code( stack->MinorFunction ) ); + break; + } + + irp->IoStatus.Status = ret; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return ret; +} + +static NTSTATUS WINAPI bluetooth_pnp( DEVICE_OBJECT *device, IRP *irp ) +{ + if (device == bus_fdo) + return fdo_pnp( device, irp ); + return pdo_pnp( device, irp ); +} + +static NTSTATUS WINAPI driver_add_device( DRIVER_OBJECT *driver, DEVICE_OBJECT *pdo ) +{ + NTSTATUS ret; + + TRACE( "(%p, %p)\n", driver, pdo ); + ret = IoCreateDevice( driver, 0, NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &bus_fdo ); + if (ret != STATUS_SUCCESS) + { + ERR( "failed to create FDO: %#lx\n", ret ); + return ret; + } + + IoAttachDeviceToDeviceStack( bus_fdo, pdo ); + bus_pdo = pdo; + bus_fdo->Flags &= ~DO_DEVICE_INITIALIZING; + return STATUS_SUCCESS; +} + +static void WINAPI driver_unload( DRIVER_OBJECT *driver ) {} + +NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) +{ + TRACE( "(%p, %s)\n", driver, debugstr_w( path->Buffer ) ); + + driver->DriverExtension->AddDevice = driver_add_device; + driver_obj = driver; + + driver->MajorFunction[IRP_MJ_PNP] = bluetooth_pnp; + driver->DriverUnload = driver_unload; + + return STATUS_SUCCESS; +} diff --git a/dlls/winebth.sys/winebth.inf b/dlls/winebth.sys/winebth.inf new file mode 100644 index 00000000000..6b3b8be0ed0 --- /dev/null +++ b/dlls/winebth.sys/winebth.inf @@ -0,0 +1,22 @@ +[Version] +Signature="$CHICAGO$" +ClassGuid={4d36e97d-e325-11ce-bfc1-08002be10318} +Class=System + +[Manufacturer] +Wine=mfg_section + +[mfg_section] +Wine Bluetooth bus driver=device_section,root\winebth + +[device_section.Services] +AddService = winebth,0x2,svc_section + +[svc_section] +Description="Wine Bluetooth bus driver" +DisplayName="Wine Bluetooth bus" +ServiceBinary="%12%\winebth.sys" +LoadOrderGroup="WinePlugPlay" +ServiceType=1 +StartType=3 +ErrorControl=1 diff --git a/dlls/winebth.sys/winebth.rc b/dlls/winebth.sys/winebth.rc new file mode 100644 index 00000000000..33157042b7c --- /dev/null +++ b/dlls/winebth.sys/winebth.rc @@ -0,0 +1,20 @@ +/* + * 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 + */ + +/* @makedep: winebth.inf */ +1 WINE_DATA_FILE winebth.inf diff --git a/dlls/winebth.sys/winebth_priv.h b/dlls/winebth.sys/winebth_priv.h new file mode 100644 index 00000000000..25d69dd2386 --- /dev/null +++ b/dlls/winebth.sys/winebth_priv.h @@ -0,0 +1,74 @@ +/* + * Private winebth.sys defs + * + * 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_WINEBTH_H_ +#define __WINE_WINEBTH_WINEBTH_H_ + +#ifdef __ASM_USE_FASTCALL_WRAPPER +extern void * WINAPI wrap_fastcall_func1(void *func, const void *a); +__ASM_STDCALL_FUNC(wrap_fastcall_func1, 8, + "popl %ecx\n\t" + "popl %eax\n\t" + "xchgl (%esp),%ecx\n\t" + "jmp *%eax"); +#define call_fastcall_func1(func,a) wrap_fastcall_func1(func,a) +#else +#define call_fastcall_func1(func,a) func(a) +#endif + +#define XX(i) case (i): return #i + + +static inline const char *debugstr_minor_function_code( UCHAR code ) +{ + switch(code) + { + XX(IRP_MN_START_DEVICE); + XX(IRP_MN_QUERY_REMOVE_DEVICE); + XX(IRP_MN_REMOVE_DEVICE); + XX(IRP_MN_CANCEL_REMOVE_DEVICE); + XX(IRP_MN_STOP_DEVICE); + XX(IRP_MN_QUERY_STOP_DEVICE); + XX(IRP_MN_CANCEL_STOP_DEVICE); + XX(IRP_MN_QUERY_DEVICE_RELATIONS); + XX(IRP_MN_QUERY_INTERFACE); + XX(IRP_MN_QUERY_CAPABILITIES); + XX(IRP_MN_QUERY_RESOURCES); + XX(IRP_MN_QUERY_RESOURCE_REQUIREMENTS); + XX(IRP_MN_QUERY_DEVICE_TEXT); + XX(IRP_MN_FILTER_RESOURCE_REQUIREMENTS); + XX(IRP_MN_READ_CONFIG); + XX(IRP_MN_WRITE_CONFIG); + XX(IRP_MN_EJECT); + XX(IRP_MN_SET_LOCK); + XX(IRP_MN_QUERY_ID); + XX(IRP_MN_QUERY_PNP_DEVICE_STATE); + XX(IRP_MN_QUERY_BUS_INFORMATION); + XX(IRP_MN_DEVICE_USAGE_NOTIFICATION); + XX(IRP_MN_SURPRISE_REMOVAL); + XX(IRP_MN_QUERY_LEGACY_BUS_INFORMATION); + default: + return wine_dbg_sprintf( "(unknown %#x)", code ); + } +} +#undef XX + + +#endif /* __WINE_WINEBTH_WINEBTH_H_ */ diff --git a/loader/wine.inf.in b/loader/wine.inf.in index 181a6d62c9b..50fb2c828cb 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -2629,6 +2629,7 @@ services,"@%11%\ws2_32.dll,-4" [InfFiles] input.inf,"@%12%\hidclass.sys,-1" mouhid.inf,"@%12%\mouhid.sys,-1" +winebth.inf,"@%12%\winebth.sys,-1" winebus.inf,"@%12%\winebus.sys,-1" winehid.inf,"@%12%\winehid.sys,-1" wineusb.inf,"@%12%\wineusb.sys,-1" diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index 20260f94369..318939d1daa 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -1544,6 +1544,7 @@ static void install_root_pnp_devices(void) } root_devices[] = { + {"root\\wine\\winebth", "root\\winebth\0", "C:\\windows\\inf\\winebth.inf"}, {"root\\wine\\winebus", "root\\winebus\0", "C:\\windows\\inf\\winebus.inf"}, {"root\\wine\\wineusb", "root\\wineusb\0", "C:\\windows\\inf\\wineusb.inf"}, };