[PATCH 5/5] hidclass.sys: Send rawinput messages with HID report.

Arkadiusz Hiler ahiler at codeweavers.com
Fri Feb 12 08:25:00 CST 2021


On Wed, Feb 10, 2021 at 08:07:17PM +0100, Rémi Bernon wrote:
> On 2/10/21 1:23 PM, Rémi Bernon wrote:
> > Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506
> > Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> > ---
> >   dlls/hidclass.sys/device.c | 22 ++++++++++++++++++++++
> >   1 file changed, 22 insertions(+)
> > 
> > diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
> > index fc1dfd07db1..8d7bae5cafa 100644
> > --- a/dlls/hidclass.sys/device.c
> > +++ b/dlls/hidclass.sys/device.c
> > @@ -26,6 +26,7 @@
> >   #include "winuser.h"
> >   #include "setupapi.h"
> > +#include "wine/server.h"
> >   #include "wine/debug.h"
> >   #include "ddk/hidsdi.h"
> >   #include "ddk/hidtypes.h"
> > @@ -237,6 +238,25 @@ static NTSTATUS copy_packet_into_buffer(HID_XFER_PACKET *packet, BYTE* buffer, U
> >           return STATUS_BUFFER_OVERFLOW;
> >   }
> > +static void HID_Device_sendRawInput(DEVICE_OBJECT *device, HID_XFER_PACKET *packet)
> > +{
> > +    BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
> > +
> > +    SERVER_START_REQ(send_hardware_message)
> > +    {
> > +        req->win                  = 0;
> > +        req->flags                = 0;
> > +        req->input.type           = HW_INPUT_HID;
> > +        req->input.hid.device     = 0; /* FIXME */
> > +        req->input.hid.usage_page = ext->preparseData->caps.UsagePage;
> > +        req->input.hid.usage      = ext->preparseData->caps.Usage;
> > +        req->input.hid.length     = packet->reportBufferLen;
> > +        wine_server_add_data(req, packet->reportBuffer, packet->reportBufferLen);
> > +        wine_server_call(req);
> > +    }
> > +    SERVER_END_REQ;
> > +}
> > +
> >   static void HID_Device_processQueue(DEVICE_OBJECT *device)
> >   {
> >       IRP *irp;
> > @@ -320,6 +340,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
> >               if (irp->IoStatus.u.Status == STATUS_SUCCESS)
> >               {
> >                   RingBuffer_Write(ext->ring_buffer, packet);
> > +                HID_Device_sendRawInput(device, packet);
> >                   HID_Device_processQueue(device);
> >               }
> > @@ -366,6 +387,7 @@ static DWORD CALLBACK hid_device_thread(void *args)
> >                   else
> >                       packet->reportId = 0;
> >                   RingBuffer_Write(ext->ring_buffer, packet);
> > +                HID_Device_sendRawInput(device, packet);
> >                   HID_Device_processQueue(device);
> >               }
> > 
> 
> There's apparently some outstanding issue related to the HID report carried
> by WM_INPUT, possibly making this patch not entirely correct.
> 
> I think it only impacts this last patch though, not the previous changes
> that are required to send WM_INPUT messages with HID data.

Hey,

WM_INPUT / GetRawInputData() uses the same format for reports as
HidD_GetInputReport(), i.e.: the first byte is always used for the
report id even if the device is not using report ids, in which case it
is set to zero (reserved by the HID spec).

HID_XFER_PACKET contains the reports verbatim, so at times we have to
prepend that zero.

Add something like this before the wine_server_add_data() call:

    if (ext->preparseData->reports[0].reportID == 0) {
        BYTE zero_byte = 0;
        req->input.hid.length++;
        wine_server_add_data(req, &zero_byte, sizeof(zero_byte));
    }

-- 
Cheers,
Arek



More information about the wine-devel mailing list