+static DWORD CALLBACK hid_device_thread(void *args) +{
- DEVICE_OBJECT *device = (DEVICE_OBJECT*)args;
- IRP *irp;
- IO_STATUS_BLOCK irp_status;
- IO_STACK_LOCATION *irpsp;
- DWORD rc;
- HANDLE events[2];
- NTSTATUS ntrc;
- BASE_DEVICE_EXTENSION *ext = device->DeviceExtension;
- events[0] = CreateEventA(NULL, FALSE, FALSE, NULL);
- events[1] = ext->halt_event;
- if (ext->information.Polled)
- {
while(1){HID_XFER_PACKET *packet;ResetEvent(events[0]);packet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*packet) + ext->preparseData->caps.InputReportByteLength);packet->reportBufferLen = ext->preparseData->caps.InputReportByteLength;packet->reportBuffer = ((BYTE*)packet) + sizeof(*packet);packet->reportId = 0;irp = IoBuildDeviceIoControlRequest(IOCTL_HID_GET_INPUT_REPORT,device, NULL, 0, packet, sizeof(packet), TRUE, events[0],&irp_status);irpsp = IoGetNextIrpStackLocation(irp);irpsp->CompletionRoutine = read_Completion;irpsp->Control = SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR;ntrc = IoCallDriver(device, irp);if (ntrc == STATUS_PENDING)rc = WaitForMultipleObjects(2, events, FALSE, INFINITE);if (irp->IoStatus.u.Status == STATUS_SUCCESS){RingBuffer_Write(ext->ring_buffer, packet);I'm not opposed to what you have here, but a get-buffer/commit-buffer model would avoid an allocation and a memcpy. Although this would complicate simultaneous writes, if that's a concern.
Part of the trickiness here is that the the packet gets 'consumed' by the IoCallDriver/IoCompleteRequest process. It needs to be a stack pointer. So I end up having to allocate it on the stack and then copy the result out of it.
-aric