USB filter driver

Hi all.

I’m fairly new to KMDF development, but I do have experience with WDM, and I’m trying to develop a USB filter driver in KMDF, which is added to every device stack of certain USB devices (e.g. storage).

1.How should I register and install it?

  • as of now, I tried adding it manually to the registry, as one of the Net class’s LowerFilters, and setting the INF to show that it was of the “Filter” load order group.

2.Is there a way to add it as a filter to a specific device in a certain Class? say I want to filter just one type of USB devices, according to it’s vendor and product ID.

3.After being added as a device in the net class, and adding a USB device, my driver recieved an internal IOCTL of “IOCTL_INTERNAL_USB_SUBMIT_URB”.
This is supposed to happen, and the request I receive hold a large buffer for the output result. I send the request down the stack (without allocating additional memory) to the default WDFIOTARGET and the sending returns a success status.
I tried allocating additional memory before the send, in a similar way to what Doron Holan has shown in his article titled “Formatting a WDFREQUEST for any IRP_MJ code”. but when I call send the request, I get a BUGCODE_USB_DRIVER bug check.

When I tried sending the request without formatting it or allocating a WDFMEMORY object, I do get to the completion routing during which, when I try to extract the output buffer, I get a NULL buffer pointer.

What am I doing wring?

Thank you all,
Ariel.

xxxxx@hotmail.com wrote:

I’m fairly new to KMDF development, but I do have experience with WDM, and I’m trying to develop a USB filter driver in KMDF, which is added to every device stack of certain USB devices (e.g. storage).

1.How should I register and install it?

  • as of now, I tried adding it manually to the registry, as one of the Net class’s LowerFilters, and setting the INF to show that it was of the “Filter” load order group.

2.Is there a way to add it as a filter to a specific device in a certain Class? say I want to filter just one type of USB devices, according to it’s vendor and product ID.

You can either filter one SPECIFIC USB device, or you can filter a whole
class of devices. What you need to do is install yourself as a class
filter, and fail during initialization if the VID and PID aren’t one of
the ones you want to filter. You will then be unloaded.

3.After being added as a device in the net class, and adding a USB device, my driver recieved an internal IOCTL of “IOCTL_INTERNAL_USB_SUBMIT_URB”.
This is supposed to happen, and the request I receive hold a large buffer for the output result. I send the request down the stack (without allocating additional memory) to the default WDFIOTARGET and the sending returns a success status.
I tried allocating additional memory before the send, in a similar way to what Doron Holan has shown in his article titled “Formatting a WDFREQUEST for any IRP_MJ code”. but when I call send the request, I get a BUGCODE_USB_DRIVER bug check.

When I tried sending the request without formatting it or allocating a WDFMEMORY object, I do get to the completion routing during which, when I try to extract the output buffer, I get a NULL buffer pointer.

How are you accessing the output buffer? You can’t use
WdfRequestRetrieveOutputBuffer for an URB. URBs are internal requests
that do not use the normal input and output buffers that you get from a
user-mode IRP. To find an URB’s buffer, you have to fetch the IRP from
the WDFREQUEST, then get the URB from the IRP in the normal way. Once
you have the URB, you get the output buffer like you normally would,
based on the pipe type.


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

Thank you, Tim! Is there any example or article about how to implement a
USB filter driver?

----- Original Message -----
From: “Tim Roberts”
To: “Windows System Software Devs Interest List”
Sent: Friday, April 25, 2008 4:42 AM
Subject: Re: [ntdev] USB filter driver

> xxxxx@hotmail.com wrote:
>> I’m fairly new to KMDF development, but I do have experience with WDM,
and I’m trying to develop a USB filter driver in KMDF, which is added to
every device stack of certain USB devices (e.g. storage).
>>
>> 1.How should I register and install it?
>> - as of now, I tried adding it manually to the registry, as one of the
Net class’s LowerFilters, and setting the INF to show that it was
of the “Filter” load order group.
>>
>> 2.Is there a way to add it as a filter to a specific device in a
certain Class? say I want to filter just one type of USB devices,
according to it’s vendor and product ID.
>>
>
> You can either filter one SPECIFIC USB device, or you can filter a whole

