Rémi Bernon : hidclass.sys: Move product string overrides from winexinput.sys.
Alexandre Julliard
julliard at winehq.org
Tue Oct 5 15:51:41 CDT 2021
Module: wine
Branch: master
Commit: 60ef452922ddae15007764ae6450590d1abee6fe
URL: https://source.winehq.org/git/wine.git/?a=commit;h=60ef452922ddae15007764ae6450590d1abee6fe
Author: Rémi Bernon <rbernon at codeweavers.com>
Date: Tue Oct 5 09:11:54 2021 +0200
hidclass.sys: Move product string overrides from winexinput.sys.
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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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;
More information about the wine-cvs
mailing list