Universal Windows driver (KMDF) Example

As discussed during the WPERF Sprint-2 Planning I want WindowsPerf developers to get familiar with technologies we will be using. These technologies and techniques may change in a future but for now we are kick-starting with:

Visual Studio 2022 Community Edition

Please download Visual Studio 2022 Community Edition for your x86_64 development host. We will develop our Kernel-Mode driver (WindowsPerf::wperf-driver) and CLI application (WindowsPerf::wperf) on x86_64 Windows 10/11 machines and cross-compiler to ARM64 targets.

You must use x86_64 MSVC 2022 as ARM64 MSVC 2022 Preview do not support Kernel-mode driver development.

Please also install (see details below):

  • Windows Driver Kit – Windows 10.0.22000.x

  • Windows Software Development Kit – Windows 10.0.22000.y

    • Should be installed from MSVC installer.

Please note that to work together WDK and SDK must be installed with the same version. In this case 10.0.22000. The .x and .y minor versions can differ.

Visual Studio Individual Components (MSVC Installer)

Please note that when you install MSVC you can just go to ‘Individual Components” and make sure you select all packages that are in the column on the right. These packages are used currently to develop WindowsPerf Kernel-Mode driver and CLI application.

Note that you can and should install Windows SDK from this MSVC installer and after it’s installed proceed and install WDK which will match DSK version so that first three numbers of the version are the same. For example, 10.0.22000.1 and 10.0.22000.194 is a match.

Also note the convenient filter to search for ARM64 packages in this window.

Latest MSVC 2022 SDK and WDK setup

[05 Oct 2022 update] I’ve tested MSVC with latest SDK and WDK which is 10.0.22621.x. It seems this is latest working setup for WindowsPerf.

 

 

KMDF

We will focus on developing Kernel-Mode Driver Framework (KMDF) driver to satisfy WindowsPerf functionality. Please note that there is another mode for Kernel Drivers in WDF Framework called User-Mode Driver Framework (UMDF) 2 driver.

We selected KMDF as more flexible one. Please see differences between both here:

This is a flexible choice as it’s easy (in theory) to convert a Kernel-Mode Driver Framework (KMDF) driver into a User-Mode Driver Framework (UMDF) version 2 driver, and vice-versa.

TODO: Actual Example

We should be able to build and deploy simple KMDF example provided by Microsoft online. We will use KMDF echo example from here:

Although ECHO (KMDF) sample demonstrates how to use a sequential queue to serialize read and write requests presented to the driver it’s also a good example of all the gears required to implement simple functional Kernel-Mode driver and client app.

Please have a look at:

  • AutoSync and

  • Exe projects in ECHO sample.

Note that there’s a DriverSync example of Kernel-Mode driver. We will not be interested in it for now as AutoSync and exe are great examples of fully functioning driver and application.

Building project on x86_64 (cross-compilation)

To open project in MSVC please open solution file kmdfecho.sln in the project and try to build it. If all components, DSK/WDK Kits are installed you should be able to build project.
Please note that you may have issues with building driver (AutoSync) and or application (exe). If so, please try to solve these problems. If you are stuck, please shout on mailing list for help.

When you have built a project, you should be able to produce:

  • echo.sys and echo.inf files

  • echoapp.exe

In respective project build directories under MSVC solution.

Kernel Driver Installation

Kernel driver can be installed on ARM64 machine with below command:

$ devcon install echo.inf Root\echotest

Other uses of devcon command are:

$ devcon remove echo.inf Root\echotest

And

$ devcon status echo.inf Root\echotest

Please note that devcon.exe should be located in c:\Program Files (x86)\Windows Kits\10\Tools\ARM64\ on your ARM64 machine.

See some details here:

To enable installing non-signed driver on WOA ARM64, one needs to execute:

$ bcdedit /set testsigning on

using Windows Admin account (via CMD). This might further require you to disable secure boot from BIOS if it has been enabled.

MSVC also provides convenient CMD with all MSVC predefined environment settings, PATH etc. to allow you e.g., to execute toolchain:

 

Using this console you can for example build MSVC solution from command line:

$ devenv kmdfecho.sln /Build Debug

