user32: GetRawInputDeviceInfo uses characters for RIDI_DEVICENAME size.

Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Andrew Eikum 2019-03-06 08:21:32 -06:00 committed by Alexandre Julliard
parent 2ed529ca6d
commit d1b19a2d0a
2 changed files with 83 additions and 11 deletions

View File

@ -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;
}

View File

@ -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]));