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