No read or writes when attaching to USB device

Hi all,

I am trying to detect read and write operations directed to removable USB devices, so I am using IoRegisterPlugPlayNotification with GUID_DEVINTERFACE_USB_DEVICE. In my test, I plug a flash USB device and I receive ARRIVAL notification, then use IoGetDeviceObjectPointer with the symbolic name, and ask for the Physical device object (by querying device relations).
I am even able to ask and correctly receive device properties, such as Description (“USB Mass storage device”), Manufacturer, and so on.
Then I create a new device object and attach to the physical device object with IoAttachDeviceToDeviceStack.

This works so far but I am able to receive only the plug and play dispatch calls, like IRP_MN_QUERY_DEVICE_RELATIONS and IRP_MN_SURPRISE_REMOVAL, but never get to receive any IRP_MJ_CREATE, READ or WRITE call (of course, I have my own distpach routines for that calls).

I get pretty much the same result when registering with GUID_DEVINTERFACE_CDROM: I can see Iocontrols and Creates, but no Read or Write. Any idea?
My guess is that I am not attaching to the right device object, but i’m not sure. I also tried to not attach to the physical device, but the device returned by IoGetDeviceObjectPointer, but with the same result.

OTOH, I don’t have an AddDevice function, should I have one? I have tried to make my own AddDevice with just a DbgPrint call and returning SUCCESS, but system never calls it and my driver gets unloaded.

Anyone could help? thanks a lot in advance!!

Harvey

  1. you are attempting to implement a filter driver, but this approach
    will not work.
  2. depending on which level of a usb device stack you manage to attach
    to, IO requests are going to be in the form of
    IRP_MJ_INTERNAL_DEVICE_CONTROL requests rather than IRP_MJ_READ/WRITE
    requests.

You are attaching to whatever happens to be the top of the device
stack when you receive a pnp arrival notification. It is almost
invariably the case that the entire stack has been created, other
participants already have their device object pointer for sending
requests down the stack, and nobody is going to send anything to you.
Instead you need to insert yourself into the stack as a upper or lower
function device filter, as in the examples in the WDK.

Mark Roddy

On Sun, May 17, 2009 at 11:07 AM, wrote:
> Hi all,
>
> I am trying to detect read and write operations directed to removable USB devices, so I am using IoRegisterPlugPlayNotification with GUID_DEVINTERFACE_USB_DEVICE. In my test, I plug a flash USB device and I receive ARRIVAL notification, then use IoGetDeviceObjectPointer with the symbolic name, and ask for the Physical device object (by querying device relations).
> I am even able to ask and correctly receive device properties, such as Description (“USB Mass storage device”), Manufacturer, and so on.
> Then I create a new device object and attach to the physical device object with IoAttachDeviceToDeviceStack.
>
> This works so far but I am able to receive only the plug and play dispatch calls, like IRP_MN_QUERY_DEVICE_RELATIONS and IRP_MN_SURPRISE_REMOVAL, but never get to receive any IRP_MJ_CREATE, READ or WRITE call (of course, I have my own distpach routines for that calls).
>
> I get pretty much the same result when registering with GUID_DEVINTERFACE_CDROM: I can see Iocontrols and Creates, but no Read or Write. Any idea?
> My guess is that I am not attaching to the right device object, but i’m not sure. I also tried to not attach to the physical device, but the device returned by IoGetDeviceObjectPointer, but with the same result.
>
> OTOH, I don’t have an AddDevice function, should I have one? I have tried to make my own AddDevice with just a DbgPrint call and returning SUCCESS, but system never calls it and my driver gets unloaded.
>
> Anyone could help? thanks a lot in advance!!
>
> Harvey
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Hi Mark,

Thanks for your reply.
So I guess I need to re-think the way my driver is acting. I will give it some more thoughts and try it again.

Thanks!


De: Mark Roddy
Para: Windows System Software Devs Interest List
Enviado: domingo, 17 de mayo, 2009 17:58:34
Asunto: Re: [ntdev] No read or writes when attaching to USB device

1) you are attempting to implement a filter driver, but this approach
will not work.
2) depending on which level of a usb device stack you manage to attach
to, IO requests are going to be in the form of
IRP_MJ_INTERNAL_DEVICE_CONTROL requests rather than IRP_MJ_READ/WRITE
requests.

You are attaching to whatever happens to be the top of the device
stack when you receive a pnp arrival notification. It is almost
invariably the case that the entire stack has been created, other
participants already have their device object pointer for sending
requests down the stack, and nobody is going to send anything to you.
Instead you need to insert yourself into the stack as a upper or lower
function device filter, as in the examples in the WDK.

