From: Rémi Bernon rbernon@codeweavers.com
--- dlls/user32/tests/input.c | 14 +-------- dlls/win32u/rawinput.c | 60 ++++++++++++++------------------------- server/protocol.def | 2 +- server/queue.c | 8 ++++-- 4 files changed, 29 insertions(+), 55 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 6a96b0da5be..3a8cfec9460 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -1907,7 +1907,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" );
@@ -1917,12 +1916,9 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara if (is_wow64) { RAWINPUT64 *rawinput = (RAWINPUT64 *)(buffer + i * rawinput_size); - todo_wine_if(is_wow64 && i > 0 && iteration == 0) ok_eq( RIM_TYPEKEYBOARD, rawinput->header.dwType, UINT, "%u" ); - todo_wine_if(is_wow64 && i > 0 && iteration == 0) ok_eq( rawinput_size, rawinput->header.dwSize, UINT, "%u" ); ok_eq( wparam, rawinput->header.wParam, WPARAM, "%Iu" ); - todo_wine_if(is_wow64 && (iteration == 1 || i > 0)) ok_eq( i + 2, rawinput->data.keyboard.MakeCode, WPARAM, "%Iu" ); } else @@ -1950,9 +1946,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 */ @@ -1991,7 +1986,6 @@ static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wpara size = sizeof(rawinput); rawinput_size = sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD); 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 ); @@ -2005,7 +1999,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() ); @@ -2162,7 +2155,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); @@ -2204,9 +2196,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; @@ -2222,9 +2212,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 e6c442c6ba6..1305985dd49 100644 --- a/dlls/win32u/rawinput.c +++ b/dlls/win32u/rawinput.c @@ -92,7 +92,7 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har }; unsigned int i;
- rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWMOUSE); + rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + sizeof(RAWMOUSE); rawinput->header.hDevice = WINE_MOUSE_HANDLE; rawinput->header.wParam = 0;
@@ -136,7 +136,7 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har } else if (msg_data->rawinput.type == RIM_TYPEKEYBOARD) { - rawinput->header.dwSize = FIELD_OFFSET(RAWINPUT, data) + sizeof(RAWKEYBOARD); + rawinput->header.dwSize = sizeof(RAWINPUTHEADER) + sizeof(RAWKEYBOARD); rawinput->header.hDevice = WINE_KEYBOARD_HANDLE; rawinput->header.wParam = 0;
@@ -177,7 +177,7 @@ static bool rawinput_from_hardware_message( RAWINPUT *rawinput, const struct har 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.dwSize = FIELD_OFFSET( RAWINPUT, data.hid.bRawData[size] ); rawinput->header.hDevice = ULongToHandle( msg_data->rawinput.hid.device ); rawinput->header.wParam = 0;
@@ -614,29 +614,27 @@ 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; + unsigned int count = 0, remaining, next_size; struct rawinput_thread_data *thread_data; struct hardware_msg_data *msg_data; RAWINPUT *rawinput; + UINT_PTR align; int i;
- if (NtCurrentTeb()->WowTebOffset) - rawinput_size = sizeof(RAWINPUT64); - else - rawinput_size = sizeof(RAWINPUT); - overhead = rawinput_size - sizeof(RAWINPUT); + if (NtCurrentTeb()->WowTebOffset) align = sizeof(UINT) - 1; + else align = sizeof(UINT_PTR) - 1;
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) @@ -644,26 +642,26 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade 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->header_size = header_size; req->buffer_size = 0; - if (wine_server_call( req )) return ~0u; + if (wine_server_call_err( req )) return -1; *data_size = reply->next_size; } SERVER_END_REQ; return 0; }
- if (!(thread_data = get_rawinput_thread_data())) return ~0u; + if (!(thread_data = get_rawinput_thread_data())) return -1; 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->header_size = header_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; + if (wine_server_call_err( req )) return -1; next_size = reply->next_size; count = reply->count; } @@ -672,42 +670,26 @@ UINT WINAPI NtUserGetRawInputBuffer( RAWINPUT *data, UINT *data_size, UINT heade remaining = *data_size; for (i = 0; i < count; ++i) { + UINT_PTR next = (UINT_PTR)data; 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); + next = (next + data->header.dwSize + align) & ~align; + remaining -= (char *)next - (char *)data; + data = (RAWINPUT *)next; }
if (!next_size) { - if (!count) - *data_size = 0; - else - next_size = rawinput_size; + if (count) next_size = sizeof(RAWINPUT); + else *data_size = 0; }
if (next_size && *data_size <= next_size) { RtlSetLastWin32Error( ERROR_INSUFFICIENT_BUFFER ); *data_size = next_size; - count = ~0u; + count = -1; }
TRACE( "data %p, data_size %p (%u), header_size %u, count %u\n", diff --git a/server/protocol.def b/server/protocol.def index 5d60e7fcda3..1e047162082 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3783,7 +3783,7 @@ struct handle_info
/* Batch read rawinput message data */ @REQ(get_rawinput_buffer) - data_size_t rawinput_size; /* size of RAWINPUT structure */ + data_size_t header_size; /* size of RAWINPUTHEADER structure */ data_size_t buffer_size; /* size of output buffer */ @REPLY data_size_t next_size; /* minimum size to get next message data */ diff --git a/server/queue.c b/server/queue.c index cd913ae03e5..b8ff71b0cdb 100644 --- a/server/queue.c +++ b/server/queue.c @@ -3447,12 +3447,16 @@ DECL_HANDLER(get_rawinput_buffer) { 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); + data_size_t data_size, extra_size = data->size - sizeof(*data);
ptr = list_next( &input->msg_list, ptr ); if (msg->msg != WM_INPUT) continue;
- next_size = req->rawinput_size + extra_size; + if (data->rawinput.type == RIM_TYPEKEYBOARD) data_size = sizeof(RAWKEYBOARD); + else if (data->rawinput.type == RIM_TYPEMOUSE) data_size = sizeof(RAWMOUSE); + else data_size = sizeof(RAWHID); + + next_size = req->header_size + data_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)