Hi all,
I apologize if this is going to be a too broad question but I’m really stuck on this problem and I’m too new to the kmdf to figure out the optimal solution.
I’m writing a filter driver (USB) that creates a raw pdo for a user mode process to connect to. The raw pdo is used to monitor some reports that match a certain criteria. Basically the driver handles the IOCTL_INTERNAL_USB_SUBMIT_URB function URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER and if there’s a match, it posts an event using the raw pdo.
The link between the main code path and the raw pdo EvtIoRead handler is through a ringbuffer. Basically, from the EvtIoInternalDeviceControl when I want to post a new event, I enqueue a message to the ringbuffer. When I get an EvtIoRead for the raw pdo, I dequeue the message and complete the request with it.
Now the issues with this: if I get a IoRead request but the ring buffer is empty, I can’t complete the IoRead with anything useful on the other end I cannot really get rid of it either.
Also, upon enqueue, I’d like to be able to start processing any pending IoRead.
One first idea was to set the IoRead queue as manual. The problem is that if I enqueue something but there’s no IoRead pending yet, I have no way to get the queue running when the IoRead comes in.
I also thought about setting the IoRead queue as sequential and stop the queue right away. Then when I enqueue something in the ringbuffer I start the queue. In the IoRead handler I stop the queue (asynchronously), dequeue and complete. The problem I see with this is that it’s not entirely clear to me what happens if I try to enqueue (and thus start the queue) WHILE I’m trying to stop it. Even if start and stop are synchronized, if for some reason the start comes while I’m in the IoRead handler but before I stopped the queue and end up with inconsistencies. I thought about checking the status of the ringbuffer before attempting the stop but in other to do that meaningfully I should be able to lock together the check and the stop and in the enqueue process lock the enqueue and the start, but this I can’t do since I can’t hold a lock while starting a queue.
I have the feeling that there’s a simpler way to use the framework to code this in the right way but I just can’t see it.
Could anybody point me in the right direction?
Thank you in advance,
Marco.