Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results
The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.
Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/
Primarily to aid my understanding I was hoping someone with more knowledge than I would be able to explain the "blocking" behavior in the following pseudocode.
h = CreateFileW(L"XXX", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); //On worker thread for(;;) { DeviceIoControl(h, IOCTL_INVERTED_CALL, ...); PrintData(); } //On Main switch(userInput) { CASE 1: DeviceIoControl(h, IOCTL_OTHER, ...); //BLOCKS until IOCTL_INVERTED_CALL is completed. My IoHandler in the kernel is not called. }
I had originally thought that IOCTL_OTHER was blocking because my default IOQueue(WdfIoQueueCreate) was WdfIoQueueDispatchSequential. However, even when I change this to WdfIoQueueDispatchParallel my handler is not called. Things all work fine when the worker thread operates own it's own handle (CreateFileW'ed seperately), but i was hoping to avoid multiple handles.
What exactly is causing the "blocking" in this circumstance? I don't think it's my driver's IOQueue? Is this something to do with the mysterious OVERLAPPED structure that I've been able to avoid thus far?
Thanks,
Jason
Upcoming OSR Seminars | ||
---|---|---|
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead! | ||
Writing WDF Drivers | 7 Dec 2020 | LIVE ONLINE |
Internals & Software Drivers | 25 Jan 2021 | LIVE ONLINE |
Developing Minifilters | 8 March 2021 | LIVE ONLINE |
Comments
You need to open the handle as OVERLAPPED. A handle without OVERLAPPED will serialize IO requests at IO manager dispatching layer before it is sent to the driver.
I see. I've done some further tinkering and I'm struggling to understand something else.
Why does blocking NOT occur / Why does my IOCTL_OTHER handler get called in the example above?
Since my handler for IOCTL_INVERTED_CALL will not call WdfRequestCompleteWithInformation, the queue is WdfIoQueueDispatchSequential and the docs state:
I would have assumed IOCTL_OTHER should block?
This is obvliously related to the use of two different usermode file handles, but I don't understand how that would affect my drives IO queue?
Thanks,
Jason
It's just dawned on me, perhaps this is because the WDFREQUEST has been forwarded to my pending request queue? (WdfRequestForwardToIoQueue?)
Nope. Both should block until the IOCTL is complete... and I/O done on different handles is considered separately.
In general, blocking in your app has no relationship to Queuing in your driver.
Later ETA: While how your driver receives and processes I/O Requests can affect when an asynchronous I/O operation returns to your app, this isn’t related to the Queue type or dispatch method.
You need to check the return status of the calls to DeviceIoControl... if the second one is returning without waiting, I suspect that’s because it’s failing.
Peter
Peter Viscarola
OSR
@OSRDrivers
Thanks, the quotes above have helped tremendously.
I was working under the misconception that if CreateFile was called to create a synchronous handle I could use this handle for IOCTL_INVERTED_CALL on ThreadA and IOCTL_OTHER on ThreadB if my DriverIO queue was WdfIoQueueDispatchParallel.
I now understand that in order for this to be possible I need to either use OverlappedIO on the single handle, or open multiple handles.
Thanks,
Jason
Yes! Exactly correct.
Peter
Peter Viscarola
OSR
@OSRDrivers