diff -urN wine-3.9-orig/dlls/user32/input.c wine-3.9/dlls/user32/input.c
--- wine-3.9-orig/dlls/user32/input.c	2018-05-26 03:38:57 +0900
+++ wine-3.9/dlls/user32/input.c	2018-05-28 15:50:11 +0900
@@ -523,7 +523,11 @@
 */
 UINT WINAPI GetRawInputDeviceList(RAWINPUTDEVICELIST *devices, UINT *device_count, UINT size)
 {
-    TRACE("devices %p, device_count %p, size %u.\n", devices, device_count, size);
+    int num_devices;
+    const char *xinput_str;
+    int i;
+
+    TRACE("devices %p, device_count %p (%d), size %u.\n", devices, device_count, device_count ? *device_count : 0, size);
 
     if (size != sizeof(*devices))
     {
@@ -537,16 +541,27 @@
         return ~0U;
     }
 
+    num_devices = 2;
+    xinput_str = getenv("WINEXINPUTDEVICES");
+    if (xinput_str)
+    {
+        int xinput_count = atoi(xinput_str);
+        if (xinput_count > 4)
+            num_devices += 4;
+        else if (xinput_count > 0)
+            num_devices += xinput_count;
+    }
+
     if (!devices)
     {
-        *device_count = 2;
+        *device_count = num_devices;
         return 0;
     }
 
-    if (*device_count < 2)
+    if (*device_count < num_devices)
     {
         SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        *device_count = 2;
+        *device_count = num_devices;
         return ~0U;
     }
 
@@ -554,8 +569,12 @@
     devices[0].dwType = RIM_TYPEMOUSE;
     devices[1].hDevice = WINE_KEYBOARD_HANDLE;
     devices[1].dwType = RIM_TYPEKEYBOARD;
+    for (i = 2; i < num_devices; i++) {
+        devices[i].hDevice = WINE_XINPUT_HANDLE(i-2);
+        devices[i].dwType = RIM_TYPEHID;
+    }
 
-    return 2;
+    return num_devices;
 }
 
 
@@ -664,7 +683,7 @@
 {
     UINT ret;
 
-    TRACE("device %p, command %u, data %p, data_size %p.\n", device, command, data, data_size);
+    TRACE("device %p, command %u, data %p, data_size %p (%d).\n", device, command, data, data_size, data_size ? *data_size : 0);
 
     ret = GetRawInputDeviceInfoW(device, command, data, data_size);
     if (command == RIDI_DEVICENAME && ret && ret != ~0U)
@@ -682,15 +701,23 @@
     /* FIXME: Most of this is made up. */
     static const WCHAR keyboard_name[] = {'\\','\\','?','\\','W','I','N','E','_','K','E','Y','B','O','A','R','D',0};
     static const WCHAR mouse_name[] = {'\\','\\','?','\\','W','I','N','E','_','M','O','U','S','E',0};
+    static const WCHAR xinput_name[] = {'\\','\\','?','\\','W','I','N','E','_','X','I','N','P','U','T','&','I','G','_','0','0',0};
+    WCHAR xinput_namebuf[22];
     static const RID_DEVICE_INFO_KEYBOARD keyboard_info = {0, 0, 1, 12, 3, 101};
     static const RID_DEVICE_INFO_MOUSE mouse_info = {1, 5, 0, FALSE};
+    static const RID_DEVICE_INFO_HID xinput_info = {0, 0, 0, 1, 4};
     const WCHAR *name = NULL;
     RID_DEVICE_INFO *info;
     UINT s;
 
-    TRACE("device %p, command %u, data %p, data_size %p.\n", device, command, data, data_size);
+    TRACE("device %p, command %u, data %p, data_size %p (%d).\n", device, command, data, data_size, data_size ? *data_size : 0);
 
-    if (!data_size || (device != WINE_MOUSE_HANDLE && device != WINE_KEYBOARD_HANDLE)) return ~0U;
+    if (!data_size || (device != WINE_MOUSE_HANDLE &&
+                       device != WINE_KEYBOARD_HANDLE &&
+                       device != WINE_XINPUT_HANDLE(0) &&
+                       device != WINE_XINPUT_HANDLE(1) &&
+                       device != WINE_XINPUT_HANDLE(2) &&
+                       device != WINE_XINPUT_HANDLE(3))) return ~0U;
 
     switch (command)
     {
@@ -700,11 +727,19 @@
             s = sizeof(mouse_name);
             name = mouse_name;
         }
-        else
+        else if (device == WINE_KEYBOARD_HANDLE)
         {
             s = sizeof(keyboard_name);
             name = keyboard_name;
         }
+        else
+        {
+            assert(sizeof(xinput_namebuf) >= sizeof(xinput_name));
+            memcpy(xinput_namebuf, xinput_name, sizeof(xinput_name));
+            xinput_namebuf[(sizeof(xinput_name)/2)-2] = '0' + ((char *)device - (char *)WINE_XINPUT_HANDLE(0));
+            s = sizeof(xinput_name);
+            name = xinput_namebuf;
+        }
         break;
     case RIDI_DEVICEINFO:
         s = sizeof(*info);
@@ -738,11 +773,16 @@
         info->dwType = RIM_TYPEMOUSE;
         info->u.mouse = mouse_info;
     }
-    else
+    else if (device == WINE_KEYBOARD_HANDLE)
     {
         info->dwType = RIM_TYPEKEYBOARD;
         info->u.keyboard = keyboard_info;
     }
+    else
+    {
+        info->dwType = RIM_TYPEHID;
+        info->u.hid = xinput_info;
+    }
     return s;
 }
 
diff -urN wine-3.9-orig/dlls/user32/user_private.h wine-3.9/dlls/user32/user_private.h
--- wine-3.9-orig/dlls/user32/user_private.h	2018-05-26 03:38:57 +0900
+++ wine-3.9/dlls/user32/user_private.h	2018-05-28 15:50:11 +0900
@@ -39,6 +39,7 @@
 
 #define WINE_MOUSE_HANDLE       ((HANDLE)1)
 #define WINE_KEYBOARD_HANDLE    ((HANDLE)2)
+#define WINE_XINPUT_HANDLE(n)   ((HANDLE)(3+(n)))
 
 struct window_surface;
 