TODO: Checklist

  1. Install Visual Studio 2022 on your x86_64 workstation.

  2. Install as described above all MSVC individual components.

  3. Install WDK with the same version as SDK you installed with MSVC.

  4. Clone ECHO example from Microsoft page.

  5. Open Solution with MSVC and make sure you are building for ARM64. You can add new target based on existing ones.

  6. Build solutions.

    1. Make sure you can overcome all errors and missing dependencies. If not ask on mailing list.

    2. Make sure you’ve produced AutoSync (sys & inf file) and exe application targeted for ARM64 device.

    3. Copy driver files and exe binary to your ARM64 machine.

  7. On ARM machine:

    1. Configure your ARM64 machine so that you can install driver on it. See description above.

    2. Deploy driver and execute exe application to run example.

  8. Get printouts from exe application showing successful exchange between Kernel-Mode driver and application.

There’s an interesting documentation here describing how to, for ECHO example debug Kernel-Mode driver. I haven’t tried it yet but it’s a good read as well:

 

You can see Kernel-Mode driver debug printouts with DebugView:

Kernel-Mode debug prints are produced with macros KdPrint and KdPrintEx. Please note that these macros are described as WDM ones but they are a valid debugging printouts within WDF project.

Expected Errors when building ECHO Example

Rebuild started... 1>------ Rebuild All started: Project: echo, Configuration: Debug x64 ------ 1>Building 'echo' with toolset 'WindowsKernelModeDriver10.0' and the 'Universal' target platform. 1>Stamping x64\Debug\echo.inf 1>Stamping [Version] section with DriverVer=10/05/2022,21.8.30.26 1>D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx(16-16): warning 1324: [Version] section should specify PnpLockdown=1 to prevent external apps from modifying installed driver files. 1>D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. 1>D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx(30-30): error 1285: Cannot specify [ClassInstall32] section for Microsoft-defined class. 1>D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx(64-64): error 1293: Service name 'ECHO' is reserved. 1>D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx(90-90): error 1293: Service name 'ECHO' is reserved. 1>Done building project "echo.vcxproj" -- FAILED. ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Please first clean these errors and warning

warning 1324: [Version] section should specify PnpLockdown=1 to prevent external apps from modifying installed driver files. error 1284: Class "Sample" is reserved for use by Microsoft. error 1285: Cannot specify [ClassInstall32] section for Microsoft-defined class.

After above is cleaned you will get

Rebuild started... 1>------ Rebuild All started: Project: echo, Configuration: Debug ARM64 ------ 1>Building 'echo' with toolset 'WindowsKernelModeDriver10.0' and the 'Universal' target platform. 1>Stamping ARM64\Debug\echo.inf 1>Stamping [Version] section with DriverVer=10/05/2022,21.15.56.888 1>device.c 1>driver.c 1>queue.c 1>Generating code 1>Finished generating code 1>echo.vcxproj -> D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\ARM64\Debug\echo.sys 1>Done Adding Additional Store 1>Successfully signed: D:\Workspace\Windows-driver-samples\general\echo\kmdf\driver\AutoSync\ARM64\Debug\echo.sys 1> 1>Driver is 'Universal'. 1>........................ 1>Signability test failed. 1> 1>Errors: 1>22.9.1: echotest.sys in [drivers_dir] of echo\echo.inf is missing or cannot be decompressed from source media. Please verify all path values specified in SourceDisksNames, SouceDisksFiles, and CopyFiles sections resolve to the actual location of the file, and are expressed in terms relative to the location of the inf. 1> 1>Warnings: 1>None 1>ARM64\Debug\inf2catOutput.log : Inf2Cat error -2: "Inf2Cat, signability test failed." Double click to see the tool output. 1>Done building project "echo.vcxproj" -- FAILED. ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========

Above issue is more complicated and requires some modifications / edit to Windows-driver-samples\general\echo\kmdf\driver\AutoSync\echo.inx file. Error error 1293: Service name ‘ECHO' is reserved. is not (at all) documented: https://learn.microsoft.com/en-us/windows-hardware/drivers/devtest/inf-validation-errors-and-warnings#syntax-in-the-inf-file-1100-1299 or at least I can’t find it’s description. I’m sure there’s more than one way to fix it. Easiest is to replace name ECHO with some arbitrary name.

Finally All errors cleaned

Extra bedtime read