> class of devices. What you need to do is install yourself as a class
> filter, and fail during initialization if the VID and PID aren’t one of
> the ones you want to filter. You will then be unloaded.
>
>> 3.After being added as a device in the net class, and adding a USB
device, my driver recieved an internal IOCTL of
“IOCTL_INTERNAL_USB_SUBMIT_URB”.
>> This is supposed to happen, and the request I receive hold a large
buffer for the output result. I send the request down the stack (without
allocating additional memory) to the default WDFIOTARGET and the sending
returns a success status.
>> I tried allocating additional memory before the send, in a similar way
to what Doron Holan has shown in his article titled “Formatting a
WDFREQUEST for any IRP_MJ code”. but when I call send the request, I get a
BUGCODE_USB_DRIVER bug check.
>>
>> When I tried sending the request without formatting it or allocating a
WDFMEMORY object, I do get to the completion routing during which, when I
try to extract the output buffer, I get a NULL buffer pointer.
>>
>
> How are you accessing the output buffer? You can’t use
> WdfRequestRetrieveOutputBuffer for an URB. URBs are internal requests
> that do not use the normal input and output buffers that you get from a
> user-mode IRP. To find an URB’s buffer, you have to fetch the IRP from
> the WDFREQUEST, then get the URB from the IRP in the normal way. Once
> you have the URB, you get the output buffer like you normally would,
> based on the pipe type.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.

On Fri, Apr 25, 2008 at 09:50:26AM +0800, lianghe.li@gi-de.com wrote:

Thank you, Tim! Is there any example or article about how to implement a
USB filter driver?

No, but in my opinion, USB drivers are among the easiest to filter. Now,
that might just be because I’m comfortable with USB, but the fact is that
the USB driver protocol is pretty simple. You’re only going to see the
requests that a USB device driver will generate, and there are certainly
a number of USB sample drivers.

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

Hi again.

thanks for your reply Tim.

1.How can I install myself as a USB class filter? did you meen I’ll add Lower/Upper Filter to the USB class?
2.Say I register myself as a USB class filter.
is there anyway to distinguish between different USB devices - say PDA’s/Camera’s/Mass storage devices filter one type and not the others, without having to know the VID and PID in advance?

Thanks again,
Ariel

xxxxx@hotmail.com wrote:

1.How can I install myself as a USB class filter? did you meen I’ll add Lower/Upper Filter to the USB class?
2.Say I register myself as a USB class filter.
is there anyway to distinguish between different USB devices - say PDA’s/Camera’s/Mass storage devices filter one type and not the others, without having to know the VID and PID in advance?

Filters apply to “install classes”. That is the class that is listed in
the [Version] header of the INF file. The only devices that should
install themselves in the USB class are host controllers and hubs,
although some devices have been known to break that rule.

USB mass storage devices go into storage class. Cameras usally go into
the image class, although some go into media class.

It is possible to filter all USB devices by making yourself an upper
filter to the USB class. You’ll sit on top of the host controller.
You’d have to judge each device based on VID and PID. If you want to
catch only USB cameras, you could be a lower filter to the image class,
and then check the PnP ID to make sure you were getting the USB device
you wanted.

The easy way to install a class filter is to use devcon. For production
use, you need a small installer.


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

> Filters apply to “install classes”. That is the class that is listed

in the [Version] header of the INF file. The only devices that should
install themselves in the USB class are host controllers and hubs,
although some devices have been known to break that rule.

USB mass storage devices go into storage class.

Actually count USB mass storage devices in the broken category. USBSTOR.INF uses “Class=USB” for historical reasons. That is the way it first shipped in Windows 2000 without any real thought being given to it, then it was too late to change it for Windows XP for compatibility reasons.

-Glen

I would strongly recommend against configuring your driver as an upper
filter for the whole “USB” setup class. Lots of third party INFs (and some
MSFT’s too as we see below) specify it in their INFs “without any real thought being given to it”. It causes USB class upper filters to be installed
into the device stacks they don’t belong to at all. The recent example of
this kind of trouble is the AMD’s usbfilter.sys USB class upper filter really
meant for the USB audio but causing BSODs in completely unrelated scenarios on many new AMD motherboards. I install my USB filters as
the lower filters for only FDOs of specific interest, and I believe that’s the
right way to proceed in most applications.

