[wdmaudiodev] Re: Overriding IRP_MJ_DEVICE_CONTROL handling is possible?

  • From: "Don Bell" <0dbell@xxxxxxxxx>
  • To: wdmaudiodev@xxxxxxxxxxxxx
  • Date: Mon, 9 Apr 2007 11:44:40 -0500

Tom, thank you so much for your reply - you have no idea how the
"little" tips that you provided here are helping me understand some
fundamental issues. I will use the context of your reply to explain
how or why:

On 4/9/07, Tom Eckert <teckert@xxxxxxxxxxxxxxxx> wrote:

I don't think you should be calling IoSkipCurrentIrpStackLocation() and
 IoCallDriver() to pass the call to portcls.  The miniport is not an upper
driver for portcls, actually portcls takes over your stack location so once
you've hooked it back (by overwriting the portcls call in the MajorFunction
table) this will actually re-enter your driver instead of calling portcls
(and overrun the stack).

That is exactly what I was confused about. On one hand, the book that
I have ("Writing Windows WDM Device Drivers" by Chris Cant) does an
excellent job in explaining the "assembly language" of WDM
programming. On the other hand, this could be very misleading when
writing a miniport driver... as I will soon explain in a very
fundamental question that I will present further down:

Save the address of the IRP_MJ_DEVICE_CONTROL handler that portcls installs
and call it directly when you've determined that the IRP is not from your
app.

PDRIVER_DISPATCH pPortClsDeviceControl;

extern "C" NTSTATUS DriverEntry(
 IN PDRIVER_OBJECT  DriverObject,
 IN PUNICODE_STRING RegistryPathName)
{
  NTSTATUS ntStatus = PcInitializeAdapterDriver(
                                      DriverObject,
                                      RegistryPathName,

(PDRIVER_ADD_DEVICE)AddDevice);

 if(NT_SUCCESS(ntStatus))
 {
    pPortClsDeviceControl =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
DeviceControlHandler;
 }
 return ntStatus;
}

and somewhere in DeviceControlHandler
    if(it's my IOCTL)
       status = HandleIt();
    else
       status= pPortClsDeviceControl(fdo,Irp);

That is very intuitive and makes a lot of sense. I should only ask
myself now: "Duh! How come I didn't see this before posting my
question?"

This approach works for us but it looks like PcDispatchIrp saves you the
trouble of keeping a copy of the portcls handler so to use that just
eliminate the pPortClsDeviceControl variable and call PcDispatchIrp instead.
 Maybe someone from ms will want to chime in here if there's a reason why
the PcDispatchIrp approach is better than simply calling the portcls entry?

Indeed, this is an excellent question - which adds to my fundamental
question: How am I supposed to know that I should use PcDispatchIrp()
instead of the "manual approach"? Now that I know about it, I can find
it in WDK's reference section but... Isn't there a tutorial that
provides a recipe for such scenario (which I am sure is not rare)?

You'll also need to create symbolic link to use in your user mode CreateFile
call.

Thanks for this tip, too. I understand that this symbolic link should
be different than the one created by PortCls? Am I correct?

Lastly, do you know of any book that specializes in Audio device
drivers? Chris Cant's book is good but its main focus is on  HID and
USB device drivers. I wish I had book that could "lead me by the hand"
as I am learning this exciting new field.

Hope this helps,
Tom

It really helps - thank you again!

Don
******************

WDMAUDIODEV addresses:
Post message: mailto:wdmaudiodev@xxxxxxxxxxxxx
Subscribe:    mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=subscribe
Unsubscribe:  mailto:wdmaudiodev-request@xxxxxxxxxxxxx?subject=unsubscribe
Moderator:    mailto:wdmaudiodev-moderators@xxxxxxxxxxxxx

URL to WDMAUDIODEV page:
http://www.wdmaudiodev.com/

Other related posts: