[8/13](resend)hidclass.sys: Add a processing thread for HID devices

Aric Stewart aric at codeweavers.com
Thu Sep 3 07:22:40 CDT 2015


>> +
>> +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



More information about the wine-devel mailing list