Piotr Caban : winebus.sys: Correctly set HID device input number in device endpoint path.

Alexandre Julliard julliard at winehq.org
Wed May 15 16:18:26 CDT 2019


Module: wine
Branch: master
Commit: 8cd6d6163983d9ea07fb9e6eb4e263f8a8ffb1f6
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8cd6d6163983d9ea07fb9e6eb4e263f8a8ffb1f6

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed May 15 14:56:05 2019 +0200

winebus.sys: Correctly set HID device input number in device endpoint path.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Aric Stewart <aric at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winebus.sys/bus.h       |  2 +-
 dlls/winebus.sys/bus_iohid.c |  3 ++-
 dlls/winebus.sys/bus_sdl.c   |  3 ++-
 dlls/winebus.sys/bus_udev.c  | 15 +++++++++++----
 dlls/winebus.sys/main.c      | 38 ++++++++++++++++++++++++++------------
 5 files changed, 42 insertions(+), 19 deletions(-)

diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h
index 16e9bf7..df39fb9 100644
--- a/dlls/winebus.sys/bus.h
+++ b/dlls/winebus.sys/bus.h
@@ -43,7 +43,7 @@ void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
 /* HID Plug and Play Bus */
 NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
 DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid,
-                                     DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
+                                     WORD input, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
                                      const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size) DECLSPEC_HIDDEN;
 DEVICE_OBJECT *bus_find_hid_device(const platform_vtbl *vtbl, void *platform_dev) DECLSPEC_HIDDEN;
 void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index 41a383d..86f32b6 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -345,7 +345,8 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
         }
     }
 
-    device = bus_create_hid_device(iohid_driver_obj, busidW, vid, pid, version, uid, str?serial_string:NULL, is_gamepad, &GUID_DEVCLASS_IOHID, &iohid_vtbl, sizeof(struct platform_private));
+    device = bus_create_hid_device(iohid_driver_obj, busidW, vid, pid, -1, version, uid, str?serial_string:NULL,
+            is_gamepad, &GUID_DEVCLASS_IOHID, &iohid_vtbl, sizeof(struct platform_private));
     if (!device)
         ERR("Failed to create device\n");
     else
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index cd69f83..01eb36e 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -941,7 +941,8 @@ static void try_add_device(SDL_JoystickID index)
         is_xbox_gamepad = (axis_count == 6  && button_count >= 14);
     }
 
-    device = bus_create_hid_device(sdl_driver_obj, sdl_busidW, vid, pid, version, id, serial, is_xbox_gamepad, &GUID_DEVCLASS_SDL, &sdl_vtbl, sizeof(struct platform_private));
+    device = bus_create_hid_device(sdl_driver_obj, sdl_busidW, vid, pid, -1, version, id, serial,
+            is_xbox_gamepad, &GUID_DEVCLASS_SDL, &sdl_vtbl, sizeof(struct platform_private));
 
     if (device)
     {
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index be953db..bb6c932 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -1064,7 +1064,7 @@ static int check_same_device(DEVICE_OBJECT *device, void* context)
 }
 
 static int parse_uevent_info(const char *uevent, DWORD *vendor_id,
-                             DWORD *product_id, WCHAR **serial_number)
+                             DWORD *product_id, WORD *input, WCHAR **serial_number)
 {
     DWORD bus_type;
     char *tmp;
@@ -1110,6 +1110,12 @@ static int parse_uevent_info(const char *uevent, DWORD *vendor_id,
                 found_serial = 1;
             }
         }
+        else if (strcmp(key, "HID_PHYS") == 0)
+        {
+            const char *input_no = strstr(value, "input");
+            if (input_no)
+                *input = atoi(input_no+5 );
+        }
 
 next_line:
         line = strtok_r(NULL, "\n", &saveptr);
@@ -1128,6 +1134,7 @@ static void try_add_device(struct udev_device *dev)
     const char *devnode;
     WCHAR *serial = NULL;
     BOOL is_gamepad = FALSE;
+    WORD input = -1;
     int fd;
     static const CHAR *base_serial = "0000";
 
@@ -1162,7 +1169,7 @@ static void try_add_device(struct udev_device *dev)
         }
 #endif
         parse_uevent_info(udev_device_get_sysattr_value(hiddev, "uevent"),
-                          &vid, &pid, &serial);
+                          &vid, &pid, &input, &serial);
         if (serial == NULL)
             serial = strdupAtoW(base_serial);
     }
