From fc64aa7e7cdf715738ed411afb4da69064939a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Fri, 28 May 2021 16:12:21 +0200 Subject: [PATCH] server: Send HID report data with the WM_INPUT messages. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50506 Signed-off-by: RĂ©mi Bernon Signed-off-by: Alexandre Julliard --- dlls/user32/message.c | 5 ++++- dlls/user32/rawinput.c | 4 ++-- include/wine/server_protocol.h | 7 +++++-- server/protocol.def | 3 +++ server/queue.c | 15 ++++++++++++++- server/request.h | 6 +++--- server/trace.c | 5 +++-- tools/make_requests | 2 +- 8 files changed, 35 insertions(+), 12 deletions(-) diff --git a/dlls/user32/message.c b/dlls/user32/message.c index 886c10e36bd..6f0f58a5f3f 100644 --- a/dlls/user32/message.c +++ b/dlls/user32/message.c @@ -3298,11 +3298,14 @@ NTSTATUS send_hardware_message( HWND hwnd, const INPUT *input, const RAWINPUT *r switch (rawinput->header.dwType) { case RIM_TYPEHID: - assert( rawinput->data.hid.dwCount <= 1 ); req->input.hw.rawinput.hid.device = HandleToUlong( rawinput->header.hDevice ); req->input.hw.rawinput.hid.param = rawinput->header.wParam; req->input.hw.rawinput.hid.usage_page = hid_usage_page; req->input.hw.rawinput.hid.usage = hid_usage; + req->input.hw.rawinput.hid.count = rawinput->data.hid.dwCount; + req->input.hw.rawinput.hid.length = rawinput->data.hid.dwSizeHid; + wine_server_add_data( req, rawinput->data.hid.bRawData, + rawinput->data.hid.dwCount * rawinput->data.hid.dwSizeHid ); break; default: assert( 0 ); diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index 87f7175a6c1..41d627c62c2 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -397,8 +397,8 @@ BOOL rawinput_from_hardware_message(RAWINPUT *rawinput, const struct hardware_ms rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device ); rawinput->header.wParam = 0; - rawinput->data.hid.dwCount = 0; - rawinput->data.hid.dwSizeHid = 0; + rawinput->data.hid.dwCount = msg_data->rawinput.hid.count; + rawinput->data.hid.dwSizeHid = msg_data->rawinput.hid.length; memcpy( rawinput->data.hid.bRawData, msg_data + 1, size ); } else diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 96b91c503a9..83b6bdb3e22 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -286,6 +286,8 @@ union rawinput unsigned int param; unsigned short usage_page; unsigned short usage; + unsigned int count; + unsigned int length; } hid; }; @@ -2763,7 +2765,8 @@ struct send_hardware_message_request user_handle_t win; hw_input_t input; unsigned int flags; - char __pad_52[4]; + /* VARARG(report,bytes); */ + char __pad_60[4]; }; struct send_hardware_message_reply { @@ -6309,7 +6312,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 709 +#define SERVER_PROTOCOL_VERSION 710 /* ### protocol_version end ### */ diff --git a/server/protocol.def b/server/protocol.def index 142064d30d3..8a68c9a5eb7 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -302,6 +302,8 @@ union rawinput unsigned int param; /* rawinput message param */ unsigned short usage_page;/* HID usage page */ unsigned short usage; /* HID usage */ + unsigned int count; /* HID report count */ + unsigned int length; /* HID report length */ } hid; }; @@ -2068,6 +2070,7 @@ enum message_type user_handle_t win; /* window handle */ hw_input_t input; /* input data */ unsigned int flags; /* flags (see below) */ + VARARG(report,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/queue.c b/server/queue.c index 76ee469ffef..e4903bcb79f 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1995,6 +1995,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ struct hardware_msg_data *msg_data; struct rawinput_message raw_msg; struct message *msg; + data_size_t report_size = 0; switch (input->hw.msg) { @@ -2007,9 +2008,21 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ raw_msg.message = input->hw.msg; raw_msg.hid_report = NULL; + if (input->hw.rawinput.type == RIM_TYPEHID) + { + raw_msg.hid_report = get_req_data(); + report_size = input->hw.rawinput.hid.length * input->hw.rawinput.hid.count; + } + + if (report_size != get_req_data_size()) + { + set_error( STATUS_INVALID_PARAMETER ); + return; + } + msg_data = &raw_msg.data; msg_data->info = 0; - msg_data->size = sizeof(*msg_data); + msg_data->size = sizeof(*msg_data) + report_size; msg_data->flags = 0; msg_data->rawinput = input->hw.rawinput; diff --git a/server/request.h b/server/request.h index cd65f79c757..ddf356c3e3f 100644 --- a/server/request.h +++ b/server/request.h @@ -693,7 +693,7 @@ C_ASSERT( sizeof(client_ptr_t) == 8 ); C_ASSERT( sizeof(data_size_t) == 4 ); C_ASSERT( sizeof(file_pos_t) == 8 ); C_ASSERT( sizeof(generic_map_t) == 16 ); -C_ASSERT( sizeof(hw_input_t) == 32 ); +C_ASSERT( sizeof(hw_input_t) == 40 ); C_ASSERT( sizeof(int) == 4 ); C_ASSERT( sizeof(ioctl_code_t) == 4 ); C_ASSERT( sizeof(irp_params_t) == 32 ); @@ -1355,8 +1355,8 @@ C_ASSERT( FIELD_OFFSET(struct post_quit_message_request, exit_code) == 12 ); C_ASSERT( sizeof(struct post_quit_message_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, win) == 12 ); C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, input) == 16 ); -C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, flags) == 48 ); -C_ASSERT( sizeof(struct send_hardware_message_request) == 56 ); +C_ASSERT( FIELD_OFFSET(struct send_hardware_message_request, flags) == 56 ); +C_ASSERT( sizeof(struct send_hardware_message_request) == 64 ); C_ASSERT( FIELD_OFFSET(struct send_hardware_message_reply, wait) == 8 ); C_ASSERT( FIELD_OFFSET(struct send_hardware_message_reply, prev_x) == 12 ); C_ASSERT( FIELD_OFFSET(struct send_hardware_message_reply, prev_y) == 16 ); diff --git a/server/trace.c b/server/trace.c index cebcc217e3a..8bfc9e56cc5 100644 --- a/server/trace.c +++ b/server/trace.c @@ -404,9 +404,9 @@ static void dump_rawinput( const char *prefix, const union rawinput *rawinput ) rawinput->kbd.message, rawinput->kbd.vkey, rawinput->kbd.scan ); break; case RIM_TYPEHID: - fprintf( stderr, "%s{type=HID,device=%04x,param=%04x,page=%04hx,usage=%04hx}", + fprintf( stderr, "%s{type=HID,device=%04x,param=%04x,page=%04hx,usage=%04hx,count=%u,length=%u}", prefix, rawinput->hid.device, rawinput->hid.param, rawinput->hid.usage_page, - rawinput->hid.usage ); + rawinput->hid.usage, rawinput->hid.count, rawinput->hid.length ); break; default: fprintf( stderr, "%s{type=%04x}", prefix, rawinput->type ); @@ -2727,6 +2727,7 @@ static void dump_send_hardware_message_request( const struct send_hardware_messa fprintf( stderr, " win=%08x", req->win ); dump_hw_input( ", input=", &req->input ); fprintf( stderr, ", flags=%08x", req->flags ); + dump_varargs_bytes( ", report=", cur_size ); } static void dump_send_hardware_message_reply( const struct send_hardware_message_reply *req ) diff --git a/tools/make_requests b/tools/make_requests index a70b29df3d2..1c4e5977c8b 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -52,7 +52,7 @@ my %formats = "luid_t" => [ 8, 4, "&dump_luid" ], "generic_map_t" => [ 16, 4, "&dump_generic_map" ], "ioctl_code_t" => [ 4, 4, "&dump_ioctl_code" ], - "hw_input_t" => [ 32, 8, "&dump_hw_input" ], + "hw_input_t" => [ 40, 8, "&dump_hw_input" ], ); my @requests = ();