Two additional CSQ rules

Cancel-safe queues are a fantastic addition to Windows from back in the XP timeframe, and I have come to rely on them in my drivers. There are a couple of important extra rules that aren’t reflected in the documentation that you should be aware of, though.

Rule #1

If you read the documentation for IoCsqInsertIrp or IoCsqInsertIrpEx, you’ll find that the routine can be called at <= DISPATCH_LEVEL. While this is true, you cannot call it while holding a spin lock.

To see why this is true, consider the case where a dispatch routine receives an IRP, and before it can queue the IRP, another thread swoops in and cancels it. If this happens, someone should call the cancel routine, and that someone is IoCsqInsertIrp. It eventually calls CsqCompleteCanceledIrp, which calls IoCompleteRequest with a status of STATUS_CANCELLED.

(Note the double-L. Very bad news for a guy who can’t spell in the first place. I’ll be looking that one up for the rest of my life.)

The rest should be obvious: it is in fact illegal to call IoCompleteRequest while holding a lock, which is exactly what winds up happening in this case. Therefore, you can’t call IoCsqInsertIrp or IoCsqInsertIrpEx while holding a lock.

Rule #2

The second rule is related to when IoCsqInsertIrpEx marks an IRP pending. The rule is simple: If the supplied CsqInsertIrpEx callback returns STATUS_SUCCESS, the IRP is marked pending. Otherwise, it’s not.

In the case of IoCsqInsertIrp, the IRP is unconditionally marked pending. This is even quasi-documented by the WDK cancel sample, but the corresponding startio sample doesn’t say anything about the behavior of IoCsqInsertIrpEx, which I had always assumed was the same based on that comment. It’s not. :-)

Neither of these rules show up in the docs (at least as of now), so hopefully this will save some confusion down the road.

2 Responses to “Two additional CSQ rules”

  1. Very interesting. Guess it’s time to look through my driver and make sure I’m not violating the two rules..

  2. [...] It turns out that something about my recent CSQ rules post triggered IE7’s automatic phishing filter. I know of no good reason that it would pick up that post (and only that post!) other than a couple of words in the title of the article it links to (about CONTAINING_RECORD), which I’m not going to repeat here phor phear of being philtered. [...]

Leave a Reply