user32/tests: Add GetRawInputBuffer tests.

Signed-off-by: Rémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rémi Bernon 2020-06-25 19:08:40 +02:00 committed by Alexandre Julliard
parent ab6f8ba0d1
commit 083cb5c783
1 changed files with 247 additions and 0 deletions

View File

@ -85,6 +85,7 @@ static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEP
static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT);
static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, void *, UINT *);
static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, void *, UINT *);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#define MAXKEYEVENTS 12
#define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one
@ -147,6 +148,7 @@ static BYTE InputKeyStateTable[256];
static BYTE AsyncKeyStateTable[256];
static BYTE TrackSysKey = 0; /* determine whether ALT key up will cause a WM_SYSKEYUP
or a WM_KEYUP message */
static BOOL is_wow64;
static void init_function_pointers(void)
{
@ -162,7 +164,13 @@ static void init_function_pointers(void)
GET_PROC(GetRawInputDeviceList);
GET_PROC(GetRawInputDeviceInfoW);
GET_PROC(GetRawInputDeviceInfoA);
hdll = GetModuleHandleA("kernel32");
GET_PROC(IsWow64Process);
#undef GET_PROC
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 ))
is_wow64 = FALSE;
}
static int KbdMessage( KEV kev, WPARAM *pwParam, LPARAM *plParam )
@ -1820,6 +1828,244 @@ static void test_RegisterRawInputDevices(void)
DestroyWindow(hwnd);
}
static int rawinputbuffer_wndproc_count;
#ifdef _WIN64
typedef RAWINPUT RAWINPUT64;
#else
typedef struct
{
RAWINPUTHEADER header;
char pad[8];
union {
RAWMOUSE mouse;
RAWKEYBOARD keyboard;
RAWHID hid;
} data;
} RAWINPUT64;
#endif
static int rawinput_buffer_mouse_x(void *buffer, size_t index)
{
if (is_wow64) return ((RAWINPUT64 *)buffer)[index].data.mouse.lLastX;
return ((RAWINPUT *)buffer)[index].data.mouse.lLastX;
}
static LRESULT CALLBACK rawinputbuffer_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
RAWINPUT ri;
char buffer[16 * sizeof(RAWINPUT64)];
UINT size, count, rawinput_size, iteration = rawinputbuffer_wndproc_count++;
MSG message;
if (is_wow64) rawinput_size = sizeof(RAWINPUT64);
else rawinput_size = sizeof(RAWINPUT);
if (msg == WM_INPUT)
{
count = GetRawInputBuffer(NULL, NULL, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
size = sizeof(buffer);
count = GetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER));
ok(count == 0, "GetRawInputBuffer returned %u\n", count);
todo_wine
ok(size == rawinput_size, "GetRawInputBuffer returned unexpected size: %u\n", size);
size = sizeof(buffer);
memset(buffer, 0, sizeof(buffer));
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == 3, "GetRawInputBuffer returned %u\n", count);
ok(size == sizeof(buffer), "GetRawInputBuffer returned unexpected size: %u\n", size);
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 0) == 2, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 0));
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 1) == 3, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 1));
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 2) == 4, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 2));
/* the first event should be removed by the next GetRawInputBuffer call
* and the others should do another round through the message loop but not more */
if (iteration == 0)
{
mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 6, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 2, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 3, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 4, 0, 0, 0);
/* even though rawinput_size is the minimum required size,
* it needs one more byte to return success */
size = rawinput_size + 1;
memset(buffer, 0, sizeof(buffer));
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == 1, "GetRawInputBuffer returned %u\n", count);
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 0) == 5, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 0));
/* peek the messages now, they should still arrive in the correct order */
while (PeekMessageA(&message, 0, WM_INPUT, WM_INPUT, PM_REMOVE)) DispatchMessageA(&message);
}
/* reading the message data now should fail on the second iteration, the data
* from the first message has been overwritten. */
size = sizeof(ri);
memset(&ri, 0, sizeof(ri));
count = GetRawInputData((HRAWINPUT)lparam, RID_INPUT, &ri, &size, sizeof(RAWINPUTHEADER));
if (iteration == 1)
{
ok(count == sizeof(ri), "GetRawInputData failed\n");
todo_wine
ok(ri.data.mouse.lLastX == 6, "Unexpected rawinput data: %d\n", ri.data.mouse.lLastX);
}
else
{
todo_wine
ok(count == ~0U, "GetRawInputData succeeded\n");
}
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
static void test_GetRawInputBuffer(void)
{
RAWINPUTDEVICE raw_devices[1];
char buffer[16 * sizeof(RAWINPUT64)];
UINT size, count, rawinput_size;
HWND hwnd;
BOOL ret;
if (is_wow64) rawinput_size = sizeof(RAWINPUT64);
else rawinput_size = sizeof(RAWINPUT);
hwnd = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONG_PTR)rawinputbuffer_wndproc);
ok(hwnd != 0, "CreateWindow failed\n");
empty_message_queue();
raw_devices[0].usUsagePage = 0x01;
raw_devices[0].usUsage = 0x02;
raw_devices[0].dwFlags = RIDEV_INPUTSINK;
raw_devices[0].hwndTarget = hwnd;
SetLastError(0xdeadbeef);
ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
ok(ret, "RegisterRawInputDevices failed\n");
ok(GetLastError() == 0xdeadbeef, "RegisterRawInputDevices returned %08x\n", GetLastError());
SetLastError(0xdeadbeef);
count = GetRawInputBuffer(NULL, NULL, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08x\n", GetLastError());
size = sizeof(buffer);
count = GetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER));
ok(count == 0U, "GetRawInputBuffer returned %u\n", count);
todo_wine
ok(size == 0U, "GetRawInputBuffer returned unexpected size: %u\n", size);
size = 0;
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
ok(count == 0U, "GetRawInputBuffer returned %u\n", count);
ok(size == 0U, "GetRawInputBuffer returned unexpected size: %u\n", size);
SetLastError(0xdeadbeef);
size = sizeof(buffer);
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, 0);
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08x\n", GetLastError());
size = sizeof(buffer);
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
ok(count == 0U, "GetRawInputBuffer returned %u\n", count);
todo_wine
ok(size == 0U, "GetRawInputBuffer returned unexpected size: %u\n", size);
mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
SetLastError(0xdeadbeef);
size = 0;
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
todo_wine
ok(size == rawinput_size, "GetRawInputBuffer returned unexpected size: %u\n", size);
todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetRawInputBuffer returned %08x\n", GetLastError());
size = 0;
count = GetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER));
ok(count == 0, "GetRawInputBuffer returned %u\n", count);
todo_wine
ok(size == rawinput_size, "GetRawInputBuffer returned unexpected size: %u\n", size);
SetLastError(0xdeadbeef);
size = sizeof(buffer);
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, 0);
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetRawInputBuffer returned %08x\n", GetLastError());
size = sizeof(buffer);
memset(buffer, 0, sizeof(buffer));
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == 1U, "GetRawInputBuffer returned %u\n", count);
ok(size == sizeof(buffer), "GetRawInputBuffer returned unexpected size: %u\n", size);
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 0) == 5, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 0));
/* NOTE: calling with size == rawinput_size returns an error, */
/* BUT it fills the buffer nonetheless and empties the internal buffer (!!) */
mouse_event(MOUSEEVENTF_MOVE, 5, 0, 0, 0);
SetLastError(0xdeadbeef);
size = rawinput_size;
memset(buffer, 0, sizeof(buffer));
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
todo_wine
ok(count == ~0U, "GetRawInputBuffer succeeded\n");
todo_wine
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetRawInputBuffer returned %08x\n", GetLastError());
todo_wine
ok(rawinput_buffer_mouse_x(buffer, 0) == 5, "Unexpected rawinput data: %d\n", rawinput_buffer_mouse_x(buffer, 0));
size = sizeof(buffer);
count = GetRawInputBuffer((RAWINPUT*)buffer, &size, sizeof(RAWINPUTHEADER));
ok(count == 0U, "GetRawInputBuffer returned %u\n", count);
rawinputbuffer_wndproc_count = 0;
mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 2, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 3, 0, 0, 0);
mouse_event(MOUSEEVENTF_MOVE, 4, 0, 0, 0);
empty_message_queue();
todo_wine
ok(rawinputbuffer_wndproc_count == 2, "Spurious WM_INPUT messages\n");
raw_devices[0].dwFlags = RIDEV_REMOVE;
raw_devices[0].hwndTarget = 0;
SetLastError(0xdeadbeef);
ret = RegisterRawInputDevices(raw_devices, ARRAY_SIZE(raw_devices), sizeof(RAWINPUTDEVICE));
ok(ret, "RegisterRawInputDevices failed\n");
ok(GetLastError() == 0xdeadbeef, "RegisterRawInputDevices returned %08x\n", GetLastError());
DestroyWindow(hwnd);
}
static BOOL rawinput_test_received_legacy;
static BOOL rawinput_test_received_raw;
static BOOL rawinput_test_received_rawfg;
@ -3522,6 +3768,7 @@ START_TEST(input)
test_GetKeyState();
test_OemKeyScan();
test_GetRawInputData();
test_GetRawInputBuffer();
test_RegisterRawInputDevices();
test_rawinput(argv[0]);