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