When explaining IO_REMOVE_LOCK and how to use it, Walter Oney says in
his book:

"Whenever you receive an I/O request ***that you plan to forward down
the stack***, you call IoAcquireRemoveLock."

I even found a post that emphasizes this issue even more:

http://tinyurl.com/277aqn

In which he clarifies:

"Claim the remove lock ***before passing an IRP down the PnP stack***,
and release it when the IRP completes. It's not necessary to use the
lock for an IRP that you don't pass down."

and continues:

"What you're really doing with the remove lock is making sure you
don't call IoDetachDevice and don't return from your
IRP_MN_REMOVE_DEVICE handler while ***the lower driver*** is
processing an IRP you've sent it."

(the "***" are my own emphasis)


OK - so I understand that calling IoAcquireRemoveLock is not necessary
in every type of IRP handling but rather only for those that are
"passed down the PnP stack".

However, I am unsure what "pass IRP down the PnP stack" means in the
context of PortCls (see diagram):

http://msdn2.microsoft.com/en-us/library/ms790577.aspx

Specifically, when I call PcDispatchIrp(), does that constitute "pass
IRP down the PnP stack"?

And what is "the PnP stack" in this context? I know what an "IRP
stack" is, but this is the first time I encounter the term "PnP
stack". Could that have been a typo (in Mr. Oney's reply)?


Thanks,
Don

Re: What is "pass IRP down the PnP stack"? in PortCls? by Walter

Walter
Fri Feb 08 15:44:16 CST 2008

0dbell@gmail.com wrote:
> Specifically, when I call PcDispatchIrp(), does that constitute "pass
> IRP down the PnP stack"?

I wouldn't think so. When you call a function to handle an IRP, you're
staying at the same level of the stack of device objects. It would be
PortCls's job to handle any IRPs that it sends to other drivers.

I haven't seen other people buying into my analysis of what
remove-locking is all about, so you may get a completely different
answer here. I'll be curious too.

--
Walter Oney, Consulting and Training
http://www.oneysoft.com

Re: What is "pass IRP down the PnP stack"? in PortCls? by Maxim

Maxim
Sat Feb 09 09:37:23 CST 2008

> I haven't seen other people buying into my analysis of what
> remove-locking is all about

I remember your analyzis :-)

Once more: on NT OSes (unlike Win9x), REMOVE will not be sent if there are file
objects opened on the devnode.

So, any IRPs sent from the top by the IO manager from some file object do _not_
require remove locking.

Looks like remove locking is only required for "self-managed IO" like the
driver sending some file-object-less IRPs from a timer callback, work item, its
own system thread or such.

So, races with REMOVE are only dangerous for the self-managed IO initiator. If
the initiator is correct and will shut down all self-managed IO before passing
REMOVE down - then the stack is safe, even if the drivers below do not use
remove locks.

So, the only purpose of the remove lock on w2k/XP/2003/Vista/2008 OSes is - to
block REMOVE till the driver will properly shut down the self-managed IO
initiated by it.

Things like registering shutdown notifications are also self-managed IO, though
sent by the IO manager, because the driver was the initial requestor of this
IRP and can cancel it by deregestering a notification (I hope this cancellation
is safe in terms of races with the IRP sent by itself).

MJ_POWER/System is synchronized with state-changing PnP like REMOVE by the
kernel and thus safe.

MJ_POWER/Device are NOT synchronized, so, if it is sent by the PPO NOT as a
result of processing MJ_POWER/System - then it must be treated as self-managed
IO.

--
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
maxim@storagecraft.com
http://www.storagecraft.com