-Ilya

> Filters apply to “install classes”. That is the class that is listed
> in the [Version] header of the INF file. The only devices that should
> install themselves in the USB class are host controllers and hubs,
> although some devices have been known to break that rule.
>
> USB mass storage devices go into storage class.

Actually count USB mass storage devices in the broken category.
USBSTOR.INF uses “Class=USB” for historical reasons. That is the
way it first shipped in Windows 2000 without any real thought being
given to it, then it was too late to change it for Windows XP for
compatibility reasons.

-Glen

Hi.

Ilya -

  1. how can I install FDO specific lower filters?
  2. There’s supposed to be a way to add filters to this by editing the device specific INF file in the “Windows\System\Inf” directory - adding the value of Lower/Upper filter service name to the registry.
    I wanted to know if there was a more elegant way of doing that.
    3)Another method I heard of, is editing the “HKLM\CCS\ENUM” entry online, after to pluging-in the device.
    Has anyone heard of that method? How should my service be started when that kind of dynamic installation was chosen?

Thanks all,
Ariel

xxxxx@hotmail.com wrote:

Ilya -

  1. how can I install FDO specific lower filters?

By adding a LowerFilters/UpperFilters key to the CCS\Enum key for the
device. However, don’t do that by modifying the registry directly.
Instead, SetupDiGetDeviceRegistryProperty and
SetupDiSetDeviceRegistryProperty can do this in a “blessed” way from a
user-mode setup application.

  1. There’s supposed to be a way to add filters to this by editing the device specific INF file in the “Windows\System\Inf” directory - adding the value of Lower/Upper filter service name to the registry.
    I wanted to know if there was a more elegant way of doing that.

GACK! If I find that your device has modified the standard system INF
files on my computer, I’ll uninstall your product and contact my lawyers.

3)Another method I heard of, is editing the “HKLM\CCS\ENUM” entry online, after to pluging-in the device.
Has anyone heard of that method? How should my service be started when that kind of dynamic installation was chosen?

You can either write a small user-mode utility that uses the
plug-and-play notification mechanism, or you can write a class filter to
watch for new devices. In either case, you’ll eventually need to modify
the Enum key to add a device-specific filter.


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

>> 2) There’s supposed to be a way to add filters to this by editing the device specific INF file in the “Windows\System\Inf” directory - adding the >value of Lower/Upper filter service name to the registry.

> I wanted to know if there was a more elegant way of doing that.
>

GACK! If I find that your device has modified the standard system INF
files on my computer, I’ll uninstall your product and contact my lawyers.

Not only that, you would violate the hash of the INF and thus invalidate its status in the the global catalog file which would make all promptless driver installs start asking the user if they want to install an unsigned driver (even if your driver is not being loaded). You do not modify the INFs in %windir%\inf.

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Tim Roberts
Sent: Monday, April 28, 2008 11:12 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] USB filter driver

xxxxx@hotmail.com wrote:

Ilya -

  1. how can I install FDO specific lower filters?

By adding a LowerFilters/UpperFilters key to the CCS\Enum key for the
device. However, don’t do that by modifying the registry directly.
Instead, SetupDiGetDeviceRegistryProperty and
SetupDiSetDeviceRegistryProperty can do this in a “blessed” way from a
user-mode setup application.

  1. There’s supposed to be a way to add filters to this by editing the device specific INF file in the “Windows\System\Inf” directory - adding the value of Lower/Upper filter service name to the registry.
    I wanted to know if there was a more elegant way of doing that.

GACK! If I find that your device has modified the standard system INF
files on my computer, I’ll uninstall your product and contact my lawyers.

3)Another method I heard of, is editing the “HKLM\CCS\ENUM” entry online, after to pluging-in the device.
Has anyone heard of that method? How should my service be started when that kind of dynamic installation was chosen?

You can either write a small user-mode utility that uses the
plug-and-play notification mechanism, or you can write a class filter to
watch for new devices. In either case, you’ll eventually need to modify
the Enum key to add a device-specific filter.


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


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

Hello again.

I think I’ll take your advice and use a dynamic loader, be it a user mode or a driver.

