From: "Vincas Miliƫnas" Subject: [PATCH 1/9] user32/tests: Added client-side raw input function tests (try 8) Message-Id: <4E07CD12.7060004@gmail.com> Date: Mon, 27 Jun 2011 03:21:38 +0300 Feedback - http://www.winehq.org/pipermail/wine-devel/2011-June/090805.html Changelog: * Split the patch into parts for each function * Everyone is telling not to commit unused code (considering each part of a patch individually), thus the solution is to cram all the component modifications in a single patch, so let's call it server+user32 for now... * Removed todo_wine, once implementation of a function is added * Added setting of required buffer size parameter in case of an insufficient buffer error --- dlls/user32/tests/input.c | 556 +++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 556 insertions(+), 0 deletions(-) diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index d45edf1..205d0ec 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -77,6 +77,19 @@ static struct { static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD); +static LRESULT (WINAPI *pDefRawInputProc) (PRAWINPUT *, INT, UINT); +static UINT (WINAPI *pGetRawInputBuffer) (PRAWINPUT, PUINT, UINT); +static INT (WINAPI *pGetRawInputData) (HRAWINPUT, UINT, LPVOID, PUINT, UINT); +static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT); +static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, LPVOID, PUINT); +static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, LPVOID, PUINT); +static UINT (WINAPI *pGetRegisteredRawInputDevices) (PRAWINPUTDEVICE, PUINT, UINT); +static BOOL (WINAPI *pRegisterRawInputDevices) (PRAWINPUTDEVICE, UINT, UINT); + +#define MOUSE_USAGE_PAGE 0x01 +#define MOUSE_USAGE_ID 0x02 +#define KEYBOARD_USAGE_PAGE 0x01 +#define KEYBOARD_USAGE_ID 0x06 #define MAXKEYEVENTS 12 #define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one @@ -160,6 +173,14 @@ static void init_function_pointers(void) GET_PROC(SendInput) GET_PROC(GetMouseMovePointsEx) + GET_PROC(DefRawInputProc) + GET_PROC(GetRawInputBuffer) + GET_PROC(GetRawInputData) + GET_PROC(GetRawInputDeviceList) + GET_PROC(GetRawInputDeviceInfoA) + GET_PROC(GetRawInputDeviceInfoW) + GET_PROC(GetRegisteredRawInputDevices) + GET_PROC(RegisterRawInputDevices) #undef GET_PROC } @@ -1598,6 +1619,531 @@ static void test_keyboard_layout_name(void) ok(!strcmp(klid, "00000409"), "expected 00000409, got %s\n", klid); } +static void test_get_raw_input_device_list(void) +{ + RAWINPUTDEVICELIST *device_list; + UINT ret, count, count2; + DWORD error; + + if (!pGetRawInputDeviceList) + { + win_skip("GetRawInputDeviceList is not available\n"); + return; + } + + count = 0; + ret = pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); + todo_wine ok(ret == 0 && count >= 1, "Given (NULL, &count, sizeof), " + "GetRawInputDeviceList should return the number of raw input devices\n"); + + device_list = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST)); + memset(device_list, 0xFF, count * sizeof(RAWINPUTDEVICELIST)); + + SetLastError(0xdeadbeef); + count2 = 0; + ret = pGetRawInputDeviceList(device_list, &count2, sizeof(RAWINPUTDEVICELIST)); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INSUFFICIENT_BUFFER && count2 == count, + "Given (device_list, &count2 = 0, sizeof), GetRawInputDeviceList should return " + "an error but got a wrong one: %u\n", error); + + count2 = count; + ret = pGetRawInputDeviceList(device_list, &count2, sizeof(RAWINPUTDEVICELIST)); + ok(ret == count && count == count2, "Given (device_list, &count2 = count, sizeof), " + "GetRawInputDeviceList should return the list of raw input devices\n"); + + todo_wine ok(device_list[0].hDevice != NULL, "First device should have a non-null handle\n"); + ok(device_list[0].dwType == RIM_TYPEMOUSE || device_list[0].dwType == RIM_TYPEKEYBOARD, + "First device should be a mouse or a keyboard"); + + HeapFree(GetProcessHeap(), 0, device_list); +} + +static void test_register_raw_input_devices(void) +{ + RAWINPUTDEVICE device; + BOOL ret; + DWORD error; + + if (!pRegisterRawInputDevices) + { + win_skip("RegisterRawInputDevices is not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pRegisterRawInputDevices(NULL, 0, 0); + error = GetLastError(); + todo_wine ok(ret == FALSE && error == ERROR_INVALID_PARAMETER, "Given (NULL, 0, 0), " + "RegisterRawInputDevices should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pRegisterRawInputDevices(NULL, 0, sizeof(RAWINPUTDEVICE)); + error = GetLastError(); + todo_wine ok(ret == FALSE && error == ERROR_INVALID_PARAMETER, "Given (NULL, 0, sizeof), " + "RegisterRawInputDevices should return an error but got a wrong one: %u\n", error); + + device.usUsagePage = 0; + device.usUsage = 0; + device.dwFlags = 0; + device.hwndTarget = 0; + SetLastError(0xdeadbeef); + ret = pRegisterRawInputDevices(&device, 0, sizeof(RAWINPUTDEVICE)); + error = GetLastError(); + todo_wine ok(ret == FALSE && error == ERROR_INVALID_PARAMETER, "Given (&device, 0, sizeof), " + "RegisterRawInputDevices should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + error = GetLastError(); + todo_wine ok(ret == FALSE && error == ERROR_INVALID_PARAMETER, "Given (&device{0,0,0,0}, 1, sizeof), " + "RegisterRawInputDevices should return an error but got a wrong one: %u\n", error); + + device.usUsagePage = MOUSE_USAGE_PAGE; + device.usUsage = MOUSE_USAGE_ID; + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,0,0}, 1, sizeof), " + "RegisterRawInputDevices should successfully subscribe to a mouse raw input device\n"); + + device.dwFlags = RIDEV_REMOVE; + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,RIDEV_REMOVE,0}, 1, sizeof), " + "RegisterRawInputDevices should successfully unsubscribe from a mouse raw input device\n"); + + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,RIDEV_REMOVE,0}, 1, sizeof), " + "RegisterRawInputDevices should return success even if already unsubscribed\n"); +} + +static void test_get_raw_input_data(void) +{ + UINT ret, count; + DWORD error; + + if (!pGetRawInputData) + { + win_skip("GetRawInputData is not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pGetRawInputData(NULL, 0, NULL, NULL, 0); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, "Given (NULL, 0, NULL, NULL, 0), " + "GetRawInputData should return an error, but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRawInputData(NULL, 0, NULL, NULL, sizeof(RAWINPUTHEADER)); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_HANDLE, "Given (NULL, 0, NULL, NULL, sizeof), " + "GetRawInputData should return an error, but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRawInputData(NULL, 0, NULL, &count, 1); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, "Given (NULL, 0, NULL, &count, 1), " + "GetRawInputData should return an error, but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRawInputData(NULL, 0, NULL, &count, sizeof(RAWINPUTHEADER)); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_HANDLE, "Given (NULL, 0, NULL, &count, sizeof), " + "GetRawInputData should return an error, but got a wrong one: %u\n", error); +} + +static BOOL get_raw_input_data_wnd_proc_was_called; + +static LRESULT CALLBACK get_raw_input_data_wnd_proc( HWND hWnd, UINT msg, WPARAM wParam, + LPARAM lParam ) +{ + RAWINPUTDEVICE devices[2]; + UINT dwSize, ret2; + RAWINPUT *raw; + BOOL ret; + LRESULT ret3; + + devices[0].usUsagePage = MOUSE_USAGE_PAGE; + devices[0].usUsage = MOUSE_USAGE_ID; + devices[0].dwFlags = 0; + devices[0].hwndTarget = hWnd; + + devices[1].usUsagePage = KEYBOARD_USAGE_PAGE; + devices[1].usUsage = KEYBOARD_USAGE_ID; + devices[1].dwFlags = 0; + devices[1].hwndTarget = hWnd; + + switch (msg) + { + case WM_CREATE: + ret = pRegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE)); + ok(ret, "Failed to register raw input devices: %u\n", GetLastError()); + break; + + case WM_DESTROY: + devices[0].dwFlags = RIDEV_REMOVE; + devices[0].hwndTarget = 0; + devices[1].dwFlags = RIDEV_REMOVE; + devices[1].hwndTarget = 0; + ret = pRegisterRawInputDevices(devices, 2, sizeof(RAWINPUTDEVICE)); + ok(ret, "Failed to unregister raw input devices: %u\n", GetLastError()); + break; + + case WM_INPUT: + ret2 = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)); + ok(ret2 == 0, "Failed to retrieve raw input data size\n"); + if (!(raw = HeapAlloc(GetProcessHeap(), 0, dwSize))) + break; + ret2 = pGetRawInputData((HRAWINPUT)lParam, RID_INPUT, raw, &dwSize, sizeof(RAWINPUTHEADER)); + ok(ret2 == dwSize, "Failed to retrieve raw input data\n"); + ok(raw->header.dwType == RIM_TYPEMOUSE || raw->header.dwType == RIM_TYPEKEYBOARD, + "Raw input data entry must be from mouse or keyboard\n"); + ret3 = pDefRawInputProc(&raw, 1, sizeof(RAWINPUTHEADER)); + HeapFree(GetProcessHeap(), 0, raw); + get_raw_input_data_wnd_proc_was_called = TRUE; + return ret3; + } + return DefWindowProcW(hWnd, msg, wParam, lParam); +} + +#define ID_TIMER 1 + +static BOOL get_raw_input_data_wnd_proc_timeout; + +static void timer_proc(HWND hParent, UINT uMsg, UINT uEventID, DWORD dwTimer) +{ + get_raw_input_data_wnd_proc_timeout = TRUE; + /* Rerun message loop */ + PostMessage(hParent, WM_USER + 100, 0, 0); +} + +static void test_get_raw_input_data_simulation(void) +{ + HWND hWnd; + MSG msg; + WNDCLASSA wclass; + HANDLE hInstance = GetModuleHandleA( NULL ); + BOOL ret; + INPUT inputs[2]; + UINT timer, size, ret2; + RAWINPUT *raw; + + if (!pRegisterRawInputDevices || !pGetRawInputData || !pDefRawInputProc || !pGetRawInputBuffer || !pSendInput) + { + win_skip("Functions required to perform raw input simulation are not available\n"); + return; + } + + wclass.lpszClassName = "GetRawInputDataTestClass"; + wclass.style = CS_HREDRAW | CS_VREDRAW; + wclass.lpfnWndProc = get_raw_input_data_wnd_proc; + wclass.hInstance = hInstance; + wclass.hIcon = LoadIconA( 0, IDI_APPLICATION ); + wclass.hCursor = LoadCursorA( NULL, IDC_ARROW ); + wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 ); + wclass.lpszMenuName = 0; + wclass.cbClsExtra = 0; + wclass.cbWndExtra = 0; + RegisterClassA( &wclass ); + + hWnd = CreateWindowA( wclass.lpszClassName, "GetRawInputDataTest", + WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100, + NULL, NULL, hInstance, NULL); + assert( hWnd ); + ShowWindow( hWnd, SW_SHOW); + SetWindowPos( hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE ); + SetForegroundWindow( hWnd ); + UpdateWindow( hWnd ); + SetFocus( hWnd ); + + memset(inputs, 0, sizeof(inputs)); + inputs[0].type = INPUT_KEYBOARD; + inputs[0].ki.wVk = 0x20; + inputs[1].type = INPUT_MOUSE; + inputs[1].mi.dx = inputs[1].mi.dy = 15; + inputs[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + pSendInput(2, inputs, sizeof(INPUT)); + + timer = SetTimer(hWnd, ID_TIMER, 3000, (TIMERPROC)timer_proc); + + get_raw_input_data_wnd_proc_was_called = FALSE; + + while((ret = GetMessage(&msg, 0, 0, 0)) && !get_raw_input_data_wnd_proc_was_called && !get_raw_input_data_wnd_proc_timeout) + { + if (ret == -1) + break; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + KillTimer(hWnd, ID_TIMER); + + ok(ret != -1, "Error getting window message: %u\n", GetLastError()); + todo_wine ok(get_raw_input_data_wnd_proc_was_called, "WM_INPUT was not received\n"); + + DestroyWindow(hWnd); + + /* clear raw input buffer */ + ret2 = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + if (ret2 == 0 && size > 0 && (raw = HeapAlloc(GetProcessHeap(), 0, size * sizeof(RAWINPUT)))) + { + pGetRawInputBuffer(raw, &size, sizeof(RAWINPUTHEADER)); + HeapFree(GetProcessHeap(), 0, raw); + } +} + +static void test_get_raw_input_buffer(void) +{ + UINT ret, size; + DWORD error; + + if (!pGetRawInputBuffer) + { + win_skip("GetRawInputBuffer is not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pGetRawInputBuffer(NULL, NULL, 0); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, + "Given (NULL, NULL, 0), GetRawInputBuffer should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRawInputBuffer(NULL, NULL, sizeof(RAWINPUTHEADER)); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, + "Given (NULL, NULL, sizeof), GetRawInputBuffer should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRawInputBuffer(NULL, &size, 1); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, + "Given (NULL, &size, 1), GetRawInputBuffer should return an error but got a wrong one: %u\n", error); + + size = (UINT)-1; + ret = pGetRawInputBuffer(NULL, &size, sizeof(RAWINPUTHEADER)); + todo_wine ok(ret == 0 && size == 0, "Given (NULL, &size, sizeof), " + "GetRawInputBuffer should that no data is buffered\n"); +} + +static void test_get_raw_input_device_info_a(void) +{ + UINT ret, size = 0, count; + RAWINPUTDEVICELIST *devices; + char buffer[1024]; + RID_DEVICE_INFO info; + DWORD error; + + if (!pGetRawInputDeviceInfoA || !pGetRawInputDeviceList) + { + win_skip("GetRawInputDeviceInfoA and pGetRawInputDeviceList are not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pGetRawInputDeviceInfoA(NULL, 0, NULL, NULL); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_NOACCESS, "Given (NULL, 0, NULL, NULL), " + "GetRawInputDeviceInfoA should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoA(NULL, 0, NULL, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_HANDLE, "Given (NULL, 0, NULL, &size), " + "GetRawInputDeviceInfoA should return an error but got a wrong one: %u\n", error); + + ok(pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) == 0, "Failed to get raw input device count\n"); + todo_wine ok(count > 0, "Should have at least one raw input device available\n"); + ok((devices = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST))) != NULL, "Failed to allocate memory for devices\n"); + ok(pGetRawInputDeviceList(devices, &count, sizeof(RAWINPUTDEVICELIST)) == count, "Failed to retrieve raw input device list"); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoA(devices[0].hDevice, 0, NULL, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, + "Given (hDevice, 0, NULL, &size), GetRawInputDeviceInfoA should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoA(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INSUFFICIENT_BUFFER, + "Given (hDevice, RIDI_DEVICENAME, buffer, &size = 0), GetRawInputDeviceInfoA should return an error but got a wrong one: %u\n", error); + + size = 0; + ret = pGetRawInputDeviceInfoA(devices[0].hDevice, RIDI_DEVICENAME, NULL, &size); + todo_wine ok(ret == 0 && size > 0, "Given (hDevice, RIDI_DEVICENAME, NULL, &size), " + "GetRawInputDeviceInfoA should return the required size to retrieve the device info\n"); + + buffer[0] = 0; + ret = pGetRawInputDeviceInfoA(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); + todo_wine ok(ret != (UINT)-1 && size > 0 && strlen(buffer) > 5, + "Given (hDevice, RIDI_DEVICENAME, buffer, &size), GetRawInputDeviceInfoA should retrieve device name\n"); + + size = sizeof(RID_DEVICE_INFO); + info.cbSize = sizeof(RID_DEVICE_INFO); + ret = pGetRawInputDeviceInfoA(devices[0].hDevice, RIDI_DEVICEINFO, &info, &size); + todo_wine ok(ret != (UINT)-1 && ret > 0 && size > 0, "Given (hDevice, RIDI_DEVICEINFO, &info, &size), " + "GetRawInputDeviceInfoA should retrieve the device info\n"); + + HeapFree(GetProcessHeap(), 0, devices); +} + +static void test_get_raw_input_device_info_w(void) +{ + UINT ret, size = 0, count; + RAWINPUTDEVICELIST *devices; + WCHAR buffer[1024]; + RID_DEVICE_INFO info; + DWORD error; + + if (!pGetRawInputDeviceInfoW || !pGetRawInputDeviceList) + { + win_skip("GetRawInputDeviceInfoW and pGetRawInputDeviceList are not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pGetRawInputDeviceInfoW(NULL, 0, NULL, NULL); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_NOACCESS, "Given (NULL, 0, NULL, NULL), " + "GetRawInputDeviceInfoW should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoW(NULL, 0, NULL, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_HANDLE, "Given (NULL, 0, NULL, &size), " + "GetRawInputDeviceInfoW should return an error but got a wrong one: %u\n", error); + + ok(pGetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) == 0, "Failed to get raw input device count\n"); + todo_wine ok(count > 0, "Should have at least one raw input device available\n"); + ok((devices = HeapAlloc(GetProcessHeap(), 0, count * sizeof(RAWINPUTDEVICELIST))) != NULL, "Failed to allocate memory for devices\n"); + ok(pGetRawInputDeviceList(devices, &count, sizeof(RAWINPUTDEVICELIST)) == count, "Failed to retrieve raw input device list"); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoW(devices[0].hDevice, 0, NULL, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, "Given (hDevice, 0, NULL, &size), " + "GetRawInputDeviceInfoW should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + size = 0; + ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INSUFFICIENT_BUFFER, "Given (hDevice, RIDI_DEVICENAME, buffer, &size = 0), " + "GetRawInputDeviceInfoW should return an error but got a wrong one: %u\n", error); + + size = 0; + ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, NULL, &size); + todo_wine ok(ret == 0 && size > 0, "Given (hDevice, RIDI_DEVICENAME, NULL, &size), " + "GetRawInputDeviceInfoW should return the required size to retrieve the device info\n"); + + buffer[0] = 0; + ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICENAME, buffer, &size); + todo_wine ok(ret != (UINT)-1 && size > 0 && lstrlenW(buffer) > 5, "Given (hDevice, RIDI_DEVICENAME, buffer, &size), " + "GetRawInputDeviceInfoW should retrieve the device name\n"); + + size = sizeof(RID_DEVICE_INFO); + info.cbSize = sizeof(RID_DEVICE_INFO); + ret = pGetRawInputDeviceInfoW(devices[0].hDevice, RIDI_DEVICEINFO, &info, &size); + todo_wine ok(ret != (UINT)-1 && ret > 0 && size > 0, "Given (hDevice, RIDI_DEVICEINFO, &info, &size), " + "GetRawInputDeviceInfoW should retrieve the device info\n"); + + HeapFree(GetProcessHeap(), 0, devices); +} + +static void test_get_registered_raw_input_devices(void) +{ + RAWINPUTDEVICE device, device2; + UINT ret, count; + DWORD error; + + if (!pGetRegisteredRawInputDevices || !pRegisterRawInputDevices) + { + win_skip("GetRegisteredRawInputDevices and pRegisterRawInputDevices are not available\n"); + return; + } + + SetLastError(0xdeadbeef); + ret = pGetRegisteredRawInputDevices(NULL, NULL, 0); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, "Given (NULL, NULL, 0), " + "GetRegisteredRawInputDevices should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRegisteredRawInputDevices(NULL, NULL, sizeof(RAWINPUTDEVICE)); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_NOACCESS, "Given (NULL, NULL, sizeof), " + "GetRegisteredRawInputDevices should return an error but got a wrong one: %u\n", error); + + SetLastError(0xdeadbeef); + ret = pGetRegisteredRawInputDevices(NULL, &count, 1); + error = GetLastError(); + todo_wine ok(ret == (UINT)-1 && error == ERROR_INVALID_PARAMETER, "Given (NULL, &count, 1), " + "GetRegisteredRawInputDevices should return an error but got a wrong one: %u\n", error); + + count = 0xdeadbeef; + ret = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); + todo_wine ok(ret == 0 && count == 0, "Given (NULL, &count, sizeof), " + "GetRegisteredRawInputDevices should return that no devices are registered\n"); + + device.usUsagePage = MOUSE_USAGE_PAGE; + device.usUsage = MOUSE_USAGE_ID; + device.dwFlags = 0; + device.hwndTarget = 0; + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,0,0}, 1, sizeof), " + "RegisterRawInputDevices should successfully subscribe to a mouse raw input device\n"); + + ret = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); + todo_wine ok(ret == 0 && count == 1, "Given (NULL, &count, sizeof), " + "GetRegisteredRawInputDevices should return that one device is registered\n"); + + memset(&device2, 0xFF, sizeof(RAWINPUTDEVICE)); + ret = pGetRegisteredRawInputDevices(&device2, &count, sizeof(RAWINPUTDEVICE)); + todo_wine ok(ret == 1 && memcmp(&device, &device2, sizeof(RAWINPUTDEVICE)) == 0, + "Given (&device2, &count, sizeof), GetRegisteredRawInputDevices should return an identical device to the one registered\n"); + + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,0,0}, 1, sizeof), " + "RegisterRawInputDevices should successfully reregister a device\n"); + + memset(&device2, 0xFF, sizeof(RAWINPUTDEVICE)); + ret = pGetRegisteredRawInputDevices(&device2, &count, sizeof(RAWINPUTDEVICE)); + todo_wine ok(ret == 1 && memcmp(&device, &device2, sizeof(RAWINPUTDEVICE)) == 0, + "Given (&device2, &count, sizeof), GetRegisteredRawInputDevices should still return one device registered\n"); + + device.dwFlags = RIDEV_REMOVE; + ret = pRegisterRawInputDevices(&device, 1, sizeof(RAWINPUTDEVICE)); + ok(ret == TRUE, "Given (&device{1,2,RIDEV_REMOVE,0}, 1, sizeof), " + "RegisterRawInputDevices should successfully unsubscribe from a mouse raw input device\n"); + + count = 0xdeadbeef; + ret = pGetRegisteredRawInputDevices(NULL, &count, sizeof(RAWINPUTDEVICE)); + todo_wine ok(ret == 0 && count == 0, "Given (NULL, &count, sizeof), " + "GetRegisteredRawInputDevices should return that no devices are registered\n"); +} + +static void test_def_raw_input_proc(void) +{ + RAWINPUT *input = NULL; + LRESULT ret; + + if (!pDefRawInputProc) + { + win_skip("DefRawInputProc is not available\n"); + return; + } + + ret = pDefRawInputProc(&input, 0, sizeof(RAWINPUTHEADER)); + ok(ret == S_OK, "Given (&input, 0, sizeof), " + "DefRawInputProc should acknowledge that no data was provided\n"); +} + START_TEST(input) { init_function_pointers(); @@ -1617,6 +2163,16 @@ START_TEST(input) test_get_async_key_state(); test_keyboard_layout_name(); + test_get_raw_input_device_list(); + test_register_raw_input_devices(); + test_get_raw_input_data(); + test_get_raw_input_buffer(); + test_get_raw_input_device_info_a(); + test_get_raw_input_device_info_w(); + test_get_registered_raw_input_devices(); + test_def_raw_input_proc(); + test_get_raw_input_data_simulation(); + if(pGetMouseMovePointsEx) test_GetMouseMovePointsEx(); else