[PATCH v2 4/6] hidclass.sys: Send rawinput messages with HID report.

Rémi Bernon rbernon at codeweavers.com
Fri Mar 5 04:49:23 CST 2021


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 | 31 +++++++++++++++++++++++++++++++
 server/protocol.def        | 10 ++++++++++
 server/trace.c             |  4 ++++
 3 files changed, 45 insertions(+)

diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c
index fc1dfd07db1..7da7ac43a62 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,34 @@ 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;
+    UCHAR report_id;
+
+    SERVER_START_REQ(send_hardware_message)
+    {
+        req->win                  = 0;
+        req->flags                = 0;
+        req->input.type           = HW_INPUT_HID;
+        req->input.hid.usage_page = ext->preparseData->caps.UsagePage;
+        req->input.hid.usage      = ext->preparseData->caps.Usage;
+        req->input.hid.length     = 0;
+
+        if (!(report_id = ext->preparseData->reports[0].reportID))
+        {
+            wine_server_add_data(req, &report_id, sizeof(report_id));
+            req->input.hid.length++;
+        }
+
+        wine_server_add_data(req, packet->reportBuffer, packet->reportBufferLen);
+        req->input.hid.length += packet->reportBufferLen;
+
+        wine_server_call(req);
+    }
+    SERVER_END_REQ;
+}
+
 static void HID_Device_processQueue(DEVICE_OBJECT *device)
 {
     IRP *irp;
@@ -320,6 +349,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 +396,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);
             }
 
diff --git a/server/protocol.def b/server/protocol.def
index dbe65c67881..ac23a8ce716 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -358,10 +358,19 @@ typedef union
         unsigned int   msg;     /* message code */
         lparam_t       lparam;  /* message param */
     } hw;
+    struct
+    {
+        int            type;    /* HW_INPUT_HID */
+        unsigned char  usage_page; /* HID usage page */
+        unsigned char  usage;   /* HID usage */
+        unsigned int   length;  /* HID report length */
+        /* followed by length bytes of HID report data  */
+    } hid;
 } hw_input_t;
 #define HW_INPUT_MOUSE    0
 #define HW_INPUT_KEYBOARD 1
 #define HW_INPUT_HARDWARE 2
+#define HW_INPUT_HID      3
 
 typedef union
 {
@@ -2027,6 +2036,7 @@ enum message_type
     user_handle_t   win;       /* window handle */
     hw_input_t      input;     /* input data */
     unsigned int    flags;     /* flags (see below) */
+    VARARG(data,bytes);        /* HID report data */
 @REPLY
     int             wait;      /* do we need to wait for a reply? */
     int             prev_x;    /* previous cursor position */
diff --git a/server/trace.c b/server/trace.c
index faaf0c78481..9c0c90f379f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -422,6 +422,10 @@ static void dump_hw_input( const char *prefix, const hw_input_t *input )
         dump_uint64( ",lparam=", &input->hw.lparam );
         fputc( '}', stderr );
         break;
+    case HW_INPUT_HID:
+        fprintf( stderr, "%s{type=HID,usage_page=%02x,usage=%02x,length=%04x}",
+                 prefix, input->hid.usage_page, input->hid.usage, input->hid.length );
+        break;
     default:
         fprintf( stderr, "%s{type=%04x}", prefix, input->type );
         break;
-- 
2.30.0




More information about the wine-devel mailing list