KMDF Class Filter Driver Installs on Vista/XP.. Fails on 2K

Discussion in 'Windows Vista Drivers' started by Gabe, Oct 18, 2006.

  1. Gabe

    Gabe Guest

    I am writing a class filter driver off the System Class. The driver
    installs just fine on Vista and XP via use of WdfPreDeviceInstall and
    WdfPostDeviceInstall and setting the class registry value for
    UpperFilters to point to my filter driver.

    XP needs a little workaround to ensure the KMDF runtime gets loaded in
    time. I had to change KMDF's load group to belong to Boot Bus Extender
    since by default KMDF belongs to WdfLoadGroup and in Vista WdfLoadGroup
    is loaded before Boot Bus Extender at boot time, but not in XP. In XP
    WdfLoadGroup is loaded after Boot Bus Extender; hence the workaround
    for XP.

    Windows 2000 has the same issue as XP. KMDF's load group needs to be
    changed to Boot Bus Extender.

    However, I get a BSOD during boot time anyways (and not in my driver).
    WinDbg shows the following:

    BugCheck 1E, {c0000005, 0, 0, 0}

    Probably caused by : ntoskrnl.exe (
    nt!IopUncacheInterfaceInformation+34 )

    LAST_CONTROL_TRANSFER: from 804bcedc to 00000000

    FAILED_INSTRUCTION_ADDRESS:
    +0
    00000000 ?? ???

    STACK_TEXT:
    WARNING: Frame IP not in any known module. Following frames may be
    wrong.
    eb83fd50 804bcedc bff76420 82702868 82730610 0x0
    eb83fd6c 804208f2 e12ed9c8 8047479c 80416bfa
    nt!IopUncacheInterfaceInformation+0x34
    eb83fd78 80416bfa 82702868 00000000 00000000
    nt!IopInvalidateDeviceStateWorker+0x32
    eb83fda8 80454ab6 82702868 00000000 00000000 nt!ExpWorkerThread+0xae
    eb83fddc 804692a2 80416b4c 00000001 00000000
    nt!PspSystemThreadStartup+0x54
    00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16


    My driver is getting loaded and my EvtDeviceAdd is getting called

    Here is the debug output before the crash:

    WdfLdr: DllInitialize - OsVersion(5.0)
    WdfLdr: WdfLdrDiagnosticsValueByNameAsULONG - Value 0x1
    WdfLdr: WdfLdrDiagnosticsValueByNameAsULONG - Status 0x0
    WdfLdr: GetVersionImageName - Version Image Name "Wdf01000.sys"
    WdfLdr: WdfRegisterLibrary - Module(827101A8)
    Breakpoint 1 hit
    nipciflt!FxDriverEntry:
    eb900708 8bff mov edi,edi
    kd> g
    WdfLdr: GetVersionRegistryHandle - Component path
    \Registry\Machine\System\CurrentControlSet\Control\Wdf\Kmdf\KmdfLibrary\Versions
    WdfLdr: GetVersionServicePath - GetVersionServicePath
    (\Registry\Machine\System\CurrentControlSet\Services\Wdf01000)
    WdfLdr: GetClientImageName - Client Image Name: nipciflt.sys
    WdfLdr: LinkClientToLibrary - Client Image Name: nipciflt.sys
    WdfLdr: WdfVersionBind - Returning with Status 0x0
    Breakpoint 2 hit
    nipciflt!DriverEntry:
    eb900490 8bff mov edi,edi
    kd> g
    PciFilter: DriverEntry - WDF version built on Oct 18 2006 14:18:55
    PciFilter: DriverEntry returning!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!
    PCI filter driver EvtDeviceAdd start!

    nipciflt.sys is my class filter driver and as you can see, it is
    calling into DriverEntry and is calling my EvtDeviceAdd method for each
    device in System Class ("PCI filter driver: EvtDeviceAdd start" debug
    print).

    Is this a bug in KMDF? Unfortunately, if we can't get the filter
    driver to work using KMDF in Windows 2000 we'll have to consider other
    options...
     
    Gabe, Oct 18, 2006
    #1
    1. Advertisements

  2. Inline

    --
    This posting is provided "AS IS" with no warranties, and confers no
    rights.
    http://www.microsoft.com/whdc/driver/wdf/default.mspx

    KMDF has chosen and created a new WdfLoadGroup on purpose instead of
    piggybacking on the existing ones. It was to prevent changes made to another
    LoadGroup from changing the workings of KMDF runtime. Also, once we have
    more major(not minor versions) this approach would be the least disruptive.
    Boot drivers belonging to the "System Reserved" and "Boot Bus Extender"
    load groups on pre-vista Os's are not the norm and more like the
    exceptions. Infact ***whenever possible*** it is best to add yourself to a
    group different from the above two.

    Are you doing anything else in your driver entry / EvtDeviceAdd callback
    besides just printing. If you are, could you comment it out to rule out your
    driver corrupting memory. Another thing you could try out is using the KMDF
    toaster filter driver by commenting out the ioctl interface. If that works
    then your driver is doing something wrong in your driver.
     
    Vishal Manan [MSFT], Oct 19, 2006
    #2
    1. Advertisements

  3. Gabe

    Gabe Guest

    Thank you for your reply.

    I believe the driver is bare bones. It does just the minimum to be a
    filter driver. When I create the service the registry key gets set to
    be part of a later group (System Bus Extender). BUT for some reason
    when I add the UpperFilters value to the System Class key
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E97D-E325-11CE-BFC1-08002BE10318}
    the OS decides to try and load the filter driver during Boot Bus
    Extender; which on XP and 2K is before WdfLoadGroup. I have no control
    when the OS tries to load the driver if I make it a class filter driver
    to System Class.

    I modified the firefly example in the KMDF examples and made it a Class
    Filter on Mouse at first, and it worked fine on that. But if I made it
    a class filter driver on System -> BSOD in XP if I don't change KMDF
    loadGroup, and BSOD 2K if I don't change loadGroup and BSOD with the
    error posted in my previous post if I do.

    Even if KMDF behaved the same on 2K as it did in XP, there is an
    installation concern; If we'll have to change the loadGroup for KMDF
    on Pre-Vista, is there a chance that installing future releases of KMDF
    could write back the load group? What about third party inf files that
    might have load group information in it (in the Wdf sections). Other
    parties could potentially change back the load group of KMDF and screw
    us.

    Anyways, here's my DriverEntry:

    NTSTATUS
    DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
    {
    WDF_DRIVER_CONFIG params;
    NTSTATUS status;

    KdPrint(("PciFilter: DriverEntry - WDF version built on %s %s\n",
    __DATE__, __TIME__));

    WDF_DRIVER_CONFIG_INIT(
    &params,
    niPCIFltEvtDeviceAdd
    );

    //
    // Create the framework WDFDRIVER object, with the handle
    // to it returned in Driver.
    //
    status = WdfDriverCreate(DriverObject,
    RegistryPath,
    WDF_NO_OBJECT_ATTRIBUTES,
    &params,
    WDF_NO_HANDLE);
    if (!NT_SUCCESS(status)) {
    //
    // Framework will automatically cleanup on error Status return
    //
    KdPrint(("PciFilter: Error Creating WDFDRIVER 0x%x\n",
    status));
    }
    KdPrint(("PciFilter: DriverEntry returning!"));
    return status;
    }

    And Heres my EvtDeviceAdd (With context definitions)

    typedef struct _DEVICE_CONTEXT
    {
    UNICODE_STRING PdoName;
    } DEVICE_CONTEXT, *PDEVICE_CONTEXT;

    WDF_DECLARE_CONTEXT_TYPE(DEVICE_CONTEXT)

    NTSTATUS niPCIFltEvtDeviceAdd(
    WDFDRIVER Driver,
    PWDFDEVICE_INIT DeviceInit
    )
    {
    WDF_OBJECT_ATTRIBUTES attributes;
    NTSTATUS status;
    PDEVICE_CONTEXT pDeviceContext;
    WDFDEVICE device;
    WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;

    UNREFERENCED_PARAMETER(Driver);

    PAGED_CODE();

    //
    // Configure the device as a filter driver
    //
    KdPrint(("PCI filter driver EvtDeviceAdd start!"));

    WdfFdoInitSetFilter(DeviceInit);

    WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_UNKNOWN);

    WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes,
    DEVICE_CONTEXT);

    status = WdfDeviceCreate(&DeviceInit, &attributes, &device);

    if (!NT_SUCCESS(status))
    {
    KdPrint(("PciFilter: WdfDeviceCreate, Error %x\n", status));
    return status;
    }

    //
    // Driver Framework always zero initializes an objects context
    memory
    //
    pDeviceContext = WdfObjectGet_DEVICE_CONTEXT(device);

    return STATUS_SUCCESS;
    }

    I don't think I am doing anything more than the minimal.

    It seems that there isn't a MS "blessed" solution for XP and 2K and
    class filter drivers that are on devices loaded during Boot Bus
    Extender (i.e. System Class). I guess that is OK since we can still
    use WDM. I think in this case WDM is the best route to take. I don't
    think I'm doing anything wrong. I think my use case is something that
    MS didn't test on XP or 2K, or at least didn't expect/want developers
    writing class filter drivers on machine sensitive classes such as
    system.

    Again, thank you for your reply.

    Gabe
     
    Gabe, Oct 20, 2006
    #3
  4. Inline

    --
    This posting is provided "AS IS" with no warranties, and confers no
    rights.
    http://www.microsoft.com/whdc/driver/wdf/default.mspx

    In my previous mail I had mentioned because of your specical scenario you
    should change the KMdf runtime service "wdf01000" to belong to either of the
    groups "System Reserved" or " "Boot Bus Extender" (insetad of the
    wdflodagroup) and use tags to determine the load order. This will take care
    of your concern below.
    By doing the above you don't need to worry about this as the Service will
    not be updated once it is created.
     
    Vishal Manan [MSFT], Oct 20, 2006
    #4
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.