Mark Roddy

On Sun, May 17, 2009 at 11:07 AM, wrote:
> Hi all,
>
> I am trying to detect read and write operations directed to removable USB devices, so I am using IoRegisterPlugPlayNotification with GUID_DEVINTERFACE_USB_DEVICE. In my test, I plug a flash USB device and I receive ARRIVAL notification, then use IoGetDeviceObjectPointer with the symbolic name, and ask for the Physical device object (by querying device relations).
> I am even able to ask and correctly receive device properties, such as Description (“USB Mass storage device”), Manufacturer, and so on.
> Then I create a new device object and attach to the physical device object with IoAttachDeviceToDeviceStack.
>
> This works so far but I am able to receive only the plug and play dispatch calls, like IRP_MN_QUERY_DEVICE_RELATIONS and IRP_MN_SURPRISE_REMOVAL, but never get to receive any IRP_MJ_CREATE, READ or WRITE call (of course, I have my own distpach routines for that calls).
>
> I get pretty much the same result when registering with GUID_DEVINTERFACE_CDROM: I can see Iocontrols and Creates, but no Read or Write. Any idea?
> My guess is that I am not attaching to the right device object, but i’m not sure. I also tried to not attach to the physical device, but the device returned by IoGetDeviceObjectPointer, but with the same result.
>
> OTOH, I don’t have an AddDevice function, should I have one? I have tried to make my own AddDevice with just a DbgPrint call and returning SUCCESS, but system never calls it and my driver gets unloaded.
>
> Anyone could help? thanks a lot in advance!!
>
> Harvey
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

So, let’s suppose that I want to filter different device types, such as USB devices, tape and CD-ROM drives, with the same driver. Should I add the “UpperFilters” registry value key to every class that I want to filter?

I tried that, adding a “AddDevice” function, but I am getting exactly the same result than relying on IoRegisterPlugPlayNotification + AttachToPhysicalDeviceobject, so what’s the difference?

TIA.

>drives, with the same driver. Should I add the “UpperFilters” registry value key to every class that I

want to filter?

Yes.

IoRegisterPlugPlayNotification + AttachToPhysicalDeviceobject, so what’s the difference?

First works correctly, second can misbehave in lots of different ways.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

xxxxx@yahoo.es wrote:

So, let’s suppose that I want to filter different device types, such as USB devices, tape and CD-ROM drives, with the same driver. Should I add the “UpperFilters” registry value key to every class that I want to filter?

What would be the point? Every device class has its own unique
interface. You can’t perform any useful functions globally in such a
filter.

I presume you represent yet another attempt to waste perfectly good
developer resources trying to PREVENT the normal operation of my
computer, instead of trying to ENHANCE my experience. It is apparently
well-known that I am on a quest to squash that practice. If you don’t
have physical security, then your environment is toast already.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hi Tim,

This is just an experiment. The point would be: if I can use a DEVICE_INTERFACE_GUID

(sorry for my mistake in the last message)

Hi Tim,

Thanks for your response.

This is just an experiment. The point would be: if I can use a DEVICE_INTERFACE_GUID and IoRegisterPlugPlayNotification to be warned about the arrival of such device, could I avoid the need to register the driver as an “upper filter” for every class and instead do it programmatically?
This way, I could support a new device class just by using its GUID, received via Iocontrol or some other way, with no need to reboot the computer.

Is it really that wrong? Just asking from my ignorance, of course…

Thanks anyway for your answers.

You might want to explain what you are really trying to do. You are,
as many here do, explaining the pitfalls of your proposed solution
without providing the context that lead you to that solution.

A general purpose upper filter driver is an odd creature of limited
utility. Usually one wants a class or bus filter driver for the more
general cases, or a device specific upper filter for altering the
behavior of a specific device type within a class.

Mark Roddy

On Mon, May 18, 2009 at 2:41 PM, wrote:
> (sorry for my mistake in the last message)
>
> Hi Tim,
>
> Thanks for your response.
>
> This is just an experiment. The point would be: if I can use a DEVICE_INTERFACE_GUID and IoRegisterPlugPlayNotification to be warned about the arrival of such device, could I avoid the need to register the driver as an “upper filter” for every class and instead do it programmatically?
> This way, I could support a new device class just by using its GUID, received via Iocontrol or some other way, with no need to reboot the computer.
>
> Is it really that wrong? Just asking from my ignorance, of course…
>
> Thanks anyway for your answers.
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

Hi Mark,

