Commit 068511f8 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

winebus.sys: Keep a separate report buffer for each input report id.

And use them for IOCTL_HID_GET_INPUT_REPORT ioctls. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51824Signed-off-by: 's avatarRémi Bernon <rbernon@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 91329790
...@@ -76,6 +76,7 @@ struct device_extension ...@@ -76,6 +76,7 @@ struct device_extension
ULONG report_desc_length; ULONG report_desc_length;
HIDP_DEVICE_DESC collection_desc; HIDP_DEVICE_DESC collection_desc;
BYTE *last_reports[256];
BYTE *last_report; BYTE *last_report;
DWORD last_report_size; DWORD last_report_size;
BOOL last_report_read; BOOL last_report_read;
...@@ -444,6 +445,9 @@ static void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length ...@@ -444,6 +445,9 @@ static void process_hid_report(DEVICE_OBJECT *device, BYTE *report, DWORD length
ext->last_report_size = length; ext->last_report_size = length;
ext->last_report_read = FALSE; ext->last_report_read = FALSE;
if (!ext->collection_desc.ReportIDs[0].ReportID) memcpy(ext->last_reports[0], report, length);
else memcpy(ext->last_reports[report[0]], report, length);
if ((irp = pop_pending_read(ext))) if ((irp = pop_pending_read(ext)))
{ {
stack = IoGetCurrentIrpStackLocation(irp); stack = IoGetCurrentIrpStackLocation(irp);
...@@ -815,6 +819,8 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) ...@@ -815,6 +819,8 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
struct device_extension *ext = device->DeviceExtension; struct device_extension *ext = device->DeviceExtension;
NTSTATUS status = irp->IoStatus.Status; NTSTATUS status = irp->IoStatus.Status;
IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp);
HIDP_REPORT_IDS *reports;
ULONG i, size;
TRACE("device %p, irp %p, minor function %#x.\n", device, irp, irpsp->MinorFunction); TRACE("device %p, irp %p, minor function %#x.\n", device, irp, irpsp->MinorFunction);
...@@ -849,8 +855,14 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) ...@@ -849,8 +855,14 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
ERR("Failed to parse device %p report descriptor, status %#x\n", device, status); ERR("Failed to parse device %p report descriptor, status %#x\n", device, status);
else else
{ {
ext->state = DEVICE_STATE_STARTED;
status = STATUS_SUCCESS; status = STATUS_SUCCESS;
reports = ext->collection_desc.ReportIDs;
for (i = 0; i < ext->collection_desc.ReportIDsLength; ++i)
{
if (!(size = reports[i].InputLength)) continue;
if (!(ext->last_reports[reports[i].ReportID] = RtlAllocateHeap(GetProcessHeap(), 0, size))) status = STATUS_NO_MEMORY;
}
if (!status) ext->state = DEVICE_STATE_STARTED;
} }
} }
RtlLeaveCriticalSection(&ext->cs); RtlLeaveCriticalSection(&ext->cs);
...@@ -878,6 +890,12 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp) ...@@ -878,6 +890,12 @@ static NTSTATUS pdo_pnp_dispatch(DEVICE_OBJECT *device, IRP *irp)
irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(irp, IO_NO_INCREMENT); IoCompleteRequest(irp, IO_NO_INCREMENT);
reports = ext->collection_desc.ReportIDs;
for (i = 0; i < ext->collection_desc.ReportIDsLength; ++i)
{
if (!reports[i].InputLength) continue;
RtlFreeHeap(GetProcessHeap(), 0, ext->last_reports[reports[i].ReportID]);
}
HidP_FreeCollectionDescription(&ext->collection_desc); HidP_FreeCollectionDescription(&ext->collection_desc);
RtlFreeHeap(GetProcessHeap(), 0, ext->report_desc); RtlFreeHeap(GetProcessHeap(), 0, ext->report_desc);
...@@ -1020,14 +1038,10 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp) ...@@ -1020,14 +1038,10 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
} }
case IOCTL_HID_GET_INPUT_REPORT: case IOCTL_HID_GET_INPUT_REPORT:
{ {
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer); HID_XFER_PACKET *packet = (HID_XFER_PACKET *)irp->UserBuffer;
TRACE_(hid_report)("IOCTL_HID_GET_INPUT_REPORT\n"); memcpy(packet->reportBuffer, ext->last_reports[packet->reportId], packet->reportBufferLen);
irp->IoStatus.Status = deliver_last_report(ext, irp->IoStatus.Information = packet->reportBufferLen;
packet->reportBufferLen, packet->reportBuffer, irp->IoStatus.Status = STATUS_SUCCESS;
&irp->IoStatus.Information);
if (irp->IoStatus.Status == STATUS_SUCCESS)
packet->reportBufferLen = irp->IoStatus.Information;
break; break;
} }
case IOCTL_HID_READ_REPORT: case IOCTL_HID_READ_REPORT:
......
Markdown is supported
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