Filter Driver Question.

Hello,

I have some questions regarding filter drivers.

  1. Is all that is required to “install” a filter driver a registry entry in the
    \HKLM\SYSTEM\CCS\Enum<class><vid-pid><instance>
    that is a REG_MULTI_SZ type either named “UpperFilters” or “LowerFilters”?
    Are there any other registry entries that are required?

    2. What is the difference in the sequence of actions/events between “UpperFilters”
    and “LowerFilters”?

    3. I am attempting to write a simple lower device filter driver for a custom USB HID Device.
    From all of the examples I have seen the DriverEntry does not create a DeviceObject.
    The DriverUnload, AddDevice, and all of the IRP functions are filled in and that is about
    it. As I understand it, the DeviceObject for the filter is created in the AddDevice. Am I
    missing something here? For some reason when I plug in my USB HID device my filter
    is loaded and then promptly unloaded. DriverEntry is called and then shortly thereafter
    DriverUnload. Is this typical of some defect in filter drivers?

    4. Is there some resource (book, webpage, etc) that gives a very thorough treament of
    filter driver development?

    Thanks,

    Trey

Comments inline:

<trey.taylor> wrote in message news:xxxxx@ntdev…
> Hello,
>
> I have some questions regarding filter drivers.
>
> 1. Is all that is required to “install” a filter driver a registry entry
> in the
> \HKLM\SYSTEM\CCS\Enum<class><vid-pid><instance>
> that is a REG_MULTI_SZ type either named “UpperFilters” or
> “LowerFilters”?
> Are there any other registry entries that are required?

Well you need the standard services key data for any driver.

> 2. What is the difference in the sequence of actions/events between
> “UpperFilters”
> and “LowerFilters”?

The only difference is whether the driver is above drivers of the class or
below.

> 3. I am attempting to write a simple lower device filter driver for a
> custom USB HID Device.
> From all of the examples I have seen the DriverEntry does not create a
> DeviceObject.
> The DriverUnload, AddDevice, and all of the IRP functions are filled in
> and that is about
> it. As I understand it, the DeviceObject for the filter is created in
> the AddDevice. Am I
> missing something here? For some reason when I plug in my USB HID device
> my filter
> is loaded and then promptly unloaded. DriverEntry is called and then
> shortly thereafter
> DriverUnload. Is this typical of some defect in filter drivers?

The filter for a PnP stack (which USB is) must be PnP itself. So yes,
DriverEntry does very
little. You should be getting an AddDevice call when the USB device is
seen.

> 4. Is there some resource (book, webpage, etc) that gives a very thorough
> treament of
> filter driver development?

No, filters are just a variant on regular drivers. You mention things
above that lead me to assume your driver is a WDM based filter. Nowadays
and especially for USB I would be looking at KMDF instead, it may solve some
of your problems.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply</trey.taylor>

trey.taylor@mm-games.com wrote:

  1. Is all that is required to “install” a filter driver a registry entry in the
    \HKLM\SYSTEM\CCS\Enum<class><vid-pid><instance>
    > that is a REG_MULTI_SZ type either named “UpperFilters” or “LowerFilters”?
    > Are there any other registry entries that are required?
    >

    The UpperFilters and LowerFilters values refer to a service name, so
    your filter driver must have an entry in the CCS\Services tree.

    > 2. What is the difference in the sequence of actions/events between “UpperFilters”
    > and “LowerFilters”?

    I would have thought that was intuitive. A lower filter is loaded
    before the driver being filtered, and receives the requests that it
    sends down. An upper filter is loaded after the driver being filtered,
    and receives requests from above before they are seen by the driver.

    > 3. I am attempting to write a simple lower device filter driver for a custom USB HID Device.
    > From all of the examples I have seen the DriverEntry does not create a DeviceObject.
    > The DriverUnload, AddDevice, and all of the IRP functions are filled in and that is about
    > it.

    For a PnP driver, that’s true. Non-PnP drivers create their device
    objects in DriverEntry. That is the way the system tells the difference.

    > As I understand it, the DeviceObject for the filter is created in the AddDevice. Am I
    > missing something here?

    Right.

    > For some reason when I plug in my USB HID device my filter
    > is loaded and then promptly unloaded. DriverEntry is called and then shortly thereafter
    > DriverUnload. Is this typical of some defect in filter drivers?
    >

    Are you setting up a DriverObject->DriverExtension->AddDevice handler?
    Did you return STATUS_SUCCESS?

    > 4. Is there some resource (book, webpage, etc) that gives a very thorough treament of
    > filter driver development?
    >

    No, but there’s just not that much to them. KMDF makes it practically
    trivial.


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

