winebus.sys: Correctly set HID device input number in device endpoint path.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Aric Stewart <aric@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6a0005747c
commit
8cd6d61639
|
@ -43,7 +43,7 @@ void *get_platform_private(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
|
||||||
/* HID Plug and Play Bus */
|
/* HID Plug and Play Bus */
|
||||||
NTSTATUS WINAPI common_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) DECLSPEC_HIDDEN;
|
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,
|
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;
|
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;
|
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;
|
void bus_remove_hid_device(DEVICE_OBJECT *device) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -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)
|
if (!device)
|
||||||
ERR("Failed to create device\n");
|
ERR("Failed to create device\n");
|
||||||
else
|
else
|
||||||
|
|
|
@ -941,7 +941,8 @@ static void try_add_device(SDL_JoystickID index)
|
||||||
is_xbox_gamepad = (axis_count == 6 && button_count >= 14);
|
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)
|
if (device)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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,
|
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;
|
DWORD bus_type;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
@ -1110,6 +1110,12 @@ static int parse_uevent_info(const char *uevent, DWORD *vendor_id,
|
||||||
found_serial = 1;
|
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:
|
next_line:
|
||||||
line = strtok_r(NULL, "\n", &saveptr);
|
line = strtok_r(NULL, "\n", &saveptr);
|
||||||
|
@ -1128,6 +1134,7 @@ static void try_add_device(struct udev_device *dev)
|
||||||
const char *devnode;
|
const char *devnode;
|
||||||
WCHAR *serial = NULL;
|
WCHAR *serial = NULL;
|
||||||
BOOL is_gamepad = FALSE;
|
BOOL is_gamepad = FALSE;
|
||||||
|
WORD input = -1;
|
||||||
int fd;
|
int fd;
|
||||||
static const CHAR *base_serial = "0000";
|
static const CHAR *base_serial = "0000";
|
||||||
|
|
||||||
|
@ -1162,7 +1169,7 @@ static void try_add_device(struct udev_device *dev)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
parse_uevent_info(udev_device_get_sysattr_value(hiddev, "uevent"),
|
parse_uevent_info(udev_device_get_sysattr_value(hiddev, "uevent"),
|
||||||
&vid, &pid, &serial);
|
&vid, &pid, &input, &serial);
|
||||||
if (serial == NULL)
|
if (serial == NULL)
|
||||||
serial = strdupAtoW(base_serial);
|
serial = strdupAtoW(base_serial);
|
||||||
}
|
}
|
||||||
|
@ -1205,13 +1212,13 @@ static void try_add_device(struct udev_device *dev)
|
||||||
|
|
||||||
if (strcmp(subsystem, "hidraw") == 0)
|
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));
|
&GUID_DEVCLASS_HIDRAW, &hidraw_vtbl, sizeof(struct platform_private));
|
||||||
}
|
}
|
||||||
#ifdef HAS_PROPER_INPUT_HEADER
|
#ifdef HAS_PROPER_INPUT_HEADER
|
||||||
else if (strcmp(subsystem, "input") == 0)
|
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));
|
&GUID_DEVCLASS_LINUXEVENT, &lnxev_vtbl, sizeof(struct wine_input_private));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -71,7 +71,7 @@ struct device_extension
|
||||||
{
|
{
|
||||||
struct pnp_device *pnp_device;
|
struct pnp_device *pnp_device;
|
||||||
|
|
||||||
WORD vid, pid;
|
WORD vid, pid, input;
|
||||||
DWORD uid, version, index;
|
DWORD uid, version, index;
|
||||||
BOOL is_gamepad;
|
BOOL is_gamepad;
|
||||||
WCHAR *serial;
|
WCHAR *serial;
|
||||||
|
@ -119,15 +119,15 @@ void *get_platform_private(DEVICE_OBJECT *device)
|
||||||
return ext->platform_private;
|
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;
|
struct pnp_device *ptr;
|
||||||
DWORD index = 1;
|
DWORD index = 0;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(ptr, &pnp_devset, struct pnp_device, entry)
|
LIST_FOR_EACH_ENTRY(ptr, &pnp_devset, struct pnp_device, entry)
|
||||||
{
|
{
|
||||||
struct device_extension *ext = (struct device_extension *)ptr->device->DeviceExtension;
|
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);
|
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 WCHAR *get_instance_id(DEVICE_OBJECT *device)
|
||||||
{
|
{
|
||||||
static const WCHAR formatW[] = {'%','s','\\','V','i','d','_','%','0','4','x','&', 'P','i','d','_','%','0','4','x','&',
|
static const WCHAR formatW[] = {'%','s','\\','v','i','d','_','%','0','4','x','&','p','i','d','_','%','0','4','x',
|
||||||
'%','s','_','%','i','\\','%','i','&','%','s','&','%','x',0};
|
'\\','%','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;
|
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
|
||||||
const WCHAR *serial = ext->serial ? ext->serial : zero_serialW;
|
const WCHAR *serial = ext->serial ? ext->serial : zero_serialW;
|
||||||
DWORD len = strlenW(ext->busid) + strlenW(serial) + 64;
|
DWORD len = strlenW(ext->busid) + strlenW(serial) + 64;
|
||||||
WCHAR *dst;
|
WCHAR *dst;
|
||||||
|
|
||||||
if ((dst = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
|
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;
|
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,
|
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)
|
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};
|
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;
|
NTSTATUS status;
|
||||||
DWORD length;
|
DWORD length;
|
||||||
|
|
||||||
TRACE("(%p, %s, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver, debugstr_w(busidW), vid, pid,
|
TRACE("(%p, %s, %04x, %04x, %04x, %u, %u, %s, %u, %s, %p, %u)\n", driver,
|
||||||
version, uid, debugstr_w(serialW), is_gamepad, debugstr_guid(class), vtbl, platform_data_size);
|
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))))
|
if (!(pnp_dev = HeapAlloc(GetProcessHeap(), 0, sizeof(*pnp_dev))))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -236,9 +249,10 @@ DEVICE_OBJECT *bus_create_hid_device(DRIVER_OBJECT *driver, const WCHAR *busidW,
|
||||||
ext->pnp_device = pnp_dev;
|
ext->pnp_device = pnp_dev;
|
||||||
ext->vid = vid;
|
ext->vid = vid;
|
||||||
ext->pid = pid;
|
ext->pid = pid;
|
||||||
|
ext->input = input;
|
||||||
ext->uid = uid;
|
ext->uid = uid;
|
||||||
ext->version = version;
|
ext->version = version;
|
||||||
ext->index = get_vidpid_index(vid, pid);
|
ext->index = get_device_index(vid, pid, input);
|
||||||
ext->is_gamepad = is_gamepad;
|
ext->is_gamepad = is_gamepad;
|
||||||
ext->serial = strdupW(serialW);
|
ext->serial = strdupW(serialW);
|
||||||
ext->busid = busidW;
|
ext->busid = busidW;
|
||||||
|
|
Loading…
Reference in New Issue