From d1b19a2d0acad40ab8786f5d75c0cebd52ae6cf2 Mon Sep 17 00:00:00 2001 From: Andrew Eikum Date: Wed, 6 Mar 2019 08:21:32 -0600 Subject: [PATCH] user32: GetRawInputDeviceInfo uses characters for RIDI_DEVICENAME size. Signed-off-by: Andrew Eikum Signed-off-by: Alexandre Julliard --- dlls/user32/rawinput.c | 41 ++++++++++++++++++++++-------- dlls/user32/tests/input.c | 53 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/dlls/user32/rawinput.c b/dlls/user32/rawinput.c index b247c157dcc..2085fd3f9f1 100644 --- a/dlls/user32/rawinput.c +++ b/dlls/user32/rawinput.c @@ -329,16 +329,37 @@ UINT WINAPI DECLSPEC_HOTPATCH GetRawInputBuffer(RAWINPUT *data, UINT *data_size, */ UINT WINAPI GetRawInputDeviceInfoA(HANDLE device, UINT command, void *data, UINT *data_size) { - UINT ret; - TRACE("device %p, command %#x, data %p, data_size %p.\n", device, command, data, data_size); - ret = GetRawInputDeviceInfoW(device, command, data, data_size); - if (command == RIDI_DEVICENAME && ret && ret != ~0U) - ret = WideCharToMultiByte(CP_ACP, 0, data, -1, data, *data_size, NULL, NULL); + /* RIDI_DEVICENAME data_size is in chars, not bytes */ + if (command == RIDI_DEVICENAME) + { + WCHAR *nameW; + UINT ret, nameW_sz; - return ret; + if (!data_size) return ~0U; + + nameW_sz = *data_size; + + if (data && nameW_sz > 0) + nameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * nameW_sz); + else + nameW = NULL; + + ret = GetRawInputDeviceInfoW(device, command, nameW, &nameW_sz); + + if (ret && ret != ~0U) + WideCharToMultiByte(CP_ACP, 0, nameW, -1, data, *data_size, NULL, NULL); + + *data_size = nameW_sz; + + HeapFree(GetProcessHeap(), 0, nameW); + + return ret; + } + + return GetRawInputDeviceInfoW(device, command, data, data_size); } /*********************************************************************** @@ -366,18 +387,18 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT case RIDI_DEVICENAME: if (device == WINE_MOUSE_HANDLE) { - s = sizeof(mouse_name); + s = ARRAY_SIZE(mouse_name); name = mouse_name; } else if (device == WINE_KEYBOARD_HANDLE) { - s = sizeof(keyboard_name); + s = ARRAY_SIZE(keyboard_name); name = keyboard_name; } else { hid_device = device; - s = (strlenW(hid_device->path) + 1) * sizeof(WCHAR); + s = strlenW(hid_device->path) + 1; name = hid_device->path; } break; @@ -402,7 +423,7 @@ UINT WINAPI GetRawInputDeviceInfoW(HANDLE device, UINT command, void *data, UINT if (command == RIDI_DEVICENAME) { - memcpy(data, name, s); + memcpy(data, name, s * sizeof(WCHAR)); return s; } diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c index 835dfb108d1..625de3d7688 100644 --- a/dlls/user32/tests/input.c +++ b/dlls/user32/tests/input.c @@ -80,6 +80,8 @@ static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t); static BOOL (WINAPI *pGetCurrentInputMessageSource)( INPUT_MESSAGE_SOURCE *source ); static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD); static UINT (WINAPI *pGetRawInputDeviceList) (PRAWINPUTDEVICELIST, PUINT, UINT); +static UINT (WINAPI *pGetRawInputDeviceInfoW) (HANDLE, UINT, void *, UINT *); +static UINT (WINAPI *pGetRawInputDeviceInfoA) (HANDLE, UINT, void *, UINT *); #define MAXKEYEVENTS 12 #define MAXKEYMESSAGES MAXKEYEVENTS /* assuming a key event generates one @@ -164,6 +166,8 @@ static void init_function_pointers(void) GET_PROC(GetCurrentInputMessageSource); GET_PROC(GetMouseMovePointsEx); GET_PROC(GetRawInputDeviceList); + GET_PROC(GetRawInputDeviceInfoW); + GET_PROC(GetRawInputDeviceInfoA); #undef GET_PROC } @@ -1555,7 +1559,7 @@ static void test_GetMouseMovePointsEx(void) static void test_GetRawInputDeviceList(void) { RAWINPUTDEVICELIST devices[32]; - UINT ret, oret, devcount, odevcount; + UINT ret, oret, devcount, odevcount, i; DWORD err; SetLastError(0xdeadbeef); @@ -1587,6 +1591,53 @@ static void test_GetRawInputDeviceList(void) ret = pGetRawInputDeviceList(devices, &devcount, sizeof(devices[0])); ok(ret > 0, "expected non-zero\n"); + for(i = 0; i < devcount; ++i) + { + WCHAR name[128]; + char nameA[128]; + UINT sz, len; + RID_DEVICE_INFO info; + + /* get required buffer size */ + name[0] = '\0'; + sz = 5; + ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz); + ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err); + ok(sz > 5 && sz < ARRAY_SIZE(name), "Size should have been set and not too large (got: %u)\n", sz); + + /* buffer size for RIDI_DEVICENAME is in CHARs, not BYTEs */ + ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICENAME, name, &sz); + ok(ret == sz, "GetRawInputDeviceInfo gave wrong return: %d\n", err); + len = lstrlenW(name); + ok(len + 1 == ret, "GetRawInputDeviceInfo returned wrong length (name: %u, ret: %u)\n", len + 1, ret); + + /* test A variant with same size */ + ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, nameA, &sz); + ok(ret == sz, "GetRawInputDeviceInfoA gave wrong return: %d\n", err); + len = strlen(nameA); + ok(len + 1 == ret, "GetRawInputDeviceInfoA returned wrong length (name: %u, ret: %u)\n", len + 1, ret); + + /* buffer size for RIDI_DEVICEINFO is in BYTEs */ + memset(&info, 0, sizeof(info)); + info.cbSize = sizeof(info); + sz = sizeof(info) - 1; + ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz); + ok(ret == -1, "GetRawInputDeviceInfo gave wrong failure: %d\n", err); + ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n"); + + ret = pGetRawInputDeviceInfoW(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz); + ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err); + ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n"); + ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType); + + memset(&info, 0, sizeof(info)); + info.cbSize = sizeof(info); + ret = pGetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &info, &sz); + ok(ret == sizeof(info), "GetRawInputDeviceInfo gave wrong return: %d\n", err); + ok(sz == sizeof(info), "GetRawInputDeviceInfo set wrong size\n"); + ok(info.dwType == devices[i].dwType, "GetRawInputDeviceInfo set wrong type: 0x%x\n", info.dwType); + } + /* check if variable changes from larger to smaller value */ devcount = odevcount = ARRAY_SIZE(devices); oret = ret = pGetRawInputDeviceList(devices, &odevcount, sizeof(devices[0]));