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/
Hi Guys,
I am seeing something very strange (at least to me). I have a code something like this:-
``VERIFY_IS_IRQL_PASSIVE_LEVEL(); if (KeGetCurrentIrql() != PASSIVE_LEVEL) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "%s [ERROR]: Wait Specified At Non Passive Level\n", __FUNCTION__); return STATUS_INVALID_PARAMETER; }``
This code is at a start of a function. The function fires a command to the controller and then waits on a event passed to it.
I am sure that I am calling this function at IRQL passive level. The VERIFY_IS_IRQL_PASSIVE_LEVEL() does not complain and passes without issues.
But right after that KeGetCurrentIrql() returns a NON passive level IRQL and the driver returns STATUS_INVALID_PARAMETER.
There is only one command in the driver and I am testing the Abort of that command. I am in debugger doing step by step. This is a debug build of the driver. All the prints are redirected to debugger. I know my DPC is not running.
I am no sure how this is possible or what am I missing here.
Any ideas highly appreciated.
-Aj
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! | ||
Kernel Debugging | 16-20 October 2023 | Live, Online |
Developing Minifilters | 13-17 November 2023 | Live, Online |
Internals & Software Drivers | 4-8 Dec 2023 | Live, Online |
Writing WDF Drivers | 10-14 July 2023 | Live, Online |
Comments
Debug build may not be enough
https://learn.microsoft.com/en-us/windows-hardware/drivers/wdf/verify-is-irql-passive-level
The VERIFY_IS_IRQL_PASSIVE_LEVEL code breaks into a kernel debugger if one of the following is true:
My Cancellation routine is being called at Dispatch level. Not sure why. I need it to be called at IRQL passive level. Is this because I set the WdfSynchronizationScopeQueue when I create my FDO (WdfDeviceCreate)?
-Aj
Cancellation routines are always called at dispatch level, because they hold the "cancel spin lock". In a WDF driver, you can call IoReleaseCancelSpinLock to shift back down to passive.
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-iosetcancelroutine
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
@Tim_Roberts
When framework calls the "CancelRoutine" with "CancelSpinLock" held, Wouldn't it try to release the SpinLock when I return from the Cancel Routine? If my cancel routine releases the Spinlock IoReleaseCancelSpinLock and returns, it would be a problem isn't it? So before returning I will have to acquire the spin lock again, isn't it?
Thanks
Aj
@Tim_Roberts
To avoid meddling with Cancel Spin lock I am using WdfWorkItemEnqueue to enqueue a work item to perform the abort operation.
This I think should work. But not sure which approach of the two is better. [WorkItem Vs Releasing the SpinLock].
Any thoughts appreciated!!
-Aj
A WDM cancel handler is always supposed to call IoReleaseCancelSpinLock -- every time. With KMDF, you can use synchronization scope, but if the work item works in your case, that's easier.
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.