As I said, it’s just an idea. You can think of it as an “omni-filter”, just like you said: I am thinking of a general purpose filter, for the most usual device classes, that may be used to filter the IRPs coming to any USB device, a CD-ROM device, or even a serial or parallel port. Whatever device, the filter would be configured by sending it the GUID for the target device class.

Then one may decide to change the filtered data (write or read), log or redirect operations to another device, and so on.

xxxxx@yahoo.es wrote:

Hi Mark,

As I said, it’s just an idea. You can think of it as an “omni-filter”, just like you said: I am thinking of a general purpose filter, for the most usual device classes, that may be used to filter the IRPs coming to any USB device, a CD-ROM device, or even a serial or parallel port. Whatever device, the filter would be configured by sending it the GUID for the target device class.

Then one may decide to change the filtered data (write or read), log or redirect operations to another device, and so on.

There is a certain magnetic appeal in having a very general solution,
but in this case you’re going to find that it doesn’t lead to
happiness. The various device classes are just too different. Except
for logging, you don’t gain anything by slamming them together, and the
IRP logging problem has already been solved.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Do you plan for an “universal USB redirector” like VMWare’s ?
Then install VMware and observe how they did it.
– pa

xxxxx@yahoo.es wrote:

Hi Mark,

As I said, it’s just an idea. You can think of it as an “omni-filter”, just like you said: I am thinking of a general purpose filter, for the most usual device classes, that may be used to filter the IRPs coming to any USB device, a CD-ROM device, or even a serial or parallel port. Whatever device, the filter would be configured by sending it the GUID for the target device class.

Then one may decide to change the filtered data (write or read), log or redirect operations to another device, and so on.

That would fit into the bus filter category, not the general filter
holy grail. Bus specific filters make sense. Class filters make sense.
Everything filters not so much

Mark Roddy

On Mon, May 18, 2009 at 3:46 PM, Pavel A. wrote:
> Do you plan for an “universal USB redirector” like VMWare’s ?
> Then install VMware and observe how they did it.
> – pa
>
> xxxxx@yahoo.es wrote:
>>
>> Hi Mark,
>>
>> As I said, it’s just an idea. You can think of it as an “omni-filter”,
>> just like you said: I am thinking of a general purpose filter, for the most
>> usual device classes, that may be used to filter the IRPs coming to any USB
>> device, a CD-ROM device, or even a serial or parallel port. Whatever device,
>> the filter would be configured by sending it the GUID for the target device
>> class.
>>
>> Then one may decide to change the filtered data (write or read), log or
>> redirect operations to another device, and so on.
>>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>

So, what about those security products that claim to protect every port, physical interface, wireless and storage devices?
Do they use a different filter driver for every device class?
Or maybe they just block every Iocontrol or IRP_MJ_CREATE received and do nothing else?

> So, what about those security products that claim to protect every port, physical interface, wireless

and storage devices?
Do they use a different filter driver for every device class?

I think yes.

The classes are different. They have major differences. So, different filters.

Yes, these different filters can be combined to 1 binary, but they are different nevertheless.

Or maybe they just block every Iocontrol or IRP_MJ_CREATE received and do nothing else?

Blocking IO control and CREATE on network adapter is useless, for instance :slight_smile:

You cannot filter devices of different classes by the same logic. You need different filters.

Also note that attaching the filter on PnP notification is too late, somebody could have already opened the file against the devnode at this moment.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Then I guess my problem is to believe that the device stack model would allow every device class to manage the same IRPs, such as CREATE, READ and WRITE…

It is not so, for instance, network adapter does not use IRPs (except PnP and power) at all.

With USB storage, you have different IRPs between different layers. Between the FSD and Disk, you have blockwise read/write IRPs.

Between Disk and USBSTOR, you have IRP_MJ_SCSI IRPs with SRBs and CDBs (SCSI commands).

Between USBSTOR and the rest of USB, you have the URBs.

With sockets on pre-Vista, you have read/write (and also undocumented “send” IOCTLs) between the user land and afd.sys. Between afd.sys and tcpip.sys, you have TDI_SEND and TDI_RECEIVE which are not read and write at all. Also note that, with TDI, the receive path relies on callbacks heavily instead of IRPs. This is done to allow the receive buffer to be implemented in TDI client (and be common for many protocols) and not in the TDI protocol.

Don’t know how this works on Vista+ where TDI is a legacy-compatibility wrapper over Wsk and used by a couple of legacy kernel-mode clients only.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

wrote in message news:xxxxx@ntdev…
> Then I guess my problem is to believe that the device stack model would allow every device class to manage the same IRPs, such as CREATE, READ and WRITE…
>

Ok, I see this is far more complicated than expected :slight_smile:

Thanks Maxim for the detailed explanation.