IRP_MN_QUERY_INTERFACE

Hi,

I’m experimenting with IRP_MN_QUERY_INTERFACE. My bus driver implements an
interface type I defined myself and the function driver queries it.

I just read from the docs that the INTERFACE structure to allocate and pass
in the IRP must be allocated from PagedPool. It means that this structure
will not be available at DISPATCH since it can be paged out. And that also
means my interface will not be callable from DISPATCH.

I’m thinking of 2 different scenarios:

  1. Allocate the structure in NonPagedPool. How can this be a source of
    problem? Well, the allocation will be made in the driver which queries the
    interface and the freeing will be in the InterfaceDereference() function
    which is in the driver which provides the interface. -> Two different
    drivers. Is it a sufficient reason not to use NonPagedPool?

  2. Find out how to lock down the associated memory pages so they don’t get
    paged out (I guess I would use an MDL and MmProbeAndLockPages?).

Any experience with this? All comments are welcome.

Mat

Mathieu Routhier wrote:

I just read from the docs that the INTERFACE structure to allocate and pass
in the IRP must be allocated from PagedPool. It means that this structure
will not be available at DISPATCH since it can be paged out. And that also
means my interface will not be callable from DISPATCH.

That doc is almost surely wrong. Just allocate the memory from
NonPagedPool. It can then be used at any IRQL and freed at <=
DISPATCH_LEVEL.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com

Oh and another thing from the docs which seems wrong…

In the “Sending this IRP” section, it says:
[the called should] deallocate the IRP and the INTERFACE structure when they
are no longer needed.

Why define a referencing/dereferencing system then?? I would have expected
the InterfaceDereference function to be responsible for freeing the
INTERFACE when the reference count reaches zero (just like COM!). Not one
of the caller, who does not know the current reference count…

Mat

-----Original Message-----
From: Walter Oney [mailto:xxxxx@oneysoft.com]
Sent: Thursday, May 22, 2003 2:59 PM
To: NT Developers Interest List
Subject: [ntdev] Re: IRP_MN_QUERY_INTERFACE

Mathieu Routhier wrote:

I just read from the docs that the INTERFACE structure to allocate and
pass
in the IRP must be allocated from PagedPool. It means that this structure
will not be available at DISPATCH since it can be paged out. And that
also
means my interface will not be callable from DISPATCH.

That doc is almost surely wrong. Just allocate the memory from
NonPagedPool. It can then be used at any IRQL and freed at <=
DISPATCH_LEVEL.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com


You are currently subscribed to ntdev as: xxxxx@guillemot.com
To unsubscribe send a blank email to xxxxx@lists.osr.com

The reference count is on the interface itself, not the interface structure.
The caller allocates the structure, only the caller uses the structure, only
the caller need be concerned with deallocation of the structure. The
contents of the structure, in particular the function pointers and anything
else put there by the interface are what is reference counted. Obviously you
do not want the interface provider to get unloaded while you still have
pointers into its former code and data.

-----Original Message-----
From: Mathieu Routhier [mailto:xxxxx@guillemot.com]
Sent: Thursday, May 22, 2003 3:20 PM
To: NT Developers Interest List
Subject: [ntdev] Re: IRP_MN_QUERY_INTERFACE

Oh and another thing from the docs which seems wrong…

In the “Sending this IRP” section, it says:
[the called should] deallocate the IRP and the INTERFACE
structure when they are no longer needed.

Why define a referencing/dereferencing system then?? I would
have expected the InterfaceDereference function to be
responsible for freeing the INTERFACE when the reference
count reaches zero (just like COM!). Not one of the caller,
who does not know the current reference count…

Mat

-----Original Message-----
From: Walter Oney [mailto:xxxxx@oneysoft.com]
Sent: Thursday, May 22, 2003 2:59 PM
To: NT Developers Interest List
Subject: [ntdev] Re: IRP_MN_QUERY_INTERFACE

Mathieu Routhier wrote:
> I just read from the docs that the INTERFACE structure to
allocate and
pass
> in the IRP must be allocated from PagedPool. It means that this
> structure will not be available at DISPATCH since it can be
paged out.
> And that
also
> means my interface will not be callable from DISPATCH.

That doc is almost surely wrong. Just allocate the memory
from NonPagedPool. It can then be used at any IRQL and freed
at <= DISPATCH_LEVEL.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com


You are currently subscribed to ntdev as:
xxxxx@guillemot.com To unsubscribe send a blank email to
xxxxx@lists.osr.com


You are currently subscribed to ntdev as:
xxxxx@stratus.com To unsubscribe send a blank email to
xxxxx@lists.osr.com

Mathieu Routhier wrote:

In the “Sending this IRP” section, it says:
[the called should] deallocate the IRP and the INTERFACE structure when they
are no longer needed.

Why define a referencing/dereferencing system then?? I would have expected
the InterfaceDereference function to be responsible for freeing the
INTERFACE when the reference count reaches zero (just like COM!). Not one
of the caller, who does not know the current reference count…

Sigh. That seems like more misleading doc. I think you’d normally use a
synchronous IRP_MJ_PNP to send this request down the stack, and the
system will clean it up. There’s no need for you to “deallocate the IRP”
at all in this situation. If you use an asynchronous IRP, you’ll call
IoFreeIrp in your completion routine. This is just normal IRP handling
– there’s nothing additional or special about it being a
QUERY_INTERFACE request.

As far as telling you to deallocate the INTERFACE structure, this is
just gratuitous advice in my view. You’re probably going to put that
structure into your DEVICE_EXTENSION structure, and it will go away
pretty much by default. Even if you allocated the structure specially,
telling you to deallocate it when no longer needed seems to assume you
might, but for the admonition, be tempted to deallocate it while it was
still in use. I don’t think so…

The doc is misleading when it says that a driver “returns” an INTERFACE
structure. It does not. It *fills in* an INTERFACE structure that you
provide.

The reference/derefence protocol is so that whoever implements the
interface can know when there are no longer any pointers outstanding to
the functions in the interface, basically so he can know when it’s safe
to unload. That implementer does *not* keep a pointer to your INTERFACE
structure.

I would also quarrel with the blanket statement “A driver that handles
this IRP should avoid passing the IRP to another device stack to get the
requested interface.” The ostensible reason is that “such a design would
create dependencies between the device stacks that are difficult to
manage.” Yet, later on, they tell you how to use
IoRegisterPlugPlayNotification to avoid these dependencies. Furthermore,
I think a multifunction driver pretty much *must* repeat this IRP on the
parent driver stack to let child function drivers get at the underlying
bus.


Walter Oney, Consulting and Training
Basic and Advanced Driver Programming Seminars
Check out our schedule at http://www.oneysoft.com

>From: Roddy, Mark [mailto:xxxxx@stratus.com]

The reference count is on the interface itself, not the interface
structure.

Thank you for pointing out that the INTERFACE is not the object which is
referenced; I did not completely realize this fact!

From: Walter Oney [mailto:xxxxx@oneysoft.com]
Furthermore, I think a multifunction driver pretty much *must* repeat this
IRP on the parent driver stack to let child function drivers get at the
underlying bus.

Well, I would say it depends if the driver wants to make it available to its
children… :slight_smile: But I agree; since the bus driver FDO has implemented
QUERY_BUS_RELATIONS and returned its PDOs, this is a guarantee that the bus
driver’s stack will be present during the full child FDO’s lifetime.

Thank you Mark and Walter, this was very interesting.

Mat