Posts Tagged ‘filter driver’

Installation and Signing of filter drivers

August 29, 2011

My goal is to demystify and make the process of install of filter drivers simpler. I spent time in this blog describing install issues, driver signing and some miscellaneous topics like PCI express capabilities. I will go into more depths of bus and class filter drivers in my next blog. In this blog I tackle the issues of deploying, debugging, signing filter drivers and small tidbits on PCI express capability structure defined in the PCI spec. There are lots of general guidelines in the Windows Driver Kit(WDK) on how to write filter drivers.

The figure below shows types of filter drivers and where a filter driver can be in the device stack.

FIlter driver types

The toaster filter driver in the WDK is a good starting point: http://msdn.microsoft.com/en-us/library/ff558716(v=VS.85).aspx The toaster sample set is huge and shows how to write different types of filter drivers – upper/lower class, bus and device filter. The filter deriver I recently wrote was a PCI bus filter driver and a USB class filter. Among other things the challenge was debugging and installing it.

Class filter  – If you instantiate a CLASS filter, you do so for all devices in the CLASS. Thus, any new devices that are added in the filtered device class wind-up having the filter instantiated. More details here: http://msdn.microsoft.com/en-us/library/ff537905(v=vs.85).aspx

Bus filter drivers typically add value to a bus and are supplied by Microsoft or a system OEM. Bus filter drivers are optional. There can be any number of bus filter drivers for a bus. A bus filter driver could, for example, implement proprietary enhancements to standard bus hardware. For devices described by an ACPI BIOS, the power manager inserts a Microsoft-supplied ACPI filter (bus filter driver) above the bus driver for each such device. The ACPI filter carries out device power policy and powers on and off devices. The ACPI filter is transparent to other drivers and is not present on non-ACPI machines.

 Debugging the pci bus filter – USB is not a great means for debugging it as the USB controllers which are PCI devices didn’t do too well when my filter driver hit a bug. That’s why resorted to 1394 and serial. I all my initial development and debugging on a desktop with serial ports and then started testing on a laptop. Inf file The install is challenging in how you need to write the inf file and then how do you install the filter driver. The places where this inf differs from a regular function drivers inf is the key to specify whether this is an upper or lower filter. Since this is a PCI bus filter it has the needs and Include directive as well since it is dependent on the PCI bus driver. Note the driver is a boot start since it is a PCI bus filter. It also uses the System class.

The highlighted part in  bold below is the one unique to filter drivers.

[Version]

Signature=”$WINDOWS NT$”

Class=System

ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}

Provider=%MSFT%

LayoutFile=layout.inf

DriverVer=09/21/2006,6.0.5736.1

[DestinationDirs]

DefaultDestDir = 12

[SourceDisksNames]

1 = %DiskId1%,,,””

[SourceDisksFiles]

PCIfilter.sys  = 1,,

;*****************************************

; Install Section

;*****************************************

[Manufacturer]

%StdMfg%=Standard

[Standard]

%PCIfilter.DeviceDesc%=PCIfilter_Device, *PNP0A03

%PCIfilter.DeviceDesc%=PCIfilter_Device, *PNP0A08

[PCIfilter_Device.NT]

Include=machine.inf

Needs=PCI_DRV_ROOT

CopyFiles=Drivers_Dir

[PCIfilter_Device.NT.HW]

AddReg=PCIfilter_Device.NT.HW.AddReg

[Drivers_Dir]

PCIfilter.sys

[PCIfilter_Device.NT.HW.AddReg]

HKR,,”UpperFilters”,0x00010000,”PCIfilter”

;————– Service installation

; Function and filter driver for the bus

[PCIfilter_Device.NT.Services]

Include=machine.inf

Needs=PCI_DRV_ROOT.Services

AddService = PCIfilter,, PCIfilter_Service_Inst

; ————– busupper Driver install section

[PCIfilter_Service_Inst]

DisplayName    = %PCIfilter.SVCDESC%

ServiceType    = 1               ; SERVICE_KERNEL_DRIVER

StartType      = 0               ; SERVICE_DEMAND_BOOT

ErrorControl   = 1               ; SERVICE_ERROR_NORMAL

