From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/winebth.c | 68 +++++++++++++++++++++++++++++++++++++- include/Makefile.in | 1 + include/bthdef.h | 23 +++++++++++++ include/bthioctl.h | 49 +++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 include/bthioctl.h
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index 3e631e871da..7b90c9e538b 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -31,8 +31,10 @@ #include <winnls.h> #include <initguid.h> #include <devpkey.h> +#include <bthsdpdef.h> +#include <bluetoothapis.h> #include <bthdef.h> -#include <winioctl.h> +#include <bthioctl.h> #include <ddk/wdm.h> #include <ddk/bthguid.h>
@@ -78,6 +80,69 @@ struct bluetooth_radio UNICODE_STRING bthradio_symlink_name; };
+static NTSTATUS WINAPI dispatch_bluetooth( DEVICE_OBJECT *device, IRP *irp ) +{ + struct bluetooth_radio *ext = (struct bluetooth_radio *)device->DeviceExtension; + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; + ULONG outsize = stack->Parameters.DeviceIoControl.OutputBufferLength; + NTSTATUS status = irp->IoStatus.Status; + + TRACE( "device %p irp %p code %#lx\n", device, irp, code ); + + switch (code) + { + case IOCTL_BTH_GET_LOCAL_INFO: + { + BTH_LOCAL_RADIO_INFO *info = (BTH_LOCAL_RADIO_INFO *)irp->AssociatedIrp.SystemBuffer; + + if (!info || outsize < sizeof(*info)) + { + status = STATUS_INVALID_USER_BUFFER; + break; + } + + memset( info, 0, sizeof( *info ) ); + + EnterCriticalSection( &ext->props_cs ); + if (ext->props_mask & WINEBLUETOOTH_RADIO_PROPERTY_ADDRESS) + { + info->localInfo.flags |= BDIF_ADDRESS; + info->localInfo.address = RtlUlonglongByteSwap( ext->props.address.ullLong ); + } + if (ext->props_mask & WINEBLUETOOTH_RADIO_PROPERTY_NAME) + { + info->localInfo.flags |= BDIF_NAME; + strcpy( info->localInfo.name, ext->props.name ); + } + if (ext->props_mask & WINEBLUETOOTH_RADIO_PROPERTY_CLASS) + { + info->localInfo.flags |= BDIF_COD; + info->localInfo.classOfDevice = ext->props.class; + } + if (ext->props_mask & WINEBLUETOOTH_RADIO_PROPERTY_VERSION) + info->hciRevision = info->radioInfo.lmpVersion = ext->props.version; + if (ext->props.connectable) + info->flags |= LOCAL_RADIO_CONNECTABLE; + if (ext->props.discoverable) + info->flags |= LOCAL_RADIO_DISCOVERABLE; + if (ext->props_mask & WINEBLUETOOTH_RADIO_PROPERTY_MANUFACTURER) + info->radioInfo.mfg = ext->props.manufacturer; + LeaveCriticalSection( &ext->props_cs ); + + status = STATUS_SUCCESS; + break; + } + default: + FIXME( "Unimplemented IOCTL code: %#lx\n", code ); + break; + } + + irp->IoStatus.Status = status; + IoCompleteRequest( irp, IO_NO_INCREMENT ); + return status; +} + void WINAPIV append_id( struct string_buffer *buffer, const WCHAR *format, ... ) { va_list args; @@ -543,5 +608,6 @@ NTSTATUS WINAPI DriverEntry( DRIVER_OBJECT *driver, UNICODE_STRING *path ) driver->DriverExtension->AddDevice = driver_add_device; driver->DriverUnload = driver_unload; driver->MajorFunction[IRP_MJ_PNP] = bluetooth_pnp; + driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = dispatch_bluetooth; return STATUS_SUCCESS; } diff --git a/include/Makefile.in b/include/Makefile.in index 0712cfb2793..13c3f791619 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -59,6 +59,7 @@ SOURCES = \ bitsmsg.h \ bluetoothapis.h \ bthdef.h \ + bthioctl.h \ bthsdpdef.h \ cderr.h \ cdosys.idl \ diff --git a/include/bthdef.h b/include/bthdef.h index 2b81235a776..d71b2e005e7 100644 --- a/include/bthdef.h +++ b/include/bthdef.h @@ -29,6 +29,29 @@ DEFINE_GUID( GUID_BTHPORT_DEVICE_INTERFACE, 0x850302a, 0xb344, 0x4fda, 0x9b, 0xe DEFINE_GUID( GUID_BLUETOOTH_RADIO_INTERFACE, 0x92383b0e, 0xf90e, 0x4ac9, 0x8d, 0x44, 0x8c, 0x2d, 0x0d, 0x0e, 0xbd, 0xa2 );
+typedef ULONG BTH_COD; + +#define BTH_MAX_NAME_SIZE (248) + +#define BDIF_ADDRESS 0x00000001 +#define BDIF_COD 0x00000002 +#define BDIF_NAME 0x00000004 +#define BDIF_PAIRED 0x00000008 +#define BDIF_PERSONAL 0x00000010 +#define BDIF_CONNECTED 0x00000020 + +#define BDIF_SSP_SUPPORTED 0x00000100 +#define BDIF_SSP_PAIRED 0x00000200 +#define BDIF_SSP_MITM_PROTECTED 0x00000200 + +typedef struct _BTH_DEVICE_INFO +{ + ULONG flags; + BTH_ADDR address; + BTH_COD classOfDevice; + CHAR name[BTH_MAX_NAME_SIZE]; +} BTH_DEVICE_INFO, *PBTH_DEVICE_INFO; + #ifdef __cplusplus } #endif diff --git a/include/bthioctl.h b/include/bthioctl.h new file mode 100644 index 00000000000..61f1ec7a42b --- /dev/null +++ b/include/bthioctl.h @@ -0,0 +1,49 @@ +/* + * IOCTL definitions for interfacing with winebth.sys + * + * 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_BTHIOCTL_H_ +#define __WINE_BTHIOCTL_H_ + +#include <winioctl.h> + +#define IOCTL_BTH_GET_LOCAL_INFO CTL_CODE(FILE_DEVICE_BLUETOOTH, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define LOCAL_RADIO_DISCOVERABLE 0x0001 +#define LOCAL_RADIO_CONNECTABLE 0x0002 + +typedef struct _BTH_RADIO_INFO +{ + ULONGLONG lmpSupportedFeatures; + USHORT mfg; + USHORT lmpSubversion; + UCHAR lmpVersion; +} BTH_RADIO_INFO, *PBTH_RADIO_INFO; + +typedef struct _BTH_LOCAL_RADIO_INFO +{ + BTH_DEVICE_INFO localInfo; + ULONG flags; + USHORT hciRevision; + UCHAR hciVerison; + BTH_RADIO_INFO radioInfo; +} BTH_LOCAL_RADIO_INFO, *PBTH_LOCAL_RADIO_INFO; + +#endif /* __WINE_BTHIOCTL_H_ */