I have a few more questions, if you will -

  1. Looking at the WDF documentation, especially the osrusbfx2 code, I started to develop my filter driver.
    The driver there is a FDO, for a specific USB device.
    If I wanted to create a USB filter driver that will be able to synthesize Requests and to Pass/Block requests incoming from the bus driver below, of the driver above me does anything need to be added to the osrusbfx2 functionality? - is two/three pipes enough? must I create a pipe for every pipe in the selected USB intersafe?

2)Say I want my filter to support one inbound enpoint (read) and one outbound endpoint (write) - do I have to create another pipe all together? what about enpoints I choose not to create pipes for - do they even exist for the USB device to use?
It is very important for me to be sure no other data traffic, of any kind, goes through my driver other than approved traffic.

Thanks again,
Ariel.

You are describing a function driver. not a filter driver. Perhaps you
intend to create some sort of virtualized USB device/devices? In that case a
filter driver might be a starting point, but you are going to end up with a
hybrid filter/bus driver design.

On Tue, Apr 29, 2008 at 10:39 AM, wrote:

> Hello again.
>
> I think I’ll take your advice and use a dynamic loader, be it a user mode
> or a driver.
>
> I have a few more questions, if you will -
> 1) Looking at the WDF documentation, especially the osrusbfx2 code, I
> started to develop my filter driver.
> The driver there is a FDO, for a specific USB device.
> If I wanted to create a USB filter driver that will be able to synthesize
> Requests and to Pass/Block requests incoming from the bus driver below, of
> the driver above me does anything need to be added to the osrusbfx2
> functionality? - is two/three pipes enough? must I create a pipe for every
> pipe in the selected USB intersafe?
>
> 2)Say I want my filter to support one inbound enpoint (read) and one
> outbound endpoint (write) - do I have to create another pipe all together?
> what about enpoints I choose not to create pipes for - do they even exist
> for the USB device to use?
> It is very important for me to be sure no other data traffic, of any kind,
> goes through my driver other than approved traffic.
>
> Thanks again,
> Ariel.
>
>
>
>
>
> —
> 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
>


Mark Roddy

xxxxx@hotmail.com wrote:

I have a few more questions, if you will -

  1. Looking at the WDF documentation, especially the osrusbfx2 code, I started to develop my filter driver.
    The driver there is a FDO, for a specific USB device.
    If I wanted to create a USB filter driver that will be able to synthesize Requests and to Pass/Block requests incoming from the bus driver below, of the driver above me does anything need to be added to the osrusbfx2 functionality? - is two/three pipes enough? must I create a pipe for every pipe in the selected USB intersafe?

2)Say I want my filter to support one inbound enpoint (read) and one outbound endpoint (write) - do I have to create another pipe all together? what about enpoints I choose not to create pipes for - do they even exist for the USB device to use?
It is very important for me to be sure no other data traffic, of any kind, goes through my driver other than approved traffic.

Your description is very confusing. I think you are asking detailed
questions when you don’t really understand the general overview yet.

What are you REALLY trying to accomplish? What is the overall goal? If
you tell us what you are really trying to do, we can provide advice that
will probably lead you to a workable solution, without have you chase
down a bunch of useless rat holes.


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

Hey again.

Tim - I’m trying to write a USB filter, to filter traffic to/from an external USB device.
There should be some handshake protocol between the two sides, so my driver should have the option of creating and parsing custom requests, as well as receiving custom requests back from the external USB device.

Other than that, I need my driver to filter all read/write traffic to and from the external USB device, and block it until the handshake succeeds.

The description above sounds somewhat like a combination of a FDO and a filter driver…

Ariel.

xxxxx@hotmail.com wrote:

Tim - I’m trying to write a USB filter, to filter traffic to/from an external USB device.
There should be some handshake protocol between the two sides, so my driver should have the option of creating and parsing custom requests, as well as receiving custom requests back from the external USB device.

Other than that, I need my driver to filter all read/write traffic to and from the external USB device, and block it until the handshake succeeds.

The description above sounds somewhat like a combination of a FDO and a filter driver…

It sounds like a abortive attempt to implement some kind of half-assed
security, virtually certain to lead to more problems that it solves.
What kind of a device are you trying to filter?


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