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;