Piotr Caban : hidclass.sys: Limit written data to the actual report size.

Alexandre Julliard julliard at winehq.org
Tue May 14 15:43:03 CDT 2019


Module: wine
Branch: master
Commit: 99114803b80f6e687f1d4ed11e0808b821cdbf22
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=99114803b80f6e687f1d4ed11e0808b821cdbf22

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Tue May 14 12:52:58 2019 +0200

hidclass.sys: Limit written data to the actual report size.

Linux hidraw devices are not accepting to large set feature ioctls.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/hidclass.sys/device.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index 0654619..4495300 100644
--- a/dlls/hidclass.sys/device.c
+++ b/dlls/hidclass.sys/device.c
@@ -482,7 +482,9 @@ static NTSTATUS HID_get_feature(DEVICE_OBJECT *device, IRP *irp)
 static NTSTATUS HID_set_to_device(DEVICE_OBJECT *device, IRP *irp)
 {
     IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
+    BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
     HID_XFER_PACKET packet;
+    ULONG max_len;
     NTSTATUS rc;
 
     TRACE_(hid_report)("Device %p Buffer length %i Buffer %p\n", device, irpsp->Parameters.DeviceIoControl.InputBufferLength, irp->AssociatedIrp.SystemBuffer);
@@ -491,12 +493,23 @@ static NTSTATUS HID_set_to_device(DEVICE_OBJECT *device, IRP *irp)
     {
         packet.reportBuffer = &((BYTE*)irp->AssociatedIrp.SystemBuffer)[1];
         packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength - 1;
+        if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_HID_SET_FEATURE)
+            max_len = ext->preparseData->caps.FeatureReportByteLength;
+        else
+            max_len = ext->preparseData->caps.OutputReportByteLength;
     }
     else
     {
         packet.reportBuffer = irp->AssociatedIrp.SystemBuffer;
         packet.reportBufferLen = irpsp->Parameters.DeviceIoControl.InputBufferLength;
+        if (irpsp->Parameters.DeviceIoControl.IoControlCode == IOCTL_HID_SET_FEATURE)
+            max_len = (ext->preparseData->reports[ext->preparseData->reportIdx[HidP_Feature][packet.reportId]].bitSize + 7) / 8;
+        else
+            max_len = (ext->preparseData->reports[ext->preparseData->reportIdx[HidP_Output][packet.reportId]].bitSize + 7) / 8;
     }
+    if (packet.reportBufferLen > max_len)
+        packet.reportBufferLen = max_len;
+
     TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet.reportId, packet.reportBufferLen, packet.reportBuffer);
 
     rc = call_minidriver(irpsp->Parameters.DeviceIoControl.IoControlCode,
@@ -740,7 +753,9 @@ NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp)
 NTSTATUS WINAPI HID_Device_write(DEVICE_OBJECT *device, IRP *irp)
 {
     IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp );
+    BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
     HID_XFER_PACKET packet;
+    ULONG max_len;
     NTSTATUS rc;
 
     irp->IoStatus.Information = 0;
@@ -751,12 +766,17 @@ NTSTATUS WINAPI HID_Device_write(DEVICE_OBJECT *device, IRP *irp)
     {
         packet.reportBuffer = &((BYTE*)irp->AssociatedIrp.SystemBuffer)[1];
         packet.reportBufferLen = irpsp->Parameters.Write.Length - 1;
+        max_len = ext->preparseData->caps.OutputReportByteLength;
     }
     else
     {
         packet.reportBuffer = irp->AssociatedIrp.SystemBuffer;
         packet.reportBufferLen = irpsp->Parameters.Write.Length;
+        max_len = (ext->preparseData->reports[ext->preparseData->reportIdx[HidP_Output][packet.reportId]].bitSize + 7) / 8;
     }
+    if (packet.reportBufferLen > max_len)
+        packet.reportBufferLen = max_len;
+
     TRACE_(hid_report)("(id %i, len %i buffer %p)\n", packet.reportId, packet.reportBufferLen, packet.reportBuffer);
 
     rc = call_minidriver(IOCTL_HID_WRITE_REPORT, device, NULL, 0, &packet, sizeof(packet));




More information about the wine-cvs mailing list