Andrew Eikum : user32: GetRawInputDeviceInfo uses characters for RIDI_DEVICENAME size.
Alexandre Julliard
julliard at winehq.org
Wed Mar 6 15:29:40 CST 2019
Module: wine
Branch: master
Commit: d1b19a2d0acad40ab8786f5d75c0cebd52ae6cf2
URL: https://source.winehq.org/git/wine.git/?a=commit;h=d1b19a2d0acad40ab8786f5d75c0cebd52ae6cf2
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Wed Mar 6 08:21:32 2019 -0600
user32: GetRawInputDeviceInfo uses characters for RIDI_DEVICENAME size.
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 b247c15..2085fd3 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 835dfb1..625de3d 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]));
More information about the wine-cvs
mailing list