[PATCH 7/8] winexinput.sys: Return native product strings on some devices.

Zebediah Figura zfigura at codeweavers.com
Mon Sep 6 12:06:50 CDT 2021


On 9/6/21 1:40 AM, Rémi Bernon wrote:
> Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
> ---
>   dlls/winexinput.sys/main.c | 53 ++++++++++++++++++++++++++++++++++++++
>   1 file changed, 53 insertions(+)
> 
> diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c
> index 724552cfcac..c61839b4a88 100644
> --- a/dlls/winexinput.sys/main.c
> +++ b/dlls/winexinput.sys/main.c
> @@ -32,6 +32,7 @@
>   #include "ddk/wdm.h"
>   #include "ddk/hidport.h"
>   #include "ddk/hidpddi.h"
> +#include "ddk/hidtypes.h"
>   
>   #include "wine/asm.h"
>   #include "wine/debug.h"
> @@ -314,17 +315,69 @@ 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&IG_00", .product = L"Controller (XBOX 360 For Windows)" },
> +    { .id = L"VID_045E&PID_028F&IG_00", .product = L"Controller (XBOX 360 For Windows)" },
> +    { .id = L"VID_045E&PID_02D1&IG_00", .product = L"Controller (XBOX One For Windows)" },
> +    { .id = L"VID_045E&PID_02DD&IG_00", .product = L"Controller (XBOX One For Windows)" },
> +    { .id = L"VID_045E&PID_02E3&IG_00", .product = L"Controller (XBOX One For Windows)" },
> +    { .id = L"VID_045E&PID_02EA&IG_00", .product = L"Controller (XBOX One For Windows)" },
> +    { .id = L"VID_045E&PID_02FD&IG_00", .product = L"Controller (XBOX One For Windows)" },
> +    { .id = L"VID_045E&PID_0719&IG_00", .product = L"Controller (XBOX 360 For Windows)" },
> +};
> +
>   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, *match_id;
> +    DWORD i;
>   
>       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:
> +            match_id = wcsrchr(impl->device_id, '\\') + 1;
> +            for (i = 0; i < ARRAY_SIZE(device_strings); ++i)
> +                if (!wcsicmp(device_strings[i].id, match_id))
> +                    break;
> +            if (i < ARRAY_SIZE(device_strings)) str = device_strings[i].product;
> +            break;

Just a suggestion, really, but this might be cleaner as a helper function?

> +        }
> +
> +        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-devel mailing list