@@ -1205,13 +1212,13 @@ static void try_add_device(struct udev_device *dev)
 
     if (strcmp(subsystem, "hidraw") == 0)
     {
-        device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, vid, pid, version, 0, serial, is_gamepad,
+        device = bus_create_hid_device(udev_driver_obj, hidraw_busidW, vid, pid, input, version, 0, serial, is_gamepad,
                                        &GUID_DEVCLASS_HIDRAW, &hidraw_vtbl, sizeof(struct platform_private));
     }
 #ifdef HAS_PROPER_INPUT_HEADER
     else if (strcmp(subsystem, "input") == 0)
     {
-        device = bus_create_hid_device(udev_driver_obj, lnxev_busidW, vid, pid, version, 0, serial, is_gamepad,
+        device = bus_create_hid_device(udev_driver_obj, lnxev_busidW, vid, pid, input, version, 0, serial, is_gamepad,
                                        &GUID_DEVCLASS_LINUXEVENT, &lnxev_vtbl, sizeof(struct wine_input_private));
     }
 #endif
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 094a25d..0abadf4 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -71,7 +71,7 @@ struct device_extension
 {
     struct pnp_device *pnp_device;
 
-    WORD vid, pid;
+    WORD vid, pid, input;
     DWORD uid, version, index;
     BOOL is_gamepad;
     WCHAR *serial;
@@ -119,15 +119,15 @@ void *get_platform_private(DEVICE_OBJECT *device)
     return ext->platform_private;
 }
 
-static DWORD get_vidpid_index(WORD vid, WORD pid)
+static DWORD get_device_index(WORD vid, WORD pid, WORD input)
 {
     struct pnp_device *ptr;
-    DWORD index = 1;
+    DWORD index = 0;
 
     LIST_FOR_EACH_ENTRY(ptr, &pnp_devset, struct pnp_device, entry)
     {
         struct device_extension *ext = (struct device_extension *)ptr->device->DeviceExtension;
-        if (ext->vid == vid && ext->pid == pid)
+        if (ext->vid == vid && ext->pid == pid && ext->input == input)
             index = max(ext->index + 1, index);
     }
 
@@ -136,16 +136,28 @@ static DWORD get_vidpid_index(WORD vid, WORD pid)
 
 static WCHAR *get_instance_id(DEVICE_OBJECT *device)
 {
-    static const WCHAR formatW[] =  {'%','s','\\','V','i','d','_','%','0','4','x','&', 'P','i','d','_','%','0','4','x','&',
-                                     '%','s','_','%','i','\\','%','i','&','%','s','&','%','x',0};
+    static const WCHAR formatW[] =  {'%','s','\\','v','i','d','_','%','0','4','x','&','p','i','d','_','%','0','4','x',
+                                     '\\','%','i','&','%','s','&','%','x','&','%','i',0};
+    static const WCHAR format_inputW[] = {'%','s','\\','v','i','d','_','%','0','4','x','&','p','i','d','_','%','0','4','x','&',
+                                     '%','s','_','%','i','\\','%','i','&','%','s','&','%','x','&','%','i',0};
     struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
     const WCHAR *serial = ext->serial ? ext->serial : zero_serialW;
     DWORD len = strlenW(ext->busid) + strlenW(serial) + 64;
     WCHAR *dst;
 
     if ((dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
-        sprintfW(dst, formatW, ext->busid, ext->vid, ext->pid, ext->is_gamepad ? igW : miW,
-                 ext->index, ext->version, serial, ext->uid);
+    {
+        if (ext->input == (WORD)-1)
+        {
+            sprintfW(dst, formatW, ext->busid, ext->vid, ext->pid,
+                    ext->version, serial, ext->uid, ext->index);
+        }
+        else
+        {
+            sprintfW(dst, format_inputW, ext->busid, ext->vid, ext->pid, ext->is_gamepad ? igW : miW,
+                    ext->input, ext->version, serial, ext->uid, ext->index);
+        }
+    }
 
     return dst;
 }
@@ -197,7 +209,7 @@ static WCHAR *get_compatible_ids(DEVICE_OBJECT *device)
 }
 
 DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW, WORD vid, WORD pid,
-                                     DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
+                                     WORD input, DWORD version, DWORD uid, const WCHAR *serialW, BOOL is_gamepad,
                                      const GUID *class, const platform_vtbl *vtbl, DWORD platform_data_size)
 {
     static const WCHAR device_name_fmtW[] = {'\\','D','e','v','i','c','e','\\','%','s','#','%','p',0};
@@ -212,8 +224,9 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
     NTSTATUS status;
     DWORD length;
 
-    TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver, debugstr_w(busidW), vid, pid,
-          version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class), vtbl, platform_data_size);
+    TRACE("(%p, %s, %04x, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver,
+            debugstr_w(busidW), vid, pid, input, version, uid, debugstr_w(serialW),
+            is_gamepad, debugstr_guid(class), vtbl, platform_data_size);
 
     if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev))))
         return NULL;
@@ -236,9 +249,10 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
     ext->pnp_device         = pnp_dev;
     ext->vid                = vid;
     ext->pid                = pid;
+    ext->input              = input;
     ext->uid                = uid;
     ext->version            = version;
-    ext->index              = get_vidpid_index(vid, pid);
+    ext->index              = get_device_index(vid, pid, input);
     ext->is_gamepad         = is_gamepad;
     ext->serial             = strdupW(serialW);
     ext->busid              = busidW;




More information about the wine-cvs mailing list