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 73e2e9fdd1d..7ba7761031a 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: + { + struct winebth_le_device_get_gatt_services_params *services = irp->AssociatedIrp.SystemBuffer; + struct bluetooth_gatt_service *svc; + SIZE_T rem; + + if (!services || outsize < sizeof( *services )) + { + status = STATUS_INVALID_USER_BUFFER; + break; + } + + rem = (outsize - sizeof( *services ))/sizeof( struct winebth_gatt_service ) + 1; + status = STATUS_SUCCESS; + irp->IoStatus.Information = 0; + services->count = 0; + + EnterCriticalSection( &ext->le_cs ); + LIST_FOR_EACH_ENTRY( svc, &ext->gatt_services, struct bluetooth_gatt_service, entry ) + { + services->count++; + if (rem > 0) + { + struct winebth_gatt_service *info; + + info = &services->services[services->count - 1]; + info->uuid = svc->uuid; + info->handle = svc->handle; + + irp->IoStatus.Information += sizeof( *info ); + rem--; + } + } + LeaveCriticalSection( &ext->le_cs ); + + irp->IoStatus.Information += sizeof( *services ); + if (services->count) + irp->IoStatus.Information -= sizeof( struct winebth_gatt_service ); + if (rem) + status = STATUS_INVALID_BUFFER_SIZE; + break; + } + default: + FIXME( "Unimplemented IOCTL code: %#lx\n", code ); + } + IoCompleteRequest( irp, IO_NO_INCREMENT ); return status; } diff --git a/include/wine/winebth.h b/include/wine/winebth.h index c785d08d88e..c21267a86ac 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[1]; +}; + #pragma pack(pop)
#endif /* __WINEBTH_H__ */