From: Vibhav Pant vibhavp@gmail.com
--- dlls/winebth.sys/winebth.c | 52 +++++++++++++++++++++++++++++++++++++- include/wine/winebth.h | 15 +++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/dlls/winebth.sys/winebth.c b/dlls/winebth.sys/winebth.c index aefd0b14096..a5f83e129c8 100644 --- a/dlls/winebth.sys/winebth.c +++ b/dlls/winebth.sys/winebth.c @@ -157,10 +157,60 @@ static NTSTATUS WINAPI dispatch_auth( DEVICE_OBJECT *device, IRP *irp ) static NTSTATUS bluetooth_remote_device_dispatch( DEVICE_OBJECT *device, struct bluetooth_remote_device *ext, IRP *irp ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + ULONG outsize = stack->Parameters.DeviceIoControl.OutputBufferLength; ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; NTSTATUS status = irp->IoStatus.Status;
- FIXME( "device=%p, ext=%p, irp=%p, code=%#lx: stub!\n", device, ext, irp, code ); + TRACE( "device=%p, ext=%p, irp=%p, code=%#lx\n", device, ext, irp, code ); + + switch (code) + { + case IOCTL_WINEBTH_LE_DEVICE_GET_GATT_SERVICES: + { + const SIZE_T min_size = offsetof( struct winebth_le_device_get_gatt_services_params, services[0] ); + struct winebth_le_device_get_gatt_services_params *services = irp->AssociatedIrp.SystemBuffer; + struct bluetooth_gatt_service *svc; + SIZE_T rem; + + if (!services || outsize < min_size) + { + status = STATUS_INVALID_USER_BUFFER; + break; + } + + rem = (outsize - min_size)/sizeof( *services->services ); + status = STATUS_SUCCESS; + services->count = 0; + + EnterCriticalSection( &ext->le_cs ); + LIST_FOR_EACH_ENTRY( svc, &ext->gatt_services, struct bluetooth_gatt_service, entry ) + { + if (!svc->primary) + continue; + services->count++; + if (rem) + { + struct winebth_gatt_service *info; + + info = &services->services[services->count - 1]; + info->uuid = svc->uuid; + info->handle = svc->handle; + + rem--; + } + } + LeaveCriticalSection( &ext->le_cs ); + + irp->IoStatus.Information = offsetof( struct winebth_le_device_get_gatt_services_params, services[services->count] ); + if (services->count > rem) + status = STATUS_MORE_ENTRIES; + break; + } + default: + FIXME( "Unimplemented IOCTL code: %#lx\n", code ); + } + + irp->IoStatus.Status = status; IoCompleteRequest( irp, IO_NO_INCREMENT ); return status; } diff --git a/include/wine/winebth.h b/include/wine/winebth.h index c785d08d88e..26858568a12 100644 --- a/include/wine/winebth.h +++ b/include/wine/winebth.h @@ -36,6 +36,9 @@ #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)
+/* Get all primary GATT services for the LE device. */ +#define IOCTL_WINEBTH_LE_DEVICE_GET_GATT_SERVICES CTL_CODE(FILE_DEVICE_BLUETOOTH, 0xc0, METHOD_BUFFERED, FILE_ANY_ACCESS) + DEFINE_GUID( GUID_WINEBTH_AUTHENTICATION_REQUEST, 0xca67235f, 0xf621, 0x4c27, 0x85, 0x65, 0xa4, 0xd5, 0x5e, 0xa1, 0x26, 0xe8 );
@@ -75,6 +78,18 @@ struct winebth_radio_start_auth_params BTH_ADDR address; };
+struct winebth_gatt_service +{ + GUID uuid; + UINT16 handle; +}; + +struct winebth_le_device_get_gatt_services_params +{ + ULONG count; + struct winebth_gatt_service services[0]; +}; + #pragma pack(pop)
#endif /* __WINEBTH_H__ */