Thanks for the responses…

So there is a registry entry in CCS\Services tree for the filter driver.

I use SetupDiSetDeviceRegistryProperty to set the “LowerFilters” value to the filter driver name
listed in the CCS\Services tree.

SetupDiSetDeviceRegistryProperty(devs, &devInfo, SPDRP_LOWERFILTERS, (LPBYTE)service, size);

This is successful and upon inspection the entry is in the proper place in the registry.

My code is just a skeleton…

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS returnValue = STATUS_UNSUCCESSFUL;
int i;

KdPrint((“----DriverEntry----\n”));
KdPrint((“DriverObject->DriverName.Length:%d\n”, DriverObject->DriverName.Length));
KdPrint((“DriverObject->DriverName.Buffer:%S\n”, DriverObject->DriverName.Buffer));
KdPrint((“DriverObject->DeviceObject:0x%08X\n”, DriverObject->DeviceObject));
KdPrint((“RegistryPath:%S\n”, RegistryPath->Buffer));

for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION;i++)
{
DriverObject->MajorFunction[i] = DispatchFuntion;
}

DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;

return STATUS_SUCCESS;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint((“DriverUnload - unloading driver.\n”));
}



I have KdPrint’s on the entry of all of my functions and am watching in DebugView. When I plug
the USB device in to the USB port, the filter loads (DriverEntry is called) and then DriverUnload is
called, no other function besides those two.

The USB Hid device does not go away…I also am watching it in DeviceManager.

Is there anything about my DriverEntry that is suspect?

If I have the “LowerFilters” set correctly in the

\HKLM\SYSTEM\CCS\Enum\HID\VID-PID<instance>\ registry and the filter service set in the
CSS\Services tree, what else is there?

Any and all information helpful.

Thanks,

Trey

trey.taylor@mm-games.com wrote:

My code is just a skeleton…

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS returnValue = STATUS_UNSUCCESSFUL;
int i;

KdPrint((“----DriverEntry----\n”));
KdPrint((“DriverObject->DriverName.Length:%d\n”, DriverObject->DriverName.Length));
KdPrint((“DriverObject->DriverName.Buffer:%S\n”, DriverObject->DriverName.Buffer));
KdPrint((“DriverObject->DeviceObject:0x%08X\n”, DriverObject->DeviceObject));
KdPrint((“RegistryPath:%S\n”, RegistryPath->Buffer));

for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION;i++)
{
DriverObject->MajorFunction[i] = DispatchFuntion;
}

DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;

return STATUS_SUCCESS;
}

VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
KdPrint((“DriverUnload - unloading driver.\n”));
}

I have KdPrint’s on the entry of all of my functions and am watching in DebugView. When I plug
the USB device in to the USB port, the filter loads (DriverEntry is called) and then DriverUnload is
called, no other function besides those two.

There is nothing wrong with this code. I have used the exact same code
many times. Are you absolutely sure that you return STATUS_SUCCESS, and
not “returnValue”, which is initialized to STATUS_UNSUCCESSFUL?

And you’re certain AddDevice isn’t getting called?

If I have the “LowerFilters” set correctly in the

\HKLM\SYSTEM\CCS\Enum\HID\VID-PID<instance>\ registry and the filter service set in the
> CSS\Services tree, what else is there?
>

Nothing.


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

Hey Tim,

I tried just returning STATUS_SUCCESS directly and still no joy.

Strangely enough I tried TOASTER and FIREFLY and both behave the same as my driver.

I plug the HID Device into the USB port, DriverEntry is called and then DriverUnload.

I put a KdPrint at the head of AddDevice and I didn’t see anything pop up on DebugView…
so I am assuming it was never called.

I am going to try a completly different HID device to see if anything changes.

> I have some questions regarding filter drivers.

  1. Is all that is required to “install” a filter driver a registry entry in
    the
    \HKLM\SYSTEM\CCS\Enum<class><vid-pid><instance>
    > that is a REG_MULTI_SZ type either named “UpperFilters” or
    “LowerFilters”?
    > Are there any other registry entries that are required?

    This is device filter.

    If you need a class filter filtering all devices of the class, not 1 devnode,
    then you should use SYSTEM\CCS\Control\Class{guid} instead.

    > 2. What is the difference in the sequence of actions/events between
    >“UpperFilters”
    > and “LowerFilters”?

    Lower filters create DOs between the main driver and the PDO, while upper
    filters create DOs between userland and the main driver.

    > it. As I understand it, the DeviceObject for the filter is created in the
    AddDevice.

    Yes.


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