
If you’ve never written a driver for Windows before, your first question is likely to be: Where do I start? While building drivers for the modern Windows operating systems is widely covered by numerous tutorials on the Internet, it might be challenging to find the information and necessary tools for the legacy operating systems. This tutorial covers all steps of Windows Packet Filter drivers customization and build process for all supported Windows platforms (from Windows 95 up to Windows 10).
Windows Packet Filter source code layout
When you install Windows Packet Filter Source Code package, you have got the folder named Kernel under the main installation folder with the following structure:
- /bin – contains driver’s binaries for all supported Windows versions
- /common – contains the source code shared along all supported Windows versions. If you plan to build a kernel mode solution based on Windows Packet Filter, then it makes sense to add the new code here by modifying files in this folder or adding the new ones.
- /IM – contains files specific to NDIS 5.1 Intermediate driver build. This type of driver is used on Windows XP and Windows Server 2003. This driver can also be installed and used on Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8.0, Windows Server 2012, Windows 8.1, Windows Server 2012 R2, however, it can’t be installed on Windows 10, it does not support Windows 7 Mobile Broadband stack (PPIP type of drivers) and since NDIS Intermediate drivers support was added for compatibility reasons it is less performance effective than Lightweight Filter driver.
- /LWF – contains files specific to NDIS 6.x Lightweight Filter driver’s builds. This type of driver is used from Windows Vista (NDIS 6.0) up to Windows 10 (NDIS 6.30).
- /ndisrdlwf Package – NDIS 6.x Lightweight Filter driver companion Visual Studio 2012 project. It can be used for building installation packages (generate and sign CAT file) for NDIS 6.x Lightweight Filter driver. Please note that in Visual Studio 2015 this type of project is deprecated.
- /SYS – contains files specific to Windows NT 4.0 and Windows 2000 NDIS-hooking drivers. This driver can also be used for Windows XP/2003 32 bit; however, it can’t be used on 64 bit builds because of PatchGuard and the general recommendation is using NDIS 5.1 Intermediate driver for Windows XP/2003.
- /VxD – contains files specific to Windows 95, Windows 98 and Windows Millennium.
- /ndisapi – contains the source code for the NDISAPI.DLL, which provides C/C++ interfaces to Windows Packet Filter drivers.
- /INF – contains INF files required for building installation packages for NDIS 5.1 Intermediate driver and NDIS 6.x Lightweight Filter driver.
Building drivers for legacy systems prerequisites
To build Windows Packet Filter drivers for the legacy Windows versions, you may need some legacy tools, which may be difficult to find these days.
- Windows 95, Windows 98, Windows ME:
Visual Studio 6.0 and VToolsD (the latest version was released as a part of Compuware Driver Studio 2.7). - Windows NT 4.0 and Windows 2000:
Microsoft Windows 2000 Driver Developer Kit - Windows XP and Windows Server 2003:
You need one of the Driver Development Kits, which includes Microsoft Windows Server 2003 build environments. You can use Microsoft Windows Server 2003 Driver Developer Kit, Windows Vista WDK or Windows 7 WDK.
Building driver for modern Windows systems prerequisites
If you only need to build drivers for Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Widows 8, Windows Server 2012, Windows 8, Windows Server 2012 R2 and Windows 10 it is enough to install Microsoft Visual Studio 2012 with Windows 8 WDK. This combination of tools is preferred because it allows building a wide range of drivers, from Windows Vista up to Windows 10 from the same environment. Also, projects shipped with driver’s source code are also created with Visual Studio 2012.
It is also possible to use later versions of Microsoft Visual Studio and Windows Driver Kit, an example Microsoft Visual Studio 2015 with Windows 10 WDK, however this tools combination misses the support for building Windows Vista and Windows Server 2008 drivers.
Pre-build preparations
- You have to choose a new driver/device name to replace standard “NDISRD” (for backward compatibility it should not exceed 8 symbols in length) and generate a new GUID for NDIS 6.x Lightweight Filter driver.
- Starting with 64-bit versions of Windows Vista and later versions of Windows, driver code signing policy requires that all driver code have a digital signature. So, for your production build, you have to obtain code signing certificates from one of Microsoft authorized CA authorities. Windows 10 release has also introduced a requirement to obtain Extended Validation (EV) Code Signing certificate and sign driver’s build for Window 10 using Windows Hardware Developer Center Dashboard portal.
From my personal experience it is recommended to have two code signing certificates: SHA-1 code signing certificate and EV code signing certificate (SHA-256), and use the first one for signing drivers for Windows Vista and up to Windows 8.1 (and Windows Server 2012 R2) and second one for Windows 10 and later. This inconvenience is caused by missing the support for SHA-256 code signing certificates under Windows Vista and limited support (hotfix required) under Windows 7. Although, EV code signing certificate can also be used for signing drivers for Windows 8 and later.
Please follow CA instructions to install the code signing certificates on your system.
Visual Studio can care of driver’s signing and driver packages generation processes; you just have to configure correct certificates in project settings. However, Windows 10 requires some additional steps to sign driver using Windows Hardware Developer Center Dashboard portal. More details are available here, Driver Signing Changes in Windows 10. Meanwhile, Windows 10 accepts drivers without Windows Hardware Developer Center Dashboard signature, but the grace period has already expired and this may end any moment.
Building Windows Packet Filter drivers
Part I. Common changes
Open WinpkFilter/include/common.h
and replace all NDISRD
and ndisrd
occurrences in the common strings with the new name you have chosen for driver/device:
// Common strings set
#define DRIVER_NAME_A "NDISRD"
#define DRIVER_NAME_U L"NDISRD"
#define DEVICE_NAME L"\\Device\\NDISRD"
#define SYMLINK_NAME L"\\DosDevices\\NDISRD"
#define WIN9X_REG_PARAM "System\\CurrentControlSet\\Services\\VxD\\ndisrd\\Parameters"
#define WINNT_REG_PARAM TEXT("SYSTEM\\CurrentControlSet\\Services\\ndisrd\\Parameters")
#define FILTER_FRIENDLY_NAME L"WinpkFilter NDIS LightWeight Filter"
#define FILTER_UNIQUE_NAME L"{CD75C963-E19F-4139-BC3B-14019EF72F19}" //unique name, quid name
#define FILTER_SERVICE_NAME L"NDISRD"
You also have to change FILTER_UNIQUE_NAME
with the new GUID you have generated for NDIS 6.x Lightweight Filter driver, and it is recommended to replace FILTER_FRIENDLY_NAME
with some description more suitable for your software.
Next, open WinpkFilter/Kernel/INF
and rename ndisrd.inf
, ndisrd_m.inf
and ndisrd_lwf.inf
by changing ndisrd
to the new driver/device you have chosen. Next, open each of these INF files and replace all occurrences of ndisrd
with your new driver/device name. Also, at the end of each INF file there is [Strings] section. In this section, you can also change strings to more suitable for your project. For the ndisrd_lwf.inf
you need to do one more thing, find the [Install] section and string starting from “NetCfgInstanceId =” in this section and replace the GUID with the one you have generated and have put into the common.h FILTER_UNIQUE_NAME
value. It is important that GUID in INF file matches GUID in common.h.
Part II. Building NDIS 6.x Lightweight Filter drivers
First, it is needed to change Visual Studio NDIS 6.x Lightweight Filter project WinpkFilter/Kernel/LWF/ndisrdlwf.vcxproj
. The easiest way to reconfigure ndisrdlwf.vcxproj
to build driver and packages using new driver/device name is opening it in text editor and replacing ndisrd
to your chosen driver/device name in all strings containing ndisrd
, ndisrd.cat
and ndisrd_lwf.inf
. Then just open modified ndisrdlwf.vcxproj
in Visual Studio.
Using Visual Studio resource editor, you can edit project version resource and add your company product name and copyright information.
Steps above are common for Visual Studio 2012 with Windows 8 WDK and Visual Studio 2015 with Windows 10 WDK. However, next steps are a bit different.
Visual Studio 2012 with Windows 8 WDK
Since projects included into the Windows Packet Filter package were designed for Visual Studio 2012 the following steps are easy and straightforward:
- Open
ndisrdlwf
andndisrdlwf Package
in one workspace. - Configure your code signing certificates in
ndisrdlwf
andndisrdlwf Package
projects properties (Configuration Properties ⇾ Driver Signing). It is recommended to specify Test certificate for debug builds and production certificate for Release ones. - Rebuild all projects. When building
ndisrdlwf
, Visual Studio 2012 will build and sign driver binaries. When buildingndisrdlwf Package
, it will generate and sign CAT files.
Visual Studio 2015 with Windows 10 WDK
- Unlike Visual Studio 2012 you don’t need
ndisrdlwf Project
here, so simply openndisrdlwf.vcxproj
and allow Visual Studio 2015 to auto-convert it. - Open project properties, select Configuration ⇾ All Configurations, select Platform ⇾ All Platforms. Click Configuration Properties ⇾ General and change Target Platform Version from
8.1 to 10.0.1040.0. - In the same window, change Platform Toolset from WindowsKernelModeDriver8.0 to WindowsKernelModeDriver10.0.
- After the changes above, it should look like below:
- Configure your code signing certificates in
ndisrdlwf
project properties (Configuration Properties ⇾ Driver Signing). It is recommended to specify Test certificate for debug builds and production certificate for Release ones. - Rebuild the project’s configurations. Visual Studio will build and sign driver binaries and generate and sign CAT files as well. Please note that Windows Vista configuration fails to build because Windows Vista is not supported by Windows 10 WDK.
Part III. Building NDIS 5.1 Intermediate driver
This type of driver is used for Windows XP and Windows Server 2003 and can be built using Microsoft Windows Server 2003 Driver Developer Kit, Windows Vista WDK or Windows 7 WDK.
- Go to
WinpkFilter/Kernel/IM
- Edit
ndisrd.rc
to include any company, product or copyright information into the version resource. - Open a file named
sources
and in the first stringTARGETNAME=ndisrd
replacendisrd
with the driver/device name you have chosen. - Start Windows Server 2003 x64 Free Build Environment and Windows Server 2003 x86 Free Build Environment. Each will open a new command line window.
- In each command line window opened in previous step, change directory to
WinpkFilter/Kernel/IM
and rundbuild.bat
script.
Part IV. Building Windows NT 4.0 and Windows 2000 NDIS-hooking driver
This type of driver is used for Windows NT 4.0, Windows 2000 (also possible to use on Windows XP 32 bit) and can be built using Windows 2000 Driver Development Kit.
- Go to
WinpkFilter/Kernel/SYS
folder. - Edit
ndisrd.rc
to include any company, product or copyright information into the version resource. - Open a file named
sources
and in the first stringTARGETNAME=ndisrd
replacendisrd
with the driver/device name you have chosen. - Start Windows 200 Free Build Environment to open a new command line window.
- In command line window opened in previous step, change directory to
WinpkFilter/Kernel/SYS
and rundbuild.bat
script.
Part V. Building Windows 95, Windows 98, Windows Millennium Edition NDIS-hooking driver
This type of driver is used for Windows 95, Windows 98 and Windows Millennium Edition and you will need some legacy tools to build it:
- Microsoft Visual Studio 6.0
- Compuware/Numega VToolsD (the latest release was included in Compuware Driver Studio 2.0)
To customize the driver name and resources please perform the steps below:
- Navigate to
WinpkFilter/Kernel/VxD
- Open
NDISRDr.mak
in text editor. Find the stringDEVICENAME = NDISRD
and changeNDISRD
to the driver/device name you have chosen. - Repeat the step above for
NDISRD.mak
. - Rename
NDISRD.VRC
toYOU_DRIVER_NAME.VRC
and edit this version resource to include any company, product or copyright information. - Open
w9xndisrd.dsp
in Microsoft Visual Studio 6.0 and rebuild the project.