Commit 9479e217 authored by Rémi Bernon's avatar Rémi Bernon 💬 Committed by Alexandre Julliard
Browse files

hidclass.sys: Always read InputReportByteLength bytes when not polling.



This fixes several games (e.g. ICEY) not working well with DS4 gamepad
over bluetooth, as we fixup the input report sizes, and the game expects
them to be longer.
Signed-off-by: Rémi Bernon's avatarRémi Bernon <rbernon@codeweavers.com>
Signed-off-by: Alexandre Julliard's avatarAlexandre Julliard <julliard@winehq.org>
parent 095204a9
......@@ -2314,7 +2314,6 @@ static void test_hidp( HANDLE file, HANDLE async_file, int report_id, BOOL polle
ret = GetOverlappedResult( async_file, &overlapped, &value, TRUE );
ok( ret, "GetOverlappedResult failed, last error %u\n", GetLastError() );
todo_wine_if( report_id )
ok( value == caps.InputReportByteLength, "got length %u, expected %u\n", value, caps.InputReportByteLength );
CloseHandle( overlapped.hEvent );
......
......@@ -53,15 +53,16 @@ static void WINAPI read_cancel_routine(DEVICE_OBJECT *device, IRP *irp)
IoCompleteRequest(irp, IO_NO_INCREMENT);
}
static struct hid_report *hid_report_create( HID_XFER_PACKET *packet )
static struct hid_report *hid_report_create( HID_XFER_PACKET *packet, ULONG length )
{
struct hid_report *report;
if (!(report = malloc( offsetof( struct hid_report, buffer[packet->reportBufferLen] ) )))
if (!(report = malloc( offsetof( struct hid_report, buffer[length] ) )))
return NULL;
report->ref = 1;
report->length = packet->reportBufferLen;
memcpy( report->buffer, packet->reportBuffer, report->length );
report->length = length;
memcpy( report->buffer, packet->reportBuffer, packet->reportBufferLen );
memset( report->buffer + packet->reportBufferLen, 0, length - packet->reportBufferLen );
return report;
}
......@@ -218,18 +219,19 @@ static struct hid_report *hid_queue_pop_report( struct hid_queue *queue )
static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *packet )
{
BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
HIDP_COLLECTION_DESC *desc = ext->u.pdo.device_desc.CollectionDesc;
const BOOL polled = ext->u.pdo.information.Polled;
ULONG size, report_len = polled ? packet->reportBufferLen : desc->InputLength;
struct hid_report *last_report, *report;
struct hid_queue *queue;
LIST_ENTRY completed, *entry;
RAWINPUT *rawinput;
ULONG size;
KIRQL irql;
IRP *irp;
if (IsEqualGUID( ext->class_guid, &GUID_DEVINTERFACE_HID ))
{
size = offsetof( RAWINPUT, data.hid.bRawData[packet->reportBufferLen] );
size = offsetof( RAWINPUT, data.hid.bRawData[report_len] );
if (!(rawinput = malloc( size ))) ERR( "Failed to allocate rawinput data!\n" );
else
{
......@@ -240,8 +242,9 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
rawinput->header.hDevice = ULongToHandle( ext->u.pdo.rawinput_handle );
rawinput->header.wParam = RIM_INPUT;
rawinput->data.hid.dwCount = 1;
rawinput->data.hid.dwSizeHid = packet->reportBufferLen;
rawinput->data.hid.dwSizeHid = report_len;
memcpy( rawinput->data.hid.bRawData, packet->reportBuffer, packet->reportBufferLen );
memset( rawinput->data.hid.bRawData + packet->reportBufferLen, 0, report_len - packet->reportBufferLen );
input.type = INPUT_HARDWARE;
input.hi.uMsg = WM_INPUT;
......@@ -253,7 +256,7 @@ static void hid_device_queue_input( DEVICE_OBJECT *device, HID_XFER_PACKET *pack
}
}
if (!(last_report = hid_report_create( packet )))
if (!(last_report = hid_report_create( packet, report_len )))
{
ERR( "Failed to allocate hid_report!\n" );
return;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment