NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp) { HID_XFER_PACKET *packet; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer); NTSTATUS rc = STATUS_SUCCESS; IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); int ptr = -1; packet = HeapAlloc(GetProcessHeap(), 0, buffer_size); ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext ); irp->IoStatus.Information = 0; RingBuffer_ReadNew(ext->ring_buffer, ptr, packet, &buffer_size); if (buffer_size) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); NTSTATUS rc; ULONG out_length; packet->reportBuffer = (BYTE *)packet + sizeof(*packet); TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen); rc = copy_packet_into_buffer(packet, irp->AssociatedIrp.SystemBuffer, irpsp->Parameters.Read.Length, &out_length); irp->IoStatus.Information = out_length; irp->IoStatus.u.Status = rc; IoCompleteRequest(irp, IO_NO_INCREMENT); } else { BASE_DEVICE_EXTENSION *extension = device->DeviceExtension; if (extension->poll_interval) { TRACE_(hid_report)("Queue irp\n"); InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.s.ListEntry); rc = STATUS_PENDING; } else { HID_XFER_PACKET packet; TRACE("No packet, but opportunistic reads enabled\n"); packet.reportId = ((BYTE*)irp->AssociatedIrp.SystemBuffer)[0]; packet.reportBuffer = &((BYTE*)irp->AssociatedIrp.SystemBuffer)[1]; packet.reportBufferLen = irpsp->Parameters.Read.Length - 1; rc = call_minidriver(IOCTL_HID_GET_INPUT_REPORT, device, NULL, 0, &packet, sizeof(packet)); if (rc == STATUS_SUCCESS) { ((BYTE*)irp->AssociatedIrp.SystemBuffer)[0] = packet.reportId; irp->IoStatus.Information = packet.reportBufferLen + 1; irp->IoStatus.u.Status = rc; } IoCompleteRequest(irp, IO_NO_INCREMENT); } } HeapFree(GetProcessHeap(), 0, packet); return rc; }
static void HID_Device_processQueue(DEVICE_OBJECT *device) { LIST_ENTRY *entry; IRP *irp; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer); HID_XFER_PACKET *packet; packet = HeapAlloc(GetProcessHeap(), 0, buffer_size); entry = RemoveHeadList(&ext->irp_queue); while(entry != &ext->irp_queue) { int ptr; irp = CONTAINING_RECORD(entry, IRP, Tail.Overlay.ListEntry); ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext ); RingBuffer_Read(ext->ring_buffer, ptr, packet, &buffer_size); if (buffer_size) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation(irp); TRACE_(hid_report)("Processing Request (%i)\n",ptr); if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) { memcpy(irp->AssociatedIrp.SystemBuffer, packet->reportBuffer, packet->reportBufferLen); irp->IoStatus.Information = packet->reportBufferLen; irp->IoStatus.u.Status = STATUS_SUCCESS; } else { irp->IoStatus.Information = 0; irp->IoStatus.u.Status = STATUS_BUFFER_OVERFLOW; } } else { irp->IoStatus.Information = 0; irp->IoStatus.u.Status = STATUS_UNSUCCESSFUL; } IoCompleteRequest( irp, IO_NO_INCREMENT ); entry = RemoveHeadList(&ext->irp_queue); } HeapFree(GetProcessHeap(), 0, packet); }
NTSTATUS WINAPI HID_Device_read(DEVICE_OBJECT *device, IRP *irp) { HID_XFER_PACKET *packet; BASE_DEVICE_EXTENSION *ext = device->DeviceExtension; UINT buffer_size = RingBuffer_GetBufferSize(ext->ring_buffer); NTSTATUS rc = STATUS_SUCCESS; int ptr = -1; packet = HeapAlloc(GetProcessHeap(), 0, buffer_size); ptr = PtrToUlong( irp->Tail.Overlay.OriginalFileObject->FsContext ); irp->IoStatus.Information = 0; RingBuffer_Read(ext->ring_buffer, ptr, packet, &buffer_size); if (buffer_size) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); TRACE_(hid_report)("Got Packet %p %i\n", packet->reportBuffer, packet->reportBufferLen); if (irpsp->Parameters.Read.Length >= packet->reportBufferLen) { memcpy(irp->AssociatedIrp.SystemBuffer, packet->reportBuffer, packet->reportBufferLen); irp->IoStatus.Information = packet->reportBufferLen; irp->IoStatus.u.Status = STATUS_SUCCESS; } else { irp->IoStatus.Information = 0; irp->IoStatus.u.Status = STATUS_BUFFER_OVERFLOW; } IoCompleteRequest( irp, IO_NO_INCREMENT ); } else { TRACE_(hid_report)("Queue irp\n"); InsertTailList(&ext->irp_queue, &irp->Tail.Overlay.ListEntry); rc = STATUS_PENDING; } HeapFree(GetProcessHeap(), 0, packet); return rc; }