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\Servic es\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...
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\Contro l\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(
¶ms,
niPCIFltEvtDeviceAdd
);
//
// Create the framework WDFDRIVER object, with the handle
// to it returned in Driver.
//
status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
¶ms,
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(&attribute s,
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
Vishal Manan [MSFT] wrote: