-- v9: win32u: Get rid of the rawinput thread data and buffer. server: Fix rawinput buffer sizes and alignment on WoW64. server: Move rawinput message conversion from win32u.
From: Rémi Bernon rbernon@codeweavers.com
Appending the entire RAWMOUSE / RAWKEYBOARD / RAWHID + report structs after the hardware message data, instead of using a custom intermediate structure. --- dlls/user32/tests/input.c | 11 +- dlls/win32u/rawinput.c | 127 ++++------------------- include/wine/server_protocol.h | 34 ++----- server/protocol.def | 32 ++---- server/queue.c | 180 ++++++++++++++++++++++++++------- server/request.h | 2 +- tools/make_requests | 2 +- 7 files changed, 183 insertions(+), 205 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 350baff600d..657730fa099 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1915,7 +1915,6 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara
size = sizeof(buffer); memset( buffer, 0, sizeof(buffer) ); - todo_wine_if(is_wow64 && iteration == 1) ok_ret( 3, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER)) ); ok_eq( sizeof(buffer), size, UINT, "%u" );
@@ -1958,9 +1957,8 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara * it needs one more byte to return success */ size = sizeof(rawinput) + 1; memset( buffer, 0, sizeof(buffer) ); - todo_wine_if(is_wow64) ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) ); - if (is_wow64) todo_wine ok_eq( 5, rawbuffer64->data.keyboard.MakeCode, WPARAM, "%Iu" ); + if (is_wow64) ok_eq( 5, rawbuffer64->data.keyboard.MakeCode, WPARAM, "%Iu" ); else ok_eq( 5, rawbuffer->data.keyboard.MakeCode, WPARAM, "%Iu" );
/* peek the messages now, they should still arrive in the correct order */ @@ -2013,7 +2011,6 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara SetLastError( 0xdeadbeef ); size = sizeof(rawinput); ok_ret( rawinput_size, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER) ) ); - todo_wine_if(is_wow64) ok_eq( 6, rawinput.data.keyboard.MakeCode, UINT, "%u" );
SetLastError( 0xdeadbeef ); @@ -2027,7 +2024,6 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara { todo_wine ok_ret( rawinput_size, GetRawInputData( handle, RID_INPUT, &rawinput, &size, sizeof(RAWINPUTHEADER64) ) ); - todo_wine ok_eq( 6, rawinput.data.keyboard.MakeCode, UINT, "%u" ); todo_wine ok_ret( 0xdeadbeef, GetLastError() ); @@ -2184,7 +2180,6 @@ static void test_GetRawInputBuffer(void)
size = 0; ok_ret( 0, GetRawInputBuffer( NULL, &size, sizeof(RAWINPUTHEADER) ) ); - todo_wine ok_eq( rawinput_size, size, UINT, "%u" );
size = sizeof(buffer); @@ -2226,9 +2221,7 @@ static void test_GetRawInputBuffer(void) /* rawinput buffer survives registered device changes */
size = rawinput_size + 1; - todo_wine ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) ); - todo_wine ok_eq( rawinput_size + 1, size, UINT, "%u" );
raw_devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC; @@ -2244,9 +2237,7 @@ static void test_GetRawInputBuffer(void) ok_ret( 1, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) ); ok_eq( rawinput_size + 1, size, UINT, "%u" ); size = sizeof(buffer); - todo_wine ok_ret( 0, GetRawInputBuffer( rawbuffer, &size, sizeof(RAWINPUTHEADER) ) ); - todo_wine ok_eq( 0, size, UINT, "%u" );
raw_devices[0].dwFlags = RIDEV_REMOVE; diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 3ea29f2da77..524d1b820b2 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -73,125 +73,40 @@ static struct rawinput_thread_data *get_rawinput_thread_data(void) return data; }
-static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct hardware_msg_data *msg_data ) +static BOOL rawinput_from_hardware_message( RAWINPUT *rawinput, const struct hardware_msg_data *msg_data ) { - SIZE_T size; + SIZE_T size = msg_data->size - sizeof(*msg_data); + if (sizeof(RAWINPUTHEADER) + size > rawinput->header.dwSize) return FALSE; + + rawinput->header.dwType = msg_data->rawinput.type; + rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + size; + rawinput->header.hDevice = UlongToHandle( msg_data->rawinput.device ); + rawinput->header.wParam = msg_data->rawinput.wparam;
- rawinput->header.dwType = msg_data->rawinput.type; if (msg_data->rawinput.type == RIM_TYPEMOUSE) { - static const unsigned int button_flags[] = - { - 0, /* MOUSEEVENTF_MOVE */ - RI_MOUSE_LEFT_BUTTON_DOWN, /* MOUSEEVENTF_LEFTDOWN */ - RI_MOUSE_LEFT_BUTTON_UP, /* MOUSEEVENTF_LEFTUP */ - RI_MOUSE_RIGHT_BUTTON_DOWN, /* MOUSEEVENTF_RIGHTDOWN */ - RI_MOUSE_RIGHT_BUTTON_UP, /* MOUSEEVENTF_RIGHTUP */ - RI_MOUSE_MIDDLE_BUTTON_DOWN, /* MOUSEEVENTF_MIDDLEDOWN */ - RI_MOUSE_MIDDLE_BUTTON_UP, /* MOUSEEVENTF_MIDDLEUP */ - }; - unsigned int i; - - rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWMOUSE); - rawinput->header.hDevice = WINE_MOUSE_HANDLE; - rawinput->header.wParam = 0; - - rawinput->data.mouse.usFlags = MOUSE_MOVE_RELATIVE; - rawinput->data.mouse.usButtonFlags = 0; - rawinput->data.mouse.usButtonData = 0; - for (i = 1; i < ARRAY_SIZE(button_flags); ++i) - { - if (msg_data->flags & (1 << i)) - rawinput->data.mouse.usButtonFlags |= button_flags[i]; - } - if (msg_data->flags & MOUSEEVENTF_WHEEL) - { - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_WHEEL; - rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data; - } - if (msg_data->flags & MOUSEEVENTF_HWHEEL) - { - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL; - rawinput->data.mouse.usButtonData = msg_data->rawinput.mouse.data; - } - if (msg_data->flags & MOUSEEVENTF_XDOWN) - { - if (msg_data->rawinput.mouse.data == XBUTTON1) - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN; - else if (msg_data->rawinput.mouse.data == XBUTTON2) - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN; - } - if (msg_data->flags & MOUSEEVENTF_XUP) - { - if (msg_data->rawinput.mouse.data == XBUTTON1) - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_4_UP; - else if (msg_data->rawinput.mouse.data == XBUTTON2) - rawinput->data.mouse.usButtonFlags |= RI_MOUSE_BUTTON_5_UP; - } - - rawinput->data.mouse.ulRawButtons = 0; - rawinput->data.mouse.lLastX = msg_data->rawinput.mouse.x; - rawinput->data.mouse.lLastY = msg_data->rawinput.mouse.y; - rawinput->data.mouse.ulExtraInformation = msg_data->info; + if (size != sizeof(RAWMOUSE)) return FALSE; + rawinput->data.mouse = *(RAWMOUSE *)(msg_data + 1); } else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD) { - rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWKEYBOARD); - rawinput->header.hDevice = WINE_KEYBOARD_HANDLE; - rawinput->header.wParam = 0; - - rawinput->data.keyboard.MakeCode = msg_data->rawinput.kbd.scan; - rawinput->data.keyboard.Flags = (msg_data->flags & KEYEVENTF_KEYUP) ? RI_KEY_BREAK : RI_KEY_MAKE; - if (msg_data->flags & KEYEVENTF_EXTENDEDKEY) - rawinput->data.keyboard.Flags |= RI_KEY_E0; - rawinput->data.keyboard.Reserved = 0; - - switch (msg_data->rawinput.kbd.vkey) - { - case VK_LSHIFT: - case VK_RSHIFT: - rawinput->data.keyboard.VKey = VK_SHIFT; - rawinput->data.keyboard.Flags &= ~RI_KEY_E0; - break; - - case VK_LCONTROL: - case VK_RCONTROL: - rawinput->data.keyboard.VKey = VK_CONTROL; - break; - - case VK_LMENU: - case VK_RMENU: - rawinput->data.keyboard.VKey = VK_MENU; - break; - - default: - rawinput->data.keyboard.VKey = msg_data->rawinput.kbd.vkey; - break; - } - - rawinput->data.keyboard.Message = msg_data->rawinput.kbd.message; - rawinput->data.keyboard.ExtraInformation = msg_data->info; + if (size != sizeof(RAWKEYBOARD)) return FALSE; + rawinput->data.keyboard = *(RAWKEYBOARD *)(msg_data + 1); } else if (msg_data->rawinput.type == RIM_TYPEHID) { - size = msg_data->size - sizeof(*msg_data); - if (size > rawinput->header.dwSize - sizeof(*rawinput)) return false; - - rawinput->header.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData ) + size; - rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device ); - rawinput->header.wParam = 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 ); + RAWHID *hid = (RAWHID *)(msg_data + 1); + if (size < offsetof(RAWHID, bRawData[0])) return FALSE; + if (size != offsetof(RAWHID, bRawData[hid->dwCount * hid->dwSizeHid])) return FALSE; + memcpy( &rawinput->data.hid, msg_data + 1, size ); } else { FIXME( "Unhandled rawinput type %#x.\n", msg_data->rawinput.type ); - return false; + return FALSE; }
- return true; + return TRUE; }
struct device @@ -621,10 +536,10 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade int i;
if (NtCurrentTeb()->WowTebOffset) - rawinput_size = sizeof(RAWINPUT64); + rawinput_size = sizeof(RAWINPUTHEADER64); else - rawinput_size = sizeof(RAWINPUT); - overhead = rawinput_size - sizeof(RAWINPUT); + rawinput_size = sizeof(RAWINPUTHEADER); + overhead = rawinput_size - sizeof(RAWINPUTHEADER);
if (header_size != sizeof(RAWINPUTHEADER)) { diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 80cc8bd3bd5..00b2ebdf971 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -263,32 +263,12 @@ struct hw_msg_source unsigned int origin; };
-union rawinput +struct rawinput { - int type; - struct - { - int type; - unsigned int message; - unsigned short vkey; - unsigned short scan; - } kbd; - struct - { - int type; - int x; - int y; - unsigned int data; - } mouse; - struct - { - int type; - unsigned int device; - unsigned int wparam; - unsigned int usage; - unsigned int count; - unsigned int length; - } hid; + int type; + unsigned int device; + unsigned int wparam; + unsigned int usage; };
struct hardware_msg_data @@ -299,7 +279,7 @@ struct hardware_msg_data unsigned int hw_id; unsigned int flags; struct hw_msg_source source; - union rawinput rawinput; + struct rawinput rawinput; };
struct callback_msg_data @@ -6512,7 +6492,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 791 +#define SERVER_PROTOCOL_VERSION 792
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index e896f6cb72a..a88e1534d24 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -279,32 +279,12 @@ struct hw_msg_source unsigned int origin; /* source origin (IMO_* values) */ };
-union rawinput +struct rawinput { - int type; - struct - { - int type; /* RIM_TYPEKEYBOARD */ - unsigned int message; /* message generated by this rawinput event */ - unsigned short vkey; /* virtual key code */ - unsigned short scan; /* scan code */ - } kbd; - struct - { - int type; /* RIM_TYPEMOUSE */ - int x; /* x coordinate */ - int y; /* y coordinate */ - unsigned int data; /* mouse data */ - } mouse; - struct - { - int type; /* RIM_TYPEHID */ - unsigned int device; /* rawinput device index */ - unsigned int wparam; /* rawinput message wparam */ - unsigned int usage; /* HID device usage */ - unsigned int count; /* HID report count */ - unsigned int length; /* HID report length */ - } hid; + int type; /* rawinput data type (RIM_* values) */ + unsigned int device; /* rawinput device pseudo-handle */ + unsigned int wparam; /* wparam of the WM_INPUT* message */ + unsigned int usage; /* HID device usage */ };
struct hardware_msg_data @@ -315,7 +295,7 @@ struct hardware_msg_data unsigned int hw_id; /* unique id */ unsigned int flags; /* hook flags */ struct hw_msg_source source; /* message source */ - union rawinput rawinput; /* rawinput message data */ + struct rawinput rawinput; /* rawinput message data */ };
struct callback_msg_data diff --git a/server/queue.c b/server/queue.c index 07870f98711..e3aa0f685ca 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1782,6 +1782,116 @@ static struct thread *get_foreground_thread( struct desktop *desktop, user_handl return NULL; }
+/* user32 reserves 1 & 2 for winemouse and winekeyboard, + * keep this in sync with user_private.h */ +#define WINE_MOUSE_HANDLE 1 +#define WINE_KEYBOARD_HANDLE 2 + +static void rawmouse_init( struct rawinput *header, RAWMOUSE *rawmouse, int x, int y, unsigned int flags, + unsigned int buttons, lparam_t info ) +{ + static const unsigned int button_flags[] = + { + 0, /* MOUSEEVENTF_MOVE */ + RI_MOUSE_LEFT_BUTTON_DOWN, /* MOUSEEVENTF_LEFTDOWN */ + RI_MOUSE_LEFT_BUTTON_UP, /* MOUSEEVENTF_LEFTUP */ + RI_MOUSE_RIGHT_BUTTON_DOWN, /* MOUSEEVENTF_RIGHTDOWN */ + RI_MOUSE_RIGHT_BUTTON_UP, /* MOUSEEVENTF_RIGHTUP */ + RI_MOUSE_MIDDLE_BUTTON_DOWN, /* MOUSEEVENTF_MIDDLEDOWN */ + RI_MOUSE_MIDDLE_BUTTON_UP, /* MOUSEEVENTF_MIDDLEUP */ + }; + unsigned int i; + + header->type = RIM_TYPEMOUSE; + header->device = WINE_MOUSE_HANDLE; + header->wparam = 0; + header->usage = MAKELONG(HID_USAGE_GENERIC_MOUSE, HID_USAGE_PAGE_GENERIC); + + rawmouse->usFlags = MOUSE_MOVE_RELATIVE; + rawmouse->usButtonFlags = 0; + rawmouse->usButtonData = 0; + for (i = 1; i < ARRAY_SIZE(button_flags); ++i) + { + if (flags & (1 << i)) rawmouse->usButtonFlags |= button_flags[i]; + } + if (flags & MOUSEEVENTF_WHEEL) + { + rawmouse->usButtonFlags |= RI_MOUSE_WHEEL; + rawmouse->usButtonData = buttons; + } + if (flags & MOUSEEVENTF_HWHEEL) + { + rawmouse->usButtonFlags |= RI_MOUSE_HORIZONTAL_WHEEL; + rawmouse->usButtonData = buttons; + } + if (flags & MOUSEEVENTF_XDOWN) + { + if (buttons == XBUTTON1) rawmouse->usButtonFlags |= RI_MOUSE_BUTTON_4_DOWN; + if (buttons == XBUTTON2) rawmouse->usButtonFlags |= RI_MOUSE_BUTTON_5_DOWN; + } + if (flags & MOUSEEVENTF_XUP) + { + if (buttons == XBUTTON1) rawmouse->usButtonFlags |= RI_MOUSE_BUTTON_4_UP; + if (buttons == XBUTTON2) rawmouse->usButtonFlags |= RI_MOUSE_BUTTON_5_UP; + } + + rawmouse->ulRawButtons = 0; + rawmouse->lLastX = x; + rawmouse->lLastY = y; + rawmouse->ulExtraInformation = info; +} + +static void rawkeyboard_init( struct rawinput *rawinput, RAWKEYBOARD *keyboard, unsigned short scan, unsigned short vkey, + unsigned int flags, unsigned int message, lparam_t info ) +{ + rawinput->type = RIM_TYPEKEYBOARD; + rawinput->device = WINE_KEYBOARD_HANDLE; + rawinput->wparam = 0; + rawinput->usage = MAKELONG(HID_USAGE_GENERIC_KEYBOARD, HID_USAGE_PAGE_GENERIC); + + keyboard->MakeCode = scan; + keyboard->Flags = (flags & KEYEVENTF_KEYUP) ? RI_KEY_BREAK : RI_KEY_MAKE; + if (flags & KEYEVENTF_EXTENDEDKEY) keyboard->Flags |= RI_KEY_E0; + keyboard->Reserved = 0; + + switch (vkey) + { + case VK_LSHIFT: + case VK_RSHIFT: + keyboard->VKey = VK_SHIFT; + keyboard->Flags &= ~RI_KEY_E0; + break; + + case VK_LCONTROL: + case VK_RCONTROL: + keyboard->VKey = VK_CONTROL; + break; + + case VK_LMENU: + case VK_RMENU: + keyboard->VKey = VK_MENU; + break; + + default: + keyboard->VKey = vkey; + break; + } + + keyboard->Message = message; + keyboard->ExtraInformation = info; +} + +static void rawhid_init( struct rawinput *rawinput, RAWHID *hid, const hw_input_t *input ) +{ + rawinput->type = RIM_TYPEHID; + rawinput->device = input->hw.hid.device; + rawinput->wparam = input->hw.wparam; + rawinput->usage = input->hw.hid.usage; + + hid->dwCount = input->hw.hid.count; + hid->dwSizeHid = input->hw.hid.length; +} + struct rawinput_message { struct thread *foreground; @@ -1789,30 +1899,48 @@ struct rawinput_message struct hw_msg_source source; unsigned int time; unsigned int message; - lparam_t info; unsigned int flags; - union rawinput rawinput; - const void *hid_report; + struct rawinput rawinput; + union + { + RAWKEYBOARD keyboard; + RAWMOUSE mouse; + RAWHID hid; + } data; + const void *hid_report; };
/* check if process is supposed to receive a WM_INPUT message and eventually queue it */ static int queue_rawinput_message( struct process* process, void *arg ) { - const struct rawinput_message* raw_msg = arg; + const struct rawinput_message *raw_msg = arg; const struct rawinput_device *device = NULL; struct desktop *target_desktop = NULL, *desktop = NULL; struct thread *target_thread = NULL, *foreground = NULL; struct hardware_msg_data *msg_data; struct message *msg; - data_size_t report_size; + data_size_t report_size = 0, data_size = 0; int wparam = RIM_INPUT; + lparam_t info = 0;
if (raw_msg->rawinput.type == RIM_TYPEMOUSE) + { device = process->rawinput_mouse; + data_size = sizeof(raw_msg->data.mouse); + info = raw_msg->data.mouse.ulExtraInformation; + } else if (raw_msg->rawinput.type == RIM_TYPEKEYBOARD) + { device = process->rawinput_kbd; + data_size = sizeof(raw_msg->data.keyboard); + info = raw_msg->data.keyboard.ExtraInformation; + } else - device = find_rawinput_device( process, raw_msg->rawinput.hid.usage ); + { + device = find_rawinput_device( process, raw_msg->rawinput.usage ); + data_size = offsetof(RAWHID, bRawData[0]); + report_size = raw_msg->data.hid.dwCount * raw_msg->data.hid.dwSizeHid; + } if (!device) return 0;
if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && !(device->flags & RIDEV_DEVNOTIFY)) return 0; @@ -1832,10 +1960,7 @@ static int queue_rawinput_message( struct process* process, void *arg ) wparam = RIM_INPUTSINK; }
- if (raw_msg->rawinput.type != RIM_TYPEHID || !raw_msg->hid_report) report_size = 0; - else report_size = raw_msg->rawinput.hid.count * raw_msg->rawinput.hid.length; - - if (!(msg = alloc_hardware_message( raw_msg->info, raw_msg->source, raw_msg->time, report_size ))) goto done; + if (!(msg = alloc_hardware_message( info, raw_msg->source, raw_msg->time, data_size + report_size ))) goto done; msg->win = device->target; msg->msg = raw_msg->message; msg->wparam = wparam; @@ -1844,12 +1969,13 @@ static int queue_rawinput_message( struct process* process, void *arg ) msg_data = msg->data; msg_data->flags = raw_msg->flags; msg_data->rawinput = raw_msg->rawinput; - if (report_size) memcpy( msg_data + 1, raw_msg->hid_report, report_size ); + memcpy( msg_data + 1, &raw_msg->data, data_size ); + if (report_size) memcpy( (char *)(msg_data + 1) + data_size, raw_msg->hid_report, report_size );
if (raw_msg->message == WM_INPUT_DEVICE_CHANGE && raw_msg->rawinput.type == RIM_TYPEHID) { - msg->wparam = raw_msg->rawinput.hid.wparam; - msg->lparam = raw_msg->rawinput.hid.device; + msg->wparam = raw_msg->rawinput.wparam; + msg->lparam = raw_msg->rawinput.device; }
queue_hardware_message( desktop, msg, 1 ); @@ -1927,13 +2053,9 @@ static int queue_mouse_message( struct desktop *desktop, user_handle_t win, cons raw_msg.source = source; raw_msg.time = time; raw_msg.message = WM_INPUT; - - raw_msg.info = input->mouse.info; - raw_msg.flags = flags; - raw_msg.rawinput.type = RIM_TYPEMOUSE; - raw_msg.rawinput.mouse.x = x - desktop->cursor.x; - raw_msg.rawinput.mouse.y = y - desktop->cursor.y; - raw_msg.rawinput.mouse.data = input->mouse.data; + raw_msg.flags = flags; + rawmouse_init( &raw_msg.rawinput, &raw_msg.data.mouse, x - desktop->cursor.x, y - desktop->cursor.y, + raw_msg.flags, input->mouse.data, input->mouse.info );
enum_processes( queue_rawinput_message, &raw_msg ); release_object( foreground ); @@ -2063,13 +2185,9 @@ static int queue_keyboard_message( struct desktop *desktop, user_handle_t win, c raw_msg.source = source; raw_msg.time = time; raw_msg.message = WM_INPUT; - - raw_msg.info = input->kbd.info; - raw_msg.flags = input->kbd.flags; - raw_msg.rawinput.type = RIM_TYPEKEYBOARD; - raw_msg.rawinput.kbd.message = message_code; - raw_msg.rawinput.kbd.vkey = vkey; - raw_msg.rawinput.kbd.scan = input->kbd.scan; + raw_msg.flags = input->kbd.flags; + rawkeyboard_init( &raw_msg.rawinput, &raw_msg.data.keyboard, input->kbd.scan, vkey, + raw_msg.flags, message_code, input->kbd.info );
enum_processes( queue_rawinput_message, &raw_msg ); release_object( foreground ); @@ -2134,13 +2252,7 @@ static void queue_custom_hardware_message( struct desktop *desktop, user_handle_ set_error( STATUS_INVALID_PARAMETER ); return; } - - raw_msg.rawinput.hid.type = RIM_TYPEHID; - raw_msg.rawinput.hid.device = input->hw.hid.device; - raw_msg.rawinput.hid.wparam = input->hw.wparam; - raw_msg.rawinput.hid.usage = input->hw.hid.usage; - raw_msg.rawinput.hid.count = input->hw.hid.count; - raw_msg.rawinput.hid.length = input->hw.hid.length; + rawhid_init( &raw_msg.rawinput, &raw_msg.data.hid, input );
enum_processes( queue_rawinput_message, &raw_msg ); return; diff --git a/server/request.h b/server/request.h index 79a76f02392..e37fa5a44fa 100644 --- a/server/request.h +++ b/server/request.h @@ -716,7 +716,7 @@ C_ASSERT( sizeof(ioctl_code_t) == 4 ); C_ASSERT( sizeof(irp_params_t) == 32 ); C_ASSERT( sizeof(lparam_t) == 8 ); C_ASSERT( sizeof(mem_size_t) == 8 ); -C_ASSERT( sizeof(message_data_t) == 56 ); +C_ASSERT( sizeof(message_data_t) == 48 ); C_ASSERT( sizeof(mod_handle_t) == 8 ); C_ASSERT( sizeof(obj_handle_t) == 4 ); C_ASSERT( sizeof(pe_image_info_t) == 88 ); diff --git a/tools/make_requests b/tools/make_requests index 77b5ab331f4..e3eaaf45b6f 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -57,7 +57,7 @@ my %formats = "context_t" => [ 1720, 8 ], "cursor_pos_t" => [ 24, 8 ], "debug_event_t" => [ 160, 8 ], - "message_data_t" => [ 56, 8 ], + "message_data_t" => [ 48, 8 ], "pe_image_info_t" => [ 88, 8 ], "property_data_t" => [ 16, 8 ], "select_op_t" => [ 264, 8 ],
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/input.c | 3 - dlls/win32u/rawinput.c | 103 ++++----------------------------- include/wine/server_protocol.h | 6 +- server/protocol.def | 4 +- server/queue.c | 96 +++++++++++++++++++----------- server/request.h | 4 +- server/trace.c | 4 +- 7 files changed, 82 insertions(+), 138 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 657730fa099..be95bd150b4 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1924,12 +1924,9 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara if (is_wow64) { RAWINPUT64 *rawinput = (RAWINPUT64 *)(buffer + i * rawinput_size); - flaky_wine_if(is_wow64) ok_eq( RIM_TYPEKEYBOARD, rawinput->header.dwType, UINT, "%u" ); - flaky_wine_if(is_wow64) ok_eq( rawinput_size, rawinput->header.dwSize, UINT, "%u" ); ok_eq( wparam, rawinput->header.wParam, WPARAM, "%Iu" ); - flaky_wine_if(is_wow64) ok_eq( i + 2, rawinput->data.keyboard.MakeCode, WPARAM, "%Iu" ); } else diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index 524d1b820b2..e4f43091b9b 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -42,7 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(rawinput);
#ifdef _WIN64 typedef RAWINPUTHEADER RAWINPUTHEADER64; -typedef RAWINPUT RAWINPUT64; #else typedef struct { @@ -51,17 +50,6 @@ typedef struct ULONGLONG hDevice; ULONGLONG wParam; } RAWINPUTHEADER64; - -typedef struct -{ - RAWINPUTHEADER64 header; - union - { - RAWMOUSE mouse; - RAWKEYBOARD keyboard; - RAWHID hid; - } data; -} RAWINPUT64; #endif
static struct rawinput_thread_data *get_rawinput_thread_data(void) @@ -529,104 +517,35 @@ UINT WINAPI NtUserGetRawInputDeviceInfo( HANDLE handle, UINT command, void *data */ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT header_size ) { - unsigned int count = 0, remaining, rawinput_size, next_size, overhead; - struct rawinput_thread_data *thread_data; - struct hardware_msg_data *msg_data; - RAWINPUT *rawinput; - int i; + UINT count;
- if (NtCurrentTeb()->WowTebOffset) - rawinput_size = sizeof(RAWINPUTHEADER64); - else - rawinput_size = sizeof(RAWINPUTHEADER); - overhead = rawinput_size - sizeof(RAWINPUTHEADER); + TRACE( "data %p, data_size %p, header_size %u\n", data, data_size, header_size );
if (header_size != sizeof(RAWINPUTHEADER)) { - WARN( "Invalid structure size %u.\n", header_size ); RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); - return ~0u; + return -1; }
if (!data_size) { RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); - return ~0u; + return -1; }
- if (!data) - { - TRACE( "data %p, data_size %p (%u), header_size %u\n", data, data_size, *data_size, header_size ); - SERVER_START_REQ( get_rawinput_buffer ) - { - req->rawinput_size = rawinput_size; - req->buffer_size = 0; - if (wine_server_call( req )) return ~0u; - *data_size = reply->next_size; - } - SERVER_END_REQ; - return 0; - } + /* with old WOW64 mode we didn't go through the WOW64 thunks, patch the header size here */ + if (NtCurrentTeb()->WowTebOffset) header_size = sizeof(RAWINPUTHEADER64);
- if (!(thread_data = get_rawinput_thread_data())) return ~0u; - rawinput = thread_data->buffer; - - /* first RAWINPUT block in the buffer is used for WM_INPUT message data */ - msg_data = (struct hardware_msg_data *)NEXTRAWINPUTBLOCK(rawinput); SERVER_START_REQ( get_rawinput_buffer ) { - req->rawinput_size = rawinput_size; - req->buffer_size = *data_size; - wine_server_set_reply( req, msg_data, RAWINPUT_BUFFER_SIZE - rawinput->header.dwSize ); - if (wine_server_call( req )) return ~0u; - next_size = reply->next_size; - count = reply->count; + req->header_size = header_size; + if ((req->read_data = !!data)) wine_server_set_reply( req, data, *data_size ); + if (!wine_server_call_err( req )) count = reply->count; + else count = -1; + *data_size = reply->next_size; } SERVER_END_REQ;
- remaining = *data_size; - for (i = 0; i < count; ++i) - { - data->header.dwSize = remaining; - if (!rawinput_from_hardware_message( data, msg_data )) break; - if (overhead) - { - /* Under WoW64, GetRawInputBuffer always gives 64-bit RAWINPUT structs. */ - RAWINPUT64 *ri64 = (RAWINPUT64 *)data; - memmove( (char *)&data->data + overhead, &data->data, - data->header.dwSize - sizeof(RAWINPUTHEADER) ); - ri64->header.dwSize += overhead; - - /* Need to copy wParam before hDevice so it's not overwritten. */ - ri64->header.wParam = data->header.wParam; -#ifdef _WIN64 - ri64->header.hDevice = data->header.hDevice; -#else - ri64->header.hDevice = HandleToULong(data->header.hDevice); -#endif - } - remaining -= data->header.dwSize; - data = NEXTRAWINPUTBLOCK(data); - msg_data = (struct hardware_msg_data *)((char *)msg_data + msg_data->size); - } - - if (!next_size) - { - if (!count) - *data_size = 0; - else - next_size = rawinput_size; - } - - if (next_size && *data_size <= next_size) - { - RtlSetLastWin32Error( ERROR_INSUFFICIENT_BUFFER ); - *data_size = next_size; - count = ~0u; - } - - TRACE( "data %p, data_size %p (%u), header_size %u, count %u\n", - data, data_size, *data_size, header_size, count ); return count; }
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 00b2ebdf971..80290302405 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -5438,8 +5438,8 @@ struct get_cursor_history_reply struct get_rawinput_buffer_request { struct request_header __header; - data_size_t rawinput_size; - data_size_t buffer_size; + data_size_t header_size; + int read_data; char __pad_20[4]; }; struct get_rawinput_buffer_reply @@ -6492,7 +6492,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 792 +#define SERVER_PROTOCOL_VERSION 793
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index a88e1534d24..8b51618ebe0 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3768,8 +3768,8 @@ struct handle_info
/* Batch read rawinput message data */ @REQ(get_rawinput_buffer) - data_size_t rawinput_size; /* size of RAWINPUT structure */ - data_size_t buffer_size; /* size of output buffer */ + data_size_t header_size; /* size of RAWINPUTHEADER structure */ + int read_data; /* read the rawinput buffer data */ @REPLY data_size_t next_size; /* minimum size to get next message data */ unsigned int count; diff --git a/server/queue.c b/server/queue.c index e3aa0f685ca..6f38227aa84 100644 --- a/server/queue.c +++ b/server/queue.c @@ -1866,7 +1866,6 @@ static void rawkeyboard_init( struct rawinput *rawinput, RAWKEYBOARD *keyboard, case VK_RCONTROL: keyboard->VKey = VK_CONTROL; break; - case VK_LMENU: case VK_RMENU: keyboard->VKey = VK_MENU; @@ -3541,52 +3540,81 @@ DECL_HANDLER(get_cursor_history)
DECL_HANDLER(get_rawinput_buffer) { + const size_t align = is_machine_64bit( current->process->machine ) ? 7 : 3; + data_size_t buffer_size = get_reply_max_size() & ~align; struct thread_input *input = current->queue->input; - data_size_t size = 0, next_size = 0, pos = 0; - struct list *ptr; - char *buf, *tmp; - int count = 0, buf_size = 16 * sizeof(struct hardware_msg_data); + struct message *msg, *next_msg; + int count = 0; + char *buffer;
- if (!req->buffer_size) buf = NULL; - else if (!(buf = mem_alloc( buf_size ))) return; + if (req->header_size != sizeof(RAWINPUTHEADER)) + { + set_error( STATUS_INVALID_PARAMETER ); + return; + }
- ptr = list_head( &input->msg_list ); - while (ptr) + if (!req->read_data) { - struct message *msg = LIST_ENTRY( ptr, struct message, entry ); - struct hardware_msg_data *data = msg->data; - data_size_t extra_size = data->size - sizeof(*data); + LIST_FOR_EACH_ENTRY( msg, &input->msg_list, struct message, entry ) + { + if (msg->msg == WM_INPUT) + { + struct hardware_msg_data *msg_data = msg->data; + data_size_t size = msg_data->size - sizeof(*msg_data); + reply->next_size = sizeof(RAWINPUTHEADER) + size; + break; + } + }
- ptr = list_next( &input->msg_list, ptr ); - if (msg->msg != WM_INPUT) continue; + } + else if ((buffer = mem_alloc( buffer_size ))) + { + size_t total_size = 0, next_size = 0; + + reply->next_size = get_reply_max_size();
- next_size = req->rawinput_size + extra_size; - if (size + next_size > req->buffer_size) break; - if (pos + data->size > get_reply_max_size()) break; - if (pos + data->size > buf_size) + LIST_FOR_EACH_ENTRY_SAFE( msg, next_msg, &input->msg_list, struct message, entry ) { - buf_size += buf_size / 2 + extra_size; - if (!(tmp = realloc( buf, buf_size ))) + if (msg->msg == WM_INPUT) { - free( buf ); - set_error( STATUS_NO_MEMORY ); - return; + RAWINPUT *rawinput = (RAWINPUT *)(buffer + total_size); + struct hardware_msg_data *msg_data = msg->data; + data_size_t data_size = msg_data->size - sizeof(*msg_data); + + if (total_size + sizeof(RAWINPUTHEADER) + data_size > buffer_size) + { + next_size = sizeof(RAWINPUTHEADER) + data_size; + break; + } + + rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + data_size; + rawinput->header.dwType = msg_data->rawinput.type; + rawinput->header.hDevice = UlongToHandle(msg_data->rawinput.device); + rawinput->header.wParam = msg_data->rawinput.wparam; + memcpy( &rawinput->header + 1, msg_data + 1, data_size ); + + total_size += (rawinput->header.dwSize + align) & ~align; + list_remove( &msg->entry ); + free_message( msg ); + count++; } - buf = tmp; }
- memcpy( buf + pos, data, data->size ); - list_remove( &msg->entry ); - free_message( msg ); + if (!next_size) + { + if (count) next_size = sizeof(RAWINPUT); + else reply->next_size = 0; + }
- size += next_size; - pos += sizeof(*data) + extra_size; - count++; - } + if (next_size && get_reply_max_size() <= next_size) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + reply->next_size = next_size; + }
- reply->next_size = next_size; - reply->count = count; - set_reply_data_ptr( buf, pos ); + reply->count = count; + set_reply_data_ptr( buffer, total_size ); + } }
DECL_HANDLER(update_rawinput_devices) diff --git a/server/request.h b/server/request.h index e37fa5a44fa..cff7b5e7979 100644 --- a/server/request.h +++ b/server/request.h @@ -2285,8 +2285,8 @@ C_ASSERT( FIELD_OFFSET(struct set_cursor_reply, last_change) == 48 ); C_ASSERT( sizeof(struct set_cursor_reply) == 56 ); C_ASSERT( sizeof(struct get_cursor_history_request) == 16 ); C_ASSERT( sizeof(struct get_cursor_history_reply) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, rawinput_size) == 12 ); -C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, buffer_size) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, header_size) == 12 ); +C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_request, read_data) == 16 ); C_ASSERT( sizeof(struct get_rawinput_buffer_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, next_size) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_rawinput_buffer_reply, count) == 12 ); diff --git a/server/trace.c b/server/trace.c index fdd192e1749..f06cf29591f 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4482,8 +4482,8 @@ static void dump_get_cursor_history_reply( const struct get_cursor_history_reply
static void dump_get_rawinput_buffer_request( const struct get_rawinput_buffer_request *req ) { - fprintf( stderr, " rawinput_size=%u", req->rawinput_size ); - fprintf( stderr, ", buffer_size=%u", req->buffer_size ); + fprintf( stderr, " header_size=%u", req->header_size ); + fprintf( stderr, ", read_data=%d", req->read_data ); }
static void dump_get_rawinput_buffer_reply( const struct get_rawinput_buffer_reply *req )
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 12 +-- dlls/win32u/rawinput.c | 142 ++++++++++++++--------------------- 2 files changed, 57 insertions(+), 97 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 11bb7f4baf6..3b6cab5bdc9 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -38,16 +38,6 @@ enum system_timer_id SYSTEM_TIMER_KEY_REPEAT = 0xfff0, };
-struct rawinput_thread_data -{ - UINT hw_id; /* current rawinput message id */ - RAWINPUT buffer[1]; /* rawinput message data buffer */ -}; - -/* on windows the buffer capacity is quite large as well, enough to */ -/* hold up to 10s of 1kHz mouse rawinput events */ -#define RAWINPUT_BUFFER_SIZE (512 * 1024) - struct user_object { HANDLE handle; @@ -133,7 +123,7 @@ struct user_thread_info MSG key_repeat_msg; /* Last WM_KEYDOWN message to repeat */ HKL kbd_layout; /* Current keyboard layout */ UINT kbd_layout_id; /* Current keyboard layout ID */ - struct rawinput_thread_data *rawinput; /* RawInput thread local data / buffer */ + struct hardware_msg_data *rawinput; /* Current rawinput message data */ UINT spy_indent; /* Current spy indent */ BOOL clipping_cursor; /* thread is currently clipping */ DWORD clipping_reset; /* time when clipping was last reset */ diff --git a/dlls/win32u/rawinput.c b/dlls/win32u/rawinput.c index e4f43091b9b..1120ce053aa 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -52,51 +52,6 @@ typedef struct } RAWINPUTHEADER64; #endif
-static struct rawinput_thread_data *get_rawinput_thread_data(void) -{ - struct user_thread_info *thread_info = get_user_thread_info(); - struct rawinput_thread_data *data = thread_info->rawinput; - if (data) return data; - data = thread_info->rawinput = calloc( 1, RAWINPUT_BUFFER_SIZE + sizeof(struct user_thread_info) ); - return data; -} - -static BOOL rawinput_from_hardware_message( RAWINPUT *rawinput, const struct hardware_msg_data *msg_data ) -{ - SIZE_T size = msg_data->size - sizeof(*msg_data); - if (sizeof(RAWINPUTHEADER) + size > rawinput->header.dwSize) return FALSE; - - rawinput->header.dwType = msg_data->rawinput.type; - rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + size; - rawinput->header.hDevice = UlongToHandle( msg_data->rawinput.device ); - rawinput->header.wParam = msg_data->rawinput.wparam; - - if (msg_data->rawinput.type == RIM_TYPEMOUSE) - { - if (size != sizeof(RAWMOUSE)) return FALSE; - rawinput->data.mouse = *(RAWMOUSE *)(msg_data + 1); - } - else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD) - { - if (size != sizeof(RAWKEYBOARD)) return FALSE; - rawinput->data.keyboard = *(RAWKEYBOARD *)(msg_data + 1); - } - else if (msg_data->rawinput.type == RIM_TYPEHID) - { - RAWHID *hid = (RAWHID *)(msg_data + 1); - if (size < offsetof(RAWHID, bRawData[0])) return FALSE; - if (size != offsetof(RAWHID, bRawData[hid->dwCount * hid->dwSizeHid])) return FALSE; - memcpy( &rawinput->data.hid, msg_data + 1, size ); - } - else - { - FIXME( "Unhandled rawinput type %#x.\n", msg_data->rawinput.type ); - return FALSE; - } - - return TRUE; -} - struct device { HANDLE file; @@ -552,69 +507,83 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade /********************************************************************** * NtUserGetRawInputData (win32u.@) */ -UINT WINAPI NtUserGetRawInputData( HRAWINPUT rawinput, UINT command, void *data, UINT *data_size, UINT header_size ) +UINT WINAPI NtUserGetRawInputData( HRAWINPUT handle, UINT command, void *data, UINT *data_size, UINT header_size ) { - struct rawinput_thread_data *thread_data; - UINT size; - - TRACE( "rawinput %p, command %#x, data %p, data_size %p, header_size %u.\n", - rawinput, command, data, data_size, header_size ); + struct user_thread_info *thread_info = get_user_thread_info(); + struct hardware_msg_data *msg_data; + RAWINPUT *rawinput = data; + UINT size = 0;
- if (!(thread_data = get_rawinput_thread_data())) - { - RtlSetLastWin32Error( ERROR_OUTOFMEMORY ); - return ~0u; - } + TRACE( "handle %p, command %#x, data %p, data_size %p, header_size %u.\n", + handle, command, data, data_size, header_size );
- if (!rawinput || thread_data->hw_id != (UINT_PTR)rawinput) + if (!(msg_data = thread_info->rawinput) || msg_data->hw_id != (UINT_PTR)handle) { RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); - return ~0u; + return -1; }
if (header_size != sizeof(RAWINPUTHEADER)) { WARN( "Invalid structure size %u.\n", header_size ); RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); - return ~0u; - } - - switch (command) - { - case RID_INPUT: - size = thread_data->buffer->header.dwSize; - break; - - case RID_HEADER: - size = sizeof(RAWINPUTHEADER); - break; - - default: - RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); - return ~0u; + return -1; } + if (command != RID_HEADER && command != RID_INPUT) goto failed; + if (command == RID_INPUT) size = msg_data->size - sizeof(*msg_data);
if (!data) { - *data_size = size; + *data_size = sizeof(RAWINPUTHEADER) + size; return 0; }
- if (*data_size < size) + if (*data_size < sizeof(RAWINPUTHEADER) + size) { RtlSetLastWin32Error( ERROR_INSUFFICIENT_BUFFER ); - return ~0u; + return -1; + } + + rawinput->header.dwType = msg_data->rawinput.type; + rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + msg_data->size - sizeof(*msg_data); + rawinput->header.hDevice = UlongToHandle( msg_data->rawinput.device ); + rawinput->header.wParam = msg_data->rawinput.wparam; + if (command == RID_HEADER) return sizeof(RAWINPUTHEADER); + + if (msg_data->rawinput.type == RIM_TYPEMOUSE) + { + if (size != sizeof(RAWMOUSE)) goto failed; + rawinput->data.mouse = *(RAWMOUSE *)(msg_data + 1); + } + else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD) + { + if (size != sizeof(RAWKEYBOARD)) goto failed; + rawinput->data.keyboard = *(RAWKEYBOARD *)(msg_data + 1); + } + else if (msg_data->rawinput.type == RIM_TYPEHID) + { + RAWHID *hid = (RAWHID *)(msg_data + 1); + if (size < offsetof(RAWHID, bRawData[0])) goto failed; + if (size != offsetof(RAWHID, bRawData[hid->dwCount * hid->dwSizeHid])) goto failed; + memcpy( &rawinput->data.hid, msg_data + 1, size ); + } + else + { + FIXME( "Unhandled rawinput type %#x.\n", msg_data->rawinput.type ); + goto failed; } - memcpy( data, thread_data->buffer, size ); - return size; + + return rawinput->header.dwSize; + +failed: + WARN( "Invalid command %u or data size %u.\n", command, size ); + RtlSetLastWin32Error( ERROR_INVALID_PARAMETER ); + return -1; }
BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_data *msg_data ) { - struct rawinput_thread_data *thread_data; - - if (!(thread_data = get_rawinput_thread_data())) - return FALSE; + struct user_thread_info *thread_info = get_user_thread_info();
if (msg->message == WM_INPUT_DEVICE_CHANGE) { @@ -624,9 +593,10 @@ BOOL process_rawinput_message( MSG *msg, UINT hw_id, const struct hardware_msg_d } else { - thread_data->buffer->header.dwSize = RAWINPUT_BUFFER_SIZE; - if (!rawinput_from_hardware_message( thread_data->buffer, msg_data )) return FALSE; - thread_data->hw_id = hw_id; + struct hardware_msg_data *tmp; + if (!(tmp = realloc( thread_info->rawinput, msg_data->size ))) return FALSE; + memcpy( tmp, msg_data, msg_data->size ); + thread_info->rawinput = tmp; msg->lParam = (LPARAM)hw_id; }
This merge request was approved by Alexandre Julliard.