diff --git a/dlls/winebus.sys/bus.h b/dlls/winebus.sys/bus.h index 16e9bf7d540..df39fb9ce7c 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 41a383d76aa..86f32b69a26 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 cd69f831d76..01eb36e516e 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 be953db4396..bb6c9329833 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 094a25d0258..0abadf4160e 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;