Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This is a series of patches from Proton, improving the compatibility for some popular controllers.
dlls/winexinput.sys/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c index 79c566e7cc8..56d60f55570 100644 --- a/dlls/winexinput.sys/main.c +++ b/dlls/winexinput.sys/main.c @@ -325,11 +325,11 @@ static const struct device_strings device_strings[] = { { .id = L"VID_045E&PID_028E", .product = L"Controller (XBOX 360 For Windows)" }, { .id = L"VID_045E&PID_028F", .product = L"Controller (XBOX 360 For Windows)" }, - { .id = L"VID_045E&PID_02D1", .product = L"Controller (XBOX One For Windows)" }, - { .id = L"VID_045E&PID_02DD", .product = L"Controller (XBOX One For Windows)" }, - { .id = L"VID_045E&PID_02E3", .product = L"Controller (XBOX One For Windows)" }, - { .id = L"VID_045E&PID_02EA", .product = L"Controller (XBOX One For Windows)" }, - { .id = L"VID_045E&PID_02FD", .product = L"Controller (XBOX One For Windows)" }, + { .id = L"VID_045E&PID_02D1", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02DD", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02E3", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02EA", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02FD", .product = L"Controller (Xbox One For Windows)" }, { .id = L"VID_045E&PID_0719", .product = L"Controller (XBOX 360 For Windows)" }, };
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winexinput.sys/main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c index 56d60f55570..8ea9e160fc9 100644 --- a/dlls/winexinput.sys/main.c +++ b/dlls/winexinput.sys/main.c @@ -331,6 +331,10 @@ static const struct device_strings device_strings[] = { .id = L"VID_045E&PID_02EA", .product = L"Controller (Xbox One For Windows)" }, { .id = L"VID_045E&PID_02FD", .product = L"Controller (Xbox One For Windows)" }, { .id = L"VID_045E&PID_0719", .product = L"Controller (XBOX 360 For Windows)" }, + { .id = L"VID_045E&PID_0B00", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B05", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B12", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B13", .product = L"Controller (Xbox One For Windows)" }, };
static const WCHAR *find_product_string(const WCHAR *device_id)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winebus.sys/unixlib.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c index c9d5fa5fd43..790becf4bc3 100644 --- a/dlls/winebus.sys/unixlib.c +++ b/dlls/winebus.sys/unixlib.c @@ -53,6 +53,10 @@ BOOL is_xbox_gamepad(WORD vid, WORD pid) if (pid == 0x02e6) return TRUE; /* Wireless XBox Controller Dongle */ if (pid == 0x02ea) return TRUE; /* Xbox One S Controller */ if (pid == 0x02fd) return TRUE; /* Xbox One S Controller (Firmware 2017) */ + if (pid == 0x0b00) return TRUE; /* Xbox Elite 2 */ + if (pid == 0x0b05) return TRUE; /* Xbox Elite 2 Wireless */ + if (pid == 0x0b12) return TRUE; /* Xbox Series */ + if (pid == 0x0b13) return TRUE; /* Xbox Series Wireless */ if (pid == 0x0719) return TRUE; /* Xbox 360 Wireless Adapter */ return FALSE; }
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hidclass.sys/device.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index cebdc3e1e65..2e618df2927 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -404,25 +404,14 @@ static void handle_IOCTL_HID_GET_COLLECTION_DESCRIPTOR( IRP *irp, BASE_DEVICE_EX } }
-static void handle_minidriver_string( BASE_DEVICE_EXTENSION *ext, IRP *irp, SHORT index ) +static void handle_minidriver_string( BASE_DEVICE_EXTENSION *ext, IRP *irp, ULONG index ) { - IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); - WCHAR buffer[127]; - ULONG InputBuffer; - - InputBuffer = MAKELONG(index, 0); - - call_minidriver( IOCTL_HID_GET_STRING, ext->u.pdo.parent_fdo, ULongToPtr( InputBuffer ), - sizeof(InputBuffer), buffer, sizeof(buffer), &irp->IoStatus ); + IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); + WCHAR *output_buf = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); + ULONG output_len = stack->Parameters.DeviceIoControl.OutputBufferLength;
- if (irp->IoStatus.Status == STATUS_SUCCESS) - { - WCHAR *out_buffer = MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority); - int length = irpsp->Parameters.DeviceIoControl.OutputBufferLength/sizeof(WCHAR); - TRACE("got string %s from minidriver\n",debugstr_w(buffer)); - lstrcpynW(out_buffer, buffer, length); - irp->IoStatus.Information = (lstrlenW(buffer)+1) * sizeof(WCHAR); - } + call_minidriver( IOCTL_HID_GET_STRING, ext->u.pdo.parent_fdo, ULongToPtr( index ), + sizeof(index), output_buf, output_len, &irp->IoStatus ); }
static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP *irp )
Some games expect the DS4 gamepads to be named like native drivers, and they aren't detected xinput-compatible when access through hidraw, so it's not possible to override their product string in winexinput.sys.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hidclass.sys/device.c | 52 +++++++++++++++++++++++++++++-- dlls/winexinput.sys/main.c | 63 -------------------------------------- 2 files changed, 50 insertions(+), 65 deletions(-)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 2e618df2927..80cbcdae59a 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -404,14 +404,62 @@ static void handle_IOCTL_HID_GET_COLLECTION_DESCRIPTOR( IRP *irp, BASE_DEVICE_EX } }
+struct device_strings +{ + const WCHAR *id; + const WCHAR *product; +}; + +static const struct device_strings device_strings[] = +{ + { .id = L"VID_045E&PID_028E", .product = L"Controller (XBOX 360 For Windows)" }, + { .id = L"VID_045E&PID_028F", .product = L"Controller (XBOX 360 For Windows)" }, + { .id = L"VID_045E&PID_02D1", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02DD", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02E3", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02EA", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_02FD", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0719", .product = L"Controller (XBOX 360 For Windows)" }, + { .id = L"VID_045E&PID_0B00", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B05", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B12", .product = L"Controller (Xbox One For Windows)" }, + { .id = L"VID_045E&PID_0B13", .product = L"Controller (Xbox One For Windows)" }, +}; + +static const WCHAR *find_product_string( const WCHAR *device_id ) +{ + const WCHAR *match_id = wcsrchr( device_id, '\' ) + 1; + DWORD i; + + for (i = 0; i < ARRAY_SIZE(device_strings); ++i) + if (!wcsnicmp( device_strings[i].id, match_id, 17 )) + return device_strings[i].product; + + return NULL; +} + static void handle_minidriver_string( BASE_DEVICE_EXTENSION *ext, IRP *irp, ULONG index ) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation( irp ); WCHAR *output_buf = MmGetSystemAddressForMdlSafe( irp->MdlAddress, NormalPagePriority ); ULONG output_len = stack->Parameters.DeviceIoControl.OutputBufferLength; + const WCHAR *str = NULL;
- call_minidriver( IOCTL_HID_GET_STRING, ext->u.pdo.parent_fdo, ULongToPtr( index ), - sizeof(index), output_buf, output_len, &irp->IoStatus ); + if (index == HID_STRING_ID_IPRODUCT) str = find_product_string( ext->device_id ); + + if (!str) call_minidriver( IOCTL_HID_GET_STRING, ext->u.pdo.parent_fdo, ULongToPtr( index ), + sizeof(index), output_buf, output_len, &irp->IoStatus ); + else + { + irp->IoStatus.Information = (wcslen( str ) + 1) * sizeof(WCHAR); + if (irp->IoStatus.Information > output_len) + irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + else + { + memcpy( output_buf, str, irp->IoStatus.Information ); + irp->IoStatus.Status = STATUS_SUCCESS; + } + } }
static void hid_device_xfer_report( BASE_DEVICE_EXTENSION *ext, ULONG code, IRP *irp ) diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c index 8ea9e160fc9..d9a6fd5dd70 100644 --- a/dlls/winexinput.sys/main.c +++ b/dlls/winexinput.sys/main.c @@ -315,80 +315,17 @@ static NTSTATUS try_complete_pending_read(DEVICE_OBJECT *device, IRP *irp) return IoCallDriver(fdo->bus_device, xinput_irp); }
-struct device_strings -{ - const WCHAR *id; - const WCHAR *product; -}; - -static const struct device_strings device_strings[] = -{ - { .id = L"VID_045E&PID_028E", .product = L"Controller (XBOX 360 For Windows)" }, - { .id = L"VID_045E&PID_028F", .product = L"Controller (XBOX 360 For Windows)" }, - { .id = L"VID_045E&PID_02D1", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_02DD", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_02E3", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_02EA", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_02FD", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_0719", .product = L"Controller (XBOX 360 For Windows)" }, - { .id = L"VID_045E&PID_0B00", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_0B05", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_0B12", .product = L"Controller (Xbox One For Windows)" }, - { .id = L"VID_045E&PID_0B13", .product = L"Controller (Xbox One For Windows)" }, -}; - -static const WCHAR *find_product_string(const WCHAR *device_id) -{ - const WCHAR *match_id = wcsrchr(device_id, '\') + 1; - DWORD i; - - for (i = 0; i < ARRAY_SIZE(device_strings); ++i) - if (!wcsnicmp(device_strings[i].id, match_id, 17)) - return device_strings[i].product; - - return NULL; -} - static NTSTATUS WINAPI gamepad_internal_ioctl(DEVICE_OBJECT *device, IRP *irp) { IO_STACK_LOCATION *stack = IoGetCurrentIrpStackLocation(irp); ULONG output_len = stack->Parameters.DeviceIoControl.OutputBufferLength; ULONG code = stack->Parameters.DeviceIoControl.IoControlCode; struct func_device *fdo = fdo_from_DEVICE_OBJECT(device); - struct device *impl = impl_from_DEVICE_OBJECT(device); - const WCHAR *str = NULL;
TRACE("device %p, irp %p, code %#x, bus_device %p.\n", device, irp, code, fdo->bus_device);
switch (code) { - case IOCTL_HID_GET_STRING: - switch ((ULONG_PTR)stack->Parameters.DeviceIoControl.Type3InputBuffer) - { - case HID_STRING_ID_IPRODUCT: - str = find_product_string(impl->device_id); - break; - } - - if (!str) - { - IoSkipCurrentIrpStackLocation(irp); - return IoCallDriver(fdo->bus_device, irp); - } - - irp->IoStatus.Information = (wcslen(str) + 1) * sizeof(WCHAR); - if (output_len < irp->IoStatus.Information) - { - irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; - IoCompleteRequest(irp, IO_NO_INCREMENT); - return STATUS_BUFFER_TOO_SMALL; - } - - wcscpy(irp->UserBuffer, str); - irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - case IOCTL_HID_GET_DEVICE_DESCRIPTOR: { HID_DESCRIPTOR *descriptor = (HID_DESCRIPTOR *)irp->UserBuffer;
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/hidclass.sys/device.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/dlls/hidclass.sys/device.c b/dlls/hidclass.sys/device.c index 80cbcdae59a..29b9215aa22 100644 --- a/dlls/hidclass.sys/device.c +++ b/dlls/hidclass.sys/device.c @@ -412,6 +412,7 @@ struct device_strings
static const struct device_strings device_strings[] = { + /* Microsoft controllers */ { .id = L"VID_045E&PID_028E", .product = L"Controller (XBOX 360 For Windows)" }, { .id = L"VID_045E&PID_028F", .product = L"Controller (XBOX 360 For Windows)" }, { .id = L"VID_045E&PID_02D1", .product = L"Controller (Xbox One For Windows)" }, @@ -424,6 +425,11 @@ static const struct device_strings device_strings[] = { .id = L"VID_045E&PID_0B05", .product = L"Controller (Xbox One For Windows)" }, { .id = L"VID_045E&PID_0B12", .product = L"Controller (Xbox One For Windows)" }, { .id = L"VID_045E&PID_0B13", .product = L"Controller (Xbox One For Windows)" }, + /* Sony controllers */ + { .id = L"VID_054C&PID_05C4", .product = L"Wireless Controller" }, + { .id = L"VID_054C&PID_09CC", .product = L"Wireless Controller" }, + { .id = L"VID_054C&PID_0BA0", .product = L"Wireless Controller" }, + { .id = L"VID_054C&PID_0CE6", .product = L"Wireless Controller" }, };
static const WCHAR *find_product_string( const WCHAR *device_id )