ServiceBinary  = %12%\PCIfilter.sys

LoadOrderGroup = PnP Filter

[Strings]

SPSVCINST_ASSOCSERVICE= 0x00000002

MSFT = “Microsoft”

StdMfg = “(Standard system devices)”

DiskId1 = ” PCI  Bus
Installation Disk #1″

PCIfilter.SVCDESC = ” PCI Bus Upper Filter”

PCIfilter.DeviceDesc = ” PCI Bus filter”

Install:

devcon.exe install pcifilter.inf *PNP0A03

if the above fails

devcon.exe install pcifilter.inf *PNP0A08

NOTE: devcon.exe is a tool in  the Wdk

Conmmand line way to right click and install an inf

rundll32 syssetup,SetupInfObjectInstallAction DefaultInstall 128 .\usbcfltr.inf

Reboot

You will need to reboot the system after install.

Installation on 64 bit system

You will need to enable test signing to install the filter or sign it.

bcedit /set testsigning ON

Debugging inf issues in install

To do this we need to turn on the verbosity
levels in the Setup logs to look at the  Setupapidev.log .

The default value for log levels is  0x2000ff00

Turning the verbosity of logging

Setting SetupAPI Logging Levels

OSR’s link – http://osronline.com/ddkx/install/troubleshoot_7s6f.htm

Checking all the classfilters

For the USB class filter I wrote this command is what I used. More information in devcon help

devcon classfilter usb lower

Uninstall a class filter

  • using devcon.exe

devcon -r classfilter usb lower !usbcfltr

  • Registry

Renaming the key in the registry. For eg: If the name of the service is
usbcfltr, look for that in the registry and rename it.

Device stack after install of PCI filter driver

This is how the device stack looked for :

PCIbus

|

V

MyFilterdriver

|

V

ACPI

|

V

                                                          PCI root port

The attachedDevice field in the DEVICE_OBJECT structure points to the guy above him in the stack.

Getting PDO from an FDO

This is a common operation for writing filter drivers.

You can send an IRP_MN_QUERY_DEVICE_RELATIONS type TargetDeviceRelation down the stack to get a
referenced pointer to the PDO.

Signing Drivers during
Development and Test (Windows Vista and Later)

The following link describes the steps involved.

http://msdn.microsoft.com/en-us/library/ff552275.aspx

http://msdn.microsoft.com/en-us/library/ff552275(VS.85).aspx

The basic steps are outlined below with examples. Note the example  just show one way of doing it and not the only way. You will need the WDK installed to use the tools  for this.

  • Create a certificate called  testdriverfile

MakeCert -r -pe -ss PrivateCertStore -n “CN=testdriver” testdriverfile.cer

  • Copy all the files to a  folder which includes the .sys file, the inf file and any coinstallers like wdfcoinstaller01009.dll etc.
  • Sign the driver sys file

SignTool sign /a /v /s PrivateCertStore /n testdriver /t http://timestamp.verisign.com/scripts/timestamp.dll  .\cat\pcifilter.sys

  • Generate the catalogue  file.

Inf2Cat /v /driver:\signing\cat /os:7_X64

  • Sign the cat fileSignTool sign /a /v /s PrivateCertStore /n testdriver /t http://timestamp.verisign.com/scripts/timestamp.dll .\cat\pcifilter.cat
    • Install the certificate    on the test machine

    Certutil -addstore -f “Trusted Root Certification Authorities” testdriver.cer

    Also run this command on the 64 bit system to allow test

    bcedit /set testsigning ON

Miscellaneous tidbits  about PCI express capabilities

  • Format is capability _ptr  followed by capability_id
  • In the initial 255     bytes of the PCI space it uses 8 bytes for capability_ptr and 8 for capability_id
  • PCI express extended capability     region – After that it uses  16 bytes
    for capability_id and then  1 byte for version and then 15 bytes for capability_ptr
  • Last cap has the capability_ptr     field set to 0
  • Following capability pointers
    • Check status register – 0x6 bit 0x10 for cap ptr
    • Register 0xe gives the      type of PCI device type like Bridge, endpoint etc