Windows-driver-samples Documentation

This repo contains driver samples prepared for use with Microsoft Visual Studio and the Windows Driver Kit (WDK). It contains both Universal Windows Driver...

7,879 stars C C 1 file · ~125,974 tokens
RAW Doc

Technical Documentation: microsoft/Windows-driver-samples

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`README.md`)

Driver samples for Windows 11

These are the official Microsoft Windows Driver Kit (WDK) driver code samples for Windows 11. They provide a foundation for Universal Windows driver support of all hardware form factors, from phones to desktop PCs. Use these samples with Visual Studio 2022 and Windows Driver Kit (WDK) 11.

Windows Driver Kit documentation

Windows 11 driver development

Use Visual Studio 2022 and Windows Driver Kit (WDK) 11 to build, test, and deploy your drivers. With Windows 11, the driver development environment is integrated into Visual Studio. To get started, download the driver development kits and tools for Windows 11.

Download the WDK, WinDbg, and associated tools

Windows Driver Kit (WDK)

Take a look at the compilation of the new and changed driver-related content for Windows 11. Areas of improvement include camera, print, display, Near Field Communication (NFC), WLAN, Bluetooth, and more.

Find out what's new in the WDK

Universal Windows drivers

Write one driver that runs on Windows 11 for desktop editions, as well as other Windows editions that share a common set of interfaces.

Getting Started with Universal Windows drivers

Windows Driver Frameworks

The Windows Driver Frameworks (WDF) are a set of libraries that make it simple to write high-quality device drivers.

WDF driver development guide

Samples

Use the samples in this repo to guide your Windows driver development. Whether you're just getting started or porting an older driver to the newest version of Windows, code samples are valuable guides on how to write drivers.

For information about important changes that need to be made to the WDK sample drivers before releasing device drivers based on the sample code, see the following topic:

From Sample Code to Production Driver - What to Change in the Samples

Build your first driver

If you're writing your first driver, use these exercises to get started. Each exercise is independent of the others, so you can do them in any order.

Write a UMDF driver based on a template

Write a KMDF Hello World driver

Write a KMDF driver based on a template

Use GitHub Actions to build a simple driver project

Microsoft Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.


Overview (`TrEE/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

TrEE sample

The Trusted Execution Environment (TrEE) sample.


Overview (`gnss/ReadMe.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

GNSS UMDF Sample Driver (UMDF Version 2)

Provides a base sample driver that IHVs and partners can use to extend to build their custom Windows GPS/GNSS drivers.

Overview

What is covered

  • This is a sample that adheres to GNSS driver design for Windows 10 outlined in the GNSS driver design guide for Windows 10.

  • Serves as base sample driver that IHVs and partners can use as a template and guidance to extend to build their custom Windows GNSS drivers.

  • Follows the WDF guidelines and best practices around PnP device arrival/removal, power management and driver installation/uninstallation.

  • Supports the GNSS DDI mandatory requirements.

  • This driver successfully passes HLK tests and WDF tests provided by Visual studio.

What is not covered

  • This sample currently doesn't support Geofence, SUPL, and AGNSS, as this is not mandatory GNSS DDI functionality.

  • SUPL and AGNSS are mandatory only if required by mobile operator, and the sample does not support them currently.

  • Not a production driver.

What a Partner needs to do

  • Customer can install WDK and run Location HLK tests to validate their driver. All test cases should be either pass or skip without failure.

  • Partner owns the following:

    • Installing the driver.

    • Adding certificate and driver signing.

    • Updating manufacturer name driver version etc. (the code has comments to update).

  • The GNSS sample code has "FIX ME" comments. Partner should update them accordingly.

Design

  • The sample demonstrates a very basic software only driver that meets the minimum requirements from the GNSS DDI.

  • The sample currently always returns a fake hardcoded location. Driver developers can extend this to fetch fake positions from a file or inject through a custom IOCTL or instead implement getting real positions from GNSS hardware.

  • Driver developer can extend this to pull the fake positions from a file or through custom IOCTLs if needed.

Trace Logging

  • The sample code provides Trace logging WPRP file.

  • To capture trace log, copy GnssUmdfSampleDriver.wprp in the solution folder into the device under test. On command line (MyLog.etl is an example file name below):

    cmd
    wpr -start GnssUmdfSampleDriver.wprp -filemode
        <Reproduce the issue>
    wpr -stop MyLog.etl
  • Inspect MyLog.etl with trace file analyzer. Note that corresponding PDB file is needed to decode the logging information.

Test Plan

Customer should validate their driver after customizing it.

Test method 1

  • This tests WDF fundamental functionality (PnP etc.), rather than Location-specific features.

  • Run Visual studio built-in run-time test for WDF.

  • General information available at .

  • Expected result / Pass criteria: Pass rate 100%

Test method 2

  • This tests Location-specific functionality (Getting fix etc.).

  • Run HLK tests with existing and standard GNSS driver tests.

  • Run "TE.exe GNSSDriverTest.dll".

  • Expected result / Pass criteria: Pass rate 100%

  • Note that this sample does not support AGNSS, SUPL and Geofencing currently. Based on the capability of driver, HLK skips them automatically.

Test method 3

  • Test the Windows Geolocation API layer on real apps.

  • Get current location by clicking on "Show my location" from the In-box Windows Maps app.

  • Run the tracking scenario from the Geolocation Sample app.

  • Get current location by clicking on "Start" from GPS Satellite app in Windows Store.

Resources

GNSS DDI reference

Getting started with Windows drivers

Windows Driver Kit documentation

NMEA format documentation


Overview (`print/README.md`)

Printer Device Development with Print Support Apps (PSA)

We recommend that you use Microsoft's IPP inbox class driver, along with Print Support Apps (PSA), to customize the print experience in Windows 10 and 11 for printer device development.

For more information, see Print support app design guide.


Overview (`prm/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PrmFunc sample application

The PRMFunc sample demonstrates how to write a KMDF driver to utlize the Windows Platform Runtime Mechanism (PRM) direct-call interface.

Platform Runtime Mechanism Specification


Overview (`simbatt/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimBatt: Simulated Battery Driver Sample

SimBatt is simulated battery device driver.

This source code is intended to demonstrate implementation of Windows battery driver interfaces.

This is a KMDF based sample.

You may use this sample as a starting point to implement a battery miniport specific to your needs.


Overview (`smartcrd/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PCMCIA Smart Card Driver

[!WARNING]
This sample and its documentation are known to be out of date. They will be updated soon. Please be aware that some functionality may not work as expected.

The PCMCIA Smart Card Driver is used for the SCM PCMCIA smart card reader. This driver is written using Kernel-Mode Driver Framework.

This driver in its original form was written in WDM. It was converted to KMDF to take advantage of all the benefits provided by KMDF in terms of reducing complexity and making it robust. Since this driver still needs to work with the existing smartcard library to handle smartcard specific processing, the driver is not restricted to using only KMDF interfaces. Escaping out of KMDF is necessary for processing I/O requests to get the underlying IRPs and provide that to the smartcard library. The driver also uses advanced IRP handling techniques to work around the limitations imposed by the smartcard library. Except for this quirk, the driver is a fully functional KMDF driver. As a sample, it also makes it easier to adapt this driver for USB devices since KMDF has good support for interfacing with USB devices.

Power Management is described in detail in the WDK documentation. There is, however, one situation that is specific to smart card readers: how to deal with smart card insertions and removals while the system is in standby or hibernation mode.

A card reader will not see any card insertion or removal events in these modes, because the bus might not even have power. The card state must be saved before the reader goes into standby or hibernation mode. After the system returns from these modes, it is necessary to determine what the state of the card is. Card tracking calls must complete whenever there was a card in the reader before standby or hibernation mode or whenever there is a card in the reader after these modes. This step is necessary because the user could have changed the card while the system was in a low-power mode.

Build the sample

For information on how to build a driver solution using Microsoft Visual Studio, see Building a Driver with Visual Studio and the WDK.

[!NOTE]
You can obtain the co-installers by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components.

Run the sample

Installation

The PSCR.SYS driver is available from Windows Update. Therefore, when the SCM 488 PCMCIA reader is inserted, the system will automatically install the driver. However, if you want to customize the source code of this driver and replace the driver from Windows Update with your driver, use the supplied INF file.

Tools

Microsoft offers a test tool (Ifdtest.exe) that allows you to use a smart card reader directly from the command line. Normally, the smart card resource manager is connected to a reader. To use Ifdtest.exe, you must stop the smart card resource manager (Scardsvr.exe) by typing net stop scardsvr at the command line. Ifdtest.exe is also used for the smart card reader logo test.

The driver will not unload as long as you have Ifdtest.exe running and connected to the driver.

Resources

ISO 7816 Part 3 describes smart cards and smart card protocols in detail. Refer to the PC99 Handbook for smart card reader requirements.

For more information about Windows smart card reader drivers, see Smart Card Reader Devices Design Guide.


Overview (`wia/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Image Acquisition (WIA) Driver Samples

The Windows Image Acquisition driver sample set contains samples and test tools for Windows Image Acquisition (WIA), a driver architecture and user interface for acquiring images from still image devices such as scanners.

PRODUCTION SCANNING WIA 2.0 DRIVER

The ProdScan directory contains a sample WIA 2.0 mini-driver. This sample shows how to add Production Scanning features to a WIA 2.0 mini-driver.

EXTENDED WIA 2.0 MONSTER DRIVER

The Wiadriverex directory contains a sample WIA 2.0 mini-driver. This sample shows how to write a WIA 2.0 mini-driver that uses the stream-based WIA 2.0 transfer model. It also shows an implementation of a very simple segmentation filter, image processing filter, and error handling extension for the WIA 2.0 mini-driver.

For more information, see Introduction to WIA.

Build the sample

You can build the sample in two ways: using the Visual Studio Integrated Development Environment (IDE) or from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe).

Building the sample using Visual Studio

  1. Open Visual Studio. From the File menu, select Open Project/Solution. Within your WDK installation, navigate to src\wia and open the wia.sln project file.

  2. Right-click the solution in the Solution Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Windows 8.1 Debug or Windows 8.1 Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can use the Visual Studio Command Prompt window for all build configurations.

Building the sample using the command line (MSBuild)

  1. Open a Visual Studio Command Prompt window. Click Start and search for Developer Command Prompt. If your project is under %PROGRAMFILES%, you need to open the command prompt window using elevated permissions (Run as administrator). From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called extend.vcxproj, navigate to the project directory and enter the following MSBuild command: msbuild /t:clean /t:build .\extend.vcxproj.

  3. If the build succeeds, you will find the driver (extend.dll) in the binary output directory corresponding to the target platform, for example src\wia\extend\Windows 8.1 Debug.

Run the sample

Run the "copywia.cmd” batch file to gather all of the binaries into a subdirectory named “wiabins”. The WIA driver sample can be installed by using the Add Device icon in the Scanners and Cameras control panel. Use the Have Disk button to point to the wiabins\drivers or wiabins\drivers folder. Wiatest.exe (from the WDK Tools\Wia directory), MS Paint, the Scanner and Camera Wizard, or any TWAIN application (through the WIA TWAIN compatibility layer) can be used to test the samples.


Overview (`.github/pdu/PduReadme.md`)

PDU Setup: Eaton Tripp Lite Switched Power Distribution Unit (PDUMH15NET)

Requirements:

HW:

  • USBA-to-MicroUSB cable, needed for 1st time PDU login and password change, if IP address is unknown.
  • Ethernet cable, can be used if the IP address is known.

SW:

  • Tera Term 5.6.1 terminal client:
    • Terminal client for PDU login and configuration via serial.
  • PuTTY 0.84 terminal client:
    • Plink.exe needed for PowerShell scripting via network.
    • Note: PuTTY terminal client GUI does not appear to work, so Tera Term client was used instead, but Plink.exe is needed for passing passwords via SSH in PowerShell scripts.

Serial Connection

What's my IP address?

  • If the PDU is connected to a network with DHCP, then we need to find it's IP address first by using serial connection.
    • If the PDU is not connected to a network with DHCP, then its default static IP address should be 169.254.0.1.
    • If that's the case, then you can login to the PDU via a browser by skipping the the section Network Connection.

Tera Term:

  • Connect the PC to the PDU (CONFIG port) with a USBA-to-MiniUSB cable.
  • On the PC, go to Device Manager and verify under Ports (COM & LPT), the USB Serial Device (COM3) device is present.
  • Download and install Tera Term on PC, if not already present.
    • You may use other Terminal Emulation Programs, but this is the one used in the manufacturer's user manual to connect to the WEBCARDLX network interface card.
  • Launch Tera Term and select the "Serial" connection type and ensure Port: "COM3: USB Serial Device (COM3) is selected, then click "OK".
  • When the blinking cursor in the empty prompt stops blinking, hit Enter key to wake up console.
  • The Ubuntu 18.04.6 LTS poweralert-0006674a215f (<-- MAC Address) should show up in the prompt asking for login.
    • Default login is: localadmin
    • Default 1st time password is: localadmin
      • Must change password after 1st logon.
      • Change password to @Password123 to match what the pdu.ps1 PowerShell script uses.
  • Once logged in, type show network to display network information such as current IP address.
    • If on DHCP network, note the IP address assigned to the PDU.
    • PDU default if no DHCP:
      • IPv4: 169.254.0.1
      • Subnet Mask: 255.255.0.0
  • Test pinging the IPv4 address of the PDU from the PC.
    • ping
  • Now that you have the IP address, it may be easier to switch over to the browser interface to configure the rest of the PDU.

Network Connection

  • Connect an Ethernet cable from the PC to the PDU Ethernet port.
  • Since we have the IP of the PDU, it's easier to configure the PDU via a browser interface.
  • Open an Internet browser and enter the IPv4 address of the PDU into the browser.
    • If it prompts you about any security warnings, just find a way to accept and continue anyway.
  • The Power Alert LX web interface should prompt for username and password.
  • If 1st time login...
    • Default login is: localadmin
    • Default 1st time password is: localadmin
      • Must change password after 1st logon.
      • Change password to @Password123 to match what the pdu.ps1 PowerShell script uses.
  • Select Load tab on the left of screen to see all the loads on the 16 power ports.
  • Click on the State slider to show the Load options, Turn Off Load and Cycle Load.
  • To enable SSH for PowerShell scripting later, select Network tab, then Services, then enable SSH Enabled.

Scripting

  • The Pdu.ps1 PowerShell script can be used for automating power ON/OFF/CYCLE of the PDU ports.
  • Usage: .\Pdu.ps1 [on | off | cycle] [1-16]
  • Update the following variables in the Pdu.ps1 script if necessary.
    • $PduIP = "169.254.0.1"
    • $Password = "@Password123"
  • The script will check first if there's a serial connection first, then network connection if serial is not present, before issuing the PDU command.

References


Overview (`audio/SoundWire/README.md`)

Soundwire

Microsoft Soundwire Samples and Guides


Overview (`audio/simpleaudiosample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Simple Audio Sample Device Driver

Introduction

The Microsoft Simple Audio Sample Device Driver shows how to develop a simple WDM audio driver that exposes support for two basic audio devices (a speaker and microphone array). These audio devices are embedded in the system (not pluggable) and the driver uses WaveRT for rendering these devices. The driver also uses a "virtual audio device" instead of an actual hardware-based adapter.

Driver developers can use the framework in this sample to provide support for various audio devices without concern for hardware dependencies. The framework includes implementations of the following interfaces:

  • The CAdapterCommon interface gives the miniports access to virtual mixer hardware. It also implements the IAdapterPowerManagement interface.

  • The CMiniportTopologySimpleAudioSample interface is the base class for all sample topologies. It has very basic common functions. In addition, this class contains common topology property handlers.

The following table shows the contents of the various subdirectories of this sample.

Directory Description
Source Contains all of the source code for the Simple Audio Sample driver.
Filters Contains the definitions of the wave and topology filters of the endpoints that are present in the Simple Audio Sample driver (speaker and microphone array).
Main Contains the core functionality of the driver.
Utilities Contains helper files that provide additional functionality, such as a test tone generator and an audio file reader.

Build the sample

If you simply want to build this sample driver and don't intend to run or test it, then you do not need a target computer (also called a test computer). If, however, you would like to deploy, run and test this sample driver, then you need a second computer that will serve as your target computer. Instructions are provided in the Run the sample section to show you how to set up the target computer - also referred to as provisioning a target computer.

Perform the following steps to build this sample driver.

1. Open the driver solution in Visual Studio

In Microsoft Visual Studio, Click File > Open > Project/Solution... and navigate to the folder that contains the sample files (for example, C:\Windows-driver-samples\audio\SimpleAudioSample). Double-click the SimpleAudioSample solution file.

In Visual Studio locate the Solution Explorer. (If this is not already open, choose Solution Explorer from the View menu.) In Solution Explorer, you can see one solution that has five projects.

2. Set the sample's configuration and platform

In Solution Explorer, right-click Solution ‘SimpleAudioSample’ (5 of 5 projects), and choose Configuration Manager. Make sure that the configuration and platform settings are the same for the five projects. By default, the configuration is set to Debug, and the platform is set to Win32 for all the projects. If you make any configuration and/or platform changes for one project, you must make the same changes for all the remaining projects.

3. Build the sample using Visual Studio

In Visual Studio, click Build > Build Solution.

4. Locate the built driver package

In File Explorer, navigate to the folder that contains the sample files. For example, you would navigate to C:\Windows-driver-samples\audio\SimpleAudioSample, if that's the folder you specified in the preceding Step 1.

In the folder, the location of the driver package varies depending on the configuration and platform settings that you selected in the Configuration Manager. For example, if you left the default settings unchanged, then the built driver package will be saved to a folder named Debug inside the same folder as the sample files. Double-click the folder for the built driver package, and then double-click the folder named package.

The package should contain these files:

File Description
SimpleAudioSample.sys The driver file.
SimpleAudioSample.cat A signed catalog file, which serves as the signature for the entire package.
SimpleAudioSample.inf A non-componentized information (INF) file that contains information needed to install the driver.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from the computer on which you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy the SimpleAudioSample driver automatically or manually.

Prepare the target computer

First of all, install the latest Windows Driver Kit (WDK) on the target computer.

Before you manually deploy a driver, you must prepare the target computer by turning on test signing and by installing a certificate. You also need to locate the DevCon tool in your WDK installation. After that you're ready to run the built driver sample.

Open a Command Prompt window as Administrator. Then enter the following command:

bcdedit /set TESTSIGNING ON

and reboot the target computer.

[!IMPORTANT]
Before using BCDEdit to change boot information you may need to temporarily suspend Windows security features such as BitLocker and Secure Boot on the test PC.

Re-enable these security features when testing is complete and appropriately manage the test PC, when the security features are disabled.

After rebooting, navigate to the Tools folder in your WDK installation and locate the DevCon tool. For example, look in the following folder:

C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe

Copy devcon.exe to a folder on the target computer where it is easier to find. For example, create a C:\Tools folder and copy devcon.exe to that folder.

Create a folder on the target for the built driver package (for example, C:\SimpleAudioSampleDriver). Copy all the files from the built driver package on the host computer and save them to the folder that you created on the target computer.

Create a folder on the target computer for the certificate created by the build process. For example, you could create a folder named C:\Certificates on the target computer, and then copy package.cer to it from the host computer. You can find this certificate in the same folder on the host computer, as the package folder that contains the built driver files. On the target computer, right-click the certificate file, and click Install, then follow the prompts to install the test certificate.

If you need more detailed instructions for setting up the target computer, see Preparing a Computer for Manual Driver Deployment.

A note on signatures

Since most of these binary files are executed in kernel mode, it is important that they are signed and, optionally, to have a kernel debugger attached.

Without any signature or kernel debugger, the driver will not be installed in the target computer. With a kernel debugger attached, the driver can be installed and the driver files (.sys extension) would be loaded. The only way of installing and executing the driver sample without a kernel debugger attached is to have both the .sys and .cat files signed with a trusted certificate.

For more information on the subject, see Driver signing.

Install the driver

To install SimpleAudioSample.inf, open a Command Prompt window as administrator on the target computer, then navigate to your driver package folder and enter the following command:

devcon install SimpleAudioSample.inf Root\SimpleAudioSample

If you get an error message about devcon not being recognized, try adding the path to the devcon tool. For example, if you copied it to a folder called C:\Tools, then try using the following command:

C:\\tools\\devcon install SimpleAudioSample.inf Root\SimpleAudioSample

This installs the Simple Audio Sample driver with a hardware ID of "Root\SimpleAudioSample".

Once the INF file is installed, a device should appear in Device Manager named Microsoft Virtual Audio Device (WDM) - Simple Audio Sample.

After successfully installing the sample driver, you're now ready to test it.

For more detailed instructions, see Provision a computer for driver deployment and testing.

Test the driver

On the target computer, in a Command Prompt window, enter devmgmt.msc to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Virtual Audio Device (WDM) – Simple Audio Sample. This is typically under the Sound, video and game controllers node.

On the target computer, open Control Panel and navigate to Hardware and Sound > Manage audio devices. In the Sound dialog box, select the speaker icon labeled as Virtual Audio Device (WDM) – Simple Audio Sample, then click Set Default, but do not click OK. This will keep the Sound dialog box open.

Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound dialog box, verify that there is activity in the volume level indicator associated with the Virtual Audio Device (WDM) – Simple Audio Sample driver.


Overview (`audio/sysvad/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk
    urlFragment: sysvad-virtual-audio-device-driver-sample

SysVAD Virtual Audio Device Driver Sample

[!NOTE]
With the end of support for Windows 10 Mobile, the Phone Audio sample has been also removed from the SysVAD driver sample.

Introduction

The Microsoft SysVAD Virtual Audio Device Driver (SYSVAD) shows how to develop a WDM audio driver that exposes support for multiple audio devices.

Some of these audio devices are embedded in the system (for example, speakers, microphone arrays) while others are pluggable (like headphones, Bluetooth headsets etc.). The driver uses WaveRT and audio offloading for rendering devices. The driver uses a "virtual audio device" instead of an actual hardware-based adapter, and highlights the different aspects of the audio offloading WDM audio driver architecture.

Driver developers can use the framework in this sample to provide support for various audio devices without concern for hardware dependencies. The framework includes implementations of the following interfaces:

  • The CAdapterCommon interface gives the miniports access to virtual mixer hardware. It also implements the IAdapterPowerManagement interface.

  • The CMiniportTopologySYSVAD interface is the base class for all sample topologies. It has very basic common functions. In addition, this class contains common topology property handlers.

The following table shows the features that are implemented in the various subdirectories of this sample.

Directory Description
TabletAudioSample Endpoints that are present in TabletAudioSample driver.
EndpointsCommon Endpoints that are present in both TabletAudioSample and PhoneAudioSample. It also contains other common code shared by both sample drivers.
SwapAPO Sample APO that installs onto endpoints exposed by the SysVAD sample driver and swaps the left and right channels.
DelayAPO Sample APO that adds a delay to the input samples.
KwsAPO Sample APO that uses KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION to determine if the keyword spotter pin is interleaving loopback audio with the microphone audio and identify which channels contain loopback audio. If it is interleaved the APO will strip out the loopback audio and deliver only the microphone audio upstream. Because channel data is removed, the APO negotiates an output format which is different than the input format.
AecAPO Sample capture MFX APO that implements Acoustic Echo Cancellation. This APO demonstrates the use of echo cancellation interfaces that an AEC APO uses to obtain reference audio for cancellation.
KeywordDetectorAdapter Sample Keyword Detector Adapter.

For more information about the Windows audio engine, see Hardware-Offloaded Audio Processing, and note that audio hardware that is offload-capable replicates the architecture that is presented in the diagram shown in the topic.

Build the sample

If you simply want to build this sample driver and don't intend to run or test it, then you do not need a target computer (also called a test computer). If, however, you would like to deploy, run and test this sample driver, then you need a second computer that will serve as your target computer. Instructions are provided in Run the sample to show you how to set up the target computer - also referred to as provisioning a target computer.

Perform the following steps to build this sample driver.

Setup the development computer

For building the sample driver, the following components must be installed:

  • Visual Studio,
  • Windows SDK,
  • Windows Driver Kit (WDK).

Please refer to Download the Windows Driver Kit for instructions on how to download and install each one.

From the Visual Studio Installer, the following individual packages must be installed in order to build SysVAD:

  • C++ ATL for latest v142 build tools <arch>
  • C++ ATL for latest v142 build tools with Spectre Mitigations <arch>
  • MSVC v142 - VS 2019 C++ <arch> build tools (Latest)
  • MSVC v142 - VS 2019 C++ <arch> build tools Spectre-mitigated libs (Latest)

Where "<arch>" refers to your target architecture.

Configure the repository for Windows Implementation Library (WIL)

In order to build the project, it is necessary to include WIL. The Windows Driver Samples repository includes WIL as a Git submodule.

If it has not been done before (such as in a fresh clone), the following command should be run at the root of the repository:

git submodule update --init

This will populate a folder named wil at the root of the repository.

Open the driver solution in Visual Studio

In Microsoft Visual Studio, click File > Open > Project/Solution... and navigate to the folder that contains the sample files (for example, C:\Windows-driver-samples\audio\sysvad). Double-click the sysvad solution file.

In Visual Studio locate the Solution Explorer. (If this is not already open, choose Solution Explorer from the View menu.) In Solution Explorer, you can see one solution that has eight projects.

Set the sample's configuration and platform

Right-click Solution 'sysvad' (8 of 8 projects) once more and choose Configuration Manager. Make sure that the configuration and platform settings are the same for the eight projects. By default, the configuration is set to Debug, and the platform is set to Win32 for all the projects. If you make any configuration and/or platform changes for one project, you must make the same changes for all the remaining projects.

Build the sample using Visual Studio

In Visual Studio, click Build > Build Solution.

Locate the built driver package

In File Explorer, navigate to the folder that contains the sample files. For example, you would navigate to C:\Windows-driver-samples\audio\sysvad, if that's the folder you specified in the preceding Step 1.

In the folder, the location of the driver package varies depending on the configuration and platform settings that you selected in the Configuration Manager. For example, if you left the default settings unchanged, then the built driver package will be saved to a folder named Debug inside the same folder as the sample files. Double-click the folder for the built driver package, and then double-click the folder named package.

The package should contain these files:

File Description
TabletAudioSample.sys The driver file.
DelayAPO.dll The delay APO.
KeywordDetectorContosoAdapter.dll Sample Keyword detector adapter.
AecApo.dll The AEC APO.
KWSApo.dll The KWS APO.
SwapAPO.dll The swap APO.
sysvad.cat A signed catalog file, which serves as the signature for the entire package.
ComponentizedApoSample.inf A componentized information (INF) file that installs an APO device.
ComponentizedAudioSample.inf A componentized information (INF) file that contains information needed to install the Tablet Audio Sample driver.
ComponentizedAudioSampleExtension.inf An extension information (INF) file that extends the Tablet Audio Sample driver functionality by associating an APO device to it.
TabletAudioSample.inf A non-componentized information (INF) file that contains information needed to install the driver.

For more information on extension INF files, see Using an extension INF file.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from the computer on which you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy the TabletAudioSample sample driver automatically or manually.

Setup the target computer

First of all, install the latest Windows Driver Kit (WDK) on the target computer.

Before you manually deploy a driver, you must prepare the target computer by turning on test signing and by installing a certificate. You also need to locate the DevCon tool in your WDK installation. After that you're ready to run the built driver sample.

Open a Command Prompt window as Administrator. Then enter the following command:

bcdedit /set TESTSIGNING ON

and reboot the target computer.

[!IMPORTANT]
Before using BCDEdit to change boot information you may need to temporarily suspend Windows security features such as BitLocker and Secure Boot on the test PC.

Re-enable these security features when testing is complete and appropriately manage the test PC, when the security features are disabled.

After rebooting, navigate to the Tools folder in your WDK installation and locate the DevCon tool. For example, look in the following folder:

C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe

Copy devcon.exe to a folder on the target computer where it is easier to find. For example, create a C:\Tools folder and copy devcon.exe to that folder.

Create a folder on the target for the built driver package (for example, C:\SysvadDriver). Copy all the files from the built driver package on the host computer and save them to the folder that you created on the target computer.

Create a folder on the target computer for the certificate created by the build process. For example, you could create a folder named C:\Certificates on the target computer, and then copy package.cer to it from the host computer. You can find this certificate in the same folder on the host computer, as the package folder that contains the built driver files. On the target computer, right-click the certificate file, and click Install, then follow the prompts to install the test certificate.

If you need more detailed instructions for setting up the target computer, see Preparing a Computer for Manual Driver Deployment.

A note on signatures

Since most of these binary files are executed in kernel mode, it is important that they are signed and, optionally, to have a kernel debugger attached.

Without any signature or kernel debugger, the driver will not be installed in the target computer. With a kernel debugger attached, the driver can be installed and the driver files (.sys extension) would be loaded, but any user mode files (.dll files) will not be loaded.

The only way of installing and executing the whole driver sample is to have all the files (.sys, .dll and .cat) signed with a trusted certificate. This will allow the entire driver to be loaded even without a kernel debugger attached.

For more information on the subject, see Driver signing.

Install the driver

Componentized INF files

The TabletAudioSample driver package contains a sample driver, an extension sample and an APO software component. The following instructions show you how to install and test the sample driver, the APO component and then the extension to apply the software component to the driver.

First, the base INF, ComponentizedAudioSample.inf, has to be installed. To install it, open a Command Prompt window as administrator on the target computer, then navigate to your driver package folder and enter the following command:

devcon install ComponentizedAudioSample.inf Root\Sysvad_ComponentizedAudioSample

If you get an error message about devcon not being recognized, try adding the path to the devcon tool. For example, if you copied it to a folder called C:\Tools, then try using the following command:

C:\\tools\\devcon install ComponentizedAudioSample.inf Root\Sysvad_ComponentizedAudioSample

This installs the base Tablet Audio Sample driver with a hardware ID of "Root\Sysvad_ComponentizedAudioSample".

Then, either the extension INF (ComponentizedAudioSampleExtension.inf) or the APO INF (ComponentizedApoSample.inf) can be installed.

If the extension INF is installed first, it will create a new component called Audio Proxy APO Sample. Until the APO is installed, this component will appear in Device Manager under the section of Software Components, because it does not have a driver attached yet. The driver is attached by installing the APO INF.

If the APO is installed first, it will install a driver, but it will not create a device, so the APO will not be visible in Device Manager until the extension INF creates a software component that will then have the APO driver installed.

Both extension and APO INFs can be installed by right-clicking on any of the files and selecting "install" from the menu.

Once the three componentized INF files are installed, an APO device should appear in Device Manager and the Microsoft Virtual Audio Device (WDM) - Tablet Audio Sample device should now be named SYSVAD (with APO Extensions).

For more detailed instructions, see Provision a computer for driver deployment and testing.

Single INF files

TabletAudioSample also contains an INF file, tabletaudiosample.inf, which install the sample driver using a single INF file.

Componentized driver packages are required since Windows 10 1809 release. However, for backward compatibility, instructions on how to install the TabletAudioSample.inf are provided below.

On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

devcon install TabletAudioSample.inf Root\Sysvad_TabletAudioSample

After successfully installing the sample driver, you're now ready to test it.

Test the driver

On the target computer, in a Command Prompt window, enter devmgmt.msc to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate SYSVAD (with APO Extensions). This is typically under the Sound, video and game controllers node.

On the target computer, open Control Panel and navigate to Hardware and Sound > Manage audio devices. In the Sound dialog box, select the speaker icon labeled as SYSVAD (with APO Extensions), then click Set Default, but do not click OK. This will keep the Sound dialog box open.

Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound dialog box, verify that there is activity in the volume level indicator associated with the SYSVAD (with APO Extensions) driver.

HLK testing

The sample uploaded here is tested using the latest HLK version available to make sure it passes all audio tests in the current playlist. However, since it is a virtual audio driver it does not implement audio mixing and simulates capture and loopback by generating a tone. Given these limitations, there are some HLK tests that are expected to fail because they rely on the described functionality.

In the case of audio tests, one of these exceptions is the Hardware Offload of Audio Processing Test. This test is aimed at devices that support offload capabilities and performs checks to make sure that the device complies with the appropiate requirements. In the particular case of SysVAD, this test will fail for endpoints with offload and loopback.

For endpoints with offload, the test will fail because the driver includes offload pins but it does not implement a mixer with volume, mute and peak meter nodes, etc. For the case of endpoints with loopback, the test will fail because the driver simulates loopback by returning a sine tone instead of performing real mixing of streams in host and/or offload pins.


Overview (`avstream/avscamera/README.md`)


page_type: sample
urlFragment: avscamera
languages:

  • cpp
    products:
  • windows
  • windows-wdk

AvsCamera - AVStream Camera Sample Driver

The AvsCamera sample provides a pin-centric AVStream capture driver for a simulated front and back camera. The driver performs simulated captures at 320x240 or 640x480 in RGB24, RGB32, YUY2 and NV12 formats at various frame rates. The purpose of the sample is to demonstrate how to write a fully functional AVStream camera driver.

This sample features strong parameter validation and overflow detection. It provides validation and simulation logic for all advanced camera controls in the CCaptureFilter class. A real camera driver would replace the filter automation table and CSensor and CSynthesizer class hierarchies to produce a new camera driver.

The sample comes with its own DeviceMFT called AvsCameraMft0.dll. This DeviceMFT is used to parse metadata supplied in the AvsCamera driver samples. The metadata communications from the driver is primarily a private channel to its DeviceMFT. The DeviceMFT is responsible for reformatting that information for the capture pipeline.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP. The sample works on 32-bit and 64-bit x86, amd64 and arm platforms. Once installed, the simulated camera should show in the Windows Inbox camera app.

Building the sample

The AvsCamera sample can be built by opening the AvsCamera.sln solution file. A successful build produces AvsCamera.sys, AvsCameraDMFT.dll, AvsCamera.inf and AvsCamera.cat.


Overview (`avstream/avshws/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

AVStream simulated hardware sample driver (Avshws)

The AVStream simulated hardware sample driver (Avshws) provides a pin-centric AVStream capture driver for a simulated piece of hardware. This streaming media driver performs video captures at 320 x 240 pixels in either RGB24 or YUV422 format using direct memory access (DMA) into capture buffers. The purpose of the sample is to demonstrate how to write a pin-centric AVStream minidriver. The sample also shows how to implement DMA by using the related functionality provided by the AVStream class driver.

This sample features enhanced parameter validation and overflow detection.

Provision a target computer

After you've installed the sample on your host computer, run Visual Studio, and from the File menu, select Open, then Project/Solution..., navigate to the directory where you've copied the Avshws sample, then to the C++ folder, and select avshws.vcxproj (the VC++ Project).

In the Solution Explorer pane in Visual Studio, at the top is Solution 'avshws'. Right-click this and select Configuration Manager. Follow the instructions in Building a Driver with Visual Studio and the WDK to set the platform, operating system, and debug configuration you want to use, and to build the sample. This sample project will automatically sign the driver package.

Provision your target computer using instructions in, for example, Provision a computer for driver deployment and testing. Ensure that in the Network and Sharing Center control panel your target computer has Network Discovery and File and Printer Sharing enabled.

Deploy the driver to the target computer

Now you can deploy the Avshws driver that you've just built to the target computer, using guidance in Deploying a Driver to a Test Computer. Specifically, find the package file under the Package folder in the Avshws solution. Right-click package and select Properties. Under Configuration Properties, click Driver install and then Deployment. Here you must click the check box for Enable deployment, and then click the button to the right of <Configure Computer...>. In the next dialog you enter the Target Computer Name and can let the host computer automatically provision the target computer and set up debugger options.

Finally, in Visual Studio, from the Build menu select Deploy Solution to deploy the sample to the target computer. On the target computer, you can see the deployed package in the %Systemdrive%\drivertest\drivers folder.

Install the driver

On the target computer, open Device Manager, and follow these steps:

  1. In the Action menu, click Add Legacy Hardware, and the Add Hardware Wizard appears. Click Next and then Next again.

  2. In the Add Hardware window, select Show All Devices.

  3. In the Manufacturer list in the left pane, click Microsoft.

  4. You should see the AVStream Simulated Hardware Sample in the Model pane on the right. Click this and then click Next.

  5. Click Next again to install the driver, and then click Finish to exit the wizard.

The sample driver now appears in the Device Manager console tree under Sound, video and game controllers. The Avshws INF file will be on the system drive at, for example, ...windows\System32\DriverStore\FileRepository\.

Sample code hierarchy

DriverEntry in Device.cpp is the initial point of entry into the driver. This routine passes control to AVStream by calling the KsInitializeDriver function. In this call, the minidriver passes the device descriptor, an AVStream structure that recursively defines the AVStream object hierarchy for a driver. This is common behavior for an AVStream minidriver.

At device start time, a simulated piece of capture hardware is created (the CHardwareSimulation class), and a DMA adapter is acquired from the operating system and is registered with AVStream by calling the KsDeviceRegisterAdapterObject function. This call is required for a sample that performs DMA access directly into the capture buffers, instead of using DMA access to write to a common buffer. The driver creates the KS Filter for this device dynamically by calling the KsCreateFilterFactory function.

Filter.cpp is where the sample lays out the KSPIN_DESCRIPTOR_EX structure for the single video pin. In addition, a KSFILTER_DISPATCH structure and a KSFILTER_DESCRIPTOR structure are provided in this source file. The filter dispatch provides only a create dispatch, a routine that is included in Filter.cpp. The process dispatch is provided on the pin because this is a pin-centric sample.

Capture.cpp contains source for the video capture pin on the capture filter. This is where the KSPIN_DISPATCH structure for the unique pin is provided. This dispatch structure specifies a Process callback routine, also defined in this source file. This routine is where stream pointer manipulation and cloning occurs.

The process callback is one of two routines of interest in Capture.cpp that demonstrate how to perform DMA transfers with AVStream functionality. The other is the CCapturePin::CompleteMappings method. These two methods show how to use the queue, obtain clone pointers, use scatter/gather lists, and perform other DMA-related tasks.

For more information, see the comments in all .cpp files.

Run the sample

Follow these steps to see how the sample driver functions:

  1. After installation has completed, access the driver through the Graphedt tool. Graphedt.exe is available in the tools directory of the WDK.

  2. Before running GraphEdit, use the regsvr32 utility to register the proppage.dll DLL and to enable GraphEdit to display property pages for some of the built-in Microsoft DirectShow filters. Open an elevated command window with Administrator privileges, and navigate to the WDK or SDK tools directory that contains proppage.dll.

  3. On the command line, type regsvr32 proppage.dll. If the registration succeeds, you'll get a message, "DllRegisterServer in proppage.dll succeeded." Click OK.

  4. In the Graphedt tool, click the Graph menu and click Insert Filters. The sample appears under "WDM Streaming Capture Devices" as "avshws Source."

  5. Click Insert Filter. The sample appears in the graph as a single filter labeled, "avshws Source." There is one output pin, which is the video capture pin. This pin emits video in YUY2 format.

  6. Attach this filter to either a DirectShow Video Renderer or to the VMR default video renderer. Then click Play.

The output that is produced by the sample is a 320 x 240 pixel image of standard EIA-189-A color bars. In the middle of the image near the bottom, a clock appears over the image. This clock displays the elapsed time since the graph was introduced into the run state following the last stop. The clock display format is MINUTES:SECONDS.HUNDREDTHS.

In the upper-left corner of the image, a counter counts the number of frames that have been dropped since the graph was introduced into the run state after the last stop.

File manifest

File Description
Avshws.h Main header file for the sample
Avshws.inf Sample installation file
Capture.cpp Capture pin implementation for all capture pins on the sample filter.
Capture.h Capture pin level header for all capture pins on the sample filter.
Device.cpp Device level implementation of the simulated hardware.
Device.h Device level header for the simulated hardware.
Filter.cpp Capture filter implementation (including frame synthesis) for the fake capture filter.
Filter.h Filter level header for the filter-centric capture filter.
HWSim.cpp Hardware simulation implementation, including fake "DMA" transfers, scatter gather mapping handling, ISRs, etc.
HWSim.h Hardware simulation header.
Image.cpp Image synthesis and overlay code. These objects provide image synthesis (pixel, color-bar, etc) onto RGB24 and UYVY buffers as well as software string overlay into these buffers.
Image.h Image synthesis and overlay header.
Purecall.h _purecall stub necessary for virtual function usage in drivers.

Overview (`avstream/avssamp/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

AVStream filter-centric simulated capture sample driver (Avssamp)

The AVStream filter-centric simulated capture sample driver (Avssamp) provides a filter-centric AVStream capture driver with functional audio. This streaming media driver performs video captures at 320 x 240 pixel resolution in RGB24 or YUV422 format while playing a user-provided Pulse Code Modulation (PCM) wave audio file in a loop. The sample demonstrates how to write a filter-centric AVStream minidriver.

Installation instructions

  1. Copy AVssamp.inf to a directory, for example, C:\Avstream\.

  2. In this directory, create a new subdirectory named objfre_x86 if the target operating system is x86-based, or objfre_amd64 for an x64-based target operating system, for example, C:\AVstream\objfre_x86\.

  3. Copy the processor-appropriate Avssamp.sys file to the objfre_* directory.

  4. Start a command prompt with administrator privilege and run the processor-specific WDK tool Devcon.exe to launch the installation. For example:

    C:\WinDDK\7600.16384.0\tools\devcon\i386\devcon.exe install C:\AVstream\avssamp.inf SW\{20698827-7099-4c4e-861A-4879D639A35F}

Programming tour

DriverEntry in Avssamp.cpp is the initial point of entry into the driver. This routine passes control to AVStream by calling KsInitializeDriver. In this call, the minidriver passes the device descriptor, an AVStream structure that recursively defines the AVStream object hierarchy for a driver. This is common behavior for an AVStream minidriver.

Filter.cpp is where the sample lays out the KSPIN_DESCRIPTOR_EX structure for the single capture pin. Audio.cpp contains the KSPIN_DESCRIPTOR_EX structure for the audio capture pin. This pin is dynamically created only if C:\avssamp.wav exists and is a valid and readable PCM format wave file.

The filter dispatch structure KSFILTER_DISPATCH in Filter.cpp provides dispatches to create and process data. The DispatchProcess method is defined inline in Filter.h. It calls the Process method in Filter.cpp in the context of the CCaptureFilter class. Be aware that the process dispatch is provided in KSFILTER_DISPATCH because this sample is filter-centric.

Audio.cpp lays out a KSPIN_DISPATCH pin dispatch structure, which contains the dispatch table for the audio pin. Be aware that the Process member of this structure is NULL because the sample is filter-centric. Similarly, Video.cpp contains the KSPIN_DISPATCH structure for the video capture pin, again with the Process member set to NULL.

For more information, see the comments in all .cpp files.

File manifest

File Description
Audio.cpp Audio capture pin implementation
Audio.h Header file for Audio.cpp
Avssamp.cpp Main file for the AVStream filter-centric sample.
Avssamp.h Main header for the AVStream filter-centric sample.
Avssamp.inf Installation information for the AVStream sample driver (avssamp.sys).
Capture.cpp Capture pin implementation for all capture pins on the sample filter.
Capture .h Capture pin level header for all capture pins on the sample filter.
Filter.cpp Capture filter implementation (including frame synthesis) for the fake capture filter.
Filter.h Filter level header for the filter-centric capture filter.
Image.cpp Image synthesis and overlay code. These objects provide image synthesis (pixel, color-bar, etc) onto RGB24 and UYVY buffers as well as software string overlay into these buffers.
Image.h Image synthesis and overlay header
Purecall.h _purecall stub necessary for virtual function usage in drivers.
Video.cpp Video capture pin implementation
Video.h Video capture pin header
Wave.cpp Wave object implementation
Wave.h Wave object header

Overview (`avstream/sampledevicemft/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Driver Device Transform Sample

Illustrative example for a Driver Device Transform which loads in a process streaming an Avstream based camera device using Media Foundation.

A Driver Device Transform is a new kind of a transform that's used with a specific camera when capturing video. The Driver Device Transform is also known as DeviceMFT because it is the first Device Transform applied to the video source. This Driver Device Transform is an alternative to the Driver MFT, for example, MFT0 in that it caters to the source rather than the streams. An N stream source supporting DeviceMFT will have a single instance of the Device Driver Transform loaded, while MFT0 will have N instances for each pipeline process. The DeviceMFT can advertise multiple streams at the output, which can differ from the number of streams advertised by the source. This is analogous to having a user mode driver in the MF pipeline which intercepts and processes commands before they enter/ leave the Kernel mode driver loaded for the streaming source.

In this sample, the Device Transform, when enabled, will replicate a photo sequence in the user mode from a one pin device. It acts as a passthrough for sources exposing more than one pins.

This sample is designed to be used with a specific camera. To run the sample, you need the your camera's device ID and device metadata package.

Concepts

UWP device apps for cameras

Media Foundation Transforms

Streaming media device driver design guide

Universal camera driver design guide for Windows 10

Samples

Device app for camera sample

Camera Capture UI sample


Overview (`avstream/samplemft0/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Driver MFT Sample

Provides a driver MFT for use with a camera's UWP device app.A driver MFT is a Media Foundation Transform that's used with a specific camera when capturing video. The driver MFT is also known as MFT0 because it is the first MFT applied to the video stream captured from the camera. This MFT can provide a video effect or other processing when capturing photos or video from the camera. It can be distributed along with the driver package for a camera.

In this sample, the driver MFT, when enabled, replaces a portion of the captured video with a green box. To test this sample, download the UWP device app for camera sample and the Camera Capture UI sample.

The UWP device app for camera sample provides a UWP device app that controls the effect implemented by the driver MFT.

The Camera Capture UI sample provides a way to invoke the UWP device app.

This sample is designed to be used with a specific camera. To run the sample, you need the your camera's device ID and device metadata package.

Concepts

UWP device apps for cameras

Media Foundation Transforms

Streaming media device driver design guide

Universal camera driver design guide for Windows 10

Samples

Device app for camera sample

Camera Capture UI sample


Overview (`bluetooth/bthecho/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Bluetooth Echo L2CAP Profile Driver

This sample demonstrates developing Bluetooth L2CAP profile drivers using Bluetooth L2CAP DDIs.The sample includes two drivers. One for a device that acts as an L2CAP server and another for a device that acts as an L2CAP client. The server simply echoes back any data that it receives from client on the same L2CA channel. These drivers can be used with devices that can be installed with bth.inf. Such devices get installed as 'Generic Bluetooth Radio'. Examples of such devices are Bluetooth USB dongles such as (but not limited to):

inf
Generic Bluetooth Radio=\
                         BthUsb, USB\Vid_0a12&Pid_0001
CSR Nanosira=\
                         BthUsb, USB\Vid_0a12&Pid_0003
CSR Nanosira WHQL Reference Radio=\
                         BthUsb, USB\Vid_0a12&Pid_0004
CSR Nanosira-Multimedia=\
                         BthUsb, USB\Vid_0a12&Pid_0005
CSR Nanosira-Multimedia WHQL Reference Radio=\
                         BthUsb, USB\Vid_0a12&Pid_0006

Please refer to bth.inf for the complete list of devices. The installation steps below describe how to install echo server and client with such a device. Please note that RFCOMM based profiles must be developed and accessed using user-mode socket APIs.

Build the sample

You can build the sample in two ways: using the Visual Studio Integrated Development Environment (IDE) or from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe).

Building the sample using Visual Studio

  1. Open Visual Studio. From the File menu, select Open Project/Solution and open the bthecho.sln project file.

  2. Right-click the solution in the Solution Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Building the sample using the command line (MSBuild)

  1. Open a Visual Studio Command Prompt window. Click Start and search for Developer Command Prompt. If your project is under %PROGRAMFILES%, you need to open the command prompt window using elevated permissions (Run as administrator). From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to each of the respective project directories and enter the appropriate MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called BthEcho.vcxproj, navigate to the samples\bluetooth\bthecho\bthcli\sys project directory and enter the following MSBuild command: msbuild /t:clean /t:build .\BthEchoSampleCli.vcxproj.

  3. If the build succeeds, you will find the driver (BthEchoSampleCli.sys) in the binary output directory corresponding to the target platform.

Run the sample

Installation

[!NOTE]
Bluetooth echo server device and echo client device must be installed on two different machines, as described below.

Server Installation

  1. Copy BthEchoSampleSrv.Sys, BthEchoSampleSrv.inf and bthsrvinst.exe on a temporary directory on the target machine.

  2. Run bthsrvinst.exe /i to install the echo server device. This enables the Bluetooth Enumerator (BthEnum.sys) to enumerate echo server device and create a PDO for the device (please refer to the device tree below).

  3. Step #2 causes BthEnum.sys to create a PDO. Consequently hardware installation wizard gets launched. Either go through the UI and point it to the temporary directory where you copied the binaries in step #1, or using devcon.exe from the tools\devcon folder, run the following command from the temporary directory:

devcon.exe update BthEchoSampleSrv.inf BTHENUM\{c07508f2-b970-43ca-b5dd-cc4f2391bef4}

If devcon.exe fails check the error level using:

echo %errorlevel%

If errorlevel is 1, you need to reboot the machine for KMDF update to take effect. If errorlevel is 2, please make sure that you have the driver files described in #1 available in the current directory. For more information on installation failure please check setup logs.

  1. Upon successful installation you will see 'Bluetooth Echo Sample Server' in Device Manager under Bluetooth devices.

Device tree for Echo Server device

(Drivers for FDOs are shown for each devnode in the tree.)

text
/* Detailed source-code truncated for AI context efficiency. */

Client Installation

[!IMPORTANT]
This must be done on a separate machine from the one where echo server device was installed.

  1. Copy BthEchoSampleCli.Sys, BthEchoSampleCli.inf and bthecho.exe on a temporary directory on the target machine.

  2. Run bthprops.cpl from a command line or right click on the Bluetooth icon in the system tray and select 'Show Devices' to bring up a list of installed Bluetooth devices.

  3. In the Bluetooth Devices window, click the Add a device button.

  4. In the Add a Device wizard select the server machine (the machine where you installed the echo server) as a Bluetooth device. If the server machine does not appear, please check the echo server installation and make sure that you have enabled 'Allow Bluetooth device to find this computer' on the server machine as explained above. When the server machine is correctly displayed, select it and pick 'Next'.

  5. The wizard should default to a numeric compare ceremony for pairing the machines. When this happens, ensure the numbers match on both the client and the server, select 'Yes' on both machines to indicate they match, and click 'Next' on both machines to complete the pairing.

  6. Go through Device Manager and update driver software for it. Either point the wizard to the temporary directory created in step #2, or use devcon.exe from the tools\devcon folder to install the client device:

devcon.exe update BthEchoSampleCli.inf BTHENUM\{c07508f2-b970-43ca-b5dd-cc4f2391bef4}

Check for any error from devcon.exe as described in server installation.

If the installation is successful, you will see 'Bluetooth Echo Sample Client' in Device Manager under Bluetooth devices.

The device tree for echo client device is similar to the one shown for the echo server device, since both client and server are enumerated by BthEnum.sys (although the installation mechanism and properties of client and server are different).

Uninstalling Server

  1. Uninstall the device and delete driver software using the Bluetooth Devices window by running bthprops.cpl, right clicking on the device, and selecting 'Remove Device'

  2. Run bthsrvinst.exe /u to uninstall the echo server. This would make bthenum.sys stop enumerating the echo server. Without this step 'Found New Hardware' wizard will be launched again when you reconnect the device.

Uninstalling Client

Uninstall the device and delete driver software using the Bluetooth Devices window by running bthprops.cpl, right clicking on the device, and selecting 'Remove Device'.

Testing

Run BthEcho.exe on the client machine. You should see client sending data to the server and receiving the same data echoed back. Press Ctrl+c to terminate the application. You will see output similar to below:

cmd
D:\bth\wdfcli>BthEcho.exe
DevicePath: \\?\bthenum#{c07508f2-b970-43ca-b5dd-cc4f2391bef4}_localmfg&000a#7&3
62d0a3&0&000c55ff727a_c00000001#{fc71b33d-d528-4763-a86c-78777c7bcd7b}
Opened device successfully
Written                 26 bytes: WDF Bluetooth Sample Echo
Reply from server       26 bytes: WDF Bluetooth Sample Echo
Written                 26 bytes: WDF Bluetooth Sample Echo
Reply from server       26 bytes: WDF Bluetooth Sample Echo
Written                 26 bytes: WDF Bluetooth Sample Echo
Reply from server       26 bytes: WDF Bluetooth Sample Echo
Written                 26 bytes: WDF Bluetooth Sample Echo
Reply from server       26 bytes: WDF Bluetooth Sample Echo
Written                 26 bytes: WDF Bluetooth Sample Echo
^C

You can launch multiple instances of BthEcho.exe. Each client application would cause echo client device to have an independent connection to the echo server and thereby have an independent echo session. You can also have echo client devices and apps installed on multiple machines and talking to a single echo server.

CODE TOUR

Common code

Connection object: The common code contains implementation of a connection object (in connection.*) that is utilized by both client and the server. Client uses this object to maintain the information about opened connection and the server uses this object to maintain information about the accepted connection. Connection object also supports continuous reader which is utilized by server to read the data sent by client. Connection object is implemented as a WDF user object. Connection details are maintained in BTHECHO_CONNECTION structure. This structure is used as the context for WDF user object. Passive dispose is used to make the connection object cleanup wait for disconnect completion and continuous reader rundown. Please see WDF documentation for WDF user object and passive dispose (see WdfObjectCreate).

Server

Startup: Server registers PSM and L2CA server and published SDP record on startup in BthEchoSrvEvtDeviceSelfManagedIoInit (this callback is invoked by WDF during device start). While registering the L2CA server it passes BthEchoSrvIndicationCallback as the callback for incoming connection notifications.

Server SDP record creation: The sample uses dynamic creation of server SDP record using Bluetooth DDIs. Please note that for your particular device you may be able to use static data for the SDP record.

Incoming connections: Bluetooth stack invokes BthEchoSrvIndicationCallback for the incoming connections from clients. In response server accepts the connection and passes BthEchoSrvConnectionIndicationCallback callback to Bluetooth stack for disconnect notification. It is possible to use the same indication callback for server and connection but the sample uses different callbacks for clarity. Server adds the accepted connection to the connection list it maintains. Please see below for connection rundown details.

Connection rundown: Server maintains a list of all the connections it has accepted. This allows server to properly close down these connections on orderly removal. On surprise removal bthport.sys itself gets removed and takes care of running down the connections, but in case of orderly removal driver has to make sure to rundown the connections.

Connection state machine:

txt
ConnectFailed
                           ^
                           |
                           |
                           | (connection failure)
Uninitialized   ----> Connecting -------> Connected
                           | (disconnect)  /  ^
                           |              /  /
                           |             /  /
                           V            V  / (connection complete)
                     Disconnecting
                           | (disconnect complete)
                           |
                           |
                           V
                     Disconnected

One transition to note here is that if disconnect is received in the connecting state (i.e. when the connection is not completed) we wait for connection to completed (transition to connected state) and then invoke disconnect.

[!IMPORTANT]
Such state machine is needed only if Disconnect is initiated by something other than Bluetooth stack (for example device removal in our case). Bluetooth stack itself would not send disconnect before connect completion. If you adapt this sample for your device please evaluate whether your driver would require such state machine. For example, the echo client device does not need such state machine (although we use common connection code for client and the server).

Shutdown: Server removes the SDP record and unregisters L2CAP server and PSM in BthEchoSrvEvtDeviceSelfManagedIoCleanup (this callback is invoked by WDF during device removal). It also disconnects any open connections (see Connection rundown above).

Client

Startup: Client retrieves local and server Bluetooth address in BthEchoSrvEvtDeviceSelfManagedIoInit (this callback is invoked by WDF during device start). Please note that server Bluetooth address would be available regardless of presence of the server. Thus echo client device start doesn't fail even if echo server is not available.

Connecting to server: Client connects to echo server when application opens a handle to it (BthEchoCliEvtDeviceFileCreate) and closes the connection on file close (BthEchoCliEvtFileClose).

Sending and receiving data from server: When application writes data to the client, client sends this data to server on the connection opened for the given handle. Server would echo back this data. This data is retrieved by the application using a read operation. Echo Sample Client doesn't do any draining of echoed data on its own. Application read/write are handled using a parallel WDF I/O queue.

Shutdown: Client doesn't need any specific shutdown code as connection open/close and read/write are done within the context of application's handle open.


Overview (`bluetooth/serialhcibus/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Bluetooth Serial HCI Bus Driver

The purpose of this sample is to demonstrate how to implement a basic bus driver to support the new Bluetooth Extensibility transport DDIs over the UART transport. Such a serial bus driver can support a multi-radio device over the UART transport and utilize a common Bluetooth HCI packet for communication. The lower edge of this driver interfaces with a UART controller following the Bluetooth SIG's UART (H4) transport protocol.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

[!NOTE]
This sample driver is generic. It is not designed for a specific device and allows for a vendor to adopt and enhance it for supporting Bluetooth.

This sample driver, as is, may not properly function for a device until all vendor-specific device requirements (for example, device initialization) have been incorporated.

It is recommended to use the WDK version that matches the target Windows build version or newer for the development of the serial bus driver.

File manifest

WDK header file

Bthxddi.h - contains the constants, struct, and IOCTL definitions for the Bluetooth extensibility transport. This header file is included in WDK.

Common code section

driver.c - driver initialization

driver.h - common header file for driver.c and includes other header files

Fdo.c - functions for function device object (FDO) and BTHX DDI processing

io.c - functions that perform IO read pump via UART controller

Io.h - header for io.c

pdo.c - PDO (Bluetooth function) enumeration and IOCTL processing

public.h - header to share with application to support Radio On/Off ("Airplane mode")

Note: The goal is to keep the common code section the same, so the vendor will only need to update those code sections in the device specific directory.

Device-specific code section

Debugdef.h - WPP trace GUID; user should use a new GUID (unique per driver)

device.c - device specific functions to implement:

  • DeviceInitialize() - to perform UART and Bluetooth device initialization;

  • DeviceEnable() - (optional) to bring serial bus device out of disable/reset state.

  • DevicePowerOn() - (optional) to power on the device.

  • DeviceEnableWakeControl() - (optional) to arm for device wake signal

  • DeviceDisableWakeControl() - (optional) to disarm for device wake signal

device.h - header file for device.c

driver.rc - driver version and name

SerialBusWdk.inx - device specific INF file to install this driver. The vendor will need to add the hardware ID to match the "_HID" for the Serial Bus Device (Bluetooth) in the DSCY.asl file. For example, in SerialBusWDK.inx, the hardware ID is "ACPI\<vendor>_BTH0" where <vendor> could be a 4 digit vendor name.


Overview (`filesys/cdfs/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

CDFS File System Driver

The CD-ROM file system driver (cdfs) sample is a sample file system driver that you can use to write new file systems.

Cdfs is a read-only file system that addresses various issues such as accessing data on disk, interacting with the cache manager, and handling various I/O operations such as opening files, performing reads on a file, retrieving information on a file, and performing various control operations on the file system. The Cdfs file system is included with the Microsoft Windows operating system.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.


Overview (`filesys/fastfat/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

fastfat File System Driver

The fastfat sample is file system driver that you can use as a model to write new file systems.

fastfat is a complete file system that addresses various issues such as storing data on disk, interacting with the cache manager, and handling various I/O operations such as file creation, performing read/writes on a file, setting information on a file, and performing control operations on the file system.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Build the sample

You can build the sample in two ways: using Microsoft Visual Studio or the command line (MSBuild).

Building a Driver Using Visual Studio

You build a driver the same way you build any project or solution in Visual Studio. When you create a new driver project using a Windows driver template, the template defines a default (active) project configuration and a default (active) solution build configuration. When you create a project from existing driver sources or convert existing driver code that was built with previous versions of the WDK, the conversion process preserves the target version information (operating systems and platform).

The default Solution build configuration is Debug and Win32.

To select a configuration and build a driver

  1. Open the driver project or solution in Visual Studio (find fastfat.sln or fastfat.vcxproj).

  2. Right-click the solution in the Solutions Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Debug or Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Building a Driver Using the Command Line (MSBuild)

You can build a driver from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe) Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can now use the Visual Studio Command Prompt window for all build configurations.

To select a configuration and build a driver or an application

  1. Open a Visual Studio Command Prompt window at the Start screen. From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called filtername.vcxproj, navigate to the project directory and enter the following MSBuild command:

msbuild /t:clean /t:build .\\fastfat.vcxproj

Installation

No INF file is provided with this sample because the fastfat file system driver (fastfat.sys) is already part of the Windows operating system. You can build a private version of this file system and use it as a replacement for the native driver.


Overview (`general/DCHU/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Driver package installation toolkit for universal drivers

This sample illustrates the DCHU principles of universal driver design. The sample uses the OSR FX2 learning kit. For a detailed code walkthrough, see Universal Driver Scenarios.

There are three Visual Studio solutions in this sample. Each one represents a single submission on the Windows Hardware Dev Center dashboard. The solutions are split into the following subdirectories:

  • osrfx2_DCHU_base : The driver for the OSR FX2 Learning Kit. This includes the device driver, an upper filter driver for the device (a no-op), a Win32 User Service that controls lights on the device, and a console app that can control the device.

  • osrfx2_DCHU_extension_loose: An extension INF for the OSR FX2 device. This extension modifies some registry settings originally specified by the base driver (osrfx2_DCHU_base) and also uses AddComponent to create a Software Component. There is also a component INF project that would be a separate submission to DevCenter, which runs some simple software. These two projects are loosely coupled, and can be installed in any order on the machine.

  • osrfx2_DCHU_extension_tight: An extension INF for the OSR FX2 device. This extension mimics the behavior of osrfx2_DCHU_extension_loose; however, it does so in a tightly coupled manner. Using CopyINF, both the extension and component INF are placed into one driver package (and one submission to DevCenter). Here there is less flexibility with the base/component/extension relationship, but it ensures that the component INF is applied at the same time as the extension.

Both osrfx2_DCHU_extension_loose and osrfx2_DCHU_extension_tight provide the same functionality, so installing both on the same OSR FX2 device is unnecessary. They are intended to show a different way to use extension and component INFs depending on a project's needs.

[!NOTE]
osrfx2_DCHU_extension_tight will not currently build on Windows 10 version 1703. You will see an error saying that the directive CopyINF does not work from extension INFs. This has been fixed for the Windows 10 Fall Creators Update.

Each of these solutions can be built with the latest WDK on Visual Studio 2015. Additionally, you can also download a Universal Windows Platform app (UWP) that controls the OSR FX2 Learning Kit's device. To learn how to pair a UWP app with a device, see Hardware access for Universal Windows Platform apps

The app and the contents of this sample can coexist, but on Windows 10 version 1703, to build the app with Visual Studio 2017, the computer cannot have the WDK installed.

To install these driver packages, make sure that the target machine is in Test Mode, using bcdedit /set testsigning on.

Then, use pnputil /i /a to install each of the desired driver packages. They should be installed in the following order:

  • osrfx2_DCHU_base

  • osrfx2_DCHU_extension

  • osrfx2_DCHU_component

Technically the order of osrfx2_DCHU_extension and osrfx2_DCHU_component doesn't matter, but the software within osrfx2_DCHU_component will read the registry set by the extension to show that an extension's INF settings are applied after the base INFs.


Overview (`general/PLX9x5x/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PLX9x5x PCI Driver

This sample demonstrates how to write driver for a generic PCI device using Windows Driver Framework. The target hardware for this driver is PLX9656/9653RDK-LITE board. The product kit and the hardware specification are available at the PLX Technology website.

For more information, see the PCI driver programming guide.

The device is a PCI device with port, memory, interrupt and DMA resources. The device can be stopped and started at run-time and also supports low power states. The driver is capable of doing concurrent read and write operations to the device but it can handle only one read or write request at any time. The following driver framework interfaces are demonstrated in this sample:

  • Handling PnP and Power Events
  • Registering a Device Interface
  • Hardware resource mapping: Port, Memory, and Interrupt
  • DMA Interfaces
  • Serialized Default Queue for Write requests
  • Serialized custom Queue for Read requests
  • Handling Interrupt and DPC

To test the driver, run the PLX.EXE test application.

This sample driver is a minimal driver meant to demonstrate the usage of the Windows Driver Framework. It is not intended for use in a production environment.


Overview (`general/SimpleMediaSource/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimpleMediaSource sample

This sample demonstrates how to create a custom media source and driver package that can be installed as a camera and produce frames.

For more information, see the accompanying documentation at Frame Server Custom Media Source.

Contents

  • MediaSource - COM DLL project for the custom media source
  • SimpleMediaSourceDriver - UMDF driver install package

Installation

  1. Build the solution.

  2. Navigate to the output folder, e.g. Windows-driver-samples\general\SimpleMediaSource\x64\Release, and the driver package will be in a directory also called SimpleMediaSourceDriver. Check that the folder has SimpleMediaSource.dll, simplemediasourcedriver.cat, SimpleMediaSourceDriver.dll, and SimpleMediaSourceDriver.inf.

  3. Deploy the driver package with the following command:

    devgen /add /bus ROOT /hardwareid root\SimpleMediaSource
    pnputil /add-driver SimpleMediaSourceDriver.inf /install

  4. Verify installation with Device Manager, locate SimpleMediaSource Capture Source, under the Camera category. If device does not appear there, check %windir%\inf\setupapi.dev.log for installation logs. The device instance ID will be available as the output of the devgen command and can be used as input to pnputil to determine status of the device.

    pnputil /enum-devices /instanceid "" /deviceids /services /stack /drivers

  5. Open the Microsoft Camera App, switch cameras if necessary until the camera is streaming from the SimpleMediaSource. You should see a scrolling black and white gradient.


Overview (`general/cancel/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Cancel-Safe IRP Queue Sample

This sample demonstrates the use of the cancel-safe queue routines IoCsqInitialize, IoCsqInsertIrp, IoCsqRemoveIrp, IoCsqRemoveNextIrp. These routines were introduced in Windows for queuing IRPs in the driver's internal device queue. By using these routines, driver developers do not have to worry about IRP cancellation race conditions. A common problem with cancellation of IRPs in a driver is synchronization between the cancel lock or the InterlockedExchange in the I/O Manager with the driver's queue lock. The IoCsqXxx routines abstract the cancel logic while allowing the driver to implement the queue and associated synchronization.

The sample is accompanied by a simple multithreaded Win32 console application to stress-test the driver's cancel and cleanup routines.

This driver is written for an hypothetical data-acquisition device that requires polling at a regular interval. The device has some settling period between two successive reads. On a user request, the driver reads data and records the time. When the next read request comes in, the driver checks the interval to see if it's reading the device too soon. If so, it pends the IRP and sleeps for a while, and then tries again. On arrival, IRPs are queued in a cancel-safe queue and a semaphore is signaled. A polling thread that waits indefinitely on the semaphore wakes up to the signal and processes queued IRPs sequentially.

This sample driver is not a Plug and Play driver. This is a minimal driver meant to demonstrate a feature of the operating system. Neither this driver nor its sample programs are intended for use in a production environment. Instead, they are intended for educational purposes and as a skeleton driver.

Look in the Startio directory for another version of the sample driver that shows how to use cancel-safe IRP queues to implement I/O queuing functionality similar to the IoStartPacket and IoStartNextPacket routines. The same test application works with this driver as well.

For more information, see Cancel-Safe IRP Queues.

Run the sample

To test this driver, run canclapp.exe, which is a simple Win32 multithreaded console application. The driver will automatically load and start. When you exit the application, the driver will stop and be removed.

Usage: canclapp <NumberOfThreads>

[!NOTE]
The NumberOfThreads command-line parameter is limited to a maximum of 10 threads; the default value if no parameter is specified is 1. The main thread waits for user input. If you press Q, the application exits gracefully; otherwise, it exits the process abruptly and forces all the threads to be terminated and all pending I/O operations to be canceled. Other threads perform I/O asynchronously in a loop. After every overlapped read, the thread goes into an alertable sleep and wakes as soon as the completion routine runs, which occurs when the driver completes the read IRP. You should run multiple instances of the application to stress test the driver.


Overview (`general/event/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Hardware Event Sample

This sample demonstrates two different ways a Windows kernel-mode driver can notify an application about a hardware event. One way uses an event-based method, and the other uses an IRP-based method. Because the sample driver is not talking to any real hardware, it uses a timer DPC to simulate hardware events. The test application informs the driver whether it wants to be notified by signaling an event or by completing the pending IRP. Additionally, the test application specifies a relative time at which the DPC timer must fire.

Event-based approach: The application calls the CreateEvent function to create an event. It then passes the event handle to the driver in an I/O control request that uses a private IOCTL code, IOCTL_REGISTER_EVENT. Because the driver is a monolithic, top-level driver, its IRP dispatch routines run in the application process context and, as a result, the event handle is still valid in the driver. The driver dereferences the user-mode handle into system space and saves the event object pointer for later use. Next, the driver queues a custom timer DPC. When the DPC fires, the driver signals the event by calling the KeSetEvent routine at DISPATCH_LEVEL, and deletes the references to the event object. You can't use this approach if your driver is not a monolithic, top-level driver; that is because a driver can't guarantee the process context in a multi-level driver stack if the driver is not at the top of the stack.

Pending IRP-based approach: The application makes a synchronous IOCTL_REGISTER_EVENT request. The driver sets the status of the device I/O control request to IRP pending, queues a timer DPC, and returns STATUS_PENDING. When the timer fires to indicate a hardware event, the driver completes the pending IRP to notify the application about the hardware event.

There are two advantages of IRP-based approach over the event-based approach. First, the driver can send a message to the application along with the event notification. Second, the driver routines don't have to run in the context of the process that made the request. Instead, the application can send a synchronous or asynchronous (overlapped) I/O control request to the driver.

[!NOTE]
This sample driver is not a Plug and Play driver. This is a minimal driver meant to demonstrate a feature of the operating system. Neither this driver nor its sample programs are intended for use in a production environment. Rather, they are intended for educational purposes and as a skeleton driver.

Run the sample

To test this driver, copy the test application, event.exe, and the driver to the same directory, and run the application. The application will automatically load the driver, if it's not already loaded, and interact with the driver. When you exit the app, the driver will be stopped, unloaded, and removed.

To run the test application, enter the following command in the command window:

C:\>event.exe <Delay> <0|1>

The first command-line parameter, Delay, equals the time, in seconds, to delay the event signal. For the second command-line parameter, specify 0 for IRP-based notification and 1 for event-based notification.


Overview (`general/obcallback/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

ObCallback Callback Registration Driver

The ObCallback sample driver demonstrates the use of registered callbacks for process protection. The driver registers control callbacks which are called at process creation.

Design and Operation

The sample exercises both the PsSetCreateProcessNotifyRoutineEx and the ObRegisterCallbacks routines. The first example uses the ObRegisterCallbacks routine and a callback to restrict requested access rights during a open process action. The second example uses the PsSetCreateProcessNotifyRoutineEx routine to reject a process creation by examining the command line.

The following is a command line usage scenario to exercise access restriction:

cmd
C:\> obcallbacktestctrl.exe  -?                      (for command line help)
C:\> obcallbacktestctrl.exe  -install                (installs the kernel driver)
C:\> obcallbacktestctrl.exe  -name  notepad          (specifies that the string "notepad"  will be watched as a protected executable)
                                                     (now you can start up "notepad.exe")
C:\> notepad

C:\> tlist                                           (locate the process ID of notepad.exe)

C:\> kill -f  2329                                   (attempt to kill off the notepad.exe with a PID of 2329)
process notepad.exe (2329) - 'Untitled - Notepad' could not be killed

C:\> obcallbacktestctrl.exe  -deprotect              (remove the protections on the notepad process)

C:\> kill -f  2329                                   (attempt to kill off the process - which will succeed)
C:\> obcallbacktestctrl.exe  -uninstall              (uninstall the kernel driver)

The following is another sample test you can run to prevent a process from being created:

cmd
C:\> obcallbacktestctrl.exe  -install                (installs the kernel driver)
C:\> obcallbacktestctrl.exe  -reject  notepad        (specifies that the string "notepad"  will be watched and prevented from starting as a process)

C:\> notepad                                         (now you can start up "notepad.exe")
Access is denied.

Overview (`general/pcidrv/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PCIDRV - WDF Driver for PCI Device

This sample demonstrates how to write a KMDF driver for a PCI device. The sample works with the Intel 82557/82558 based PCI Ethernet Adapter (10/100) and Intel compatibles.

This adapter supports scatter-gather DMA, wake on external event (Wait-Wake), and idle power down. The hardware specification is publicly available, and the source code to interface with the hardware is included in the WDK.

Overview

The following is a list of key KMDF interfaces demonstrated in this sample:

  • Handling PnP & Power Events

  • Registering Device Interface

  • Hardware resource mapping: Port, Memory & Interrupt

  • DMA Interfaces

  • Parallel default queue for write requests. If the write cannot be satisfied immediately, the request is put into a manual parallel queue.

  • Parallel manual queue for Read requests

  • Parallelc default queue for IOCTL requests. If the ioctl cannot be satisfied immediately, the request is put into a manual parallel queue.

  • Request cancelation

  • Handling Interrupt & DPC

  • Watchdog Timer DPC to monitor the device state.

  • Event Tracing & HEXDUMP

  • Reading & Writing to the registry

[!NOTE]
This sample provides an example of a minimal driver intended for educational purposes. Neither the driver nor its sample test programs are intended for use in a production environment.

As stated earlier, this sample is meant to demonstrate how to write a KMDF driver for a generic PCI device and not for PCI network controllers. For network controllers, you should write a monolithic NDIS miniport driver based on the samples given under the \network\ndis directory.

Note that it is still possible to use a subset of KMDF APIs when writing a NDIS miniport (see \network\ndis\usbnwifi directory for a sample on how to use KMDF interfaces to talk to USB device in an NDIS miniport).

The sample driver has been tested on the following Intel Ethernet controllers:

Device Description Hardware ID
IBM Netfinity 10/100 Ethernet Adapter PCIVEN_8086&DEV_1229&SUBSYS_005C1014&REV_05
Intel(R) PRO/100+ Management Adapter with Alert On LAN PCI\VEN_8086&DEV_1229&SUBSYS_000E8086&REV_08
Intel 8255x-based PCI Ethernet Adapter (10/100) PCI\VEN_8086&DEV_1229&SUBSYS_00000000&REV_01
Intel Pro/100 S Server Adapter PCI\VEN_8086&DEV_1229&SUBSYS_00508086&REV_0D
Intel 8255x-based PCI Ethernet Adapter (10/100) PCI\VEN_8086&DEV_1229&SUBSYS_00031179&REV_08
Intel(R) PRO/100 VE Network Connection PCI\VEN_8086&DEV_103D&SUBSYS_00011179&REV_83
Intel(R) PRO/100 VM Network Connection PCI\VEN_8086&DEV_1031&REV_42
Intel(R) PRO/100 VE Network Connection PCI\VEN_8086&DEV_1038&REV_41
Intel(R) PRO/100 SR Mobile Adapter PCI\VEN_8086&DEV_1229

Using this sample as a standalone driver

txt
---------------------
         |                     |
         |        MYPING       | <-- Usermode test application
         |                     |
          ---------------------
                   ^
                   |                                     UserMode
-------------------------------------------------------------------
                   |                                     KernelMode
                   V
          ---------------------
         |                     |
         |        PCIDRV       | <-- Installed as a function driver
         |                     |
          ---------------------
                   ^
                   | <-----Talk to the hardware using I/O resources
                   V
             ---------------
            |    H/W NIC    |
             ---------------
                    |||||||
                    -------

You can install the driver as a standalone driver of a custom setup class, called Sample Class using GENPCI.INF. The PCI device is not seen as a network controller and as a result no protocol driver is bound to the device. In order to test the read & write path of the driver, you can use the specially developed ping application, called MYPING. This test application crafts the entire Ethernet frame in usermode and sends it to the driver to be transferred on the wire. In this configuration, you can only ping another machine on the same subnet. The application does all the ARP and AARP resolution in the usermode to get the MAC address of the target machine and sends ICMP ECHO requests.

The PCIDRV sample acts as a power policy owner of the device and implements all the wait-wake and idle detection logic.

Installation

The driver can be installed as a Net class driver or as a standalone driver (user defined class). The KMDF versions of the INF files are dynamically generated from .INX file. In addition to the driver files, you have to include the WDF coinstaller DLL from the \redist\wdf folder of the WDK.

You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

Testing

To test standalone driver configuration: You should use the specially developed ping application, called MYPING that comes with the sample. The Ping.exe provided in the system will not work because in this configuration, the test card is not bound to any network protocol - it's not seen as Net device by the system. Currently the test application doesn't have ability to get an IP address from a network DHCP server. As a result, it is better to connect the network device to a private hub and ping another machine connected to that hub. For example, let us say you have a test machine A and another machine B (development box).

  • Connect machine A and Machine B to a local hub.

  • Assign a static IP address, say 128.0.0.1 to the NIC on machine B.

  • Clear the ARP table on machine B by running Arp -d on the command line

  • Now run Myping.exe. This application enumerates GUID_DEVINTERFACE_PCIDRV and displays the name of the devices with an index number. This number will be used in identifying the interface when you invoke ping dialog.

  • In the ping dialog specify the following and click okay:

  • Device Index: 1 <- number displayed in the list window

  • Source Ip Address: 128.0.0.4 <- You can make up any valid IP address for test Machine A

  • Destination IP Address: 128.0.0.1 <- IP address of machine B

  • Packet Size: 1428 <- Default max size of ping payload. Minimum value is 32 bytes.

If the machine B has more than one adapter and if the second adapter is connected to the internet (Corporate Network), instead of assigning static IP address to the adapter that's connected to the test machine, you can install Internet Connection Sharing (ICS) on it and get an IP address for ICS. This would let you use the test machine to browse the internet when the sample is installed in the miniport configuration and also in the standalone mode without making up or stealing somebody's IP address. For example, let us say the machine B has two adapters NIC1 and NIC2. NIC1 is connected to the CorpNet and NIC2 is connected to the private hub. Install ICS on NIC2 as described below:

  • Select the NIC2 in the Network Connections Applet.

  • Click the Properties button.

  • Go to the Advanced Tab and Check the box "Allow Other network users to connect through this computers internet connection" in the Internet Connection Sharing choice.

  • This will assign 192.168.0.1 IP address to NIC2.

  • Now on machine B, you can assume 192.168.0.2 as the local IP address and run Myping.exe . Or, you can install the sample in the miniport configuration and browse the internet.

Other menu options of myping applications are:

  • Reenumerate All Device: This command lets you terminate active ping threads and close handle to all the device and reenumerate the devices again and display their names with index numbers. This might cause the devices to have new index numbers.

  • Cleanup: This command terminates ping threads and closes handles to all the devices.

  • Clear Display: Clears the window.

  • Verbose: Let you get more debug messages.

  • Exit: Terminate the application.

[!NOTE]
You can use this application only on a device installed in the standalone configuration. If you run it on a device that's installed as a miniport, you will get an error message. For such devices, you can use the system provided ping.exe.

Resources

For the latest release of the Windows Driver Kit, see Download the Windows Driver Kit (WDK).

If you have questions on using or adapting this sample for your project, you can either contact Microsoft Technical Support or post your questions in the Microsoft driver development newsgroup.

File manifest

File Description
KMDF Contains the driver
KMDF\HW Contains hardware specific code
TEST Contains source of test application (MYPING)

Overview (`gpio/samples/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

GPIO Sample Drivers

The GPIO samples contain annotated code to illustrate how to write a GPIO controller driver that works in conjunction with the GPIO framework extension (GpioClx) to handle GPIO I/O control requests, and a peripheral driver that runs in kernel mode and uses GPIO resources.

The GPIO sample set contains the following samples:

Minifilter Sample description
SimGpio The files in this sample contain the source code for a GPIO controller driver that communicates with GpioClx through the GpioClx device driver interface (DDI). The GPIO controller driver is written for a hypothetical memory-mapped GPIO controller (simgpio). The code is meant to be purely instructional. An ASL file illustrates how to specify a GPIO interrupt and I/O descriptor in the ACPI firmware.
SimGpio_I2C The files in this sample contain the source code for a GPIO controller driver that communicates with GpioClx through the GpioClx DDI. In contrast to the SimGpio sample, the GPIO controller in this sample is not memory-mapped. The GPIO controller driver is written for a hypothetical GPIO controller that resides on an I2C bus (simgpio_i2c). The code is meant to be purely instructional. An ASL file illustrates how to specify a GPIO interrupt and I/O descriptor in the ACPI firmware.
SimDevice\kmdf The purpose of this sample is to show how a driver opens a device and performs I/O operations on a GPIO controller in kernel mode. Additionally, this sample demonstrates how the driver connects to a GPIO interrupt resource. The ASL file illustrates how to specify a GPIO interrupt and I/O descriptor in the ACPI firmware.
SimDevice\umdf The purpose of this sample is to show how a driver opens a device and performs I/O operations on a GPIO controller in user mode. Additionally, this sample demonstrates how the driver connects to a GPIO interrupt resource. The ASL file illustrates how to specify a GPIO interrupt and I/O descriptor in the ACPI firmware.

Overview (`hid/firefly/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

KMDF filter driver for a HID device

Firefly is a KMDF-based filter driver for a HID device. Along with illustrating how to write a filter driver, this sample shows how to use remote I/O target interfaces to open a HID collection in kernel-mode and send IOCTL requests to set and get feature reports, as well as how an application can use WMI interfaces to send commands to a filter driver.

Human Input Devices Design Guide

Human Input Devices Reference

Creating Framework-based HID Minidrivers

Build the sample

For information on how to build a driver using Microsoft Visual Studio, see Building a Driver with Visual Studio and the WDK. When you build the sample, MSBuild.exe creates luminous.lib, firefly.sys, flicker.exe, and sauron.dll. Copy these files as well as the KMDF coinstaller (wdfcoinstallerMMmmm.dll) and the INF file (firefly.inf) to a floppy disk or a temporary directory on the target system.

[!NOTE]
You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

Installation

To install the driver:

  1. Plug the Microsoft USB Optical mouse into your target machine and verify that the mouse works. The drivers for this mouse come with the operating system so the device will start working automatically when you plug in.

  2. You may need to make Group Policy changes in order to replace the existing mouse driver. If you are unable to perform steps 3-9, do the following:

    1. Open gpedit.msd.

    2. In the Group Policy Object Editor navigation pane, open the Computer Configuration folder. Then open Administrative Templates, open System, open Device Installation, and then open Device Installation Restrictions.

    3. Enable Prevent installation of devices not described by other policy settings. This will prevent Windows from automatically installing the default mouse driver so that you can then install Firefly.

    4. Enable Allow administrators to override device installation policy. This will allow you to bypass the ""The installation of this device is forbidden by system policy" error that you may otherwise receive when you attempt to install Firefly.

    5. You may need to reboot.

  3. Bring up the Device Manager (type devmgmt.msc in the Start/Run window and press enter).

  4. Find the Microsoft Optical mouse under "Mice and other pointing devices"

  5. Right click on the device and choose "Update Driver Software."

  6. Select "Browse my computer for driver software."

  7. Browse to the temporary folder you created earlier. Click Next. Click through the warning.

  8. You will see "Windows has successfully updated your driver software" for the "Shiny Things Firefly Mouse" device.

  9. The system will copy all the files and restart the mouse device to install the upper filter. Click Close and you are ready to run the test app.

Testing the Sample

Copy the flicker.exe to the target machine and run it from an elevated command prompt. The usage is:

Usage: Flicker <-0 | -1 | -2>

-0 turns off light

-1 turns on light

-2 flashes light

Testing the DLL

The following description applies to Windows Media Player 12 running on Windows 7:

  1. Copy the sauron.dll to the Windows Media player Visualization directory (C:\Program Files\Windows Media Player\Visualizations).

  2. Register the DLL with COM by calling "regsvr32 sauron.dll" in command shell.

  3. Run Windows Media Player as administrator.

  4. Click on the "Switch to Now Playing" button in the lower right of the application.

  5. Right click, select Visualizations, and you will see a menu item called "Sauron."

  6. Choose either Firefly Bars or Firefly Flash and play some music.

  7. You will see the mouse light dancing to the tune of the music.

  8. You can unregister the DLL by calling "regsvr32 -u sauron.dll".

Programming Tour

The Firefly sample is installed as an upper filter driver for the Microsoft USB Intellimouse Optical. An application provided with the sample can cause the light of the optical mouse to blink by sending commands to the filter driver using the WMI interface.

The sample consists of:

  • Driver (firefly.sys): The Firefly driver is an upper device filter driver for the mouse driver (mouhid.sys). Firefly is a generic filter driver based on the toaster filter driver sample available in the WDK. During start device, the driver registers a WMI class (FireflyDeviceInformation). The user mode application connects to the WMI namespace (root\wmi) and opens this class using COM interfaces. Then the application can make requests to read ("get") or change ("set") the current value of the TailLit data value from this class. In response to a set WMI request, the driver opens the HID collection using IoTarget and sends IOCTL_HID_GET_COLLECTION_INFORMATION and IOCTL_HID_GET_COLLECTION_DESCRIPTOR requests to get the preparsed data. The driver then calls HidP_GetCaps using the preparsed data to retrieve the capabilities of the device. After getting the capabilities of the device, the driver creates a feature report to set or clear the feature that causes the light to toggle.

  • Library (luminous.lib): The sources for this file are located in the \hid\firefly\lib folder. You will need to build the library before using it. This library is shared by the WDM and WDF samples. All the interfaces required to access the WMI is defined in this library and exposed as CLuminous class.

  • Application (flicker.exe): The sources for this file are located in the \hid\firefly\app folder. You will need to build the application before using it. This application is shared by the WDM and WDF samples. The application links to luminous.lib to open the WMI interfaces and send set requests to toggle the light.

  • Sauron (sauron.dll): The sources for this file are located in the \hid\firefly\sauron folder. You will need to build this dll before using it. The library is shared by the WDM and WDF samples. Sauron is a Windows Media Player visualization DLL, and is based on a sample from the Windows Media Player SDK kit. By using this DLL, you can cause the mouse lights to blink to the beats of the music.


Overview (`hid/hclient/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

HClient sample application

The HClient sample demonstrates how to write a user-mode client application that communicates with HID devices. (These are devices that conform to the HID device class specification.)

You will find this sample useful if you need to develop an application that communicates with, or extracts information from, a HID device. This sample illustrates a method for detecting a connected HID, opening that device for communication, and extracting or formatting the data into, or from, device reports.

Human Input Devices Design Guide

Human Input Devices Reference


Overview (`hid/hidusbfx2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

HIDUSBFX2 sample driver

The HIDUSBFX2 sample driver (hidusbfx2.sys) demonstrates how to map a non-HID USB device to a HID device.

The sample also demonstrates how to write a HID minidriver using Windows Driver Frameworks (WDF). The minidriver is written for the OSR USB-FX2 Learning Kit. Although the device is not HID-compliant, the sample exposes it as a HID device.

Human Input Devices Design Guide

Human Input Devices Reference

Creating WDF HID Minidrivers

Build the sample

For information on how to build a driver solution using Microsoft Visual Studio, see Building a Driver with Visual Studio and the WDK.

Theory of Operation

A HID USB device provides a HID descriptor (through an interface descriptor) that identifies the device as HID-compliant and enables the system-supplied HID minidriver (hidusb.sys) and the HID class driver to load, parse the HID descriptor, and enumerate child HID device stacks. The system provides strong support for HID devices, so you do not typically have to write a HID minidriver. However, there are cases in which you might need to write your own HID minidriver (for example, if it is difficult to make desired changes to HID-compliant device firmware or if you need to make a non-HID compliant device into a HID device without updating the firmware).

Overview of the Device

You can view the specification for the device in the Using the OSR USB FX-2 Learning Kit document.

The device is loosely based on the development board that is supplied with the Cypress EZ-USB FX2 Development Kit (CY3681) and contains one interface and three endpoints (Interrupt IN, Bulk Out, and Bulk IN). The firmware supports vendor commands to query or set the LED bar graph display and 7-segment LED display, and to query toggle switch states.

The interrupt endpoint sends an 8-bit value that represents the state of the switches. This value is sent on startup, resume from suspend, and whenever the switch pack setting changes. The firmware does not de-bounce the switch pack. One switch change can cause multiple bytes to be sent. The bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack).

Bulk endpoints are configured for loopback.

Overview of the Driver Stack

Kernel-Mode Driver Framework (KMDF) does not support HID minidrivers natively because the HID architecture requires that the HID class driver (hidclass.sys) own the driver dispatch table for HID minidrivers. This requirement conflicts with the KMDF requirement that it own the driver dispatch table in order to handle Plug and Play (PnP), power, and I/O requests correctly.

You can resolve this ownership conflict by using a driver stack that consists of a minimal WDM driver as a function driver and a complete KMDF driver as a lower filter driver. The function driver registers with the HID class (sohidclass.sys owns its dispatch table) and forwards all of the requests to the lower filter driver. The lower filter driver (KMDF owns the dispatch table) processes all of the requests.

The minimal function driver code is located in the \hidusbfx2\hidkmdf directory (the driver binary is named hidkmdf.sys), and the lower filter driver code is located in the \hidusbfx2\sys folder (the binary is named hidusbfx2.sys). The function driver is a minimal WDM driver and you can reuse it without any modification. Remember to rename the driver binary when you reuse it, to avoid a name conflict. You need to modify the KMDF filter driver according to your device's requirements.

Mapping a Non-HID USB Device to HID

When the HIDclass driver queries the minidriver, the minidriver returns a hard-coded report descriptor that enables the HID class driver to create child devices as described by the report descriptor. The report descriptor has three top-level application collections:

Consumer control

  • System control

  • Vendor-defined

The HID class driver creates a driver stack for each top-level collection. The operating system opens the consumer control and system control collections. These collections have input buttons and obtain data from the interrupt endpoint of the USB device. The vendor-defined collection exposes a feature button to control the 7-segment display and bar graph display. Any client application can open the vendor-defined collection to send feature requests.

Switch Pack Mapping

The switch pack on the USB device is mapped as hot keys that are commonly found on modern keyboards. This mapping is possible by exposing the switch pack as two system-supported collections: consumer control and system control. The consumer control collection provides a mapping for some application-launch and application-action keys, as shown in the following table. The system control collection provides a mapping for the power sleep function.

Switch 1 2 3 4 5 6 7 8
Mapping Sleep Calculator Mail Favorites Refresh Forward Back Browser

Segment Display and Bar Graph

The segment display and bar graph are mapped as HID feature controls that you can manipulate by using the HidD_SetFeature function from a user-mode application. The feature controls are mapped as vendor-defined usage page 0xff00. The SEVEN_SEGMENT_REPORT_ID and BARGRAPH_REPORT_ID usages are listed in the following tables. You can also use Hidclient.exe, an application that is available in the Windows Driver Kit (WDK), to manipulate the segment display and bar graph. For more information about this mapping, see the following two tables.

Segment Display Mapping

Usage ID 0xD7 0x06 0xB3 0xA7 0x66 0xE5 0xF4 0x07 0xF7 0x67
Mapping Display 0 Display 1 Display 2 Display 3 Display 4 Display 5 Display 6 Display 7 Display 8 Display 9

Bar Graph Mapping

Note that you can OR these values to light multiple LEDs.

Usage ID 0x01 0x02 0x04 0x08 0x10 0x20 0x40 0x80 0xFF 0x00
Mapping LED 1 ON LED 2 ON LED 3 ON LED 4 ON LED 5 ON LED 6 ON LED 7 ON LED 8 ON All LEDS ON All LEDS OFF

Support for Selective Suspend

The HID class driver provides support for selective suspend. The minidriver participates in this feature by handling HID class IOCTLs appropriately. To enable the selective suspend feature for your device, you need to add a "SelectiveSuspend" = 1 value in the registry in the device hardware key through the INF file. For an example, see thehidusbfx2.inf file.

Installing the sample

If you adapt this driver for your device, update the INF file to match the hardware ID (VID, PID) and the device description text to match your test board/device.

To start installing the sample, you must:

  1. Build the driver and copy the following files to a folder on your hard drive:

    • hidusbfx2.inf

    • hidusbfx2.sys

    • Hidkmdf.sys

    • The WDF coinstaller from the *<WDK ROOT>\redist\wdf\* directory.

    [!NOTE]
    You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your WDK installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

  2. Plug in the device and follow these steps:

    1. Launch Device Manager by executing command devmgmt.msc in a command window, or from the Hardware and Sound program group in Control Panel.

    2. Select OSR USB-FX2 device from Other Devices category and select Update Driver Software... from the right-click menu.

    3. Select Browse my computer for software and provide the location of the driver files.

    4. Select Install this driver software anyway when the Windows Security dialog box appears.

    5. After the driver is installed, you should see the device in Device Manager under Human Interface Devices.

Testing

Testing Switches

  • To open a Web browser, toggle switch number 8 on the device board to the On position (toggle down).

  • To start the calculator application, toggle switch number 2 on the device board to the On position (toggle down).

Testing Bar Graph and 7-Segment Display

  1. Start the hidclient.exe GUI application from the WDK. The application source code is located in the \hid\hclient directory, and you build it by using the appropriate build environment.

  2. From the HID Device to examine menu, select the device that contains "UsagePage 0ff00, Usage 01" as a substring.

  3. Click Modify Features. The Feature Data dialog box opens.

  4. Click Modify Features. The Modify features dialog box opens.

  5. In the input box, type 7 and click Send to Device. You'll see number 7 appear in the 7-segment display.

  6. Type any number from 1-8, and you'll see the respective number displayed in the 7-segment display.

  7. Type any number from (and including) 9-17, and you will see one of the LEDs on the bar graph turn on. For mapping information, see the previous table.

Report Descriptor

text
/* Detailed source-code truncated for AI context efficiency. */

Code Tour

This section includes a file manifest of the files in the \hidusbfx2 directory.

File Manifest

\\hidusbfx2\\hidkmdf

File Description
hidkmdf.c Contains code for driver entry and dispatch
Sources WDK sources file
Makefile WDK build environment makefile
hidkmdf.rc Resource file for the driver

\\hidusbfx2\\sys

File Description
Driver.c Contains code for driver entry and dispatch functions
hid.c Contains code for handling HID IOCTLS
usb.c Contains code for communicating with USB stack
Trace.h Contains trace-related definitions
Hidusbfx2.h Contains type definitions and function declarations
Hidusbfx2.rc Resource file for the driver
Hidusbfx2.inx INX file for the driver
Sources WDK sources file
Makefile WDK build environment make file
Makefile.inc A makefile that defines custom build actions, including the conversion of the .INX file into a .INF file

Overview (`hid/vhidmini2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

HID Minidriver Sample (UMDF version 2)

The HID minidriver sample demonstrates how to write a HID minidriver using User-Mode Driver Framework (UMDF).

The sample demonstrates how to communicate with an HID minidriver from an HID client using a custom-feature item in order to control certain features of the HID minidriver. This is needed since other conventional modes for communicating with a driver, like custom IOCTL or WMI, do not work with the HID minidriver. The sample also is useful in testing the correctness of a HID report descriptor without using a physical device.

Creating WDF HID Minidrivers

Human Input Devices Design Guide

Human Input Devices Reference

UMDF HID Minidriver IOCTLs


Overview (`input/kbfiltr/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Keyboard Input WDF Filter Driver (Kbfiltr)

The Kbdfltr sample is an example of a keyboard input filter driver.

This sample is WDF version of the original WDM filter driver sample. The WDM version of this sample has been deprecated.

This is an upper device filter driver sample for PS/2 keyboard. This driver layers in between the KbdClass driver and i8042prt driver and hooks the callback routine that moves keyboard inputs from the port driver to class driver. In its current state, it only hooks into the keyboard packet report chain, the keyboard initialization function, and the keyboard ISR, but does not do any processing of the data that it sees. (The hooking of the initialization function and ISR is only available in the i8042prt stack.) With additions to this current filter-only code base, the filter could conceivably add, remove, or modify input as needed.

This sample also creates a raw PDO and registers an interface so that applications can talk to the filter driver directly without going through the PS/2 devicestack. The reason for providing this additional interface is because the keyboard device is an exclusive secure device and it's not possible to open the device from usermode and send custom ioctls through it.

This driver filters input for a particular keyboard on the system. If you want to filter keyboard inputs from all the keyboards plugged into the system, you can install this driver as a class filter below the KbdClass filter driver by adding the service name of this filter driver before the KbdClass filter in the registry at:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}\UpperFilters

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Set the hardware ID in the inx file

This step is required for automatic deployment (described later) to work properly. In the kbfiltr.inx file (located with the driver source files), find the [DDK_Ex.Mfg.NT$ARCH$] section. Change the hardware ID in the %DDK_Ex% entry from the dummy value to the hardware ID of the PS/2 keyboard on the target computer. The following example shows the hardware ID change.

inf
; For XP and above
[DDK_Ex.Mfg.NT$ARCH$]
;%DDK_Ex% = kbfiltr, *PNP0BAAD
%DDK_Ex% = kbfiltr, ACPI\VEN_PNP&DEV_0303

Build the sample using Visual Studio

In Visual Studio, on the Build menu, choose Build Solution.

For more information about using Visual Studio to build a driver package, see Building a Driver with Visual Studio and the WDK.

The test application, kbftest.exe is also built as part of the solution under the 'exe' folder.

Locate the built driver package

In File Explorer, navigate to the folder that contains your built driver package. The location of this folder varies depending on what you set for configuration and platform. For example, if your settings are Debug and x64, the package is your solution folder under \Debug\Package.

The package contains these files:

File Description
Kmdfsamples.cat A signed catalog file, which serves as the signature for the entire package.
kbfiltr.inf An information (INF) file that contains information needed to install the driver.
WdfCoinstaller010xx.dll The coinstaller for version 1.xx of KMDF.
kbfiltr.sys The driver file.

Using MSBuild

As an alternative to building the Kbfiltr Filter Driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, kbfiltr.sln. Use the MSBuild command to build the solution. Here are some examples:

  • msbuild /p:configuration="Debug" /p:platform="x64" kbfiltr.sln

  • msbuild /p:configuration="Release" /p:platform="Win32" kbfiltr.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy kbfiltr sample driver automatically or manually.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Install and Verify, and choose Default Driver Package Installation Task in the list. Click OK.

  3. On the Build menu, choose Deploy Package or Build Solution.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\KbfiltrDriverPackage).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the Devcon command with the correct hardware ID, such as:

    Devcon install kbfiltr.inf ACPI\VEN_PNP&DEV_0303

    -or-

    Using Device Manager, update the driver for the PS/2 Keyboard by manually selecting kbfiltr.inf from the location where you copied the driver files.

View the installed driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate DDK Example Device that needs filtering under the Keyboards node.

Testing

To use the test application provided with the sample, it must be copied to the target computer manually. Save the kbftest.exe file from the folder where the build result is placed (for example, exe\Debug). This file is copied somewhere on the target, possibly where the driver package files are located. The test application is the executed on the target computer in a Command Prompt using kbftest as the command.

[!TIP]
To avoid DLL dependencies for kbftext.exe, and the need to copy additional files, select the statically linked run-time library when building.


Overview (`input/layout/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Keyboard Layout Samples

The keyboard layout samples demonstrate how to generate layouts for various keyboards and locales.

Build the sample

Starting in the WDK, you can build the sample in two ways: using the Visual Studio Integrated Development Environment (IDE) or from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe).

Building the sample using Visual Studio

  1. Open Visual Studio. From the File menu, select Open Project/Solution. Within your WDK installation, navigate to src\input\layout and open the kbd.sln project file.

  2. Right-click the solution in the Solution Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Windows 8.1 Debug or Windows 8.1 Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. Starting in the WDK, you can use the Visual Studio Command Prompt window for all build configurations.

Building the sample using the command line (MSBuild)

  1. Open a Visual Studio Command Prompt window. Click Start and search for Developer Command Prompt. If your project is under %PROGRAMFILES%, you need to open the command prompt window using elevated permissions (Run as administrator). From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called kbdus.vcxproj, navigate to the project directory and enter the following MSBuild command: msbuild /t:clean /t:build .\kbdus.vcxproj.

  3. If the build succeeds, you will find the driver (kbdus.dll) in the binary output directory corresponding to the target platform, for example src\input\layout\kbdus\Windows 8.1 Debug.

Design and Operation

Keyboard Layout Samples details

The layout DLL is loaded by the window manager when needed. One of the examples is the logon. The default set of the input locales is set in the HKCU registry, according to user's preference, which can be customized by the Regional and Language Options application in Control Panel. The window manager reads the HKCU registry and loads the keyboard layouts accordingly.

The samples under input/layout include the following keyboard layouts:

  • kbdus

    US-English keyboard layout

  • kbdfr

    French keyboard layout

  • kbdgr

    German keyboard layout

  • kbd101

    Japanese 101 keyboard layout

  • kbd106

    Japanese 106 keyboard layout

Conversion Tables

A keyboard layout DLL consists of a set of tables. One of the tables converts the scancode to virtual key code, while the other table provides the conversion rule from the virtual key code to the character. Not all the keys or key combinations generate the characters. The modifier keys, such as the SHIFT key or the CTRL key, alter the character generation, but do not generate the characters. The special keys, such as F1-F12 functions keys, the Delete key or the Home key, do not generate the characters either.

The conversion rule from the scancode to the virtual key code is predefined in kbd.h, but can be customized in the layout-specific header files. The layout-specific headers define the keyboard type as it appears in kbd.h, and may redefine some definitions that are specific to each layout.

For the typical keyboard hardware, three types of the scancode to the Virtual Key Code conversion table must be defined in the C source file, including non-extended scancode, E0-prefixed scancode, and E1-prefixed scancode.

The conversion table for the character generation has multiple columns. Each column represents the modifier status and contains the character corresponding to the status. The number of the columns could vary from layout to layout, depending on the number of possible combinations of the modifier keys. Generally speaking, ALT GR-enabled keyboard layouts, such as French or German keyboard layouts, have more columns than non-ALT GR-enabled keyboard, such as US-English keyboard layout.

Exports from keyboard layout DLL

The layout DLLs export one or more entry points, which are called by the window manager to obtain the table address and the information about the layouts.

For the East Asian keyboard layouts, the keyboard layout DLL has to provide language-specific entry points. Those additional entries expose the language-specific information, such as the kana conversion table, or the special conversion rule, including the VK_KANJI generation.

Installation

To install a customized version of a layout DLL, it is recommended to substitute the existing DLL installed by the operating system with the customized DLL. The layout DLLs should be installed in the %windir%\system32 directory (exceptions may apply on 64-bit platforms). You may need to disable the System File Protection (SFP) before replacing the layout DLLs. After the layout DLLs are installed, you may need to reboot the system to ensure the new layouts are used..

Loading the Sample

In order to load the layout DLLs, you may need to turn to the Regional and Language Options application in Control Panel and add input locales that use the keyboard layouts you installed.

You may also choose to do it programmatically. LoadKeyboardLayout API can be used to load the keyboard layouts. To activate the keyboard layout, you may choose to specify KLF_ACTIVATE flag to LoadKeyboardLayout API, or you may need to call ActivateKeyboardLayout API.


Overview (`input/moufiltr/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Mouse Input WDF Filter Driver (Moufiltr)

The Moufiltr sample is an example of a mouse input filter driver.

This sample is WDF version of the original WDM filter driver sample. The WDM version of this sample has been deprecated.

This driver filters input for a particular mouse on the system. In its current state, it only hooks into the mouse packet report chain and the mouse ISR, and does not do any processing of the data that it sees. (The hooking of the ISR is only available in the i8042prt stack.) With additions to this current filter-only code base, the filter could conceivably add, remove, or modify input as needed.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Installation

This sample is installed via an .inf file. The .inf file included in this sample is designed to filter a PS/2 mouse.

The .inf file must install the class driver (Mouclass) and the port driver (i8042prt, Mouhid, Sermouse, etc.) by using Msmouse.inf and the INF directives "Needs" and "Include".

The .inf file must add the correct registry values for the class and port driver, as well as using the new directives.


Overview (`nfc/NfcCxSample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

NFC CX client driver sample

A template for creating an NFC functional driver using the NFC Class Extension (CX) driver.

This is a complete version of the code created in the NFC CX quick start guide.

Prerequisites

To use the NFC CX, your NFC Controller must implement NFC Forum's NFC Controller Interface (NCI) protocol.

In addition, the NFC CX requires the driver to use the UMDF 2 framework.

Universal windows driver compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

File manifest

WDK

  • NfcCx.h - The NFC CX's client driver API. This file is included in the WDK.

Project

  • Driver.cpp

    • DriverEntry - Driver initialization.
  • Device.cpp

    • DeviceContext::AddDevice - Device initialization, including initializing the NFC CX driver.
    • DeviceContext::WriteNciPacket - The implementation of the EvtNfcCxWriteNciPacket callback function.
    • DeviceContext::ReadNciPacket - Demonstrates calling NfcCxNciReadNotification.
  • Device.h

    • DeviceContext - The class that stores the device instance's state.

Overview (`nfp/net/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Near-Field Proximity Sample Driver (UMDF Version 1)

[!WARNING]
UMDF 2 is the latest version of UMDF and supersedes UMDF 1. All new UMDF drivers should be written using UMDF 2. No new features are being added to UMDF 1 and there is limited support for UMDF 1 on newer versions of Windows 10. Universal Windows drivers must use UMDF 2.

For more info, see Getting Started with UMDF.

The UMDF v1 sample can be accessed using git checkout win11-22h2. A direct link is: https://github.com/microsoft/Windows-driver-samples/tree/win11-22h2

This sample demonstrates how to use User-Mode Driver Framework (UMDF) version 1 to write a near-field proximity driver.

Typically, a near-field proximity driver would use near-field technologies such as Near Field Communication (NFC), TransferJet, or Bump. However, this sample uses a TCP/IPv6 network connection and a static configuration between two machines to simulate near-field interaction.

See also

Getting Started with UMDF

UMDF 1.x Design Guide


Overview (`pofx/PEP/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PEP ACPI Sample

The Power Engine Plugin (PEP) provides interfaces for platform power management including device power management (DPM), processor power management (PPM), and, starting with Windows 10, ACPI runtime methods. This sample documents the latter: an interface which allows a PEP to implement ACPI runtime methods natively via a Windows driver rather than firmware (AML). A PEP using the ACPI interface is often called a Platform Extension. Note that this interface can be used independently or in conjunction with the DPM and/or PPM interfaces as appropriate.

Use the PEP ACPI interface if:

  • You want to write peripheral (off-SoC) device power management in C rather than in ACPI Source Language (ASL).

  • You need to override an ACPI method which exists in a platform's DSDT or SSDT firmware tables.

  • Shipping, maintaining, and updating a driver binary suits your platform better than firmware updates (note that you will still need FADT, MADT, DBG2, and so on in firmware, this interface is only for runtime methods).


Overview (`pofx/UMDF2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Power Framework (PoFx) Sample (UMDF Version 2)

This solution demonstrates how a User-Mode Driver Framework (UMDF) version 2 driver can implement F-state-based power management. The SingleComp project demonstrates how a UMDF version 2 driver can implement F-state-based power management for a device that has only a single component.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

KMDF Power Framework (PoFx) Sample.

User-Mode Driver Framework

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy a driver sample automatically or manually.

Automatic deployment (root enumerated)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Hardware ID Driver Update, and enter root\SingleComponentSingleState for the hardware ID. Click OK.

  3. On the Build menu, choose Build Solution.

Manual deployment (root enumerated)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, continue with these steps:

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\PoFx).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

    devcon install SingleComponentSingleStateUm.inf root\\SingleComponentSingleState

View the root enumerated driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate UMDF 2.0 Single Component Single State Device (for example, this might be under the Sample Device node).

In Device Manager, on the View menu, choose Devices by connection. Locate UMDF 2.0 Single Component Single State Device as a child of the root node of the device tree.

Build the sample using MSBuild

As an alternative to building the driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, PoFx.sln. Use the MSBuild command to build the solution. Here is an example:

msbuild /p:configuration="Release" /p:platform="Win32" PoFx.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.


Overview (`pofx/WDF/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

KMDF Power Framework (PoFx) Sample

This solution consists of two samples that demonstrate how a KMDF driver can implement F-state-based power management. The SingleComp sample demonstrates how a KMDF driver can implement F-state-based power management for a device that has only a single component. The MultiComp sample demonstrates how a KMDF driver can implement F-state-based power management for a device that has an arbitrary number of components that can be individually power-managed.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Supporting Functional Power States

SingleComp Overview

This sample demonstrates how a KMDF driver can implement F-state-based power management for a device that has only a single component.

The sample illustrates the use of the WdfDeviceWdmAssignPowerFrameworkSettings method to specify power framework settings for the single component that represents the entire device. The power framework settings that can be specified include the F-states for the component and the power framework callbacks that are invoked when the component's active/idle condition or its F-state changes.

The sample also illustrates the use of the WdfDeviceAssignS0IdleSettings method to instruct KMDF to begin power-management of the device (and the component that represents the entire device).

Installation (SingleComp)

The driver can be installed on a root-enumerated device using the devcon.exe tool.

  1. Obtain the devcon.exe tool from the WDK

  2. Copy the driver binary, INF file and the KMDF coinstaller to a directory on your test machine.

    [!NOTE]
    You can obtain redistributable framework updates by downloading the Wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

  3. Run the command "devcon.exe install SingleComponentFStateSample.inf root\SingleComponentFStateDevice".

Use the PowerFxApp.exe application to send I/O requests to the driver. Running the command "PowerFxApp.exe /?" displays detailed usage information.

For detailed information about implementing F-state-based power management for a single component device, see Supporting Multiple Functional Power States for Single-Component Devices.

MultiComp Overview

This sample demonstrates how a KMDF driver can implement F-state-based power management for a device that has an arbitrary number of components that can be individually power-managed.

The sample driver statically links to a helper library (WdfPoFx.lib) that encapsulates all of the generic code to interact with the power framework. The device-specific code is implemented in the driver itself, outside of the helper library. The idea behind this organizing the code in this manner is make the helper library reusable by other drivers. The directory structure for the sample is as follows:

  • The helper library is implemented in the 'lib' subdirectory.

  • The interface between the helper library and the rest of the driver code is defined in the 'inc' subdirectory.

  • The driver is implemented in the 'driver' subdirectory.

Installation (MultiComp)

The driver can be installed on a root-enumerated device using the devcon.exe tool.

  1. Obtain the devcon.exe tool from the WDK

  2. Copy the driver binary, INF file and the KMDF coinstaller to a directory on your test machine.

    [!NOTE]
    You can obtain the co-installers by downloading theWdfcoinstaller.msi package from WDK 8 Redistributable Components.

  3. Run the command devcon.exe install WdfMultiComp.inf WDF\WdfMultiComp.

Testing

Use the PowerFxApp.exe application to send I/O requests to the driver. Running the command "PowerFxApp.exe /?" displays detailed usage information.

Design overview

The driver controls a device that has more than one component. It needs to access one of those components for processing each I/O request that it receives. The specific component that it needs to access depends on the I/O request that it receives.

In order to support this, the driver creates one top-level, power-managed queue to receive all its requests. It also creates one secondary, power-managed queue for each of its components. These secondary queues are called component queues. This is shown in the diagram below.

When the driver's dispatch routine for the top-level queue is invoked, it examines the request to determine which component it needs to access in order to process the request. Then, it forwards the request to the component queue for the component that it needs to access for that request. When the driver's dispatch routine for the component queue is invoked, it accesses the component hardware to process the request.

The driver's top-level queue and component queues are all power-managed so KMDF ensures that the device is in D0 while the queues are in a dispatching state. The key point to note is that the driver is designed to maintain a component queue in a dispatching state only when the component is active. In order to achieve this, the driver stops the component queue when the component becomes idle and starts the component queue when the component becomes active. (To be precise, this mechanism of stopping and starting queues is encapsulated in the power framework helper library used by the driver). Thus, the driver is able to ensure that when the component queue is in a dispatching state, not only is the device in D0 but the component corresponding to that queue is also active. Thus it is safe to access the component hardware when the component queue's dispatch routine is invoked.

Implementation notes

The driver uses the power framework helper library to manage most of its interactions with the power framework. In order to achieve this, during device initialization, the driver performs the following tasks in its EvtDriverDeviceAdd callback.

  • Enables the helper library to register its own KMDF callbacks for PNP and power-management of the device.

  • Provides the helper library with power-framework-related information about the device.

  • Provides the helper library with information about the component queues.

During I/O request processing, the driver uses routines provided by helper library to forward requests to component queues and also to complete requests.

The main tasks performed by the power framework helper library on behalf of the driver are:

  • Registration and unregistration with the power framework.

  • Stopping component queues when the corresponding components become idle and starting them when the corresponding components become active.

  • Notifying the power framework when the device returns to its working state (D0) in response to the system returning from a low-power state to the working state (S0).

The power framework helper library does not have any hardware-specific information, so any tasks that are specific to the device's hardware are performed by the driver. In this sample, the device hardware is represented by a very simple simulation. The notable hardware-specific tasks in this sample are:

  • Accessing component hardware to process I/O requests.

  • Accessing component hardware to change the component's F-state.

As mentioned earlier, the hardware access shown is this sample is entirely simulated in software. This sample does not work with a real device, it installs on a root-enumerated software device.

S0-idle power management support

The power framework helper library implements support for S0-idle power management for the device. Note that this is different from the component power management support that is enabled by the power framework. Component power management enables individual components of the device to be power-managed by putting them in different F-states while the device is in a working state (D0). S0-idle power management for the device enables the device as a whole to be power-managed by putting it into different D-states while the system is in a working state (S0).

The code to implement S0-idle power management support for the device is conditionally compiled based on the value of the PFH_S0IDLE_SUPPORTED compiler switch. If the switch is set to a nonzero value, the code to implement S0-idle power management support is included. If set to zero, the code is omitted thereby resulting in a smaller binary size. Thus, a driver that requires S0-idle power management for the device can use the power framework helper library's support for it but a driver that does not require it can reduce its binary size by omitting the code that is specific to S0-idle power management.

Additional Information

For detailed information about implementing F-state-based power management for a multiple component device, see Supporting Multiple Functional Power States for Multiple-Component Devices.


Overview (`powerlimit/plclient/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

plclient - Simulated Power Limit Client Driver

This sample is a driver for a simulated power limit client device.

Universal Windows Driver Compliant

The plclient sample provides the source code for a power limit device that supports power limit management by the operating system.


Overview (`powerlimit/plpolicy/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

plpolicy - Simulated Power Limit Policy Driver

This sample is a driver for a simulated power limit policy device.

Universal Windows Driver Compliant

The plpolicy sample provides the source code for a power limit controller that supplies power limit management to the operating system.

This driver supplies IOCTLs to receive commands from other modules and plumb cooresponding information to the hardware through OS kernel
space APIs.

IOCTL_POWERLIMIT_POLICY_REGISTER: Other module supplies the BIOS name of the target device to control the power limit.

IOCTL_POWERLIMIT_POLICY_QUERY_ATTRIBUTES: Query the target device for supported power limits and attributes.

IOCTL_POWERLIMIT_POLICY_QUERY_VALUES: Query the target device for active power limit values.

IOCTL_POWERLIMIT_POLICY_SET_VALUES: Set power limit values to the target device.

For a production driver, those IOCTLs are not needed. Instead, the policy driver should:

  1. During the init phase, subscribes to GUID_DEVINTERFACE_POWER_LIMIT notifications. Then query client's BIOS name in the callback, and
    compares it with the target client device. Then create power limit request through PoCreatePowerLimitRequest, query attributes through
    PoQueryPowerLimitAttributes.

  2. At runtime, the policy driver should collect input signals and calcualte power limit target(s), then send targets to the client through
    PoSetPowerLimitValue. If necessary, the policy driver can query the current power limit of client through PoQueryPowerLimitValue.

  3. If the power limit control is no longer needed, delete the power limit request through PoDeletePowerLimitRequest.


Overview (`security/elam/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Early Launch Anti-Malware Driver

This sample demonstrates how to use the IoRegisterBootDriverCallback and IoUnRegisterBootDriverCallback DDIs from an Early Launch Anti-Malware driver, to receive notifications about the initialization of regular boot start drivers.

This sample driver is a minimal driver meant to demonstrate the usage of the APIs mentioned above. It is not intended for use in a production environment.

Signing the sample

Early Launch drivers are required to be signed with a code-signing certificate that also contains the Early Launch EKU "1.3.6.1.4.1.311.61.4.1". In a production environment, Early Launch drivers are signed by Microsoft for qualifying Anti-Malware vendors with a WHQL certificate that contains this EKU. The makecert.exe tool can be used to generate a self-signed test certificate that contains both the Early Launch EKU and the "1.3.6.1.5.5.7.3.3" Code Signing EKU. Once a certificate of this form has been created, signtool.exe can be used to sign elamsample.sys.

Run the sample

Installing the sample

  1. Copy the signed elamsample.sys file to the %WINDIR%\System32\Drivers directory on your test machine.

  2. Use the sc.exe tool present in Windows to install the driver:

    sc create ElamSample binpath=%windir%\\system32\\drivers\\elamsample.sys type=kernel start=boot error=critical group=Early-Launch

  3. Enable test signing:

    bcdedit /set testsigning on

Code tour

DriverEntry: Creates a framework driver object and calls IoRegisterBootDriverCallback to register to boot driver status callbacks.

ElamSampleEvtDriverUnload: Calls IoUnregisterBootDriverCallback to unregister for callbacks when elamsample.sys is about to be unloaded.

ElamSampleBootDriverCallback: Dispatches to other functions to process the specific callback types.

ElamSampleProcessStatusUpdate: Displays callback BdCbStatusUpdate information, such as when dependencies and drivers are about to be initialized, or when the ELAM driver is about to be unload.

ElamSampleProcessInitializeImage: Displays callback BdCbInitializeImage information, such as the driver image name and the name of the entity that signed the driver.

ElamSamplePrintHex: A utility function to display a buffer in hexadecimal form.

Testing

After installing the driver, attach the Kernel Debugger and reboot your test machine. If ELAMSAMPLE_TRACE_LEVEL is set to DPFLTR_ERROR_LEVEL, traces will be output to the debugger automatically. For example:

text
/* Detailed source-code truncated for AI context efficiency. */

Overview (`sensors/ADXL345Acc/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

ADXL345 Accelerometer Sample Driver

The ADXL345 accelerometer sample shows how to write a UMDF v2 driver to control an ADXL345 accelerometer chip.


Overview (`sensors/Activity/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Activity Sensor Driver Sample

The activity sample shows how to write a UMDF v2 driver to control an activity sensor.


Overview (`sensors/CustomSensors/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Custom Sensor Driver Sample

The CustomSensor sample shows how to write a UMDF v2 driver to control a custom sensor.


Overview (`sensors/Fusion/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Fusion Sensor Driver Sample

The FusionSensor sample shows how to write a UMDF v2 driver to control a virtual FusionSensor sensor.


Overview (`sensors/Pedometer/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Pedometer sensor sample

The Pedometer sample shows how to write a UMDF v2 driver to control a virtual pedometer sensor.


Overview (`sensors/SensorsComboDriver/readme.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Sensors Combo Driver Sample

The sensors combo driver sensor sample shows how to write UMDF v2 drivers to control various types of virtual sensors such as ambient light, barometer, gyroscope, magnetometer, geomagnetic, gravity vector, proximity, linear accelerometer and relative fusion.


Overview (`sensors/SimpleDeviceOrientationSensor/readme.md`)


topic: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimpleDeviceOrientationSensor

This sample shows you how to write a UMDF v2 sensor driver to output simple device orientation values.


Overview (`serial/VirtualSerial2/README.md`)


page_type: sample
urlFragment: virtual-serial-driver-sample-v2
languages:

  • c
    products:
  • windows
  • windows-wdk

Virtual serial driver sample (V2)

This sample demonstrates these two serial drivers:

  • A simple virtual serial driver (ComPort)

  • A controller-less modem driver (FakeModem).This driver supports sending and receiving AT commands using the ReadFile and WriteFile calls or via a TAPI interface using an application such as, HyperTerminal.

This sample driver is a minimal driver meant to demonstrate the usage of the User-Mode Driver Framework. It is not intended for use in a production environment.

For more information, see the Serial Controller Driver Design Guide.

Code tour

internal.h

  • This is the main header file for the sample driver.

driver.c and driver.h

  • Definition and implementation of the driver callback function (EVT_WDF_DRIVER_DEVICE_ADD) for the sample. This includes DriverEntry and events on the framework driver object.

device.c and driver.h

  • Definition and implementation of the device callback interface for the sample. This includes events on the framework device object.

queue.c and queue.h

  • Definition and implementation of the base queue callback interface. This includes events on the framework I/O queue object.

ringbuffer.c and ringbuffer.h

  • Definition and implement of ring buffer for pending data.

VirtualSerial.rc /FakeModem.rc

  • This file defines resource information for the sample driver.

VirtualSerial.inf / FakeModem.inf

  • INF file that contains installation information for this driver.

Overview (`serial/serenum/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Serenum sample

Serenum enumerates Plug-n-Play RS-232 devices that are compliant with the current revision of Plug and Play External COM Device. It loads as an upper filter driver to many different RS-232 device drivers that are compliant with its requirements and performs this service for them.

Serenum implements the Serenum service and its executable image is serenum.sys.

Serenum is an upper-level device filter driver that is used with a serial port function driver to enumerate the following types of devices that are connected to an RS-232 port:

  • Plug and Play serial devices that comply with Plug and Play External COM Device Specification, Version 1.00, February 28, 1995.

  • Pointer devices that comply with legacy mouse detection in Windows.

The combined operation of Serial and Serenum provides the function of a Plug and Play bus driver for an RS-232 port. Serenum supports Plug and Play and power management.

Windows provides Serenum to support Serial and other serial port function drivers that need to enumerate an RS-232 port. Hardware vendors do not have to create their own enumerator for RS-232 ports. For example, a device driver can use Serenum to enumerate the devices that are attached to the individual RS-232 ports on a multiport device.

File Manifest

File Description
Enum.c Functions that enumerate external serial devices (the main purpose of this driver)
Pnp.c Plug and Play support code
Power.c Power support code
Serenum.c Basic driver functionality
Serenum.h Local header with defines, prototypes
String.c String handling support, mainly ASCII to UNICODE functionality
Serenum.rc Resource script

For more information, see Features of Serial and Serenum.


Overview (`serial/serial/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Serial Port Driver

The Serial (16550-based RS-232) sample driver is a WDF version of the inbox Serial.sys driver in %WINDIR%\system32\drivers.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Sample overview

This sample driver is functionally equivalent to the inbox driver, with these two exceptions:

  1. This sample does not support multi-function serial devices.

  2. This sample does not support legacy serial ports. Legacy ports are not detected by the BIOS, and are, therefore, not enumerated by the operating system.

The Serial sample driver runs in kernel mode.

This sample driver supports power management. When a serial port is not in use, the driver places the port hardware in a low-power state. When the port is opened, it receives power and wakes up. The driver supports wake-on-ring for platforms that support this function. The driver can be compiled to run on both 32-bit and 64-bit versions of Windows.

For more information, see Features of Serial and Serenum.

This sample can be used for these hardware IDs without any modification to the .inx file included in the project.

  • PNP0501

  • PNP0500

If you have other hardware such as an add-in card, then you must add the hardware ID in the .inx as shown in this example.

inf
; For XP and later
[MSFT.NTamd64]
; DisplayName           Section           DeviceId
; -----------           -------           --------
%PNP0500.DevDesc%=       Serial_Inst,      *PNP0500, *PNP0501 ; Communications Port
%PNP0501.DevDesc%=       Serial_Inst,      *PNP0501, *PNP0500 ; Communications Port
%PNP0501.DevDesc%=       Serial_Inst,      MF\PCI9710_COM ; Communications Port

Overview (`setup/devcon/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Device Console (DevCon) Tool

DevCon is a command-line tool that displays detailed information about devices, and lets you search for and manipulate devices from the command line. DevCon enables, disables, installs, configures, and removes devices on the local computer and displays detailed information about devices on local and remote computers. DevCon is included in the WDK.

This document explains the DevCon design, and how to use the SetupAPI and device installation functions to enumerate devices and perform device operations in a console application. For a complete description of DevCon features and instructions for using them, see the DevCon help file included with the WDK documentation in Driver Development Tools/Tools for Testing Drivers/DevCon.

DevCon is provided in ready-to-run form in tools\devcon. For usage, refer to the document provided with devcon.exe. DevCon is a command line utility with built-in documentation available by typing "devcon help".

Build the sample

You can build the sample in two ways: using the Visual Studio Integrated Development Environment (IDE) or from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe).

Building the sample using Visual Studio

  1. Open Visual Studio. From the File menu, select Open Project/Solution. Navigate to the DevCon sample folder and open the devcon.sln project file.

  2. Right-click the solution in the Solution Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Debug or Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can use the Visual Studio Command Prompt window for all build configurations.

Building the sample using the command line (MSBuild)

  1. Open a Visual Studio Command Prompt window. Click Start and search for Developer Command Prompt. If your project is under %PROGRAMFILES%, you need to open the command prompt window using elevated permissions (Run as administrator). From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called devcon.vcxproj, navigate to the project directory and enter the following MSBuild command: msbuild /t:clean /t:build .\devcon.vcxproj.

  3. If the build succeeds, you will find the tools (devcon.exe) in the binary output directory corresponding to the target platform, for example samples\setup\devcon\Debug.

Run the sample

Type devcon find * to list device instances of all present devices on the local machine.

Type devcon status @root\rdp\_mou\0000 to list status of the terminal server mouse driver.

Type devcon status *PNP05* to list status of all COM ports.

How DevCon works

Running devcon help will provide a list of commands along with short descriptions of what each command does. devcon help <command> will give more detailed help on that command. The interpretation of each command is done via a dispatch table "DispatchTable" that is at the bottom of "cmds.cpp". Some of the commands make use of a generic device enumerator "EnumerateDevices". A few of these commands will work when given a remote target computer, and will also work if using the 32-bit devcon on Wow64.

A description of some of the more interesting functions and the APIs they use follows:

cmdClasses

cmdListClass

cmdFind cmdFindAll cmdStatus

  • A simple use of EnumerateDevices (explained below) to list devices and display different levels of information about each device. Note that all but cmdFindAll use DIGCF_PRESENT to only list information about devices that are currently present. The main functionality for these and related devices is done inside FindCallback.

cmdEnable cmdDisable cmdRestart

  • These commands show how to issue DIF_PROPERTYCHANGE to enable a device, disable a device, or restart a device. The main functionality for each of these commands is done inside ControlCallback. These operations cannot be done on a remote machine or in the context of Wow64. CFGMGR32 API's should not be used as they skip class and co-installers.

cmdUpdate

  • This command shows how to use UpdateDriverForPlugAndPlayDevices to update the driver for all devices to a specific driver. Normally INSTALLFLAG_FORCE would not be specified allowing UpdateDriverForPlugAndPlayDevices to determine if there is a better match already known. It's specified in DevCon to allow DevCon to be used more effectively as a debugging/testing tool. This cannot be done on a remote machine or in the context of Wow64.

cmdInstall

  • A variation of cmdUpdate to install a driver when there is no associated hardware. It creates a new root-enumerated device instance and associates it with a made up hardware ID specified on the command line (which should correspond to a hardware ID in the INF). This cannot be done on a remote machine or in the context of Wow64.

cmdRemove

  • A command to remove devices. Plug & Play devices that are removed will reappear in response to cmdRescan. The main functionality of this command is in RemoveCallback that demonstrates the use of DIF_REMOVE. This cannot be done on a remote machine or in the context of Wow64. CFGMGR32 API's should not be used as they skip class and co-installers.

cmdRescan

  • This command shows the correct way to rescan for all Plug & Play devices that may have previously been removed, or that otherwise require a rescan to detect them.

cmdDPAdd

  • This command allows you to add a Driver Package to the machine. The main functionality of this command demonstrates the use of SetupCopyOEMInf. Adding a Driver Package to the machine doesn't mean the drivers are installed on devices, it simply means the drivers are available automatically when a new device is plugged in or a existing device is updated.

cmdDPDelete

  • This command allows you to uninstall a Driver Package from the machine. The main functionality of this command demonstrates the use of SetupUninstallOEMInf. Removing a Driver Package from the machine does not uninstall the drivers associated with a device. If you want to accomplish both then use cmdRemove on all the devices using a given Driver Package and then cmdDPDelete to remove the Driver Package itself from the machine.

cmdDPEnum

  • This command allows you to enumerate all of the 3rd party Driver Packages currently installed on the machine and also shows you how to get some common properties from a Driver Package (Provider, Class description, DriverVer date and version).

Reboot

  • This function shows how to correctly reboot the machine from a hardware install program. In particular it passes flags to ExitWindowsEx that cause the reboot to be associated with hardware installation. You should never reboot the machine unnecessarily.

EnumerateDevices

  • Demonstrates the use of SetupDiGetClassDevsEx to enumerate all devices or all present devices, either globally or limited to a specific setup class. Demonstrates the use of SetupDiCreateDeviceInfoListEx to create a blank list associated with a class or not (for most cases, a blank list need not be associated with a class). Demonstrates the use of SetupDiOpenDeviceInfo to add a device instance into a device info list. These last two API's are ideal to obtain a SP_DEVINFO_DATA structure from a device instance and machine name when mixing CFGMGR32 API's with SETUPAPI API's. SetupDiGetDeviceInfoListDetail is called to obtain a remote machine handle that may be passed into CFGMGR32 API's. SetupDiEnumDeviceInfo is called to enumerate each and every device that is in the device info list (either explicitly added, or determined by the call to SetupDiGetClassDevsEx). The instance ID is obtained by calling CM_Get_Device_ID_Ex, using information in devInfo (obtained from SetupDiEnumerateDeviceInfo) and devInfoListDetail (obtained from SetupDiGetDeviceInfoListDetail). GetHwIds is called to obtain a list of hardware and compatible ID's (explained below). Once an interesting device has been determined (typically by checking hardware ID's) then the callback is called to operate on that individual device.

GetHwIds

GetDeviceDescription

  • Shows how to obtain descriptive information about a device. The friendly name is used if it exists, otherwise the device description is used.

DumpDeviceWithInfo

  • Shows how to obtain an instance ID (or use any CFGMGR32 API) given HDEVINFO (device info list) and PSP_DEVINFO_DATA (device info data).

DumpDeviceStatus

  • Shows how to interpret the information returned by CM_Get_DevNode_Status_Ex. Refer to cfg.h for information returned by this API.

DumpDeviceResources

  • Shows how to obtain information about resources used by a device.

DumpDeviceDriverFiles

  • Provided as a debugging aid, obtains information about the files apparently being used for a device. It uses SetupDiBuildDriverInfoList to obtain information about the driver being used for the specified device. The driver list associated with a device may be enumerated by calling SetupDiEnumDriverInfo. In this case, there will be no more than one driver listed. This function proceeds to obtain a list of files that would normally be copied for this driver using DIF_INSTALLDEVICEFILES. SetupScanFileQueue is used to enumerate the file queue to display the list of files that are associated with the driver.

DumpDeviceDriverNodes

  • Provided as a debugging aid, this function determines the list of compatible drivers for a device. It uses SetupDiBuildDriverInfoList to obtain the list of compatible drivers. In this case, all drivers are enumerated, however typically DIF_SELECTBESTCOMPATDRV and SetupDiGetSelectedDriver would be used together to find which driver the OS would consider to be the best.

DumpDeviceStack

  • This function determines class and device upper and lower filters.

Overview (`spb/SkeletonI2C/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Skeleton I2C Sample Driver

The SkeletonI2C sample demonstrates how to design a KMDF controller driver for Windows that conforms to the simple peripheral bus (SPB) device driver interface (DDI). SPB is an abstraction for low-speed serial buses (for example, I2C and SPI) that allows peripheral drivers to be developed for cross-platform use without any knowledge of the underlying bus hardware or device connections. While this sample implements an empty I2C driver, it could just as easily be the starting point for an SPI driver with only minor modifications.

Note that the SkeletonI2C sample is simplified to show the overall structure of an SPB controller, but contains only the code that the driver requires to communicate with the SPB framework extension (SpbCx) and KMDF. The SkeletonI2C sample driver omits all hardware-specific code. It does not simulate data transfers or implement request completion asynchronously. Pay close attention to code comments marked with "TODO" that refer to blocks of code that must be removed or updated.

The simplified structure of the SkeletonI2C sample driver makes it a convenient starting point for development of a real SPB controller driver that manages the hardware functions in an SPB controller.

Modifying the sample

Here are some high-level points to consider when modifying the SkeletonI2C sample for use on real hardware:

  • Edit (and likely rename) Skeletoni2c.h to describe your hardware's register set.

  • Modify Controller.cpp and Device.cpp to translate the SPB DDI and primitives into I2C or SPI protocol for your hardware. This includes initialization, I/O configuration, and interrupt processing.

  • Address any comments marked with "TODO" in the sample, especially those that short circuit the I/O path to complete requests synchronously.

  • Modify the HWID (ACPI\skeletoni2c) in Skeletoni2c.inf to match the device node in your firmware.

  • Generate and specify a unique trace GUID in I2ctrace.h.

  • Refactor the driver name, functions, comments, etc., to better describe your implementation.

Code tour

Implementing the SPB DDI

The following are relevant functions in the SkeletonI2C driver for implementing the SPB DDI.

INITIALIZATION

OnDeviceAdd

Within OnDeviceAdd, the driver makes several configuration calls for SPB.

SpbDeviceInitConfig must be called before creating the WDFDEVICE. Note that SpbCx sets a default security descriptor on the device object, but the controller driver can override it by calling WdfDeviceInitAssignSDDLString after SpbDeviceInitConfig.

After creating the WDFDEVICE, the driver configures it appropriately for SPB by calling SpbDeviceInitialize. Here the driver also sets the target and request attributes.

Finally the driver configures a WDF system-managed idle time-out.

TARGET CONNECTION

OnTargetConnect

Invoked when a client opens a handle to the specified SPB target. Queries the I2C connection parameters from the resource hub (via SPB) and initializes the target context.

SPB I/O CALLBACKS

OnRead

SPB read callback. Invokes the PbcConfigureForNonSequence function to set up the transfer.

OnWrite

SPB write callback. Invokes the PbcConfigureForNonSequence function to set up the transfer.

OnSequence

SPB sequence callback. Configures the controller for an atomic transfer*.

OnControllerLock

SPB lock controller callback. Configures to handle subsequent I/O as an atomic transfer*. For I2C the controller should place a start bit on the bus. For SPI the controller should assert the chip-select line. The driver may choose to carry this out as part of this callback or defer until the first I/O operation is received (the next call to OnRead or OnWrite).

OnControllerUnlock

SPB unlock controller callback. Marks the end of an atomic transfer*. For I2C, the controller should place a stop bit on the bus. For SPI, the controller should de-assert the chip-select line.

SPB HELPER METHODS

PbcConfigureForIndex

Configures the request context for the specified transfer index. This could be a single I/O or part of a sequence.

PbcRequestComplete

Sets the number of bytes completed for a request and invokes the SpbRequestComplete method.

*An atomic transfer in SPB is implemented using Sequence or a Lock/Unlock pair. For I2C, this means a set of reads and writes with restarts in between. For SPI, this means a set of reads and writes with the chip select-line asserted throughout.

Implementing controller-specific I2C protocol

The following are relevant functions in the SkeletonI2C driver for implementing controller-specific I2C protocol. For the most part, these are placeholders and must be filled in appropriately.

INITIALIZATION (controller-specific)

ControllerInitialize

One-time controller initialization. Prepare FIFOs, clocks, interrupts, etc.

ControllerConfigureForTransfer

Per-I/O controller configuration. Depending on the type of I/O (and whether its part of an ongoing atomic transfer), the driver may need to configure direction, set interrupts, etc.

Additionally, for I2C, the driver may need to insert a start, restart, or stop bit as necessary, and for SPI the driver may need to assert or de-assert the chip select line.

I/O PROCESSING

OnInterruptIsr

Interrupt callback. Acknowledges interrupts and saves state as necessary. Queues a DPC for processing.

OnInterruptDpc

DPC callback. Processes saved interrupts. If necessary the request is completed.

ControllerProcessInterrupts

Handles processing for both normal and error condition interrupts. Invokes ControllerCompleteTransfer() as appropriate.

ControllerCompleteTransfer

Invoked when an I/O completes or an error is detected. If this I/O is part of a sequence, PbcRequestConfigureForIndex() is called to prepare the next I/O; otherwise, the request is marked for completion.


Overview (`spb/SpbTestTool/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SpbTestTool

The SpbTestTool sample serves two purposes. First, it demonstrates how to open a handle to the SPB controller, use the SPB interface from a KMDF driver, and employ GPIO passive-level interrupts. Second, it implements a set of commands for communicating with a peripheral device to aid in debugging.

This sample is incomplete as a driver and merely demonstrates use of the SPB I/O request interface and GPIO interrupts. It is not intended for use in a production environment.

Run the sample

To install the SpbTestTool peripheral driver, follow these steps:

  1. Ensure that the driver builds without errors.

  2. Copy the SYS and INF files to a separate folder.

  3. Run Devcon.exe. You can find this program in the tools\devcon folder where you installed the WDK. Type the following command in the command window:

    devcon.exe update SpbTestTool.inf ACPI\<hwid>

To launch the SpbTestTool application, follow these steps:

  1. Navigate to the directory that contains SpbTestTool.exe.

  2. Type the following command in the command window:

    SpbTestTool.exe

  3. By default, the SpbTestTool application uses the SpbTestTool sample driver. However, an alternate peripheral driver can be used instead. To specify an alternate driver, use the following format for the command line:

    SpbTestTool.exe /p \\.\<alternate_path>

  4. An input script can used instead of an interactive prompt. The script format requires one command per line. To run the script, use the following format for the command line in the command window:

    SpbTestTool.exe /i <script.txt>

Executing commands

The SpbTestTool application loops indefinitely waiting for one of the following commands. The commands are translated to the appropriate SPB I/O request without any state tracking in the driver. Transfer status, buffer contents, and error codes are returned as necessary. Type help at any time to display this command list. Press Ctrl-C at any time to cancel the current command and exit the application.

Command Description
open Open handle to SPB controller.
close Close handle to SPB controller.
lock Lock the bus for exclusive access.
unlock Unlock the bus.
lockconn Lock the shared connection for exclusive access. This command is used to synchronize bus transfers by the sample driver with op-region accesses by the ACPI firmware.
unlockconn Unlock the shared connection.
write {} Write a byte array to the peripheral device. Example: > write {01, 02, 03}
read <*numBytes*> Read <*numBytes*> from the peripheral device. Example: > read 5
writeread {} <*numBytes*> Atomically write a byte array to the peripheral device and read <*numBytes*> back. Example: > writeread {01, 02, 03} 5
signal Inform the SpbTestTool driver that the interrupt has been handled.
help Display the list of supported commands.
Ctrl-C Press Ctrl-C at any time to cancel the outstanding command and exit the application.

Code tour

The following are the relevant functions in the SpbTestTool peripheral driver for using the SPB interface from a KMDF driver.

Function Description
OnPrepareHardware Traverses the driver's start resources and caches the connection ID of the I2C or SPI resource. This ID will be used to open the SPB controller later on.
SpbPeripheralOpen Opens a handle to the underlying SPB controller via the resource hub. This allows the peripheral driver to be developed without any underlying knowledge of the platform or hardware connections. Instead, the dependency between controller and peripheral is described in ACPI.
SpbPeripheralClose Sends IOCTL_SPB_LOCK_CONTROLLER to the SPB controller to lock the bus for exclusive access by this peripheral.
SpbPeripheralLock Sends IOCTL_SPB_LOCK_CONTROLLER to the SPB controller to lock the bus for exclusive access by this peripheral.
SpbPeripheralUnlock Sends IOCTL_SPB_UNLOCK_CONTROLLER to the SPB controller to unlock the bus from exclusive access by this peripheral.
SpbPeripheralLockConnection Sends IOCTL_SPB_LOCK_CONNECTION to the SPB controller to lock the shared connection for exclusive access by this target (file handle).
SpbPeripheralUnlockConnection Sends IOCTL_SPB_UNLOCK_CONNECTION to the SPB controller to unlock the shared connection from exclusive access by this target (file handle).
SpbPeripheralRead Sends a read request to the SPB controller.
SpbPeripheralWrite Sends a write request to the SPB controller.
SpbPeripheralWriteRead Builds a write-read sequence and sends IOCTL_SPB_EXECUTE_SEQUENCE to the SPB controller.
SpbPeripheralOnComplete Completion callback for all I/O requests.

The following are the relevant functions in the SpbTestTool peripheral driver for managing GPIO passive-level interrupts from a KMDF driver.

Function Description
OnPrepareHardware Traverses the driver's start resources. If "ConnectInterrupt" is set to 1 in the registry, the driver connects the first interrupt resource found and registers an interrupt service routine.
OnInterruptIsr The interrupt service routine, which has been configured to run at passive-level. Doing so enables the driver to acknowledge or quiesce the interrupt using the SPB interface, which cannot be called at DIRQL. Typically a driver will clear the hardware interrupt and save any volatile information in its ISR, and then it will queue a workitem to continue processing. Our sample driver instead notifies the SpbTestTool app that an interrupt has occurred and calls KeWaitForSingleObject to wait until the interrupt is handled before returning. A "real" driver should never stall in the ISR like this.
SpbPeripheralWaitOnInterrupt Called to pend a WaitOnInterrupt request in the driver, which will be completed when the next interrupt occurs.
SpbPeripheralInterruptNotify Completes an outstanding WaitOnInterrupt request to inform the SpbTestTool app that an interrupt has occurred.
SpbPeripheralSignalInterrupt Notifies the interrupt service routine that the interrupt has been handled and the ISR should return.

File manifest

The following source files are in the \SpbTestTool\sys folder and are used to build the SpbTestTool.sys and SpbTestTool.inf files.

File Description
driver.h, driver.cpp Events on the Device Object, and read, write, and IOCTLs from the SpbTestTool application. Implements the driver's interrupt service routine.
internal.h Common includes and typedefs
makefile Redirects to the real makefile that is shared by all components of the WDK.
peripheral.h, peripheral.cpp Reflection of the SpbTestTool IOCTLs to the SPB API, including opening the controller via the resource hub and using lock, unlock, read, write, and sequence.
resource.rc Resource descriptor file used for versioning
sources Lists source files and build options.
sources.dep Defines build dependencies.
spbtesttool.asl Sample ASL file for a peripheral device node. It declares I2C and GPIO interrupt resources. Note each macro specifies an ACPI path to describe direct dependencies.
spbtesttool.h Private SpbTestTool IOCTLs for use between the application and peripheral driver, and driver path names.
spbtesttool.inx Describes the installation of the driver. The build process converts this into an INF.
trace.h Sets up WPP tracing.

The following source files are in the \SpbTestTool\exe folder and are used to build the SpbTestTool.exe file.

File Description
command.h, command.cpp Classes representing each of the SpbTestTool commands. For the list of commands, see Executing commands.
internal.h Common includes and function definitions
main.cpp Application entry point, input parsing, and main execution loop. Also contains the interrupt notification thread.
makefile Redirects to the real makefile that is shared by all components of the WDK.
sources Lists source files and build options.
util.cpp Helper functions

Overview (`storage/iscsi/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

iSCSI WMI Client

WMI Implementation in an iSCSI miniport can be tested using the iSCSICLI.exe tool, the iSCSI Initiator Properties page, the WBEMTEST.exe tool, and customized WMI scripts

Installation and Operation

The iSCSI WMI sample uses the iSCSI WMI Class, and MOF definitions described at iSCSI WMI Classes in the storage WMI classes reference. Their corresponding class structure details are described at iSCSI Structures.


Overview (`storage/msdsm/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Multipath I/O (MPIO) DSM Sample

The MPIO DSM Sample is intended to serve as an example to follow when building your own vendor specific device specific modules (DSM). This sample DSM supports iSCSI and Fibre Channel devices.

You can build the sample in two ways: using Microsoft Visual Studio or the command line (MSBuild).

Building a Driver Using Visual Studio

You build a driver the same way you build any project or solution in Visual Studio. When you create a new driver project using a Windows driver template, the template defines a default (active) project configuration and a default (active) solution build configuration. When you create a project from existing driver sources or convert existing driver code that was built with previous versions of the WDK, the conversion process preserves the target version information (operating systems and platform).

The default Solution build configuration is Debug and Win32.

  1. Open the driver project or solution in Visual Studio (find samplename.sln or samplename.vcxproj).

  2. Right-click the solution in the Solutions Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Debug or Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Building a Driver Using the Command Line (MSBuild)

You can build a driver from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe) Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can now use the Visual Studio Command Prompt window for all build configurations.

  1. Open a Visual Studio Command Prompt window at the Start screen. From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called filtername.vcxproj, navigate to the project directory and enter the following MSBuild command:

    msbuild /t:clean /t:build .\<samplename>.vcxproj

Installation and Operation

The installation process depends on proper construction of your DSM's INF as well as an installation program provided by you. These are important aspects of complying with the Designed for Windows logo program. The installation was designed to allow for multiple vendors to easily add DSMs and to eliminate rebooting as much as possible. The installation process will require you to update your installation routines and to use the new .INF files. With the new process, you can only modify your DSM's INF file.

The installer sample only needs to be called one time with the INF/driver source path, the name of the DSM INF, and the DSM hardware ID. Typically this would be called from an MSI or setup package, such as one created by InstallShield or other installer technology.

The following annotated DSM INF file illustrates the correct format for your DSM. Replace only those items that are in bold italics. Remember, you must not use "GENDSM" or "MSISCDSM" or "MSDSM" as the name of your DSM. Therefore, you must replace any instances of those strings with the proper name of your DSM.

inf
;
; Copyright (c) <YOUR COMPANY NAME HERE>.  All rights reserved.
;

In the Version section, make sure the DriverVer is correct for your DSM. Ideally it should match the version in the .rc file. You must specify a different catalog file since the MPIO core drivers now come pre-signed:

inf
[Version]
Signature   = "$WINDOWS NT$"
Class       = System
ClassGuid   = {4D36E97D-E325-11CE-BFC1-08002BE10318}
Provider    = %VNDR%
CatalogFile = mydsm.cat
DriverVer   = MM/DD/YYYY,x.x.xxxx

[DestinationDirs]
DefaultDestDir = 12

;
; Multi-Path Device-Specific Module
;

[Manufacturer]
%std_mfg% = std_mfg

Substitute all instances of "gendsm" with the proper name for your DSM. For example, "mydsm":

inf
[std_mfg]
%mydsm_devicedesc% = mydsm_install, Root\MYDSM

[mydsm_install]
copyfiles = @mydsm.sys

[mydsm_install.Services]
AddService = mydsm, %SPSVCINST_ASSOCSERVICE%, mydsm_service

[mydsm_service]
DisplayName    = %mydsm_desc%
ServiceType    = %SERVICE_KERNEL_DRIVER%
StartType      = %SERVICE_BOOT_START%
ErrorControl   = %SERVICE_ERROR_NORMAL%
ServiceBinary  = %12%\mydsm.sys
LoadOrderGroup = "System Bus Extender"
AddReg         = mydsm_addreg

This next section contains the Hardware ID strings for your devices. You can have more than one. Sample format: "VENDOR PRODUCT " - remember to use spaces in a field (vendor, product ID) to pad this to be eight characters for the vendor name (as registered with STA) and sixteen for the product ID (unless the supported devices share a common prefix, in which case the product ID can be less than 16 characters).

[!NOTE]
Underscores that are part of the inquiry string (applies to vendor ID as well as product ID fields) must NOT be replaced with spaces.

In this sample, there are two different strings:

inf
;
; The following cannot be grouped (as above)
;

HKLM, "SYSTEM\CurrentControlSet\Control\MPDEV", "MPIOSupportedDeviceList", %REG_MULTI_SZ_APPEND%, "VENDOR1 PRODUCT1        "
HKLM, "SYSTEM\CurrentControlSet\Control\MPDEV", "MPIOSupportedDeviceList", %REG_MULTI_SZ_APPEND%, "VENDOR2 PRODUCT2        "

These are valid samples:

inf
HKLM, "SYSTEM\CurrentControlSet\Control\MPDEV", "MPIOSupportedDeviceList", %REG_MULTI_SZ_APPEND%, "MAXTOR  ATLASU320_18_WLS"

HKLM, "SYSTEM\CurrentControlSet\Control\MPDEV", "MPIOSupportedDeviceList", %REG_MULTI_SZ_APPEND%, "VENDOR3 PROD_PREFIX"

(to replace "VENDOR3 PROD_PREFIX_A ", "VENDOR3 PROD_PREFIX_B " and "VENDOR3 PROD_PREFIX_C ")

In the above example, it is assumed that this sample DSM will be used to support three devices from vendor "VENDOR3" with product IDs "PROD_PREFIX_A", "PROD_PREFIX_B" and "PROD_PREFIX_C" respectively. Since all the three devices share the common product ID sub-string "PROD_PREFIX", we can replace separate entries (in MPIOSupportedDeviceList) for each one of them with just one entry that uses the product ID sub-string that is common to them, without padding it with spaces to make it 16 characters.

It is advisable to use this format if your storage devices generate product IDs on-the-fly using a known product ID prefix. This can significantly reduce the size of your INF file and makes future changes to the INF file less prone to human error. Large INF files can result in very long device installation times and will fill the registry with unnecessary information. Please make sure you take advantage of this new capability as it will improve your customers' experience with MPIO.

Add one entry for each WMI GUID that you use in your DSM. This is required:

text
/* Detailed source-code truncated for AI context efficiency. */

Finally, modify the following strings:

inf
[Strings]
VNDR              = "Your Company Name Here"
std_mfg           = "(Standard system devices)"
mydsm_devicedesc = "<Your product> Multi-Path Device Specific Module"

The following string is displayed as the friendly name of your DSM:

inf
mydsm_desc       = "<Your product name> Multi-Path DSM"

;
; Handy macro substitutions (non-localizable)
;

SERVICE_KERNEL_DRIVER  = 1

SERVICE_BOOT_START     = 0
SERVICE_SYSTEM_START   = 1
SERVICE_DEMAND_START   = 3

SERVICE_ERROR_IGNORE   = 0
SERVICE_ERROR_NORMAL   = 1
SERVICE_ERROR_CRITICAL = 3

SPSVCINST_ASSOCSERVICE = 2

REG_MULTI_SZ           = 0x00010000
REG_MULTI_SZ_APPEND    = 0x00010008
REG_EXPAND_SZ          = 0x00020000
REG_DWORD              = 0x00010001
REG_BINARY_NOCLOBBER   = 0x00030003

You should be aware of the following when you install the MPIO DSM sample:

  1. The install sample assumes that all necessary files have already been copied over to a vendor specific directory (preferably a folder under Program Files) and takes that path as one of the parameters. This eliminates requests for the original media when new devices appear.

  2. As the port filter needs to go on top of every adapter that hosts (or might host) a path to the disk, all SCSI adapters are restarted at the end of the install

It is expected that the adapter that hosts the system volumes (boot/paging) will not restart, but that should not be problem if you are not multipathing the boot volume. However, if you are multipathing the boot volume, you will need to restart the system.

[!NOTE]
Other filter drivers installed as port filters may interfere with the proper operation of the MPIO port filter. Microsoft does not recommend the use of such filter drivers which may be supplied by HBA miniport vendors.

[!NOTE]
Since your DSM binary is not signed, you will get Unsigned Driver Pop-Ups. Ignore these and accept the installation of the new driver. Once your package has been successfully qualified by WHQL, your binaries will get signed and your customers will not get unsigned driver popups.


Overview (`thermal/simsensor/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimSensor - Simulated Temperature Sensor Sample Driver

This sample is a driver for a simulated temperature sensor device.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

A hardware platform designer can strategically place temperature sensors in various thermal zones around the platform. The operating system gets the temperature readings from the temperature sensor drivers and uses these readings to regulate the temperatures across the platform. Regulation can be either passive or active. For more information, see Device-Level Thermal Management.

The SimSensor sample provides the source code for a specialized sensor driver that supports platform-wide thermal management by the operating system. This driver does not make the temperature sensor accessible to applications through the Sensor API.


Overview (`thermal/thermalclient/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimThermalClient - Simulated Thermal Client Sample Driver

This sample is a driver for a simulated device that is a client of Windows thermal management. This driver publishes a GUID_THERMAL_COOLING_INTERFACE driver interface. Drivers publish this interface so that they can participate in global thermal management under the coordination of the Windows operating system.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

See also

Device-Level Thermal Management


Overview (`usb/UcmCxUcsi/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk
    urlFragment: ucmtcpcicx-port-controller-client-driver-v2

UcmCxUcsi Port Controller Client Driver

This is a sample driver that shows how to create a Windows USB Type-C port controller driver using the USB Connector Manager class extension driver (UcmCx). The sample is a driver for an embedded controller which is compliant with the USB Type-C Connector System Software Interface (UCSI).

Background reading - UcmCx documentation

Start at the UcmCx documentation at USB Type-C connector driver programming reference.

Note on UCSI

Microsoft already provides an inbox UCSI driver, UcmUcsi.sys. This UcmCxUcsi sample driver is not identical to the inbox UCSI driver. Microsoft recommends that you use the inbox UcmUcsi.sys for your UCSI-compliant system rather than writing your own. This sample driver is meant for developers bringing up a UcmCx driver for their own non-UCSI platforms. For more information about the UCSI driver, reference USB Type-C Connector System Software Interface (UCSI) driver.

This sample demonstrates the following:

  • Registration with the USB Connector Manager (UCM) class extension driver.

  • Initializing the port controller's Type-C and Power Delivery capabilities.

  • Performing data and power role swaps requested by UCM

  • Notifying UCM of Type-C and Power Delivery events on the connector.

Customizing the sample for your port controller

This sample is specific to UCSI systems. You may choose to structure your driver in a similar way for your own hardware. Understand the requirements and specification of your own system prior to writing a new UcmCx client driver. In addition to making the logic and functionality suit your specific port controller hardware, you will need to modify the .inf such that it matches your device's information.

UcmCxUcsi structure

In this sample, UCM-specific interactions are split apart from most of the UCSI-specific operations.

UcmCx interactions

The following files contain methods that interface with UcmCx.

  • UcmCallbacks.cpp

  • UcmNotifications.cpp

  • Fdo.cpp

    • FDO callbacks, functions, and types, most of which do not interface with UCM. However, the method Fdo_EvtDeviceSelfManagedIoInit contains the code segment which initializes the device with UCM.

UCSI and WDF Interactions

The remainder of the files perform operations for UCSI and WDF, non-specific to UCM.

  • Acpi.cpp

    • ACPI method evaluation helper routines.
  • Driver.cpp

    • Entry point to the driver. Initializes the driver with WDF.
  • Ppm.cpp

    • Type-C Platform Policy Manager. Main interface to talk to the UCSI-compliant hardware.

When to write a UcmCx client driver

UcmCx is intended for system port controller drivers. If you are bringing up a USB Type-C peripheral, you do not need to write a USB Type-C specific driver; a regular USB client driver will suffice. Refer to Developing Windows client drivers for USB devices to determine what type of driver, if any, you need to write to make your USB device work with Windows. You may look at Do I need to write a driver for my USB Type-C hardware? for a more detailed overview.


Overview (`usb/UcmTcpciCxClientSample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

UcmTcpciCx Port Controller Client Driver

This is a skeleton sample driver that shows how to create a Windows USB Type-C port controller driver using the USB Connector Manager Type-C Port Controller Interface class extension driver (UcmTcpciCx). UcmTcpciCx is currently only available using the Windows Insider program - documentation for UcmTcpciCx will be available at the next release of Windows.

This sample demonstrates the following:

  • Registration with the UcmTcpci class extension driver (UcmTcpciCx)

  • Initializing the port controller's Type-C and Power Delivery capabilities

  • Initializing the I2C communications channel to the port controller hardware

  • Performing reads/writes over I2C

  • Handling hardware requests from UcmTcpciCx

  • Handling alerts from the port controller hardware and notifying UcmTcpciCx of the alert

  • Power management

  • Platform-level device reset in the case of an unresponsive I2C controller

Customizing the sample for your port controller

The sample contains a number of comments prefaced with // TODO - review them and modify the code as necessary as you are writing your driver.

Note regarding Type-C port controller hardware

This sample assumes a device that complies with the USB Type-C Port Controller Interface specification, Revision 1.0 (part of the USB 3.1 specification download). Such a device uses a predefined register layout and an I2C communications channel.
If your port controller hardware is not exactly compliant with the specification, you will need to make additional modifications to the sample.

Performing read/writes over I2C

The USB Type-C Port Controller Interface specification defines I2C to be the channel by which software communicates with the port controller hardware.
If your port controller hardware is not compliant with the specification and does not use I2C as the communications channel, you will need to make additional modifications to the sample.

When to write a UcmTcpciCx client driver

UcmTcpciCx is intended for system port controller drivers. If you are bringing up a USB Type-C peripheral, you do not need to write a USB Type-C specific driver; a regular USB client driver will suffice. Refer to Developing Windows client drivers for USB devices to determine what type of driver, if any, you need to write to make your USB device work with Windows.

Testing Your Type-C Port Controller (TCPC) Implementation on Windows 10 with Raspberry Pi

Pre-requisites

This section outlines a procedure for installing and testing a TCPCI implementation for Windows 10 on a Raspberry Pi computer running Windows 10 IoT Core. You will need a Raspberry Pi 2 or 3, your TCPC device, a USB-to-Serial converter for debugging, and 7 jumper wires to connect your TCPC to the Raspberry Pi (3 for the debug board, 4 for the TCPC).

You will also need the Windows 10 IoT Core Insider Preview builds, the IoT tool set, the Windows Driver Kit (WDK), and the UcmTcpciCxClientSample source code.

Setup

Operating System

Download the latest available Windows 10 IoT Core Insider Preview and install on your Raspberry Pi 2 or 3 per the instructions at Windows for Internet of Things.

Note, you will only need to complete the first two steps, “1 Get the tools” and “2 Setup your device” to proceed with the TCPC validation described here.

PowerShell Connection

Connect to your Raspberry Pi via a PowerShell remote session. You will use this connection to setup the debugger and install your TCPCI driver package.

Windows Device Portal

Open a connection to the Raspberry Pi via the Windows Device Portal. The portal provides a Device Manager view in which you will be able to inspect your TCPC device, as well as remote shutdown and reboot controls.

Kernel Debugger

Setup the kernel debugger for your Raspberry Pi according to the instructions at the Windows Debugger (WinDbg) for IoT.

Connect TCPC Hardware

The following assumes an I2C implementation of your TCPC; if your device uses a different transport, ignore the I2C specific references and connect the transport as appropriate.

First, shutdown and remove power from both the Raspberry Pi and your TCPC hardware. Once both boards are powered down, connect the four pins outlined below. Please refer to the GPIO pinout specification for the version of the Raspberry Pi platform you are using for the specific locations.

Connect the following pins between your TCPC and the Raspberry Pi:

  • GND: many options

  • SDA: pin 3

  • SCL: pin 5

  • ALERT: can be any GPIO but the sample ACPI is setup to use GPIO 5 (pull-up) which is pin 29 on the RPi2

Note the ACPI sample assumes GPIO5 (pin 29). If you use a different bus or interrupt you will need to update the sample ASL file to reflect the selected configuration.

Once these pins are connected, both boards may be powered on. You will not see any changes to the device manager view of the Device Portal yet.

UcmTcpciCx Client Driver

Customize and Build the Driver

Edit the driver source files to add any customizations that your hardware may require. For example, the sample is designed against TCPCI Revision 1.0 Version 1.0, but if your hardware conforms to a later version that repurposes register fields that were reserved in version 1.0 you will need to update the alert handler to recognize and clear those bits accordingly.

Edit the INF to set the device path and strings to desired custom values. Build your driver in Visual Studio and copy the INF and the SYS file from the build output.

Install Driver Package

Create a driver package for IoT in the form of a CAB file for your custom UcmTcpciCx client driver.

Once you have generated the CAB file, see step 3 for instructions on installing the driver package on your Raspberry Pi via the PowerShell connection established earlier. After the package has been installed and the system has rebooted, there is still one more step to getting your driver to load: updating the ACPI tables to describe the device to the platform.

Update ACPI

Open sample.asl provided in the UcmTcpciCxClientSample driver sample and modify the following sections as necessary:

  • Ensure that the device name matches the device path specified in your INF

  • Update the resources section to reflect the actual I2C and Interrupt resources on which your TCPC is connected, default is I2C1 and GPIO5. Specify the I2C address your TCPC uses.

  • Update the connector capabilities section to reflect the capabilities of the connector on your TCPC.

On a PC with the Windows 10 WDK installed run the following command on your updated ASL file:

asl.exe sample.asl

This will produce output file ACPITABL.dat. Copy this file to C:\Windows\System32 on your Raspberry Pi device, and reboot. See the Verification section in Enable usermode access to GPIO, I2C, and SPI for more information on merging ACPI updates into an IoT image without a full UEFI build.

Once the Raspberry Pi has rebooted, your driver will load on the newly enumerated ACPI device node.

Testing

USB Type-C Connection Exerciser

The MCCI Model 3101 Type-C Connection Exerciser is a tool designed by Microsoft and manufactured by MCCI.

The tools and instructions for deploying testing with this device are available at Testing USB hardware, drivers, and apps in Windows.

Suggested testing with the Connection Exerciser device is randomized connect/disconnect for long periods of time.

Debugging

The sample driver includes standard WDF logging which can be extracted via the kernel debugger with the following debugger command:

!wdfkd.wdflogdump <driver name> -d

Other useful driver traces are available from UcmTcpciCx and UcmCx.

Driver logs may also be captured via tracelog which is included in the IoT image. Sample trace capture commands using the GUID included by default in the client sample driver is as follows:

cmd
Tracelog -start ClientSampleTrace -guid #1dc982f3-068f-4577-bcdf-1bc844e457b2 -flags 0x7fffffff -level 0xff -f clientsampletrace.etl -ft 3

<reproduce issue of interest>

Tracelog -stop ClientSampleTrace

Tracelog -remove ClientSampleTrace

Other useful driver trace guids:

UcmCx: C5964C90-1824-4835-857A-5E95F8AA33B2

UcmTcpciCx: 8DEAEA72-4C63-49A4-9B8B-25DA24DAE056

Resources

USB Type-C Port Controller Interface Specification (TCPCI) (download as part of USB 3.1 Specification)

Raspberry Pi

Windows 10 IoT Core Insider Preview

Windows for Internet of Things

Windows Insider Preview WDK

Tracelog Command Syntax


Overview (`usb/UcmUcsiAcpiSample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

UcmUcsiCx ACPI Client Driver

This is a sample driver that shows how to create a Windows USB Type-C port controller driver using the USB Connector Manager class extension driver (UcmCx). The sample is a driver for an embedded controller which is compliant with the USB Type-C Connector System Software Interface (UCSI).

Note on UCM UCSI

Microsoft already provides an inbox UCSI Class extension (UcmUcsiCx.sys) and ACPI client driver (UcmUcsiAcpiClient.sys) . This UcmUcsi ACPI sample driver is not to a very large extent identical to and functionally replaceable with UcmUcsiAcpiClient.sys. Microsoft recommends that you use this sample to bring up your UcmUcsiCx Client driver that is interfaced over a non ACPI transport.

This sample demonstrates the following:

  • Preparing connector collection with UcmUcsiCx

  • Initializing Platform Policy Manager (or PPM) object with UcmUcsiCx

  • Handling IOCTLs from UcmUcsiCx to send or get UCSI block

  • Delivering PPM notifications to UcmUcsiCx

Customizing the sample for your UCSI transport

This sample is specific to ACPI based UCSI systems. You may choose to structure your driver in a similar way for your own hardware. Understand the requirements and specification of your own system prior to writing a new UcmUcsiCx client driver. In addition to making the logic and functionality suit your specific UCSI transport, you will need to modify the .inf such that it matches your device's information.

UcmUcsiCx structure

In this sample, UCMUCSI-specific interactions are split apart from most of the UCSI-specific operations.

UcmUcsiCx Interactions

The following files contain methods that interface with UcmUcsiCx.

  • Ppm.cpp

    • Contains bulk of interactions with UcmUcsiCx. Ppm::CreateAndInitialize which is called in the context of PrepareHardware PnP callback, creates connector collection with UcmUcsiCx by calling DDI UcmUcsiConnectorCollectionCreate and UcmUcsiConnectorCollectionAddConnector. The collection serves as a parameter to initialize PPM object with the class extension when the DDI UcmUcsiPpmCreate is called. Ppm::PpmNotificationCallback function calls DDI on the event of a PPM notification. Ppm::EvtIoDeviceControl contains the logic of handling IOCTLs from UcmUcsiCx.
  • Fdo.cpp

    • FDO callbacks, functions, and types, most of which do not interface with UcmUcsiCx. However, the method Fdo::CreateAndInitialize calls to UcmUcsiCx DDIs UcmUcsiDeviceInitInitialize and UcmUcsiDeviceInitialize.

UCSI and WDF Interactions

The remainder of the files perform operations for UCSI and WDF, non-specific to UCM.

  • Acpi.cpp

    • ACPI method evaluation helper routines.
  • Driver.cpp

    • Entry point to the driver. Initializes the driver with WDF.
  • Ppm.cpp

    • Type-C Platform Policy Manager. Main interface to talk to the UCSI-compliant hardware (via ACPI transport in this case).

When to write a UcmUcsiCx client driver

UcmUcsiCx is intended to abstract UCSI protocol from UCSI based driver support. If you have a system that implements PPM logic in an Embedded controller which is connected to the system over a non ACPI transport - e.g. USB, PCI, I2C or UART, it is advised that you write a UcmUcsiCx client driver that implements the necessary transport. Ideally, you would just need to replace Acpi class and implement your way to talk to the PPM. Please note, UcmUcsiCx client is the power policy owner. The class extension does handle S0 idling if you chose to enable it in the client driver.


Overview (`usb/kmdf_enumswitches/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Sample KMDF Bus Driver for OSR USB-FX2

The kmdf_enumswitches sample demonstrates how to use Kernel-Mode Driver Framework (KMDF) as a bus driver using the OSR USB-FX2 device.

This sample is written for the OSR USB-FX2 Learning Kit.

Testing the Device

To test the device, follow these steps:

  1. If you test signed your driver package, you must enable installation of test signed drivers on the target machine. To do so, either press F8 as the target machine comes up from a reboot, or specify Bcdedit.exe -set TESTSIGNING ON and reboot. If you use F8, the change only applies until the next reboot.

  2. Plug in the OSR USB-FX-2 Learning Kit (must be version 2.00 or later).

  3. In Device Manager, select Update Driver Software, Browse my computer for driver software, Let me pick from a list of device drivers on my computer, Have Disk. Navigate to the directory that contains your driver package and select the INF file.

  4. After the driver installs, verify that the device appears under the Sample Device node in Device Manager.

  5. Flip the switches on the OSR USB-FX-2 hardware board and watch the raw PDO entries appear and disappear under Sample Device in Device Manager.

  6. Right-click a raw PDO entry, select Properties, and then click the Events tab. Under Information, examine the hardware ID for the PDO. It should be something like this:

    6FDE7521-1B65-48ae-B628-80BE62016026}\OsrUsbFxRawPdo\6&227995e2&0&08

    The last digit matches the number of the switch that you toggled.

Hardware Overview

Here is the overview of the device:

  • Device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681).

  • Contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN).

  • Firmware supports vendor commands to query or set LED Bar graph display, 7-segment LED display and query toggle switch states.

  • Interrupt Endpoint:

    • Sends an 8-bit value that represents the state of the switches.

    • Sent on startup, resume from suspend, and whenever the switch pack setting changes.

    • Firmware does not de-bounce the switch pack.

    • One switch change can result in multiple bytes being sent.

    • Bits are in the reverse order of the labels on the pack

      For example, bit 0x80 is labeled 1 on the pack

  • Bulk Endpoints are configured for loopback:

  • Device moves data from IN endpoint to OUT endpoint.

    • Device does not change the values of the data it receives nor does it internally create any data.

    • Endpoints are always double buffered.

    • Maximum packet size depends on speed (64 Full speed, 512 High speed).


Overview (`usb/kmdf_fx2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Sample KMDF Function Driver for OSR USB-FX2

The kmdf_fx2 sample is a Kernel-Mode Driver Framework (KMDF) driver for the OSR USB-FX2 device. It includes a test app and sample device metadata.

In the Windows Driver Kit (WDK), the osrusbfx2 sample demonstrates how to perform bulk and interrupt data transfers to an USB device. The sample was written for the OSR USB-FX2 Learning Kit.

The driver and sample device metadata also works with the Custom driver access sample.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Overview

Here is the overview of the device:

  • The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681).

  • It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN).

  • Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states.

  • Interrupt endpoint:

    • Sends an 8-bit value that represents the state of the switches.

    • Sent on startup, resume from suspend, and whenever the switch pack setting changes.

    • Firmware does not de-bounce the switch pack.

    • One switch change can result in multiple bytes being sent.

    • Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack).

  • Bulk endpoints are configured for loopback:

    • The device moves data from IN endpoint to OUT endpoint.

    • The device does not change the values of the data it receives nor does it internally create any data.

    • Endpoints are always double buffered.

    • Maximum packet size depends on speed (64 full speed, 512 high speed).

  • Event Tracing for Windows (ETW) events:

    • Included osrusbfx2.man, which describes events added.

    • Three events are targeted to the event log:

      • Failure during the add device routine.

      • Failure to start the OSR device on a USB 1.1 controller.

      • Invocation of the "re-enumerate device" IOCTL.

    • Read/write start/stop events can be used to measure the time taken.

    • For more information, see Unified Tracing later in this document.

Code tour

usb\\kmdf\_fx2\\driver

This directory contains driver code that demonstrates the following functionality:

  • Loads the driver and responds to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system.

  • Creates a context with the WDFDEVICE object.

  • Initializes the USB device by registering a EvtPrepareHardware callback.

  • Marks the interface restricted so that it can be accessed by a privileged UWP device app.

  • Creates a default parallel queue to receive an IOCTL request to set bar graph display.

  • Retrieves memory handle from the requests and uses it to send a vendor command to the USB device.

  • Registers read and write events on the default queue.

  • Retrieves memory from read and write requests, formats the requests, and sends it to a USB target.

  • Creates two separate sequential queues and configures them to dispatch read and write requests directly. (*kmdf_fx2 only)

  • Enables wait-wake and selective suspend support. (*kmdf_fx2 only)

  • Configures a USB target continuous reader to read toggle switch states asynchronously from the interrupt endpoint. (*kmdf_fx2 only)

  • Supports additional IOCTLs to get and set the 7-segment display and toggle switches, and to reset and re-enumerate the device. (*kmdf_fx2 only)

  • Creates ETW provider to log two events to the event log, and read/write start stop events. (*kmdf_fx2 only)

  • WPP tracing

usb\\kmdf\_fx2\\exe

This directory contains a test application that can be used to drive the KMDF driver and FX2 device.

usb\\kmdf\_fx2\\deviceMetadata

This directory contains the device metadata package for the sample. You must copy the device metadata to the system before installing the device. For information on how to update and deploy device metadata, see the Custom driver access sample.

Testing the driver

You can use the Custom driver access sample as a testing method.

The sample also includes a test application, osrusbfx2.exe, that you can use to test the device. This console application enumerates the interface registered by the driver and opens the device to send read, write, or IOCTL requests based on the command line options.

Usage for Read/Write test:

  • -r [n], where n is number of bytes to read.

  • -w [n], where n is number of bytes to write.

  • -c [n], where n is number of iterations (default = 1).

  • -v, shows verbose read data.

  • -p, plays with Bar Display, Dip Switch, 7-Segment Display.

  • -a, performs asynchronous I/O operation.

  • -u, dumps USB configuration and pipe information.

Playing with the 7 segment display, toggle switches, and bar graph display

Use the command, osrusbfx2.exe -p options 1-9, to set and clear bar graph display, set and get 7 segment state, and read the toggle switch states. The following shows the function options:

cmd
1.  Light bar
2.  Clear bar
3.  Light entire bar graph
4.  Clear entire bar graph
5.  Get bar graph state
6.  Get switch state
7.  Get switch interrupt message
8.  Get 7 segment state
9.  Set 7 segment state
10. Reset the device
11. Re-enumerate the device

12. Exit

Selection:

Reset and re-enumerate the device

Use the command, osrusbfx2.exe -p with option 10 and 11, to either reset the device or re-enumerate the device.

Read and write to bulk endpoints

The following commands send read and write requests to the device's bulk endpoint.

  • osrusbfx2.exe -r 64

    The preceding command reads 64 bytes to the bulk IN endpoint.

  • osrusbfx2.exe -w 64

    The preceding command writes 64 bytes to the bulk OUT endpoint.

  • osrusbfx2.exe -r 64 -w 64 -c 100 -v

    The preceding command first writes 64 bytes of data to bulk OUT endpoint (Pipe 1), then reads 64 bytes from bulk IN endpoint (Pipe 2), and then compares the read buffer with write buffer to see if they match. If the buffer contents match, it repeats this operation 100 times.

  • osrusbfx2.exe -a

    The preceding command reads and writes to the device asynchronously in an infinite loop.

The bulk endpoints are double buffered. Depending on the operational speed (full or high), the buffer size is either 64 bytes or 512 bytes, respectively. A request to read data does not complete if the buffers are empty. If the buffers are full, a request to write data does not complete until the buffers are emptied. When you are doing a synchronous read, make sure the endpoint buffer has data (for example, when you send a 512 bytes write request to the device operating in full speed mode). Because the endpoints are double buffered, the total buffer capacity is 256 bytes. The first 256 bytes fills the buffer, and the write request waits in the USB stack until the buffers are emptied. If you run another instance of the application to read 512 bytes of data, both write and read requests complete successfully.

Displaying descriptors

The following command displays all the descriptors and endpoint information.

osrusbfx2.exe -u

If the device is operating in high speed mode, you will get the following information:

text
/* Detailed source-code truncated for AI context efficiency. */

Unified tracing

To view events the provider manifest must be installed. As part of the installation, from an elevated prompt run the following: wevtutil im osrusbfx2.man

Registering the manifest sets up the appropriate paths where the system can find information for decoding the events. The OSR event log can be found in the system event viewer under Event Viewer\Applications and Services Logs\OSRUSBFx2\Operational channel eventlog. Triggering a device re-enumeration through osrusbfx2.exe sends an event to this log.

To trace, you can use the in-box tools, logman and tracerpt, or download XPerf (Windows Performance Toolkit) from Microsoft.

Using in-box tools

To start/stop the trace by using logman

  1. Start tracing by using the following command:

    logman start sample -o osrusbfx2.etl -ets -p OSRUSBFX2

  2. Generate activity through the osrusbfx2 test application, such as osrusbfx2.exe -a.

  3. Stop tracing by using the following command:

    Logman stop sample

  4. View the trace file using tracerpt:

    tracerpt -of csv OSRUSBFX2.etl

To start/stop the trace by using Xperf (Windows Performance Toolkit)

  1. Start tracing by using the following command:

    xperf -start sample -f osrusbfx2.etl -on OSRUSBFX2

  2. Generate activity through the osrusbfx2 test application, such as osrusbfx2.exe -a.

  3. Stop tracing by using the following command:

    xperf -stop sample

  4. View the trace file using Xperf:

    xperfview OSRUSBFX2.etl


Overview (`usb/ufxclientsample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

USB Function Client Driver

This is a skeleton sample driver that shows how to create a Windows USB function controller driver using the USB function class extension driver (UFX).

This sample demonstrates the following:

  • Registration with the UFX class extension driver

  • Handling USB transfers

  • Handling function controller events

  • Handling attach and detach notifications

  • Handling charger/port detection

  • Power management

Operating system requirements

Windows 10 Mobile

Customizing the sample for your device

This sample is not a functional driver. It is a skeleton driver intended to illustrate the general design of a UFX client driver. The sample contains a number of comments prefaced with " #### TODO ", which indicates where code will need to be added to perform the controller operation as described in the comment.

Installation Note

Installation on Windows 10 Mobile requires the creation of a package. To properly interact with the USB UI on Windows 10 Mobile, the package must include a Security Element that specifies the ID_CAP_USB capability with DEVICE_READ and DEVICE_WRITE rights.


Overview (`usb/umdf2_fx2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Sample Function Driver for OSR USB-FX2 (UMDF Version 2)

The umdf2_fx2 sample is a User-Mode Driver Framework (UMDF) version 2 driver for the OSR USB-FX2 device.

For more information, see the specification for the OSR USB FX-2 Learning Kit. The driver and sample device metadata also work with the Custom driver access sample.

User-Mode Driver Framework

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy a driver sample automatically or manually.

Automatic deployment (FX2 board)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing (WDK 10).

  1. Plug in the OSR USB-FX2 board to the target computer.

  2. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  3. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Install and Verify. Click OK.

  4. On the Build menu, choose Deploy Package or Build Solution.

Manual deployment (FX2 board)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\umdf2_fx2).

  2. Plug in the OSR USB-FX2 board to the target computer. Open a Command Prompt window and enter dvmgmt to open Device Manager. In Device Manager, locate the node for the OSR USB-FX2 board. Right click the node, and choose Properties. In the Details tab, under Properties, choose Hardware Ids. Note the hardware IDs listed for your FX2 board. One of these IDs should match one of the IDs in the osrusbfx2um.inf file. For example, Device Manager might show an ID of USB\VID_0547&PID_1002, which matches one of the IDs in the [Microsoft.xxx] section of osrusbfx2um.inf.

  3. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter this command:

    devcon update osrusbfx2um.inf"***HardwareID***"

    where HardwareID is the hardware ID of your FX2 board. Here is an example:

    devcon update osrusbfx2um.inf "USB\VID_0547&PID_1002"

View the driver for the OSR USB-FX2 board in Device Manager

On the target computer, in your Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate UMDF 2.0 Sample Driver for OSR Fx2 Learning Kit (for example, this might be under the Sample Device node).

In Device Manager, on the View menu, choose Devices by connection. Locate UMDF 2.0 Sample Driver for OSR Fx2 Learning Kit as a child of a USB hub node, which may be contained with the ACPI x64-based PC node.

Build the sample using MSBuild

As an alternative to building the driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, umdf2echo.sln. Use the MSBuild command to build the solution. Here is an example:

msbuild /p:configuration=Win8 Release /p:platform=Win32 umdf2_fx2.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.


Overview (`usb/usbsamp/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Usbsamp Generic USB Driver

The USBSAMP sample demonstrates how to perform full speed, high speed, and SuperSpeed transfers to and from bulk and isochronous endpoints of a generic USB device. USBSAMP is based on the Kernel Mode Driver Framework (KMDF). Superspeed bulk and isochronous transfers only work when the Microsoft USB 3.0 stack is loaded.

The sample also contains a console test application that initiates bulk (including stream) and isochronous transfers and obtains data from the device's I/O endpoints. The application also demonstrates how to use GUID-based device names and pipe names generated by the operating system using the SetupDiXXX user-mode APIs.

For information about USB, see Universal Serial Bus (USB) Drivers.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Hardware requirements

The sample driver can be loaded as the function driver for any of these devices:

If you have a different USB device, you can still use the driver by adding the device's hardware ID to the INX file. Note that the data transfer scenarios will work only with the endpoints supported by the device.

Set the configuration and platform in Visual Studio

In Visual Studio, in Solution Explorer, right click Solution 'usbsamp' (3 projects), and choose Configuration Manager. Set the configuration and the platform. Make sure that the configuration and platform are the same for both the driver project and the package project. Do not check the Deploy boxes.

Build the sample using Visual Studio

In Visual Studio, on the Build menu, choose Build Solution.

For more information about using Visual Studio to build a driver package, see Building a Driver with Visual Studio and the WDK.

Locate the built driver

In File Explorer, navigate to the folder that contains your built driver package. The location of this folder varies depending on what you set for configuration and platform. For example, if your settings are Debug and x64, the driver is in your solution folder under sys\driver\Debug\usbsamp.

The driver folder contains these files:

File Description
usbsamp.sys The driver file
usbsamp.inf An information (INF) file that contains information needed to install the driver.
kmdfsamples.cat A signed catalog file, which serves as the signature for the entire package.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy the USBSAMP sample automatically or manually.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing (WDK 10).

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Install and Verify. Click OK.

  3. On the Build menu, choose Deploy Package or Build Solution.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\Usbsamp).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

    devcon install usbsamp.inf USB\VID_045E&PID_078F

View the device in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate the device. For example the device name might be WDF Sample for FX2 MUTT device under theSample Device node.

Build the sample using MSBuild

As an alternative to building the USBSAMP sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, Usbsamp.sln. Use the MSBuild command to build the solution. Here are some examples:

text
`msbuild /p:configuration="Debug" /p:platform="x64" Usbsamp.sln`

`msbuild /p:configuration="Release" /p:platform="Win32" Usbsamp.sln`

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.

Testing the sample

The sample includes a test application, usbsamp.exe. This console application enumerates the interface registered by the driver and opens the device to send Read, Write, or DeviceIoControl requests based on the command line options. To test the sample,

  1. In Visual Studio, choose Solution Explorer from the View menu. Locate the application project named usbsamp, under the Exe folder.

  2. Right-click and choose Build. For example, if your settings are Debug and x64, the application executable is in your solution folder under the exe\Debug\usbsamp.exe.

  3. Run the executable on the target machine.

  • To view all descriptors and endpoint information, use the following command.

    usbsamp.exe -u

    You can use the preceding command to view pipe numbers for read and write requests.

  • To send a Read-Write request, use the following command.

    usbsamp.exe -r 1024 -w 1024 -c 100 -v

    The preceding command first writes 1024 bytes of data to bulk out endpoint (pipe 1), then reads 1024 bytes from bulk in endpoint (pipe 0), and compares the read buffer with write buffer to see if they match. If the buffer contents match, it performs this operation 100 times.

  • To send Read-Write requests to bulk endpoints, use any of the following commands, simultaneously. If Read-Write requests are sent to a SuperSpeed bulk endpoint with streams, the sample driver always uses the first underlying stream associated with that endpoint. The driver is multi-thread safe so it can handle multiple requests at a time.

    usbsamp.exe -r 65536

    The preceding command reads 65536 bytes from pipe 0.

    usbsamp.exe -w 65536

    The preceding command writes 65536 bytes to pipe 1.

    usbsamp.exe -r 65536 -i pipe02

    The preceding command reads 65536 bytes from pipe 2.

    usbsamp.exe -w 65536 -o pipe03

    The preceding command writes 65536 bytes to pipe 3.

  • To send Read and Write requests to isochronous endpoints you can use one or more of these commands simultaneously.

    usbsamp.exe -r 512 -i pipe04

    The preceding command reads 512 bytes from pipe 4.

    usbsamp.exe -w 512 -o pipe05

    The preceding command writes 512 bytes to pipe 5.

    usbsamp.exe -w 1024 -o pipe05 -r 1024 -i pipe04 -c 100 -v

    The preceding command writes 1024 bytes to pipe 5, then reads 1024 bytes from pipe 4, and compares the buffers to see if they match. If the buffer contents match, it performs this operation 100 times.

  • To skip validation of the data to be read or written in a particular request, use the command with -x option as follows:

    usbsamp.exe -r 1024 -w 1024 -c 100 -x


Overview (`usb/usbview/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

USBView sample application

Usbview.exe is a Windows GUI application that allows you to browse all USB controllers and connected USB devices on your system. The left pane in the main application window displays a connection-oriented tree view, and the right pane displays the USB data structures pertaining to the selected USB device, such as the Device, Configuration, Interface, and Endpoint Descriptors, as well as the current device configuration.

This functional application sample demonstrates how a user-mode application can enumerate USB host controllers, USB hubs, and attached USB devices, and query information about the devices from the registry and through USB requests to the devices.

The IOCTL calls (see the system include file USBIOCTL.H) demonstrated by this sample include:

For information about USB, see Universal Serial Bus (USB) Drivers.

Run the sample

Local debugging

  1. Change Debugger to launch to Local Windows Debugger.

  2. On the Debug menu, select Start debugging or hit F5.

Manual deployment to a remote target computer

If you want to debug the sample app on a remote computer,

  1. Copy the executable to a folder on the remote computer.

  2. Specify project properties as per the instructions given in Remote Debugging.

  3. Change Debugger to launch to Remote Windows Debugger.

  4. On the Debug menu, select Start debugging or hit F5.

View a USB device in Usbview

  1. Attach a USB device to one of USB ports on the computer that has Usbview running.

  2. In the device tree, locate the device. For example the device might be under the Intel(R) ICH10 Family USB Universal Host Controller - 3A34 > Root Hub node.

  3. View host controller and port properties on the right pane.

Code tour

File manifest Description
Resource.h ID definitions for GUI controls
Usbdesc.h USB descriptor type definitions
Usbview.h Main header file for this sample
Vndrlist.h List of USB Vendor IDs and vendor names
Debug.c Assertion routines for the checked build
Devnode.c Routines for accessing DevNode information
Dispaud.c Routines for displaying USB audio class device information
Enum.c Routines for displaying USB device information
Usbview.c Entry point and GUI handling routines

The major topics covered in this tour are:

  • GUI handling routines

  • Device enumeration routines

  • Device information display routines

The file Usbview.c contains the sample application entry point and GUI handling routines. On entry, the main application window is created, which is actually a dialog box as defined in Usbview.rc. The dialog box consists of a split window with a tree view control on the left side and an edit control on the right side.

The routine RefreshTree() is called to enumerate USB host controller, hubs, and attached devices and to populate the device tree view control. RefreshTree() calls the routine EnumerateHostControllers() in Enum.c to enumerate USB host controller, hubs, and attached devices. After the device tree view control has been populated, USBView_OnNotify() is called when an item is selected in the device tree view control. This calls UpdateEditControl() in Display.c to display information about the selected item in the edit control.

The file Enum.c contains the routines that enumerate the USB bus and populate the tree view control. The USB device enumeration and information collection process is the main point of this sample application. The enumeration process starts at EnumerateHostControllers() and goes like this:

  1. Enumerate Host Controllers and Root Hubs. Host controllers have symbolic link names of the form HCDx, where x starts at 0. Use CreateFile() to open each host controller symbolic link. Create a node in the tree view to represent each host controller. After a host controller has been opened, send the host controller an IOCTL_USB_GET_ROOT_HUB_NAME request to get the symbolic link name of the root hub that is part of the host controller.

  2. Enumerate Hubs (Root Hubs and External Hubs). Given the name of a hub, use CreateFile() to open the hub. Send the hub an IOCTL_USB_GET_NODE_INFORMATION request to get info about the hub, such as the number of downstream ports. Create a node in the tree view to represent each hub.

  3. Enumerate Downstream Ports. Given a handle to an open hub and the number of downstream ports on the hub, send the hub an IOCTL_USB_GET_NODE_CONNECTION_INFORMATION request for each downstream port of the hub to get info about the device (if any) attached to each port. If there is a device attached to a port, send the hub an IOCTL_USB_GET_NODE_CONNECTION_NAME request to get the symbolic link name of the hub attached to the downstream port. If there is a hub attached to the downstream port, recurse to step (2). Create a node in the tree view to represent each hub port and attached device. USB configuration and string descriptors are retrieved from attached devices in GetConfigDescriptor() and GetStringDescriptor() by sending an IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION() to the hub to which the device is attached.

The file Display.c contains routines that display information about selected devices in the application edit control. Information about the device was collected during the enumeration of the device tree. This information includes USB device, configuration, and string descriptors and connection and configuration information that is maintained by the USB stack. The routines in this file simply parse and print the data structures for the device that were collected when it was enumerated. The file Dispaud.c parses and prints data structures that are specific to USB audio class devices.


Overview (`usb/wdf_osrfx2_lab/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

WDF Sample Driver Learning Lab for OSR USB-FX2

[!WARNING]
UMDF 2 is the latest version of UMDF and supersedes UMDF 1. All new UMDF drivers should be written using UMDF 2. No new features are being added to UMDF 1 and there is limited support for UMDF 1 on newer versions of Windows 10. Universal Windows drivers must use UMDF 2.

For more info, see Getting Started with UMDF.

The UMDF v1 sample can be accessed using git checkout win11-22h2. A direct link is: https://github.com/microsoft/Windows-driver-samples/tree/win11-22h2

The wdf_osrfx2_lab sample contains a console test application and a series of iterative drivers for both Kernel-Mode Driver Framework (KMDF) and User-Mode Driver Framework (UMDF) version 1.

In the Windows Driver Kit (WDK) for Windows 7 and earlier versions of Windows, the osrusbfx2 sample demonstrated how to perform bulk and interrupt data transfers to an USB device. The sample was written for the OSR USB-FX2 Learning Kit.

Starting in Windows 8.1, the osrusbfx2 sample has been divided into these samples:

  • wdf_osrfx2: This sample is a series of iterative drivers that demonstrate how to write a "Hello World" driver and adds additional features in each step.

  • kmdf_fx2: This sample is the final version of kernel-mode wdf_osrfx2 driver. The sample demonstrates KMDF methods.

  • umdf_fx2: This sample is the final version of the user-mode driver wdf_osrfx2. The sample demonstrates UMDF methods.

This sample is written for the OSR USB-FX2 Learning Kit. For more information, see the specification for the OSR USB FX-2 Learning Kit.

Build the sample

The default Solution build configuration is Windows 8.1 Debug and Win32. You can change the default configuration to build for Windows 8 or Windows 7 version of the operating system.

To select a configuration and build a driver

  1. Open the driver project or solution in Visual Studio 2013 (find filtername.sln or filtername.vcxproj).

  2. Right-click the solution in the Solutions Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Windows 8.1 Debug or Windows 8.1 Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. Each driver project in this iterative sample creates a binary with the same name, osrusbfx2.sys. As a result, you can build only the single project you're currently working on, as well as the package project. You can do this by selecting only these two projects in Configuration Manager.

  5. From the Build menu, click Build Solution (Ctrl+Shift+B).

Overview

Here is the overview of the device:

  • The device is based on the development board supplied with the Cypress EZ-USB FX2 Development Kit (CY3681).

  • It contains 1 interface and 3 endpoints (Interrupt IN, Bulk Out, Bulk IN).

  • Firmware supports vendor commands to query or set LED Bar graph display and 7-segment LED display, and to query toggle switch states.

  • Interrupt Endpoint:

    • Sends an 8-bit value that represents the state of the switches.

    • Sent on startup, resume from suspend, and whenever the switch pack setting changes.

    • Firmware does not de-bounce the switch pack.

    • One switch change can result in multiple bytes being sent.

    • Bits are in the reverse order of the labels on the pack (for example, bit 0x80 is labeled 1 on the pack).

  • Bulk Endpoints are configured for loopback:

    • The device moves data from IN endpoint to OUT endpoint.

    • The device does not change the values of the data it receives nor does it internally create any data.

    • Endpoints are always double buffered.

    • Maximum packet size depends on speed (64 full speed, 512 high speed).

Sample Contents for KMDF

The KMDF sample contains a console test application and a series of drivers. The driver is iterative as a series of steps, starting with a basic "Hello World" driver.

usb\wdf_osrfx2_lab\kmdf\step1

The most basic step. The source file contains a minimal amount of code to get the driver loaded in memory and respond to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system.

usb\wdf_osrfx2_lab\kmdf\step2

  • Creates a context with the WDFDEVICE object

  • Initializes the USB device by registering a EvtPrepareHardware callback

  • Registers an interface so that application can open a handle to the device

Testing the driver

The sample includes a test application, osrusbfx2.exe, that you can use to test the device. This console application enumerates the interface registered by the driver and opens the device to send read, write, or IOCTL requests based on the command line options.

Usage for Read/Write test:

  • -r [n], where n is number of bytes to read.

  • -w [n], where n is number of bytes to write.

  • -c [n], where n is number of iterations (default = 1).

  • -v, shows verbose read data.

  • -p, plays with Bar Display, Dip Switch, 7-Segment Display.

  • -a, performs asynchronous I/O operation.

  • -u, dumps USB configuration and pipe information.

Playing with the 7 segment display, toggle switches and bar graph display

Use the command osrusbfx2.exe -p with options 1-9 to set and clear bar graph display, set and get 7-segment state, and read the toggle switch states. The following list shows the function options:

cmd
1. Light bar
2. Clear bar
3. Light entire bar graph
4. Clear entire bar graph
5. Get bar graph state
6. Get switch state
7. Get switch interrupt message
8. Get 7-segment state
9. Set 7-segment state
10. Reset the device
11. Re-enumerate the device

0. Exit

Selection:

Reset and re-enumerate the device

Use the command osrusbfx2.exe -p with option 10 and 11 to either reset the device or re-enumerate the device.

Read and write to bulk endpoints

The following commands send read and write requests to the device's bulk endpoint.

  • osrusbfx2.exe -r 64

    The preceding command reads 64 bytes to the bulk IN endpoint.

  • osrusbfx2.exe -w 64

    The preceding command writes 64 bytes to the bulk OUT endpoint.

  • osrusbfx2.exe -r 64 -w 64 -c 100 -v

    The preceding command first writes 64 bytes of data to bulk OUT endpoint (Pipe 1), then reads 64 bytes from bulk IN endpoint (Pipe 2), and then compares the read buffer with write buffer to see if they match. If the buffer contents match, it repeats this operation 100 times.

  • osrusbfx2.exe -a

    The preceding command reads and writes to the device asynchronously in an infinite loop.

The bulk endpoints are double buffered. Depending on the operational speed (full or high), the buffer size is either 64 bytes or 512 bytes, respectively. A request to read data doesn't complete if the buffers are empty. If the buffers are full, a request to write data does not complete until the buffers are emptied. When you are doing a synchronous read, make sure the endpoint buffer has data (for example, when you send 512 bytes write request to the device operating in full speed mode). Because the endpoints are double buffered, the total buffer capacity is 256 bytes. The first 256 bytes fills the buffer and the write request waits in the USB stack until the buffers are emptied. If you run another instance of the application to read 512 bytes of data, both write and read requests complete successfully.

Displaying descriptors

The following command displays all the descriptors and endpoint information.

osrusbfx2.exe -u

If the device is operating in high speed mode, you get the following information:

text
/* Detailed source-code truncated for AI context efficiency. */

If the device is operating in low speed mode, you will get the following information:

text
/* Detailed source-code truncated for AI context efficiency. */

Sample Contents for UMDF

The UMDF sample driver is developed as a series of steps, starting with a basic "Hello World" driver. Each step progressively adds functionality to the previous step.

usb\wdf_osrfx2_lab\umdf\step1

The most basic step. The source file contains a minimal amount of code to get the driver loaded in memory and respond to PnP and Power events. You can install, uninstall, disable, enable, suspend, and resume the system.

usb\wdf_osrfx2_lab\umdf\step2

  • The device registers a PnP device interface so that application can open a handle to the device.

  • The device object implements IPnpCallbackHardware interface and initializes USB I/O targets in IPnpCallbackHardware::OnPrepareHardware method.


Overview (`video/IndirectDisplay/README.md`)


topic: sample
page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk
    name: 'IddSample'
    statusNotificationTargets:
  • [email protected]

Indirect Display Driver Sample

This is a sample driver that shows how to create a Windows Indirect Display Driver using IddCx (Indirect Display Driver Class eXtension).

Background reading

Start at the Indirect Display Driver Model Overview on MSDN.

Customizing the sample

The sample driver code is very simplistic and does nothing more than enumerate a single monitor when its device enters the D0/started power state. Throughout the code, there are TODO blocks with important information on implementing functionality in a production driver.

Code structure

  • Direct3DDevice class
    • Contains logic for enumerating the correct render GPU from DXGI and creating a D3D device.
    • Manages the lifetime of a DXGI factory and a D3D device created for the render GPU the system is using to render frames for your indirect display device's swap-chain.
  • SwapChainProcessor class
    • Processes frames for a swap-chain assigned to the monitor object on a dedicated thread.
    • The sample code does nothing with the frames, but demonstrates a correct processing loop with error handling and notifying the OS of frame completion.
  • IndirectDeviceContext class
    • Processes device callbacks from IddCx.
    • Manages the creation and arrival of the sample monitor.
    • Handles swap-chain arrival and departure by creating a Direct3DDevice and handing it off to a SwapChainProcessor.

First steps

Consider the capabilities of your device. If the device supports multiple monitors being hotplugged and removed at runtime, you may want to abstract the monitors further from the IndirectDeviceContext class.

The INF file included in the sample needs updating for production use. One field, DeviceGroupId, controls how the UMDF driver gets pooled with other UMDF drivers in the same process. Since indirect display drivers tend to be more complicated than other driver classes, it's highly recommended that you pick a unique string for this field which will cause instances of your device driver to pool in a dedicated process. This will improve system reliability in case your driver encounters a problem since other drivers will not be affected.

Ensure the device information reported to IddCxAdapterInitAsync is accurate. This information determines how the device is reported to the OS and what static features (like support for gamma tables) the device will have available. If some information cannot be known immediately in the EvtDeviceD0Entry callback, IddCx allows the driver to call IddCxAdapterInitAsync at any point after D0 entry, before D0 exit.

Careful attention should be paid to the frame processing loop. This will directly impact the performance of the user's system, so making use of the Multimedia Class Scheduler Service and DXGI's support for GPU prioritization should be considered. Any significant work should be performed outside the main processing loop, such as by queuing work in a thread pool. See SwapChainProcessor::RunCore for more information.


Overview (`video/KMDOD/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Kernel mode display-only miniport driver (KMDOD) sample

The kernel mode display-only miniport driver (KMDOD) sample implements most of the device driver interfaces (DDIs) that a display-only miniport driver should provide to the Windows Display Driver Model (WDDM). The code is useful to understand how to write a miniport driver for a display-only device, or how to develop a full WDDM driver.

For more info on WDDM drivers, see Windows Display Driver Model (WDDM) Design Guide.

This code can also help you to understand the use and implementation of display-related DDIs. The INF file shows how to make a display miniport driver visible to other WDDM components.

The sample can be installed on top of a VESA-capable graphics adapter, or on top of a graphics device that supports access to frame buffer memory through the Unified Extensible Firmware Interface (UEFI).

The sample driver does not support the sleep power state. If it is placed in the sleep state, the driver will cause a system bugcheck to occur. There is no workaround available, by design.

If the current display driver is not a WDDM 1.2 compliant driver, the sample driver might fail to install, with error code 43 displayed. The KMDOD driver is actually installed, but it cannot be started. The workaround for this issue is to switch to the Microsoft Basic Display Adapter Driver before installing the KMDOD sample driver, or simply to reboot your system after installing the KMDOD sample.

Installation

In Microsoft Visual Studio, press F5 to build the sample and then deploy it to a target machine. For more info, see Deploying a Driver to a Test Computer.

In some cases you might need to install the driver manually, as follows.

  1. Add the following files to the directory given by ...\[x64]\C++\Package:

    • SampleDriver.cat

    • SampleDriver.inf

    • SampleDriver.sys

    • SampleDriver.cer

  2. Unless you've provided a production certificate, you should manually install the SampleDriver.cer digital certificate with the following command:

    Certutil.exe -addstore root SampleDriver.cer

  3. Then enable test signing by running the following BCDEdit command:

    Bcdedit.exe -set TESTSIGNING ON

    [!NOTE]
    After you change the TESTSIGNING boot configuration option, restart the computer for the change to take effect.

    For more info, see The TESTSIGNING Boot Configuration Option.

  4. Manually install the driver using Device Manager, which is available from Control Panel.

ACPI-based GPUs

To install the KMDOD sample driver on a GPU that is an Advanced Configuration and Power Interface (ACPI) device, add these lines to the [MS], [MS.NTamd64], and [MS.NTarm] sections of the Sampledisplay.inf file:

inf
Text
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0000
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0001
" Kernel mode display only sample driver " = KDODSamp_Inst, ACPI\CLS_0003&SUBCLS_0003

This new code provides generic identifiers for ACPI hardware.

You can optionally delete the original lines of code within these sections of the INF file.


Overview (`video/archive/README.md`)

Archived video driver samples

The samples in this folder are no longer maintained. They are archived here for reference purposes only. They are relevant for deprecated video driver technologies present in past versions of Windows.


Overview (`wmi/wmiacpi/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

WMI ACPI Sample

The WMIACPI sample contains ACPI BIOS and Microsoft Windows Management Instrumentation (WMI) sample code that enables instrumentation of the ACPI BIOS from within ACPI Source Language (ASL) code. ASL code can expose data blocks, methods, and events through WMI by leveraging the ACPI-WMI mapping driver (Wmiacpi.sys).

Operation

The WMIACPI sample contains files which allow an ACPI BIOS developer to add instrumentation from within ASL code. ASL code can expose data blocks, methods, and events through WMI by leveraging the Wmiacpi.sys driver. For more information about the mechanics of writing ASL to expose instrumentation, see the Windows Instrumentation: WMI and ACPI white paper included in this sample and available on the Windows Hardware Developer Central (WHDC) Web site.

The following table lists the files included in the sample and their function:

File Description
Device.asl ASL code that can be included in the ACPI bios that exposes a set of packages, strings, data, methods and events.
Acpimof.mof Managed object format (MOF) file that contains a description of the data blocks, methods, and events that are exposed. This description is required so that WMI can access the data blocks, methods, and events.
Acpimof.rcAcpimof.def Files that are required to build Acpimof.dll, which is a resource-only DLL.
Wmi-Acpi.htm The Windows Instrumentation: WMI and ACPI white paper.
acpimov.vcxproj Visual Studio project file for the sample.
acpimof.sln Visual Studio solution file for the sample.

Installation

To add the sample code to your ACPI bios and access through WMI:

  1. Include the contents of Device.asl to your ASL source and rebuild the DSDT. Update the operating system with the new DSDT through reflashing.

  2. Build Acpimof.dll in the WMIACPI directory. Acpimof.dll is a resource-only DLL that contains the compiled MOF in a form that WMI can import into its schema.

  3. Copy Acpimof.dll to %windir%\system32 and add a value named "MofImagePath" under the HKEY_LOCAL_MACHINE\CurrentControlSet\Services\WmiAcpi key. The contents of the value should be a path to the Acpimof.dll file.

  4. Restart your computer. When Plug and Play (PnP) recognizes the new device with a pnpid of pnp0c14, it will install Wmiacpi.sys automatically and make the MOF resource in Acpimof.dll available to the WMI schema.

Note that you do not need an INF file because Windows supplies an INF for the ACPI-WMI mapping driver device as part of the operating system.


Overview (`wmi/wmisamp/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Sample KMDF Driver Implementing a WMI Data Provider

WmiSamp WMI Provider is a sample KMDF driver that implements a WMI data provider.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

The sample demonstrates how to register the WMI providers and create provider instances for the Framework device object. It also illustrates how to handle the WMI queries sent to the device.

The Firefly, PCIDRV, and Toaster sample drivers also implement WMI data providers.

Installation

In Visual Studio, you can press F5 to build the sample and then deploy it to a target machine. For more information, see Deploying a Driver to a Test Computer.

[!NOTE]
You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

Testing

To test the WmiSamp driver, run the generated WmiSamp.vbs script file. This will cause WMI to query all data blocks and properties, and put the result in a .log file. For more sophisticated testing, the VBScript can be extended by hand. The WBEMTest tool (located in %windir%\system32\wbem\) can also be used.

WMI Mof Check Tool

WmiMofCk validates that the classes, properties, methods and events specified in a binary mof file (.bmf) are valid for use with WMI. It also generates useful output files needed to build and test the WMI data provider.

  • If the -h parameter is specified, a C language header file is created that defines the GUIDs, data structures, and method indices specified in the MOF file.

  • If the -t parameter is specified, a VBScript applet is created that will query all data blocks and properties specified in the .mof file. This can be useful for testing WMI data providers.

  • If the -x parameter is specified, a text file is created that contains the text representation of the binary .mof data. This can be included in the source of the driver if the driver supports reporting the binary .mof via a WMI query rather than a resource on the driver image file.

  • Usage: wmimofck -h<C Header output file> -x<Hexdump output file> -t<VBScript test output file> \

[!NOTE]
A byproduct of compiling the .mof file is a .vbs file. This is a VBScript file that is run from the command line on the target machine running the new device driver. It will cause WMI to query all data blocks and properties, and put the results into a .log file. This can be very useful for testing WMI support in your driver. For more sophisticated testing, the VBScript can be extended by hand.


Overview (`filesys/miniFilter/MetadataManager/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Metadata Manager File System Minifilter Driver

The Metadata Manager minifilter sample serves as an example if you want to use files for storing metadata that corresponds to your minifilters. The implementation of this sample depicts scenarios in which modifications to the file might have to be blocked or the minifilter might be required to close the file temporarily.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The Metadata Manager minifilter opens a file when it is first loaded. After that, the minifilter monitors open, close, file control, device control, and Plug and Play (PnP) operations to identify scenarios in which it should close its metadata file or block all writes to it. Applications such as chkdsk obtain implicit or explicit exclusive locks on the volume, and the metadata minifilter demonstrates how to maintain a metadata file without interfering with such lock acquisitions.

The minifilter identifies implicit locks when it sees a non-shared write open request on a volume object. In this scenario, the minifilter closes its metadata file and sets a trigger that corresponds to the volume in its instance object. Later, each close operation is examined to identify if the implicit lock on the volume is being released and, if so, a re-open of the minifilter's metadata file is triggered.

Similarly, the minifilter might close its metadata file if it sees an explicit FSCTL_DISMOUNT_VOLUME or FSCTL_LOCK_VOLUME file-system control operation. The file is later opened when the minifilter observes the FSCTL_UNLOCK_VOLUME control operation. The IRP_MN_QUERY_REMOVE_DEVICE PnP request can also cause the minifilter to close its metadata file, and the IRP_MN_SURPRISE_REMOVAL PnP request will cause it to detach.

The metadata minifilter also handles the case when a snapshot of its volume object is being taken. In this scenario, the minifilter acquires a shared exclusive lock on the metadata resource object while calling the callback that corresponds to the pre-device control operation for IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES. The lock is later released in the callback that corresponds to the post-device control operation for IOCTL_VOLSNAP_FLUSH_AND_HOLD_WRITES. The lock is acquired to prevent any modifications on the metadata file while the snapshot is being taken.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/NameChanger/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

NameChanger File System Minifilter Driver

The NameChanger minifilter grafts a directory from one part of a volume's namespace to another part using a mapping. The minifilter maintains this illusion by acting as a name provider, injecting entries into directory enumerations and forwarding directory change notifications.

Build the sample

You can build the sample in two ways: using Microsoft Visual Studio or the command line (MSBuild).

Building a driver using Visual Studio

You build a driver the same way you build any project or solution in Visual Studio. When you create a new driver project using a Windows driver template, the template defines a default (active) project configuration and a default (active) solution build configuration. When you create a project from existing driver sources or convert existing driver code that was built with previous versions of the WDK, the conversion process preserves the target version information (operating systems and platform).

The default Solution build configuration is Debug and Win32.

To select a configuration and build a driver

  1. Open the driver project or solution in Visual Studio (find filtername.sln or filtername.vcxproj).

  2. Right-click the solution in the Solutions Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Debug or Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Building a driver from the command line (MSBuild)

You can build a driver from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe) Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can now use the Visual Studio Command Prompt window for all build configurations.

To select a configuration and build a driver from the command line

  1. Open a Visual Studio Command Prompt window at the Start screen. From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called filtername.vcxproj, navigate to the project directory and enter the following MSBuild command: msbuild /t:clean /t:build .\filtername.vcxproj.

Installation

The minifilter samples come with an INF file that will install the minifilter. To install the minifilter, do the following:

  1. Make sure that filtername.sys and filtername.inf are in the same directory.

    [!NOTE]
    This installation will make the necessary registry updates to register the minifilter service and place filtername.sys in the %SystemRoot%\system32\drivers directory.

  2. In Windows Explorer, right-click filtername.inf, and click Install.

  3. To load the minifilter, run fltmc load filtername or net start filtername.

Design and operation

The NameChanger minifilter illustrates how to make one part of a volume's namespace appear as though it belongs to part of another namespace. It accomplishes this by altering the names of files that reside beneath a particular path (called the "real mapping") to appear as though they actually reside beneath a different path (called the "user mapping"). The .inf file supplied with the sample defines the real and user mappings in the [Strings] section. The three strings used for the mappings are:

String Description
UserMapping The location where files will appear to be in when the filter is attached.
UserMappingFinalComponentShort The "short" (DOS-compliant 8.3-format) name for the final component of the UserMapping path.
RealMapping The actual location where the files reside.

Before attaching the minifilter to a volume, you must set up the user and real paths. By default the .inf defines the mapping paths like in the following manner:

String Mapping
UserMapping "\X\Y"
UserMappingFinalComponentShort "Y"
RealMapping "\A\B"

To successfully attach the filter to a volume you must first create a couple of directories. For example, to attach the NameChanger minifilter to the F: volume, first create the RealMapping directory (the F:\A\B directory). Next, create the parent of the UserMapping path (the F:\X directory). The following directories are be created:

F:\A\B

F:\X

Once this is done the NameChanger filter should successfully attach to F:. It will change the directories you created to appear like the following:

F:\A

F:\X\Y

After the minifilter attaches, the "B" subdirectory of F:\A is no longer visible. Its contents now appear under the "Y" subdirectory of F:\X.

For more information on file system minifilter design, see File System Minifilter Drivers.


Overview (`filesys/miniFilter/avscan/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

AvScan File System Minifilter Driver

The AvScan minifilter is a transaction-aware file scanner. This is an example for developers who intend to write filters that examine data in files. Typically, anti-virus products fall into this category.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.


Overview (`filesys/miniFilter/cancelSafe/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

CancelSafe File System Minifilter Driver

The CancelSafe filter is a sample minifilter that you use if you want to use cancel-safe queues.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The CancelSafe minifilter initializes a cancel-safe queue when it is attached to a volume. When the minifilter is deployed, it monitors read operations that are passing through the I/O stack. If the read operation is being performed on a file named csqdemo.txt, it is queued onto the cancel-safe queue. Queued operations are completed after a brief pause through a separate worker thread that is running in system context.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/cdo/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

CDO File System Minifilter Driver

The CDO minifilter sample is an example if you intend to use a control device object (CDO) with your minifilters.

Although the filter manager infrastructure provides a message interface for communication between applications and minifilters, you might need explicit CDOs while the minifilters interface with legacy software. This sample shows how to create and use a CDO with minifilters.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

When the CDO minifilter is deployed, it creates a CDO object named "FileSystem\Filters\CdoSample" in the Microsoft Windows object namespace and enables applications to open it and perform certain operations on it.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/change/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Change File System Minifilter Driver

The Change minifilter is a transaction-aware filter that monitors file changes in real time.

This filter tracks if the files are 'dirty' by intercepting write I/O requests. This provides a way to track modifications to a file. Additionally, this filter handles the case where the transaction commits or rollbacks.

The primary tasks of the filter for tracking a transacted file are the following:

  1. In the post create callback, if a transacted file is open with attribute FILE_WRITE_DATA or FILE_APPEND_DATA, then enlist its file context into the transaction context.
  2. In the pre-operation callback, if the operation needs to be dirty, such as IRP_MJ_WRITE and the file is part of a transaction, update the transacted dirty record instead of the non-transacted dirty record.
  3. In the kernel transaction manager (KTM) notification callback, if the transaction is committed, then propagate the dirty information from the transacted dirty record to the non-transacted dirty record; if rollback, do not propagate.
  4. Properly remove the context structure in the TransactionContextCleanup routine.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.


Overview (`filesys/miniFilter/ctx/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Ctx File System Minifilter Drive

The Ctx minifilter is an example that demonstrates how to attach contexts to instances, files, streams, and stream handles in your minifilter.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The Ctx minifilter demonstrates how to attach and remove contexts from instances, files, steams, and stream handles. Ctx attaches a context whenever one of these objects is created. While attaching a context to a file, the sample also creates a stream and stream handle context. All contexts are ultimately deleted by the filter manager using the callback function that the Ctx minifilter provides.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/delete/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Delete File System Minifilter Driver

The Delete minifilter is an example that demonstrates how to detect deletions of files or streams. Deletions are reported as debug output.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The delete minifilter illustrates how to detect deletion of files and streams. It monitors IRP_MJ_CREATE requests for the FILE_DELETE_ON_CLOSE flag. Also, it detects IRP_MJ_SET_INFORMATION requests for setting FileDispositionInformation/FileDispositionInformationEx. The sample also illustrates how to handle racing deletes (in the form of multiple parallel IRP_MJ_SET_INFORMATION operations), and how to distinguish deletion of an entire file from deletion of just one stream of the file.

[!NOTE]
Because of the way in which the Windows operating system deletes files, it is not possible for the minifilter to detect in advance that a file or stream will be deleted. The minifilter can only detect operations that may cause a deletion, and then determine if the deletion took place after the operation completes.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/minispy/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Minispy File System Minifilter Driver

The Minispy sample is a tool to monitor and log any I/O and transaction activity that occurs in the system. Minispy is implemented as a minifilter.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

Minispy consists of both user-mode and kernel-mode components. The kernel-mode component registers callback functions that correspond to various I/O and transaction operations with the filter manager. These callback functions help Minispy record any I/O and transaction activity occurring in the system. When a user can request the recorded information, the recorded information is passed to the user-mode component, which can either output it on screen or log it to a file on disk.

To observe I/O activity on a device, you must explicitly attach Minispy to that device by using the Minispy user-mode component. Similarly, you can request Minispy to stop logging data for a particular device.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/nullFilter/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

NullFilter File System Minifilter Driver

The NullFilter minifilter is a sample minifilter that shows how to register a minifilter with the filter manager.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The NullFilter minifilter is a simple minifilter that registers itself with the filter manager for no callback operations.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/passThrough/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PassThrough File System Minifilter Driver

The PassThrough minifilter demonstrates how to specify callback functions for different types of I/O requests.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The PassThrough minifilter does not have any real functionality. For each type of I/O operation, the same pre and post callback functions are called. These callback functions simply forward the I/O request to the next filter on the stack.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/scanner/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Scanner File System Minifilter Driver

The Scanner minifilter is an example for developers who intend to write filters that examine data in files. Typically, antivirus products fall into this category.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The Scanner minifilter comprises both kernel-mode and user-mode components. The kernel-mode component recognizes appropriate moments for scanning a file's data and passes it to the user-mode component for further validation. The user-mode component creates a number of threads that await validation requests and corresponding data from the kernel-mode component. After scanning the data for occurrences of a "foul" string, the user-mode component sends an appropriate response to the kernel-mode component.

The kernel-mode component scans files with specific extensions only. The file is first scanned on a successful open. If the file was opened with write access, it is scanned again before a close. Scanning is also performed on data that is about to be written to a file. Writes will be rejected if any occurrences of a "foul" string are found in the data. If a "foul" string is detected during the closing of a file, a debug message is printed.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/simrep/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SimRep File System Minifilter Driver

SimRep is a sample filter that demonstrates how a file system filter can simulate file-system like reparse-point behavior to redirect a file open to an alternate path.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

Normally, if the file-system sees an open for a file with a reparse-point on it, the filesystem fills out the tag buffer and returns STATUS_REPARSE. Minifilters see the post-operation callback for this create. As the create travels up file system filter stack in post-create path, each minifilter has the opportunity to interpret the reparse point if they own the tag. If no file system filter claims the tag, IO Manager will attempt to interpret the tag based on tags known to and serviced by IO Manager. If the tag is unknown to IO manager then the create is failed with STATUS_IO_REPARSE_TAG_NOT_HANDLED. SimRep does not demonstrate how to handle the case where the file system hits a reparse-point on the file. Instead it "fakes" encountering a reparse point before the create reaches the filesystem. When SimRep detects a create for a path that it is redirecting, SimRep replaces the file name in the file object and completes the open with STATUS_REPARSE. This means we reparse without actually going to the file system.

SimRep decides to reparse according to a mapping. The mapping is made up of a "New Mapping Path" and an "Old Mapping Path". The old mapping path is the path which SimRep looks for on incoming opens. If the path specified for the create is down the Old Mapping Path, then SimRep will strip off the Old Mapping Path, and replace it with the New Mapping Path. By default, the Old Mapping Path is \x\y and the New Mapping Path is \a\b. So an open to \x\y\z will be replaced with an open to \a\b\z. These defaults are defined as registry keys at install time and are loaded on DriverEntry. See simrep.inf for details.

It is important to note that SimRep does not take long and short names into account. It literally does a string comparison to detect overlap with the mapping paths. SimRep also handles IRP_MJ_NETWORK_QUERY_OPEN. Because network query opens are FastIo operations, they cannot be reparsed. This means network query opens which need to be redirected must be failed with FLT_PREOP_DISALLOW_FASTIO. This will cause the Io Manager to reissue the open as a regular IRP based open. To prevent performance regression, SimRep only fails network query opens which need to be reparsed.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`filesys/miniFilter/swapBuffers/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SwapBuffer File System Minifilter Driver

The SwapBuffers minifilter demonstrates how to switch buffers between reads and writes of data. This technique is particularly useful for encryption filters because they have to encrypt data before writing it to disk and decrypt it after reading it from disk. Because encryption/decryption has to be done transparently, you cannot use system-supplied buffers directly, so intermediate buffers have to be introduced.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Design and Operation

The SwapBuffers minifilter introduces a new buffer before a read/write or directory control operations. The corresponding operation is then performed on the new buffer instead of the buffer that was originally provided. After the operation completes, the contents of the new buffer are copied back in to the original buffer.

For more information on file system minifilter design, start with the File System Minifilter Drivers section in the Installable File Systems Design Guide.


Overview (`general/SystemDma/wdm/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

System DMA

This sample demonstrates the usage of V3 System DMA. It shows how a driver could use a system DMA controller supported by Windows to write data to a hardware location using DMA.

The sample consists of a legacy device driver and a Win32 console mode test application. The test application opens a handle to the device exposed by the driver and makes a DeviceIoControl call to initiate the example system DMA. To understand how the V3 system DMA calls are invoked, see the SDmaWrite function in sdma.c.

[!NOTE]
This sample driver is not a PnP driver. This is a minimal driver meant to demonstrate an OS feature. Neither it nor its sample programs are intended for use in a production environment. Rather, they are intended for educational purposes and as a skeleton driver.

Run the sample

To test this driver, copy the test app, SystemDmaApp.exe, and the driver to the same directory, and run the application. The application will automatically load the driver if it's not already loaded and interact with the driver. When you exit the app, the driver will be stopped, unloaded and removed. Because no system DMA controller exists for Windows which uses the advertised DRQ, the sample driver will not proceed any further than failing to acquire a system DMA adapter.


Overview (`general/echo/kmdf/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

KMDF Echo Sample

The ECHO (KMDF) sample demonstrates how to use a sequential queue to serialize read and write requests presented to the driver.

It also shows how to synchronize execution of these events with other asynchronous events such as request cancellation and DPC.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Kernel-Mode Driver Framework

Code Tour

DriverEntry - Creates a framework driver object.

EvtDeviceAdd: Creates a device and registers self managed I/O callbacks so that it can start and stop the periodic timer when the device is entering and leaving D0 state. It registers a device interface so that application can find the device and send I/O. For managing I/O requests, the driver creates a default queue to receive only read & write requests. All other requests sent to the driver will be failed by the framework. Then the driver creates a periodic timer to simulate asynchronous event. The purpose of this timer would be to complete the currently pending request.

In the AutoSync version of the sample, the queue is created with WdfSynchronizationScopeQueue so that I/O callbacks including cancel routine are synchronized with a queue-level lock. Since timer is parented to queue and by default timer objects are created with AutomaticSerialization set to TRUE, timer DPC callbacks will be serialized with EvtIoRead, EvtIoWrite and Cancel Routine.

In the DriverSync version of the sample, the queue is created with WdfSynchronizationScopeNone, so that the framework does not provide any synchronization. The driver synchronizes the I/O callbacks, cancel routine and the timer DPC using a spinlock that it creates for this purpose.

EvtIoWrite: Allocates an internal buffer as big as the size of buffer in the write request and copies the data from the request buffer to internal buffer. The internal buffer address is saved in the queue context. If the driver receives another write request, it will free this one and allocate a new buffer to match the size of the incoming request. After copying the data, it will mark the request cancelable and return. The request will be eventually completed either by the timer or by the cancel routine if the application exits.

EvtIoRead: Retrieves request memory buffer and copies the data from the buffer created by the write handler to the request buffer, and marks the request cancelable. The request will be completed by the timer DPC callback.

Since the queue is a sequential queue, only one request is outstanding in the driver.

Testing

Usage:

  • Echoapp.exe --- Send single write and read request synchronously

  • Echoapp.exe -Async --- Send 100 reads and writes asynchronously

Exit the app anytime by pressing Ctrl-C

File Manifest

[!NOTE]
The AutoSync and DriverSync versions of the sample each have their own version of the following files:

Driver.h, Driver.c

  • DriverEntry and Events on the Driver Object.

Device.h, Device.c

  • Events on the Device Object.

Queue.h, Queue.c

  • Contains Events on the I/O Queue Objects.

Echo.inx

  • File that describes the installation of this driver. The build process converts this into an INF file.

Overview (`general/echo/umdf2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Echo Sample (UMDF Version 2)

The ECHO (UMDF version 2) sample demonstrates how to use a sequential queue to serialize read and write requests presented to the driver.

It also shows how to synchronize execution of these events with other asynchronous events such as request cancellation and DPC.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

User-Mode Driver Framework

Build the sample with Visual Studio

Open the driver solution in Visual Studio

In Microsoft Visual Studio, open the solution file (umdf2echo.sln). Choose Solution Explorer from the View menu. In Solution Explorer, you can see one solution that contains three projects. There is a driver project (Driver->AutoSync->echo), an application project (Exe->echoapp), and a package project named package (lower case).

Set the configuration and platform in Visual Studio

In Visual Studio, in Solution Explorer, right click Solution, and choose Configuration Manager. Set the configuration and the platform. Make sure that the configuration and platform are the same for both the driver project and the package project. Do not check the Deploy boxes.

Locate the built driver package

In File Explorer, navigate to the folder that contains your built driver package. The location of this folder varies depending on what you set for configuration and platform.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy a driver sample automatically or manually.

Automatic deployment (root enumerated)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Hardware ID Driver Update, and enter root\ECHO for the hardware ID. Click OK.

  3. On the Build menu, choose Build Solution.

Manual deployment (root enumerated)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\umdf2echoPkg).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

    devcon install echoum.inf root\\ECHO

View the root enumerated driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Sample WDF ECHO Driver (for example, this might be under the Sample Device node).

In Device Manager, on the View menu, choose Devices by connection. Locate Sample WDF ECHO Driver as a child of the root node of the device tree.

Build the sample using MSBuild

As an alternative to building the driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, umdf2echo.sln. Use the MSBuild command to build the solution. Here is an example:

msbuild /p:configuration="Release" /p:platform="Win32" umdf2echo.sln

For more information about using MSBuild to build a driver package, see MSBuild primer for WDK developers.


Overview (`general/ioctl/kmdf/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Non-PnP Driver Sample

This sample is primarily meant to demonstrate how to write a NON-PNP driver using the Kernel Mode Driver Framework.

It also illustrates several other important framework interfaces. Following table gives a typical usage scenario and summarizes all the features used in this sample.

This sample would be useful for writing a driver that does not interact with any hardware. Typically, such drivers are written to provide some kernel-level services to a user application. These drivers are dynamically loaded by the application when it is run and unloaded when it exits.

(Examples: FileMon, Regmon, DeviceTree are examples of tools that use this type of driver.)

  • How to Write a NON PNP driver

  • How to register EvtPreProcessCallback to handle requests in the context of the calling thread

  • Show how to probe and lock buffers in the preprocess callback for METHOD_NEITHER IOCTL requests

  • Also show how to handle other 3 types of IOCTLs (METHOD_BUFFERED, METHOD_IN_DIRECT & METHOD_OUT_DIRECT)

  • How to open a file in Kernel-mode and Read & Write to it

  • Finally show event tracing and dumping variable length data in the tracelog using HEXDUMP format.

The sample is accompanied by a simple multithreaded Win32 console application to test the driver.

[!CAUTION]
This is a minimal driver meant to demonstrate an OS feature. Neither it nor its sample programs are intended for use in a production environment. Rather, they are intended for educational purposes and as a skeleton driver.

Build the sample

For information on how to build a driver solution using Microsoft Visual Studio, see Building a Driver with Visual Studio and the WDK.

If the build succeeds, you will find the driver, nonpnp.sys, and the test application, nonpnpapp.exe, in the binary output directory specified for the build environment.

To test this driver, copy the nonpnp.inf into the same folder as the nonpnpapp.exe and the wdfcoinstaller<version>.dll .

[!NOTE]
You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

Next, run nonpnpapp.exe, a simple Win32 multithreaded console mode application. The driver will be automatically loaded and started. When you exit the app, the driver will be stopped and removed.

Usage: nonpnpapp.exe (-l) (-v version)

[!NOTE]
This application first tries to open the device (\Device\FileIo). If the device doesn't exist, it takes that as a hint that the driver is not loaded and tries to load the driver using service control manager API. If the service is loaded successfully, it tries to open the device again. If successful, it makes all four different types of DeviceControl calls to the driver. After that it makes a WriteFile call with an arbitrary size buffer. The driver, in response, writes that buffer to a file opened in the Create request. The name of the file was provided by the application as part of the device name and the directory path is hardcoded to %WINDIR%\temp. When the WriteFile returns, the application makes a ReadFile call to read the file through the driver, and then compares the data returned by the driver with the one it originally wrote. If you specify -l option in command line, the application does this Write and Read operation in an infinite loop. The -v command line option is used to specify the version of the KMDF coinstaller (wdfcoinstaller<version>.dll) to load. If none is specified then it loads the coinstaller for v1.0 (wdfcoinstaller01000.dll)

WDF SECTION

Nonpnp drivers typically don't need an INF file to install. Since we are using framework interfaces, we have to use the Kmdf coinstaller to install the framework binaries on the target machine. The Kmdf coinstaller needs a WDF specific section in the INF to get the driver service name and the version of the Kmdf library the driver is bound to. The syntax and description of the section is given below. Any non inf based driver using Kmdf library will need to have a dummy inf file with the wdf section in it. The format of the Wdf section is given below:

[Version]

Signature="$WINDOWS NT$"

[<driver name>.NT.Wdf]

KmdfService = <your driver service name here>, <driver service install subsection>

[<driver service install subsection>]

KmdfLibraryVersion = <version bound to here, in Major.minor format>

For example, for V1.0 KmdfLibraryVersion is "1.0"


Overview (`general/ioctl/wdm/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

IOCTL

This sample demonstrates the usage of four different types of IOCTLs (METHOD_IN_DIRECT, METHOD_OUT_DIRECT, METHOD_NEITHER, and METHOD_BUFFERED).

The sample shows how the user input and output buffers specified in the DeviceIoControl function call are handled, in each case, by the I/O subsystem and the driver.

The sample consists of a legacy device driver and a Win32 console test application. The test application opens a handle to the device exposed by the driver and makes all four different DeviceIoControl calls, one after another. To understand how the IRP fields are set the I/O manager, you should run the checked build version of the driver and look at the debug output.

[!CAUTION]
This sample driver is not a Plug and Play driver. This is a minimal driver meant to demonstrate a feature of the operating system. Neither this driver nor its sample programs are intended for use in a production environment. Instead, they are intended for educational purposes and as a skeleton driver.

Run the sample

To test this driver, copy the test app, Ioctlapp.exe, and the driver to the same directory, and run the application. The application will automatically load the driver, if it's not already loaded, and interact with the driver. When you exit the application, the driver will be stopped, unloaded and removed.


Overview (`general/perfcounters/kcs/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Kernel Counter Sample (Kcs)

The Kcs sample driver demonstrates the use of the kernel-mode performance library. The sample driver does not control any hardware; it simply provides example code that demonstrates how to provide counter data from a kernel-mode driver. The code contains comments to explain what each function does. The sample creates geometric wave and trigonometric wave counter sets.

This module contains sample code to demonstrate how to provide counter data from a kernel driver.

This sample driver should not be used in a production environment.

The Microsoft Windows operating system allows system components and third parties to expose performance metrics in a standard way by using Performance Counters. Kernel-mode PCW providers are installed in the system as Performance Counter Library (PERFLIB) (Version 2 providers), which allows their counters to be browsed, and allows for data collection and instance enumeration. Consumers can query KM PCW providers by using PDH and PERFLIB Version 1 without any modification to the consumer code.


Overview (`general/registry/regfltr/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

RegFltr Sample Driver

The RegFltr sample shows how to write a registry filter driver.In addition to providing some basic examples, this sample demonstrates the following:

  • How to handle transactional registry operations.

  • How and when to capture input parameters.

  • Issues and workarounds for version 1.0 of registry filtering.

  • Changes in version 1.1 of registry filtering.

  • How to use version 1 of the REG_CREATE_KEY_INFORMATION and REG_OPEN_KEY_INFORMATION data structures.

The RegFltr sample contains several examples of user-mode and kernel-mode registry-filtering operations. Each example comes with its own corresponding registry callback routine, and performs the following steps:

  1. Does some setup work.

  2. Registers the callback routine.

  3. Performs one or more registry operations.

  4. Unregisters the callback routine.

  5. Verifies that the sample completed correctly.

The sample driver is a minimal driver that is not intended to be used on production systems. To keep the samples simple, the registry callback routines provided do not check for all possible situations and error conditions. This sample is designed to demonstrate typical scenarios and no other registry filtering driver is expected to be active.


Overview (`general/toaster/toastDrv/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Toaster Sample Driver

The Toaster collection is an iterative series of samples that demonstrate fundamental aspects of Windows driver development for both Kernel-Mode Driver Framework (KMDF).

All the samples work with a hypothetical toaster bus, over which toaster devices can be connected to a PC.

The Toaster sample collection comprises driver projects (.vcxproj files) that are contained in the toaster.sln solution file (in general\toaster\toastdrv).

Windows Driver Frameworks

For detailed descriptions and code walkthroughs of each project, see Sample Toaster Driver Programming Tour. To learn how to build and run the samples, read on.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy components of the Toaster Sample automatically or manually. Here, we install the wdfsimple driver on the target computer.

Specifying which projects to deploy

Before doing this, you should back up your package.vcxproj file, located in your sample directory, for example C:\Toaster\C++\Package.

  1. In the Properties for the package project, navigate to Common Properties > References.

  2. Remove all references except WdfSimple. (Use the Remove Reference button at the bottom.)

Automatic deployment (root enumerated)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

  1. On the host computer, in Visual Studio, in Solution Explorer, right click the package project (within the package folder), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, use the drop down to select the name of a target computer that you provisioned previously. Select Hardware ID Driver Update, and enter {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster for the hardware ID. (You can find this value in the WdfSimple.inx file.) Click Apply and OK.

  3. Because this solution contains many projects, you may find it easier to remove some of them before you build and deploy a driver package. To do so, right click package (lower case), and choose Properties. Navigate to Common Properties->References and click Remove Reference to remove projects you don't want. (You can add them back later by using Add New Reference.) Click OK.

  4. On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).

  5. If you removed references and deployment does not succeed, try deleting the contents of the c:\DriverTest\Drivers folder on the target machine, and then retry deployment.

Manual deployment (root enumerated)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WdfSimplePackage).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

    devcon install WdfSimple.inf {b85b7c50-6a01-11d2-b841-00c04fad5171}\\MsToaster

View the root enumerated driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Microsoft WDF Simple Toaster (No Class Installer).

In Device Manager, on the View menu, choose Devices by connection. Locate Microsoft WDF Simple Toaster (No Class Installer) as a child of the root node of the device tree.

Build the sample using MSBuild

As an alternative to building the Toaster sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, Toaster.sln. Use the MSBuild command to build the solution. Here are some examples:

msbuild /p:configuration="Debug" /p:platform="x64" Toaster.sln

msbuild /p:configuration="Release" /p:platform="Win32" Toaster.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.


Overview (`general/toaster/toastpkg/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Toaster Package Sample Driver

The Toaster collection is an iterative series of samples that demonstrate fundamental aspects of Windows driver development for both Kernel-Mode Driver Framework (KMDF) and User-Mode Driver Framework (UMDF) version 1.

All the samples work with a hypothetical toaster bus, over which toaster devices can be connected to a PC.

The Toaster sample collection comprises driver projects (.vcxproj files) that are contained in the toaster.sln solution file (in general\toaster\toastdrv).

Windows Driver Frameworks

For detailed descriptions and code walkthroughs of each project, see Sample Toaster Driver Programming Tour. To learn how to build and run the samples, read on.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy components of the Toaster Sample automatically or manually. Here, we install the wdfsimple driver on the target computer.

Specifying which projects to deploy

Before doing this, you should back up your package.vcxproj file, located in your sample directory, for example C:\Toaster\C++\Package.

  1. In the Properties for the package project, navigate to Common Properties > References.

  2. Remove all references except WdfSimple. (Use the Remove Reference button at the bottom.)

Automatic deployment (root enumerated)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

  1. On the host computer, in Visual Studio, in Solution Explorer, right click the package project (within the package folder), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, use the drop down to select the name of a target computer that you provisioned previously. Select Hardware ID Driver Update, and enter {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster for the hardware ID. (You can find this value in the WdfSimple.inx file.) Click Apply and OK.

  3. Because this solution contains many projects, you may find it easier to remove some of them before you build and deploy a driver package. To do so, right click package (lower case), and choose Properties. Navigate to Common Properties->References and click Remove Reference to remove projects you don't want. (You can add them back later by using Add New Reference.) Click OK.

  4. On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).

  5. If you removed references and deployment does not succeed, try deleting the contents of the c:\DriverTest\Drivers folder on the target machine, and then retry deployment.

Manual deployment (root enumerated)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WdfSimplePackage).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

    devcon install WdfSimple.inf {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

View the root enumerated driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Microsoft WDF Simple Toaster (No Class Installer).

In Device Manager, on the View menu, choose Devices by connection. Locate Microsoft WDF Simple Toaster (No Class Installer) as a child of the root node of the device tree.

Build the sample using MSBuild

As an alternative to building the Toaster sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, Toaster.sln. Use the MSBuild command to build the solution. Here are some examples:

msbuild /p:configuration="Debug" /p:platform="x64" Toaster.sln

msbuild /p:configuration="Release" /p:platform="Win32" Toaster.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.

UMDF Toaster File Manifest

WUDFToaster.idl

Component Interface file

WUDFToaster.cpp

DLL Support code - provides the DLL's entry point as well as the DllGetClassObject export.

WUDFToaster.def

This file lists the functions that the driver DLL exports.

stdafx.h

This is the main header file for the sample driver.

driver.cpp and driver.h (WUDFToaster)

Definition and implementation of the IDriverEntry callbacks in CDriver class.

device.cpp and device.h (WUDFToaster)

Definition and implementation of various interfaces and their callbacks in CDevice class. Add your PnP and Power interfaces specific for your hardware.

queue.cpp and queue.h

Definition and implementation of the base queue callback class (CQueue). IQueueCallbackDevicekIoControl, IQueueCallbackRead and IQueueCallBackWrite callbacks are implemented to handle I/O control requests.

WUDFToaster.rc

This file defines resource information for the WUDF Toaster sample driver.

WUDFToaster.inf

Sample INF for installing the sample WUDF Toaster driver under the Toaster class of devices.

WUDFtoaster.ctl, internal.h

This file lists the WPP trace control GUID(s) for the sample driver. This file can be used with the tracelog command's -guid flag to enable the collection of these trace events within an established trace session.
These GUIDs must remain in sync with the trace control guids defined in internal.h.

Toastmon File Manifest

comsup.cpp and comsup.h

Boilerplate COM Support code - specifically base classes which provide implementations for the standard COM interfaces IUnknown and IClassFactory which are used throughout the sample.
The implementation of IClassFactory is designed to create instances of the CMyDriver class. If you should change the name of your base driver class, you would also need to modify this file.

dllsup.cpp

Boilerplate DLL Support code - provides the DLL's entry point as well as the single required export (DllGetClassObject).
These depend on comsup.cpp to perform the necessary class creation.

exports.def

This file lists the functions that the driver DLL exports.

internal.h

This is the main header file for the ToastMon driver

driver.cpp and driver.h (Toastmon)

Definition and implementation of the driver callback class for the ToastMon sample.

device.cpp and device.h (Toastmon)

Definition and implementation of the device callback class for the ToastMon sample. This is mostly boilerplate, but also registers for RemoteInterface Arrival notifications. When a RemoteInterface arrival callback occurs, it calls CreateRemoteInterface and creates a CMyRemoteTarget callback object to handle I/O on that RemoteInterface.

RemoteTarget.cpp and RemoteTarget.h

Definition and implementation of the remote target callback class for the ToastMon sample.

list.h

Doubly-linked-list code

ToastMon.rc

This file defines resource information for the ToastMon sample driver.

UMDFToastMon.inf

Sample INF for installing the Skeleton driver to control a root enumerated device with a hardware ID of UMDFSamples\ToastMon


Overview (`general/toaster/umdf2/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Toaster Sample (UMDF Version 2)

The Toaster (UMDF version 2) sample is an iterative series of samples that demonstrate fundamental aspects of Windows driver development.

The Toaster sample collection is comprised of driver projects (.vcxproj files) that are contained in the umdf2toaster.sln solution file.

Windows Driver Frameworks

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy a driver sample automatically or manually.

Automatic deployment (root enumerated)

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Hardware ID Driver Update, and enter root\toaster for the hardware ID. Click OK.

  3. Because this solution contains many projects, you may find it easier to remove some of them before you build and deploy a driver package. To do so, right click package (lower case), and choose Properties. Navigate to Common Properties->References and click Remove Reference to remove projects you don't want. (You can add them back later by using Add New Reference.) Click OK.

  4. On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).

  5. If you removed references and deployment does not succeed, try deleting the contents of the c:\DriverTest\Drivers folder on the target machine, and then retry deployment.

Manual deployment (root enumerated)

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\Umdf2toaster).

  2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter a command such as:

    devcon install wdfsimpleum.inf root\\toaster

View the root enumerated driver in Device Manager

On the target computer, in a Command Prompt window, enter devmgmt.msc to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate Sample WDF Toaster Service + Filter (for example, this might be under the Toaster node).

In Device Manager, on the View menu, choose Devices by connection. Locate Sample WDF Toaster Service + Filter as a child of the root node of the device tree.

Build the sample using MSBuild

As an alternative to building the driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, Umdf2toaster.sln. Use the MSBuild command to build the solution. Here is an example:

msbuild /p:configuration="Release" /p:platform="Win32" Umdf2toaster.sln

For more information about using MSBuild to build a driver package, see Building a Driver with Visual Studio and the WDK.


Overview (`general/tracing/SystemTraceControl/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SystemTraceProvider

This sample application demonstrates how to use event tracing control APIs to collect events from the system trace provider.

The sample code provided shows how to start an Event Tracing for Windows trace session and how to enable system events with stacks. When you build and run the application, it collects the trace data for 30 seconds and then stops. The sample application writes the results to a file, Systemtrace.etl. For more information, see Tools for Software Tracing.

You can process the Systemtrace.etl file using Tracerpt.exe, a command-line trace tool included in Windows that formats trace events. It also analyzes the events and generates summary reports. For more information about how to use this tool, see Tracerpt.

You can also process the file using the Windows Performance Toolkit (WPT), which is available in the SDK.


Overview (`general/tracing/evntdrv/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Eventdrv

Eventdrv is a sample kernel-mode trace provider and driver. The driver does not control any hardware; it simply generates trace events. It is designed to demonstrate the use of the Event Tracing for Windows (ETW) API in a driver.

Evntdrv registers as a provider by calling the EtwRegister API. If the registration is successful, it logs a StartEvent with the device's name, the length of the name, and the status code. Then, when the sample receives a DeviceIOControl call, it logs a SampleEventA event. Finally, when the driver gets unloaded, it logs an UnloadEvent event with a pointer to the device object

[!NOTE]
The Windows Pre-Processor (WPP) Tracing tools such as TraceView.exe cannot be used to start, stop, or view traces.

Run the sample

  1. Install the manifest (Evntdrv.xml), which is located in the Evntdrv\Eventdrv folder. Open a Visual Studio Command window (Run as administrator) and use the following command:

    wevtutil im evntdrv.xml

    Installing the manifest creates registry keys that enable tools to find the resource and message files that contain event provider information. For further details, see wevtutil.

    [!NOTE]
    Using a Visual Studio Command windows sets up the environment variables you need to run the tracing tools for this sample.

  2. Make a folder in the system directory called ETWDriverSample (for example, C:\ETWDriverSample).

    Copy Eventdrv.sys and Evntctrl.exe to the ETWDriverSample folder.

    The ETWDriverSample directory must be created because the path to the resource file that is specified in the evntdrv.xml manifest points to the %SystemRoot%\ETWDriverSample folder. If this folder is not created and the Eventdrv.sys binary is not copied, decoding tools cannot find the event information to decode the trace file.

  3. Use Tracelog to start a trace session that is called "TestEventdrv." The following command starts the trace session and creates a trace log file, Eventdrv.etl, in the local directory.

    tracelog -start TestEventdrv -guid #b5a0bda9-50fe-4d0e-a83d-bae3f58c94d6 -f Eventdrv.etl

  4. To generate trace messages, run Evntctrl.exe. Each time you type a character other than Q or q, Evntctrl sends an IOCTL to the driver that signals it to generate trace messages. To stop Evntctrl, type Q or q.

  5. To stop the trace session, run the following command:

    tracelog -stop TestEventdrv

  6. To display the traces collected in the Tracedrv.etl file, run the following command:

    tracerpt Eventdrv.etl

    This command creates two files: Summary.txt and Dumpfile.xml. Dumpfile.xml will contain the event information in an XML format.

  7. To uninstall the manifest, run the following command:

    wevtutil um evntdrv.xml

Notes

If you are building the Eventdrv sample to test on a 64-bit version of Windows, you need to sign the driver. All 64-bit versions of Windows require driver code to have a digital signature for the driver to load. See Signing a Driver and Signing a Driver During Development and Testing. You might also need to configure the test computer so that it can load test-signed kernel mode code, see The TESTSIGNING Boot Configuration Option and BCDEdit /set.


Overview (`general/tracing/tracedriver/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Tracedrv

Tracedrv is a sample driver instrumented for software tracing. The driver does not control any hardware; it simply generates trace messages. It is designed to show how to use WPP software tracing macros in a driver.

Tracedrv initializes tracing (by using WPP_INIT_TRACING) and, when it receives a DeviceIOControl call, it starts a thread that logs 100 trace messages. The WPP software tracing directives, calls, and macros in the code are accompanied by comments that explain their purpose

While examining Tracedrv, read the WPP Software Tracing in the Windows Driver Kit (WDK). This section includes a reference section that describes the directives, macros, and calls required for WPP software tracing.

Run the sample

To test the Tracedrv event tracing provider, use the following procedure.

  1. Copy the Tracectl.exe file that was created when you built the Tracedrv solution from the Tracectl directory (for example, \Documents\Visual Studio 2015\Projects\tracedrv\tracectl\platform) to the Tracedrv directory (for example, \Documents\Visual Studio 2015\Projects\tracedrv\tracedrv\platform).

  2. Use Tracepdb to create a trace message format (TMF) file and a trace message control (TMC) file from the Tracedrv.pdb file. Tracepdb is located in the C:\Program Files (x86)\Windows Kits\10\bin\platform directory. The PDB file that is used in this command is created when you the build the solution. Open a Visual Studio Command prompt window and navigate to the target build platform and configuration directory. Type the following command:

tracepdb -f tracedrv.pdb

  1. In the same Tracedrv target build directory, create a control GUID file for Tracedrv by opening a text file, adding the following content, and saving the file as Tracedrv.ctl.
txt
d58c126f-b309-11d1-969e-0000f875a5bc
  1. Use Tracelog to start a trace session that is called TestTracedrv. Tracelog is located in the C:\Program Files (x86)\Windows Kits\10\bin\platform directory. The Tracedrv.ctl file that is used in this command was created in the previous step. The following command starts a trace session and creates a trace log file, tracedrv.etl, in the local directory.

tracelog -start TestTracedrv -guid tracedrv.ctl -f tracedrv.etl -flag 1

[!NOTE]
Without the -flag parameter, Tracedrv will not generate any trace messages.

  1. To generate trace messages, run Tracectl.exe. This executable file is built when you build the solution. Each time you type a character, other than Q or q, Tracectl sends an IOCTL to the driver that signals it to generate trace messages. To stop Tracectl, type Q or q.

  2. To stop the trace session, use the following Tracelog command.

tracelog -stop TestTracedrv

  1. To display the trace messages in the Tracedrv.etl file, use Tracefmt.exe. Tracefmt.exe is located in the C:\Program Files (x86)\Windows Kits\10\bin\platform. The TMF file used in this command was created by Tracepdb.exe in step 2. The -p option specifies the directory of the TMF file. In this case, the TMF file is in the current directory. Type the following command:

tracefmt tracedrv.etl -p . -o Tracedrv.out

The resulting Tracedrv.out file is a human-readable text file of the Tracedrv trace messages. To interpret the trace messages, in the Tracedrv.c file, search for the DoTraceMessage macros.

Notes

This sample driver should not be used in a production environment.

Also, because it is not a Plug and Play driver, Tracedrv does not demonstrate tracing in a Plug and Play environment.

Tracedrv demonstrates the basic elements required for software tracing. It does not demonstrate more advanced tracing techniques, such as writing customized tracing calls (variations of DoTraceMessage), or the use of WMI calls for software tracing.

If you are building the Tracedrv sample to test on a 64-bit version of Windows, you need to sign the driver. All 64-bit versions of Windows require driver code to have a digital signature for the driver to load. See Signing a Driver and Signing a Driver During Development and Testing. You might also need to configure the test computer so that it can load test-signed kernel mode code, see The TESTSIGNING Boot Configuration Option and BCDEdit /set.


Overview (`network/config/bindview/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Bindview Network Configuration Utility

The Bindview sample demonstrates how to use INetCfg APIs to enumerate, install, uninstall, bind and unbind network components.

For more information on the INetCfg interface, see Network Configuration Interfaces.


Overview (`network/modem/fakemodem/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Fakemodem Driver

The Fakemodem sample demonstrates a simple controller-less modem driver. This driver supports sending and receiving AT commands using the ReadFile/WriteFile calls or via a TAPI interface using an application such as HyperTerminal.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.


Overview (`network/ndis/extension/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Hyper-V Extensible Switch extension filter driver

This sample contains a base library used to implement a Hyper-V Extensible Switch extension filter driver. This sample also contains two different extension filter drivers that were developed by using the library.

Hyper-V Extensible Switch extension filter drivers use the NDIS filter model. Every Hyper-V Extensible Switch has a corresponding Extension Protocol and Miniport instance. NDIS OIDs are leveraged to inform filter drivers on the driver stack about switch/port/NIC information. All packets originating from a switch port (External NIC, Synthetic NIC, Emulated NIC and Internal NIC) are first issued as a send from the Extension Protocol, which populates the packet with source information. This corresponds to the ingress data flow. Source based filtering, packet modification, packet queuing, and destination definition can occur at this stage. If the packets arrive at the Extension Miniport, they pass through the built in filtering/forwarding logic. If the packets pass filtering and must be delivered to any destination ports, they are issued as an indication (receive) from the Extension Miniport, which populate the packet with the source and destination information. This corresponds to the egress data flow. Destination based filtering can occur at this stage. If the packets arrive at the Extension Protocol, they are delivered to the defined destinations that were not marked as excluded by filtering logic. The packets then are completed back in the reverse order, as a receive completion first and then a send completion. Extension filter drivers are free to generate new packets on the ingress data path by issuing a send from their filter.

The base library provided, SxBase.lib, implements the necessary NDIS functionality common to all types of extension filter drivers. It is not necessary to make any changes to this base library. To implement your own extension filter driver, you only need to define all global variables and implement all functions that are found in SxApi.h.

MsPassthroughExt is a basic filtering extension filter driver that is implemented by using SxBase.lib. This demonstrates the bare minimum that must be implemented to use SxBase.lib. Installing and enabling MsPassthroughExt on the Hyper-V Extensible Switch does not affect switch behavior.

MsForwardExt is a basic forwarding extension filter driver that is implemented by using SxBase.lib. MsForwardExt uses basic MAC forwarding and custom switch policy to allow sends from given MAC addresses. This forwarding sample implements Hybrid Forwarding, which means that the destination table is not populated by this sample if the packet is flagged as a Hyper-V Network Virtualization (HNV) packet. HNV flagged packets' destination tables are computed by the vSwitch HNV policies instead. If this extension filter driver is unconfigured, it will block sends from all VMs, but will maintain connectivity to the host. Each switch policy, which is defined in MsForwardExtPolicy.mof, is a MAC address. Applying a switch policy to MsForwardExt allows packets to be sent from the MAC address that is defined in the policy.

Installation

Use the install.cmd script provided with each extension filter driver. The install.cmd uses netcfg to install the extension and mofcomp to register any required mof files. The PowerShell cmdlet Enable-VmSwitchExtension can then be used to enable the extension filter driver on a Hyper-V Extensible Switch.

For more information on Hyper-V Extensible Switch extensions, see Hyper-V Extensible Switch.


Overview (`network/ndis/filter/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

NDIS 6.0 Filter Driver

The Ndislwf sample is a do-nothing pass-through NDIS 6 filter driver that demonstrates the basic principles underlying an NDIS 6.0 Filter driver. The sample replaces the NDIS 5 Sample Intermediate Driver (Passthrough driver).

Although this sample filter driver is installed as a modifying filter driver, it doesn't modify any packets; it only repackages and sends down all OID requests. You can modify this filter driver to change packets before passing them along. Or you can use the filter to originate new packets to send or receive. For example, the filter could encrypt/compress outgoing and decrypt/decompress incoming data.

For more information, see NDIS Filter Drivers in the network devices design guide.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. On the Build menu, choose Build Solution.

  4. On the target computer, open Control Panel. Click Network and Internet and then open Network and Sharing Center.

  5. Under View your active networks, click the connection listed under Connections: and click Properties. If you have previously installed this sample, highlight it in the list.

  6. Click Install, then Service, then Add.

    [!NOTE]
    You may see multiple instances of the NDIS Sample LightWeight Filter service. If so, highlight the newest one.

  7. Click Have Disk.

  8. In the Install from Disk dialog, browse to the DriverTest\Drivers directory. Highlight the netlwf.inf file and click Open, then click OK. This should show NDIS Sample LightWeight Filter in a list of Network Services. Highlight NDIS Sample LightWeight Filter and click OK. Click OK. Click Close. Click Close. This installs the Ndislwf filter driver service.

[!NOTE]
If you've installed the Ndislwf sample on the target computer before, you can use the PnPUtil tool to delete the older versions from the driver store.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

Ndislwf is installed as a service (called NDIS Sample LightWeight Filter in the supplied INF). To install it, do the following:

  1. Prepare an installation directory on the target computer and copy these files from the host computer into the directory:

    • netlwf.cat

    • netlwf.inf

    • ndislwf.sys

  2. Open Control Panel.

  3. Click Network and Internet and then open Network and Sharing Center. Under View your active networks, click the connection listed under Connections: and click Properties.

  4. If you have previously installed this sample, highlight it in the list.

  5. Click Install, then Service, then Add, then Have Disk.

  6. Browse to the installation directory. Highlight the netlwf.inf file and click Open, then click OK. This should show NDIS Sample LightWeight Filter in a list of Network Services. Highlight this and click OK. Click OK. This installs the Ndislwf filter driver.

[!NOTE]
If you've installed the Ndislwf sample on the target computer before, you can use the PnPUtil tool to delete the older versions from the driver store.

Viewing sample output in the debugger

Setting up kernel-mode debugging automatically

If you chose to deploy your driver automatically, then kernel debugging is already set up for you.

On the host computer, in Visual Studio, in the Debug menu, choose Attach to Process. For Transport, choose Windows Kernel Mode Debugger. For Qualifier, choose the name of your target computer. Click Attach.

[!NOTE]
If you see a dialog box that asks you to allow the debugger to communicate through the firewall, click the boxes for all types of networks. Click Allow Access.

For more information, see Setting Up Kernel-Mode Debugging in Visual Studio.

Setting up kernel-mode debugging manually

If you chose to deploy your driver manually, then you need to set up kernel debugging manually. For instructions, see Setting Up Kernel-Mode Debugging Manually.

The kernel-mode debuggers (WinDbg.exe and Kd.exe) are included in the WDK.

On the host computer, locate and open a kernel-mode debugger (example: c:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe). Establish a kernel-mode debugging session between the host and target computers. The details of how to do this depend on the type of debug cable you are using. For information about how to start a debugging session, see Setting Up Kernel-Mode Debugging Manually.

Setting kd\_default\_mask

This sample calls DbgPrint to send trace messages to the kernel-mode debugger. To see the trace messages, you must set the value of the kd_default_mask variable.

On the host computer, break in to the debugger if you are not already broken in. (In the Debug menu, choose Break or Break All, or press CTRL-Break). At the debugger command line, enter this command: ed kd_default_mask 0x8.

To resume execution of the target computer, enter the g command in the debugger. (In the Debug menu, choose Continue.)

Viewing trace messages

On the host computer, in the kernel-mode debugger, verify that you see trace messages similar to these:

txt
NDISLWF: ===>DriverEntry...
NDISLWF: ===>FilterRegisterOptions
NDISLWF: <===FilterRegisterOptions
NDISLWF: ==>FilterRegisterDevice
NDISLWF: <==FilterRegisterDevice: 0
NDISLWF: <===DriverEntry, Status =        0
NDISLWF: ===>FilterAttach: NdisFilterHandle FFFFE00000F73650
NDISLWF: <===FilterAttach:    Status 0

What the Ndislwf sample driver does

  1. During DriverEntry, the ndislwf driver registers as an NDIS 6 filter driver.

  2. Later on, NDIS calls Ndislwf's FilterAttach handler, for each underlying NDIS adapter on which it is configured to attach.

  3. In the context of FilterAttach Handler, the filter driver calls NdisFSetAttributes to register its filter module context with NDIS. After that, the filter driver can read its own setting in registry by calling NdisOpenConfigurationEx, and call other NdisXxx functions.

  4. After FilterAttach successfully returns, NDIS restarts the filter later by calling its FilterRestart handler. FilterRestart should prepare to handle send/receive data. After restart return successfully, filter driver should be able to process send/receive.

  5. All requests and sends coming from overlying drivers for the Ndislwf filter driver are repackaged if necessary and sent down to NDIS, to be passed to the underlying NDIS driver.

  6. All indications arriving from an underlying NDIS driver are forwarded up by Ndislwf filter driver.

  7. NDIS calls the filter's FilterPause handler when NDIS needs to detach the filter from the stack or there is some configuration changes in the stack. In processing the pause request from NDIS, the Ndislwf driver waits for all its own outstanding requests to be completed before it completes the pause request.

  8. NDIS calls the Ndislwf driver's FilterDetach entry point when NDIS needs to detach a filter module from NDIS stack. The FilterDetach handler should free all the memory allocation done in FilterAttach, and undo the operations it did in FilterAttach Handler.


Overview (`network/ndis/mux/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

NDIS MUX Intermediate Driver and Notify Object

The MUX Intermediate Miniport (IM) driver is an NDIS 6.0 driver that demonstrates the operation of an "N:1" MUX driver. The sample demonstrates creating multiple virtual network devices on top of a single lower adapter. Protocols bind to these virtual adapters as if they are real adapters. Examples of Intermediate Miniport drivers that can use this framework are Virtual LAN (VLAN) drivers. Included in the project is a sample Notify Object that demonstrates how to write a notify object for installing and configuring an NDIS MUX intermediate miniport (IM) driver that implements an N:1 relationship between upper and lower bindings, for example, it creates multiple virtual network devices on top of a single lower adapter.

For more information, see NDIS Intermediate Drivers in the network devices design guide.

Installing the sample

MUX is installed as a protocol (called Sample Mux-IM Protocol Driver in the supplied INFs/notification object).

To install, follow the steps below:

  1. Prepare an installation directory that contains these files: muxp.inf, mux_mp.inf, mux.sys and mux.dll (notification object DLL, built in this DDK at network\ndis\mux\notifyob).

  2. On the desktop, right-click the My Network Places icon and choose Properties.

  3. Right-click on the relevant Local Area Connection icon and choose Properties.

  4. Click Install, then Protocol, then Add, then Have Disk.

  5. Browse to the drive/directory containing the files listed above. Click OK. This should show Sample Mux-IM Protocol Driver in a list of Network Protocols. Highlight this and click OK. This should install the MUX driver.

  6. Click OK or Yes each time the system prompts with a warning regarding installation of unsigned files. This is necessary because binaries generated via the DDK build environment are not signed.

Two .INF files are needed rather than one because MUX is installed both as a protocol and a miniport.

NDIS MUX Intermediate Driver

The driver binds to Ethernet (NdisMedium802_3) adapters as a protocol, and exposes one or more virtual Ethernet devices over each lower adapter, based on its configuration. The term "VELAN" is used to denote a Virtual Ethernet LAN adapter implemented by this driver.

When it binds to a lower adapter, MUX reads the standard "UpperBind" key to obtain a list of VELANs configured over this adapter. For each such VELAN, it calls NdisIMInitializeDeviceInstanceEx() to instantiate the NDIS miniport for the VELAN. NDIS then calls the driver's MiniportInitialize (MPInitialize) routine to start the VELAN miniport.

The MUX driver supports configuring the MAC address for each VELAN miniport using the standard "NetworkAddress" key that it reads from its MiniportInitialize routine. If this is not configured, it computes a "locally significant" MAC address for the VELAN using the MAC address of the lower adapter. The MUX driver sets its lower adapter to promiscuous mode in order to be able to receive frames directed to any of the VELAN MAC addresses. However it does implement packet-filtering (and multicast address filtering) logic for all its VELAN miniports so that it only passes up relevant frames on each VELAN. This aspect of the driver may be modified if, for example, your driver design uses the same MAC address as that of the lower adapter on all VELANs. With such a modification, it is not required to set the lower adapter to promiscuous mode and incur the costs of receiving all packets on the network.

It supports dynamic addition and deletion of VELANs in conjunction with its notify object (related sample). If a VELAN is deleted, the virtual device corresponding to the VELAN is stopped and removed, which in turn results in NDIS halting the miniport instance for the VELAN (see MPHalt). If a VELAN is added, NDIS sends a global reconfiguration event to the protocol edge of this driver. The handler function for this event, PtPNPHandler, goes through all lower adapters to see if any new VELANs have been added, i.e. if any of the "UpperBind" keys have been modified.

Since the driver implements a virtual device, it does not simply pass through most NDIS queries/sets. It keeps its own device view that is reflected in its responses to queries/sets. However it does pass through queries/sets for certain OIDs that are best handled by the lower adapter driver.

The driver supports Power Management in the sense that it allows Wake-On-LAN and related functionality, if supported by the lower adapter, to continue to function. It does so by appropriately forwarding OID_PNP_XXX queries/sets to the lower adapter.

IEEE 802.1Q VLAN Operation

The driver supports configuring a VLAN ID on each VELAN. It then inserts a tag header containing this VLAN ID on all outgoing frames. For incoming frames that contain a tag header, it verifies that a matching VLAN ID is present before indicating it up to protocols. It removes the tag header, if present, from all indicated frames. In all cases, received frames that do not contain tag headers are always handed up to protocols.

With the default configured VLAN ID of zero, the driver does not insert tag header information on sent packets, except for sent packets that contain non-zero Ieee8021QInfo per-packet information, for which the driver does insert corresponding tag headers. Receive-side filtering on VLAN ID is enabled only with a non-zero configured VLAN ID, in which case only received frames containing a matching VLAN ID are passed up. With the default configured VLAN ID of zero, the driver does not check the VLAN ID on received frames.

Configuring VLANs

The VLAN ID for each VELAN (virtual miniport) can be configured as follows. Right-click on the virtual miniport Local Area Connection icon and choose Properties. Click on the Configure button to bring up the Device Manager UI for the virtual device. Select the Advanced property sheet, this should contain a VLAN ID parameter that is configurable to the desired VLAN ID. Choosing a value of 0 (zero) disables receive-side filtering based on VLAN ID.

Programming Tour

When it loads, i.e. from its DriverEntry function, the MUX driver registers as an Intermediate miniport driver and as a protocol, in that order.

Binding and VELAN Creation

NDIS calls MUX's BindAdapter function, PtBindAdapter, for each underlying NDIS adapter to which it is configured to bind. This function allocates an ADAPT structure to represent the lower adapter, and calls NdisOpenAdapter to set up a binding to it. In the context of BindAdapterHandler, after successfully opening a binding to the underlying adapter, the driver queries the reserved keyword "UpperBindings" to get a list of device names for the virtual adapters that this particular binding is to expose, see PtBootStrapVElans for more details. Note that the MUX driver does not create bindings (for example, call NdisOpenAdapter) from any context other than its BindAdapter function. This is recommended behavior for all drivers of this type.

For each device name specified in the "UpperBindings" key, the MUX driver allocates a VELAN data structure to represent the virtual miniport, calls NdisIMInitializeDeviceInstanceEx. In response, NDIS eventually calls the MUX miniport's MiniportInitialize entry point, MPInitialize, for each VELAN. After MPInitialize successfully returns, NDIS takes care of getting upper-layer protocols to bind to the newly created virtual adapter(s).

Unbinding and Halting

NDIS calls MUX's UnbindAdapter handler, PtUnbindAdapter, to request it to unbind from a lower adapter. In processing this, MUX calls NdisIMDeInitializeDeviceInstance for each VELAN instantiated on the indicated adapter, see PtStopVElan for details. This call results in NDIS first unbinding any protocols bound to the indicated VELAN, and then calling the MiniportHalt routine, MPHalt, for that VELAN. MPHalt waits for any outstanding receives/sends on the VELAN to finish before unlinking the VELAN from the ADAPT.

PtUnbindAdapter itself blocks until all VELANs associated with the ADAPT structure have been unlinked from it. This is to make sure that no thread running in the context of a miniport-edge entry point for a VELAN will ever access an invalid lower binding handle. Once all VELANs have been unlinked, PtUnbindAdapter closes the lower binding by calling NdisCloseAdapter. Note that the MUX driver does not close its lower binding from any context other than its UnbindAdapter function. This is recommended behavior for all drivers of this type.

MPHalt may also be called if the VELAN device is disabled, e.g. from the Network Connections Folder. There is no special code within MPHalt to handle this condition. However, PtUnbindAdapter takes care to not attempt to deinitialize a VELAN miniport (via NdisIMDeInitializeDeviceInstance) that has already been halted.

Handling Queries

MPRequest is the MUX driver's function that handles queries for OID values on VELAN miniports. Most of the "Ethernet" type information for the virtual miniport is stored in the VELAN structure itself, and the driver returns information from this structure. The queries that are forwarded are OID_GEN_MEDIA_CONNECT_STATUS, OID_PNP_CAPABILITIES and OID_PNP_WAKE_UP_PATTERN_LIST. See "Handling Power Management" below for more information about the latter two OIDs.

Handling Sets

MPRequest handles setting OID values on VELAN miniports. Data management OIDs handled by the MUX driver are OID_802_3_MULTICAST_LIST and OID_GEN_CURRENT_PACKET_FILTER. The multicast list is handled entirely within the MUX driver, it just stores the set of multicast addresses in the VELAN structure, for reference during receive-side data processing. The packet filter is handled in a different way. The MUX driver combines the packet filter settings (bitwise OR) of all VELANs associated with the same lower adapter. If the combined packet filter is non-zero, MUX sends a Set request with a value of NDIS_PACKET_TYPE_PROMISCUOUS for OID_GEN_CURRENT_PACKET_FILTER to start receives on the lower adapter. If the combined packet filter is zero, MUX sets the lower adapter's packet filter to 0 (turns off all receives if there aren't any interested protocols).

Note that setting the lower adapter to promiscuous mode is only done here in order to be able to receive unicast frames directed to multiple MAC addresses. If, for example, all VELANs are assigned the same MAC address (which is identical to the address of the lower adapter), then the MUX driver should only pass down the combined (bitwise OR) setting of packet filter settings of all VELANs.

Some power management OIDs are forwarded to the lower miniport. See "Handling Power Management" below for details.

Sending Data

Data sent down on a VELAN miniport is forwarded to the lower adapter. The MUX driver itself does not generate any data of its own. The MUX driver clones a NET_BUFFER_LIST for each NetBufferList passed to its MPSendNetBufferLists function, and saves a pointer to the original NET_BUFFER_LIST in the reserved area of the NET_BUFFER_LIST structure. When the lower adapter completes the send (PtSendNBLComplete), MUX picks up the original packet and calls NdisMSendNetBufferListsComplete to complete the original send request.

If a non-zero VLAN ID is configured for the VELAN, and/or the packet has non-zero Ieee8021QInfo per-packet information, then the MUX driver inserts an NDIS buffer containing a tag header to the front of the packet before sending it down, see function MPHandleSendTagging for details.

Receiving Data

Data received from a lower adapter is indicated up on zero or more VELANs. The PtReceiveNBL function is called for each NetBufferList received from the lower adapter. The received data is checked for matches with the packet filter and multicast list for each VELAN associated with the adapter (see PtMatchPacketToVElan). Whenever a match is found, a new NET_BUFFER_LIST is allocated and set to point to the received data. A pointer to the original received NET_BUFFER_LIST (if any) is also stored in the new NET_BUFFER_LIST's reserved area. This packet is indicated up via NdisMIndicateReceiveNetBufferLists to all interested protocols on that VELAN.

The driver's MPReturnNetBufferLists function is called either by NDIS or by MUX itself when protocols are done with a received NET_BUFFER_LIST. This function returns the original NET_BUFFER_LIST indicated by the lower driver, if any, by calling NdisReturnNetBufferLists.

The driver indicates up received frames that do not have an IEEE 802.1Q tag header in them, see function PtHandleRcvTagging. It always strips off tag headers, if present, on received frames. If a non-zero VLAN ID is configured, then it checks received frames that contain tag headers for matching VLAN Ids, only matching frames are indicated up to protocols. Any VLAN/priority information present in incoming frames is copied to per-packet information fields of indicated NET_BUFFER_LIST structures.

Status Indications

The only status indications that are forwarded up by MUX are media connect status indications. See PtStatus for more details.

Handling Power Management

During initialization (MPInitialize), the MUX miniport sets the attribute NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND in its call to NdisMSetMiniportAttributes. When the MUX miniport is requested to report its Plug and Play capabilities (OID_PNP_CAPABILITIES), the MUX miniport forwards the request to the underlying miniport. If this request succeeds, then the MUX miniport overwrites the following fields before successfully completing the original request:

txt
NDIS_DEVICE_POWER_STATE          MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
NDIS_DEVICE_POWER_STATE          MinPatternWakeUp= NdisDeviceStateUnspecified;
NDIS_DEVICE_POWER_STATE          MinLinkChangeWakeUp=NdisDeviceStateUnspecified

See PtPostProcessPnPCapabilities for details.

OID_PNP_SET_POWER and OID_PNP_QUERY_POWER are not passed to the lower adapter, since the lower layer miniport will receive independent requests from NDIS.

NDIS calls the MUX driver's ProtocolPnPEvent function (PtPNPHandler) whenever the underlying adapter is transitioned to a different power state. If the underlying adapter is transitioning to a low power state, the driver waits for all outstanding sends and requests to complete.

Queries/sets received on a VELAN miniport that are to be forwarded to the underlying adapter are queued on the VELAN if the underlying adapter is at a low power state. These are picked up for processing on receiving a notification that the underlying adapter is back to a powered-up state.

Handling Global Reconfiguration

All modifications to VELAN configuration are accompanied by PnP reconfigure notifications, for example, NetEventReconfigure events passed to the MUX's PnPEventHandler, PtPNPHandler. This driver takes a broad approach to handling reconfiguration, which is to simply re-examine all the "UpperBindings" keys for all currently bound adapters, and start off VELANs for any that do not exit, see PtBootStrapVElans for details.

Canceling Sends

MUX propagates send cancellations from protocols above it to lower miniports.

Sample Notify Object

Preprocessor Flags

DISABLE\_PROTOCOLS\_TO\_PHYSICAL

When this flag is defined in the Sources file, the notify object disables the bindings of other protocols such as TCP/IP to the physical adapters during the installation. When all the virtual adapters are removed either through the custom property page or as a result of uninstalling the MUX driver, the notify object re-enables those bindings.

PASSTHRU\_NOTIFY

This flag is defined to allow the MUX driver to be used in a passthru mode. When this flag is defined, the notify object:

  1. Creates only one virtual miniport for every physical adapter the MUX protocol edge binds to.

  2. Disables the property page to prevent adding of additional virtual miniports.

  3. Stores the device name of the virtual adapter in REG_SZ registry value under HKLM\System\CurrentControlSet\Services\muxp\Parameters\Adapters\{PhysicalAdaptersInstanceGuid}\UpperBindings, because there is one to one binding. In the MUX mode (when this flag is not defined), the notify object stores the device name in a REG_MULTI_SZ registry value as there could be more than one virtual miniports.

You can also use this notify object with the Passthru driver by doing the following:

  1. Change the protocol name in file \ndis\passthru\passthru.c from PASSTHRU to MUXP.

  2. Change the driver name from Passthru to MUX in the sources file.

  3. Rebuild the driver to obtain a mux.sys driver binary.

  4. Build the MUX notify object with PASSTHRU_NOTIFY defined.

  5. Use the MUX inf files, muxp.inf and mux_mp.inf, to install the driver and dll.

The benefit of using techniques in the MUX notify object for a 1:1 intermediate driver (e.g. Passthru) is to be able to exercise higher level of control over the bindings of MUX with other components in the system, which is not possible with the IM filter driver.

CUSTOM\_EVENTS

When this macro is defined, the notify object shows how to send custom events to the MUX IM driver when a virtual miniport is added or removed.

Notify Object Operation

During installation, the notify object performs the following operations:

  • It creates one virtual adapter for each physical adapter the MUX protocol edge binds to.

  • It disables the bindings of other protocols such as TCP/IP to physical adapters if it has been compiled with DISABLE_PROTOCOLS_TO_PHYSICAL defined in the Sources file. This is the most commonly desired behavior for N:1 MUX drivers.

  • It disables the bindings of the protocol edge of the MUX IM driver with all its virtual adapters.

The notify object provides a custom property page for the MUX IM driver. The custom property page allows the user to add one or more virtual adapters on top of a physical adapter or delete an existing virtual adapter.

When the MUX IM driver is uninstalled, or binding is disabled, or the user deletes all the virtual adapters on top of a physical adapter, the notify object restores the bindings of other protocols to the physical adapter if it has been compiled with the preprocessor flag DISABLE_PROTOCOLS_TO_PHYSICAL defined in the Sources file.

File Manifest

File Description
Miniport.c Miniport related routines for the MUX driver
Mux.c DriverEntry routine and any routines common to the MUX miniport and protocol
Mux.h Prototypes of all functions and data structures used by the MUX driver
Mux.rc Resource file for the MUX driver
Muxp.inf Installation INF for the service (protocol side installation)
Mux_mp.inf Installation INF for the miniport (virtual device installation)
Precomp.h Precompile header file
Protocol.c Protocol related routines for the MUX driver
Public.h Contains the common declarations shared by driver and user applications

For more information, see NDIS Intermediate Drivers in the network devices design guide.


Overview (`network/ndis/ndisprot_kmdf/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Connection-less NDIS 6.0 Protocol KMDF Sample Driver

This sample demonstrates a connection-less NDIS 6.0 protocol KMDF driver.

The driver supports sending and receiving raw Ethernet frames using ReadFile/WriteFile calls from user-mode. As an NDIS protocol, it illustrates how to establish and tear down bindings to Ethernet adapters, i.e. those that export medium type NdisMedium802_3. It shows how to set a packet filter, send and receive data, and handle plug-and-play events.

The sample also demonstrates how to write a Notify Object dll. The Notify Object is used for calling into the Wdf Coinstaller to install and load the framework library.

Creating Framework-based Miniport Drivers

Build the sample

For information on how to build a driver solution using Microsoft Visual Studio, see Building a Driver with Visual Studio and the WDK.

The 60 subdirectory (\ndisprot_kmdf\60) indicates that the built sample will be NDIS 6.0 compatible.

Installation

Use the following steps to install the sample.

  1. When you build the sample, the build engine produces ndisprot.inf in the build target directory. Copy nprt6wdf.sys, protnotify.dll, and ndisprot.inf to a directory.

  2. Copy the KMDF coinstaller (wdfcoinstallerMMmmm.dll) to the same directory.

    [!NOTE]
    You can obtain redistributable framework updates by downloading the wdfcoinstaller.msi package from WDK 8 Redistributable Components. This package performs a silent install into the directory of your Windows Driver Kit (WDK) installation. You will see no confirmation that the installation has completed. You can verify that the redistributables have been installed on top of the WDK by ensuring there is a redist\wdf directory under the root directory of the WDK, %ProgramFiles(x86)%\Windows Kits\8.0.

  3. In Control Panel, in the Network and Internet group, open Network Connections, select an adapter, and then open Properties.

  4. Click Install, and then click Protocol.

  5. Click Add, and then click Have disk.

  6. Point to the location of the INF file and driver, click Sample NDIS Protocol Driver, and then click OK.

  7. After installing the protocol, copy the test application Uiotest.exe to a convenient location. Note that the driver service has been set to manual start in the INF file. As a result, it doesn't get loaded automatically when you install the driver.

Usage

From an administrator command prompt, to start the driver, type Net start ndisprot.

To stop the driver, type Net stop ndisprot.

You can build Prottest.exe from source code located in the \ndisprot\6x\test directory.

To test the NDIS 6.0 driver, run prottest. For help on usage, run prottest -?.

cmd
usage: PROTTEST [options] <devicename>
options:
 -e: Enumerate devices
 -r: Read
 -w: Write (default)
 -l <length>: length of each packet (default: 100)
 -n <count>: number of packets (defaults to infinity)
 -m <MAC address> (defaults to local MAC)
 -f Use a fake address to send out the packets.

Prottest exercises the IOCTLs supported by NDISPROT, and sends and/or receives data on the selected device. In order to use Prottest, the user must have administrative privilege. Users should pass down a buffer that is large enough to contain the data returned. If the length of the buffer passed down is smaller than the length of the received data, NDISPROT will only copy part of the data and discard the rest when the given buffer is full.

For an NDIS 6.0 driver, use the -e option on prottest to enumerate all devices to which NDISPROT is bound:

cmd
C:\prot>prottest -e
 0. \DEVICE\{9273DA7D-5275-4B9A-AC56-68A49D121F1F}
 - Intel-Based 10/100 Ethernet Card

The following command sends and receives 2 packets on a device. Since these packets are sent to the local MAC address (default), both packets are received. The device name parameter to prottest is picked up from the output of prottest -e (see above).

cmd
C:\prot>prottest -n 2 \DEVICE\{9273DA7D-5275-4B9A-AC56-68A49D121F1F}
DoWriteProc: finished sending 2 packets of 100 bytes each
DoReadProc finished: read 2 packets

For security reasons, this driver does not allow packets with fake MAC addresses to be sent from user-mode applications.

With a checked version of ndisprot.sys, you can control the volume of debug information generated by changing the variable ndisprotDebugLevel. Refer to debug.h for more information.

File Manifest

Directory: 60

File description
debug.c Routines to aid debugging
debug.h Debug macro definitions
excallbk.c Handles load order dependency between this sample and NDISWDM sample
macros.h Spinlock, event, referencing macros
ndisbind.c NDIS protocol entry points to handle binding/unbinding from adapters
ndisprot.h Data structure definitions
precomp.h Contains the precompiled headers
protuser.h Has the definitions of ioctls issued by protuser.exe application used on NDIS 6.0
nuiouser.h Has the definitions of ioctls issued by nuiouser.exe application used on NDIS 5.0
ndisprot.inf INF file for installing NDISPROT
ntdisp.c NT Entry points and dispatch routines for NDISPROT
recv.c NDIS protocol entry points for receiving data, and IRP_MJ_READ processing

Directory: NotifyOb

File description
Common.hpp Header file containing the common include files for the project
dllmain.cpp Handles loading/unloading of Wdf Coinstaller and the notify object dll
ProtNotify.idl Defines the interfaces for the notify object dll
ProtNotify.rc Resource file for the notify object dll

Overview (`network/netadaptercx/netvadapter/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

netvadapter — Virtual NIC Sample

netvadapter is a virtual Ethernet NIC driver that uses NetAdapterCx for its data
path. It links against the shared netvadapterlibrary static library (the same library used
by the WIFICX sample) and ships in both KMDF and UMDF flavors.

Two netvadapter instances can be paired together through the library's Emulated Network
Link (ENL)
: packets sent on one adapter are delivered to the other and vice‑versa, so you can
run connectivity tests (ping, throughput) entirely in software with no physical hardware.


Layout

Path Description
netvadapter.sln Solution containing both drivers + the library project references.
build.cmd Build wrapper (see Building — pins UMDF to 2.33).
km\netvadapterkm.vcxproj KMDF driver → netvadapter.sys (INF: km\netvadapter.inf).
um\netvadapterum.vcxproj UMDF driver → netvadapterum.dll (INF: um\netvadapterum.inf).
drivercode\ Shared driver source (see below).

Building

The UMDF driver targets UMDF 2.33 (to match netvadapterum.inf's
UmdfLibraryVersion = 2.33.0), while the shared netvadapterlibrary is checked in at UMDF
2.35
(so the WIFICX sample is unaffected). Because the WDF version must match within a single
binary, build through build.cmd, which forces the library and driver to 2.33 for this
solution only:

cmd
build.cmd                 :: Debug   x64  (defaults)
build.cmd Release x64

A plain msbuild netvadapter.sln or a Visual Studio IDE build will fail to link with an
unresolved WdfFunctions_02035 symbol, because it does not apply the 2.33 override.

Signing the package (test signing)

The build signs the binaries but does not produce a catalog. To create and test‑sign the
catalogs (required to install while in test‑signing mode):

cmd
:: From an EWDK environment, for each package folder under x64\<Config>\:
Inf2Cat /driver:.\netvadapterkm  /os:10_X64,Server10_X64
Inf2Cat /driver:.\netvadapterum  /os:10_X64,Server10_X64

signtool sign /fd SHA256 /sha1 <WDKTestCertThumbprint> /tr http://timestamp.digicert.com /td SHA256 .\netvadapterkm\netvadapter.cat
signtool sign /fd SHA256 /sha1 <WDKTestCertThumbprint> /tr http://timestamp.digicert.com /td SHA256 .\netvadapterum\netvadapterum.cat

Installing

Enable test signing once (elevated, then reboot), and install the test certificate into the
Root and TrustedPublisher stores on the target machine. Then install the driver with
devcon:

cmd
.\devcon.exe install .\netvadapterum.inf root\netvadapterum

If the command fails, inspect the device‑install log at:

text
C:\Windows\INF\setupapi.dev.log

Pairing two adapters

A working link requires two netvadapter instances. Create both by running the install
command twice:

cmd
.\devcon.exe install .\netvadapterum.inf root\netvadapterum
.\devcon.exe install .\netvadapterum.inf root\netvadapterum

Then set the MACLastByte advanced keyword to 1 and 2 on both adapters via Device Manager → adapter → Advanced, or the network adapter
property pages.

⚠️ MACLastByte defaults to 0. If an adapter is left at the default, the device fails
to start and shows a yellow bang (error) in Device Manager. Assign distinct values such as
1 and 2 for the pair to link correctly.


Managing the driver

List installed net‑class drivers (to find the oemNN.inf published name):

cmd
pnputil /enum-drivers /class net

Remove the driver and prepare for a clean reinstall (substitute the oemNN.inf from the command
above):

cmd
pnputil /delete-driver oem2.inf /uninstall /force

Overview (`network/radio/RadioManagerSample/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Radio Management Sample

The Radio Manager sample demonstrates how to structure a Radio Manager for use with the Windows Radio Management APIs.

The operating system contains a set of APIs which are used as a software mechanism to control the various radios found on the machine. The APIs work by communicating with a Radio Manager, which is a COM object that relays commands from the APIs to turn the radio on or off, and reports back radio information to the APIs. This feature is designed in such a way that a separate Radio Manager is required for each radio media type. For example, a WLAN radio will be controlled by a different Radio Manager than a GPS radio. If there are 2 WLAN radios and a GPS radio, the 2 WLAN radios will be controlled by one Radio Manager, and the GPS radio will be controlled by a different Radio Manager. The Radio Manager must be able to run correctly within Local Service Account context. Under this context, the Radio Manager will have the minimum privilege on the local computer.

When the user turns the radio off (either by using the specific radio software switch or the airplane mode switch), radio transmission must be turned off. The device can be powered off as long as the radio switch does not disappear from the UI. It is very important that the radio manager developer ensures that when the device is powered off, the radio switch does not disappear from the UI. If the radio switch disappears from the UI when the radio is turned off by the user, then user has no way to turn the radio back on! If it is desired to conserve power by cutting power to the device when the radio is turned off, but the device cannot be completely powered off because it disappears from the UI, then the solution would be to put the device in a low power state (e.g. D3).

[!IMPORTANT]
The radio manager must be given a name. This is the name of the radio switch that is displayed to the user in the Wireless page of PC Settings. The name must be simple, yet descriptive of what the radio is. For example, for NFC radios, the value of the name field should be "NFC", and for GPS radios, the value of the name field should be "GPS" or "GNSS", whichever is more appropriate. The name must not include the word "radio" or the manufacturer's name or some other word related to the functionality of the radio (e.g. "Location" OR "port").

Installation

The sample contains a script, install.cmd, which copies the radio manager DLL to the system directory, registers as a COM component, and configures the registry.

Copy the install.cmd, SampleRM.reg and SampleRM.dll files to a directory. Run install.cmd.

Code Tour

File description
install.cmd Installation script. Copies and registers the dll and executes SampleRM.reg.
SampleRM.reg Script to install the Sample Radio Manager into the registry, along with 2 radio instances.
SampleRM.sln The Visual Studio solution file for building the Sample Radio Manager dll.
sampleRM.idl The interface definition for the Sample Radio Manager.
RadioMgr.idl The interface definition for a Windows Radio Manager.
SampleRadioManager.h Header file for the functions required for a Radio Manager.
SampleRadioInstance.h Header file for the functions required for a Radio Instance.
SampleInstanceCollection.h Header file for the functions required for a Collection of Radio Instances.
precomp.h Common header file
InternalInterfaces.h Header file for internal interface used for this sample.
dllmain.cpp Standard dllmain
Sample Radio Manager. Important concepts include utilizing IMediaRadioManagerNotifySink for radio instance events, adding/Removing radio instances, and queuing and deploying worker jobs for system events.
SampleRadioInstance.cpp Implementation details for the Sample Radio Instance. Important concepts include accessors and modifiers for radio information, and instance change functions.
SampleInstanceCollection.cpp Implementation details for the Sample Instance Collection. Important concepts include radio instance discovery and retrieval.
RadioMgr_interface.cpp Helper source file to include the MIDL-generated files.

Run the sample

Operation

This sample Radio Manager does not operate on an actual radio. Instead, it uses registry keys to act as virtual radios.

Each "radio" instance can have the following values:

  • Name

  • RadioState

  • PreviousRadioState

  • IsMultiComm

  • IsAssociatingDevice

[!NOTE]
It is required that the registry key has AT LEAST a Name value, otherwise the Sample Radio Manager will fail to initialize.

[!IMPORTANT]
The radio manager must be given a name and the registry key must have, as a minimum, a Name value. Otherwise, the Sample Radio Manager will fail to initialize. This is the name of the radio switch that is displayed to the user in the Wireless page of PC Settings. The name must be simple, yet descriptive of what the radio is. For example, for NFC radios, the value of the name field should be "NFC", and for GPS radios, the value of the name field should be "GPS" or "GNSS", whichever is more appropriate. The name must not include the word "radio" or the manufacturer's name or some other word related to the functionality of the radio (e.g. "Location" OR "port").

When the Radio Manager is initialized, it uses these registry keys to retrieve the "radio" information. The radio state values can be any of the following enum values:

cpp
typedef enum _DEVICE_RADIO_STATE
{
    DRS_RADIO_ON                    = 0,
    DRS_SW_RADIO_OFF                = 1,
    DRS_HW_RADIO_OFF                = 2,
    DRS_SW_HW_RADIO_OFF             = 3,
    DRS_HW_RADIO_ON_UNCONTROLLABLE  = 4,
    DRS_RADIO_INVALID               = 5,
    DRS_HW_RADIO_OFF_UNCONTROLLABLE = 6,
    DRS_RADIO_MAX                   = DRS_HW_RADIO_OFF_UNCONTROLLABLE
} DEVICE_RADIO_STATE;

For IsMultiComm and IsAssociatingDevice, a value of 0 means 'no' and 1 means 'yes'.

Adding and Setting a Radio Instance

To add a new radio instance, add a new instance key to the registry key like the following entry:

inf
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\RadioManagement\Misc\SampleRadioManager\SampleRadioX]
"RadioState"=dword:00000000
"Name"="SampleRadioX"
"IsMultiComm"=dword:00000000

Editing a Radio Instance

Simply change the values in the registry. For example, change the radio state from DRS_RADIO_ON to DRS_SW_RADIO_OFF by changing the 'RadioState' value from 0 to 1.

Removing a Radio Instance

Delete the corresponding registry key.


Overview (`network/trans/WFPSampler/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Filtering Platform Sample

The WFPSampler sample driver is a sample firewall. It has a command-line interface which allows adding filters at various WFP layers with a wide variety of conditions. Additionally it exposes callout functions for injection, basic action, proxying, and stream inspection.

WFPSampler.Exe is the command-line interface used by the user to define the policy.

WFPSamplerService.Exe is the service which instructs BFE to add or remove policies.

WFPSamplerCalloutDriver.Sys is the driver which houses the various callout functions.

WFPSamplerProxyService.Exe is the service which listens for connections to proxy.

WFPSampler.Lib is a library of user mode helper functions used throughout the project.

WFPSamplerSys.Lib is a library of kernel mode helper functions used throughout the project.

"WFPSamplerInstall.cmd" will copy the necessary binaries to their appropriate location, and install each component.

"WFPSamplerInstall.cmd -r" will uninstall each component and remove the binaries from the appropriate location.

Once you have downloaded the sample, the .mht files in the sample's docs directory describe the various WFP filtering scenarios that you can try.

For more information about WFP callout drivers, see Windows Filtering Platform Callout Drivers.

Open the driver solution in Visual Studio

Navigate to the folder that contains the sample. Double click the solution file, WFPSampler.sln. In Visual Studio, locate Solution Explorer. (If this is not already open, choose Solution Explorer from the View menu.) In Solution Explorer, you can see one solution that has these projects:

  • a user-mode application project named WFPSampler (under the Exe node)

  • a user-mode library project named WFPSampler (under the Lib node)

  • a user-mode service project named WFPSamplerService (under the Svc node)

  • a driver project named WFPSamplerCalloutDriver (under the Sys node)

  • a kernel-mode library project named WFPSampler (under the Syslib node)

Set the configuration and platform in Visual Studio

In Visual Studio, in Solution Explorer, right click Solution 'WFPSampler' (5 projects), and choose Configuration Manager. Set the configuration and the platform. Make sure that the configuration and platform are the same for all projects. Do not check the Deploy boxes.

Set the runtime library for the user-mode application, library, and service

In Solution Explorer, right-click the WFPSampler user-mode application project (under the Exe node), and choose Properties. Navigate to Configuration Properties > C/C++ > Code Generation. For Runtime Library, select Multi-threaded Debug (/MTd). Click OK.

Repeat this process for the WFPSampler user-mode library (under the Lib node) and the WFPSampler user-mode service (under the Svc node).

Edit the restart setting in the sample installation script

Open the WfpSamplerInstall.cmd file (in the scripts folder) in Visual Studio.

Change this line:

RunDLL32.Exe syssetup,SetupInfObjectInstallAction DefaultInstall 131 %WinDir%\System32\Drivers\WFPSamplerCalloutDriver.Inf

to this:

RunDLL32.Exe syssetup,SetupInfObjectInstallAction DefaultInstall 132 %WinDir%\System32\Drivers\WFPSamplerCalloutDriver.Inf

For more information about this setting, see the Remarks section for the InstallHinfSection function.

Build the sample using Visual Studio

In Visual Studio, on the Build menu, choose Build Solution.

For more information about using Microsoft Visual Studio to build a driver package, see Building a Driver with Visual Studio and the WDK.

Locate the built driver package

In File Explorer, navigate to the folder that contains your built driver package. The location of this folder varies depending on what you set for configuration and platform. For example, if your settings are Debug and x64, the driver is in your sample folder under \Debug.

The driver folder contains these files:

File Description
wfpsamplercalloutdriver.cat A signed catalog file, which serves as the signature for the entire package.
WFPSamplerCalloutDriver.inf An information (INF) file that contains information needed to install the driver.
WFPSamplerCalloutDriver.sys The WFPSampler driver.

[!NOTE]
The build process might also put WdfCoinstaller010xx.dll in the driver folder, but this file is not really part of the driver package. The INF file does not reference any coinstallers.

Because the package does not contain a KMDF coinstaller, it is important that you set the KMDF minor version according to your target operating system when you built the driver.

Locate the symbol file (PDB) for the driver

In File Explorer, locate the symbol file, WFPSamplerCalloutDriver.pdb. The location of this file varies depending on what you set for configuration and platform. For example, if your settings are Debug and Win32, the PDB file is in your sample folder under sys\Debug.

Locate the user-mode application and its symbol file (PDB)

In File Explorer, locate the user-mode application (WFPSampler.exe) and its symbol file (WFPSampler.pdb). The location of these files varies depending on what you set for configuration and platform. For example, if your settings are Debug and x64, WFPSampler.exe and WFPSampler.pdb are in your sample folder under exe\Debug.

Locate the kernel-mode service and its symbol file (PDB)

In File Explorer, locate the kernel-mode library, WFPSamplerService.exe. The location of this file varies depending on what you set for configuration and platform. For example, if your settings are Debug and x64, WFPSamplerService.exe and WFPSamplerService.pdb are in your sample folder under svc\Debug.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver to the target computer and installing the driver is called deploying the driver. You can deploy the Windows Filtering Platform Sample driver automatically or manually.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right-click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. In the Build menu, choose Build Solution.

  4. Copy the following files to the DriverTest\Drivers folder on the target computer:

    • The user-mode application (WFPSampler.exe) file

    • The kernel-mode service (WFPSamplerService.exe) file

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, copy the following files to a folder on the target computer (for example, c:\WFPSamplerSamplePackage):

  • The 4 files in your driver package folder

  • The user-mode application (WFPSampler.exe) file

  • The kernel-mode service (WFPSamplerService.exe) file

Copy additional files to the target computer

Copy the driver's PDB file (WFPSamplerCalloutDriver.pdb), the user-mode service's PDB file (WFPSamplerService.pdb) and the user-mode application's PDB file (WFPSampler.pdb) to a folder on the target computer (for example, c:\Symbols).

Copy the TraceView and SignTool tools to a folder on the target computer (for example c:\Tools).

  • TraceView comes with the WDK. You can find it in your WDK installation folder under Tools (for example, c:\Program Files (x86)\Windows Kits\10\Tools\x64\TraceView.exe).

  • SignTool also comes with the WDK. You can find it in your WDK installation folder under bin (for example, c:\Program Files (x86)\Windows Kits\10\bin\x64\SignTool.exe).

Installing the driver

  1. On the target computer, open a Command Prompt window as Administrator. Navigate to the folder that contains the installation script:

    • For manual deployment, this will be the folder that you copied the driver page files into (for example, c:\WFPSamplerSamplePackage).

    • For automatic deployment, this will be DriverTest\Drivers.

  2. Enter WFPSamplerInstall.cmd to run the installation script.

    [!NOTE]
    If you need to uninstall a previous version of the driver, enter WFPSamplerInstall.cmd -r.

Running the user-mode application

On the target computer, open a Command Prompt window as Administrator.

If you just want to see whether you can run the application, enter WFPSampler.exe -?.

The .mht files in the docs directory describe the various WFP filtering scenarios that you can try.

For example, you can test the basic packet examination scenario by using the following command line:

WFPSampler.exe -s BASIC\_PACKET\_EXAMINATION -l FWPM\_LAYER\_INBOUND\_IPPACKET\_V4 -v

This command line adds a dynamic filter (-v) at the FWPM_LAYER_INBOUND_IPPACKET_V4 layer (-l) which references the appropriate callout driver function. This filter will have no conditions, so it will act on all traffic seen at this layer.

Start a logging session in TraceView

On the target computer, open TraceView.exe as Administrator. On the File menu, choose Create New Log Session. Click Add Provider. Select PDB (Debug Information File), and enter the path to your PDB file, WFPSamplerCalloutDriver.pdb. Click OK and click Next. Click the >> button next to Set Flags and Level, double-click the L button next to Level, and set the Level to Information. Click OK and click Finish.

If you want to test whether your TraceView.exe session is working, you can enter the following commands and see what the trace output looks like:

  • net stop WFPSamplerCallouts

  • net start WFPSamplerCallouts

For more information, see Creating a Trace Session with a PDB File.

Tracing for the sample driver can be started at any time before the driver is started or while the driver is already running.


Overview (`network/trans/ddproxy/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Filtering Platform Packet Modification Sample

The sample driver demonstrates the packet modification capabilities of the Windows Filtering Platform (WFP).

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy the Windows Filtering Platform Packet Modification Sample driver automatically or manually.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. On the Build menu, choose Build Solution.

  4. On the target computer, navigate to DriverTest\Drivers, and locate the file ddproxy.inf. Right click ddproxy.inf, and choose Install.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, continue with these steps:

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpPacketModificationSamplePackage).

  2. On the target computer, navigate to your driver package folder. Right click ddproxy.inf, and choose Install

Create Registry values

  1. On the target computer, open Regedit, and navigate to this key:

    HKLM\System\CurrentControlSet\Services\ddproxy\Parameters

  2. Create a REG_SZ entry named DestinationAddressToIntercept and set it's value to an IPV4 or IPV6 address (example: 10.0.0.1).

  3. Create a REG_SZ entry named NewDestinationAddress, and set it's value to an IPV4 or IPV6 address (example: 10.0.0.2).

You can also create and set values for the following registry entries.

  • InspectUdp (REG_DWORD type): 0 for ICMP and 1 for UDP (default)

  • DestinationPortToIntercept (REG_DWORD type): UDP port number (applicable if InspectUdp is set to 1)

  • NewDestinationPort (REG_DWORD type): UDP port number (applicable if InspectUdp is set to 1)

Start the ddproxy service

On the target computer, open a Command Prompt window as Administrator, and enter net start ddproxy. (To stop the driver, enter net stop ddproxy.)

Remarks

This sample driver consists of a kernel-mode Windows Filtering Platform (WFP) callout driver (Ddproxy.sys) that intercepts User Datagram Protocol (UDP) and nonerror Internet Control Message Protocol (ICMP) traffic of interest and acts as a redirector. For outbound traffic, Ddproxy.sys redirects the traffic to a new destination address and, for UDP, a new UDP port. For inbound traffic, Ddproxy.sys redirects the traffic back to the original address and UDP port values. This redirection is transparent to the application.

Packet modification is done out-of-band by a system worker thread by using the reference-drop-clone-modify-reinject mechanism. Therefore, the sample can serve as a basis for scenarios in which the filtering/modification decision cannot be made within the classifyFn() callout, but instead must be made, for example, by a user-mode application.

Ddproxy.sys acts as a redirector for both Internet Protocol version 4 (IPv4) and Internet Protocol version 6 (IPv6) traffic.

For more information on creating a Windows Filtering Platform Callout Driver, see Windows Filtering Platform Callout Drivers.


Overview (`network/trans/inspect/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Filtering Platform Traffic Inspection Sample

This sample driver demonstrates the traffic inspection capabilities of the Windows Filtering Platform (WFP).

The sample driver consists of a kernel-mode Windows Filtering Platform (WFP) callout driver (Inspect.sys) that intercepts all transport layer traffic (for example, Transmission Control Protocol (TCP), User Datagram Protocol (UDP), and nonerror Internet Control Message Protocol (ICMP)) sent to or received from a configurable remote peer and queues then to a worker thread for out-of-band processing.

Inspect.sys inspects inbound and outbound connections and all packets that belong to those connections. Additionally, Inspect.sys demonstrates the special considerations that are required to be compatible with Internet Protocol security (IPsec).

Inspect.sys implements the ClassifyFn callout functions for the ALE Connect, Recv-Accept, and Transport callouts. In addition, the system worker thread that performs the actual packet inspection is also implemented along with the event mechanisms that are shared between the Classify function and the worker thread.

Connect/Packet inspection is done out-of-band by a system worker thread by using the reference-drop-clone-reinject mechanism as well as the ALE pend/complete mechanism. Therefore, the sample can serve as a basis for scenarios in which a filtering decision cannot be made within the classifyFn() callout and instead must be made, for example, by a user-mode application.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. On the Build menu, choose Build Solution.

  4. On the target computer, navigate to DriverTest\Drivers, and locate the file inspect.inf. Right click inspect.inf, and choose Install.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, continue with these steps:

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpTrafficInspectionSamplePackage).

  2. On the target computer, navigate to your driver package folder. Right click inspect.inf, and choose Install

Create Registry values

  1. On the target computer, open Regedit, and navigate to this key:

    HKLM\System\CurrentControlSet\Services\inspect\Parameters

  2. Create a REG_DWORD entry named BlockTraffic and set it's value to 0 for permit or 1 to block.

  3. Create a REG_SZ entry named RemoteAddressToInspect, and set it's value to an IPV4 or IPV6 address (example: 10.0.0.2).

Start the inspect service

On the target computer, open a Command Prompt window as Administrator, and enter net start inspect. (To stop the driver, enter net stop inspect.)

Remarks

For more information on creating a Windows Filtering Platform Callout Driver, see Windows Filtering Platform Callout Drivers.


Overview (`network/trans/msnmntr/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Filtering Platform MSN Messenger Monitor Sample

This sample application and driver demonstrate the stream inspection capabilities of the Windows Filtering Platform (WFP).

The sample consists of a user mode application (Monitor.exe) that registers traffic of interest. In this case, all Transmission Control Protocol (TCP) data segments that are sent and received by an application of your choice.

[!NOTE]
Originally this sample was written to monitor the MSN Messenger application. Now it can monitor any application that you specify.

Monitor.exe adds filters and callouts to Windows through the Windows Filtering Platform (WFP) Win32 API. A kernel-mode WFP callout driver (Msnmntr.sys) intercepts TCP traffic and parses out communication patterns. Monitor.exe controls the operations of the callout driver through I/O controls (IOCTLs).

The filters and callouts added by Monitor.exe are persistent across system restarts and removed only by Monitor.exe. Adding filters and callouts requires administrator privileges. Therefore, Monitor.exe must be run from an elevated command prompt.

Msnmntr.sys registers itself at two different WFP layers: FLOW-ESTABLISHED and STREAM. For simplicity, only Internet Protocol version 4 (IPv4) traffic is inspected. Msnmntr.sys registers at the FLOW-ESTABLISHED layer to associate a callout driver-specific data structure with application identity (that is, path) recorded such that the STREAM layer will only be invoked if traffic is sent or received from that particular application.

After the filters and callouts are in place and registered, WFP indicates TCP data segments to the Msnmntr.sys for inspection. As the data flows through Msnmntr.sys, it copies them (described by a chain of NET_BUFFER_LIST structures) to a flat buffer, parses out the communication patterns (such as client-to-server/client-to-client), and sends them to the Windows Software Trace Preprocessor (WPP) for tracing.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. On the Build menu, choose Build Solution.

  4. On the target computer, navigate to DriverTest\Drivers, and locate the file msnmntr.inf. Right click msnmntr.inf, and choose Install.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, continue with these steps:

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpMsnMessengerMonitorSamplePackage).

  2. On the target computer, navigate to your driver package folder. Right click msnmntr.inf, and choose Install

Copy additional files to the target computer

Copy the user-mode application, monitor.exe to a folder on the target computer (for example, c:\WfpMsnMessengerMonitorSampleApp).

Copy the PDB file, msnmntr.pdb to a folder on the target computer (for example, c:\Symbols).

Copy the tool TraceView.exe to a folder on the target computer (for example c:\Tools). TraceView.exe comes with the WDK. You can find it in your WDK installation folder under Tools (for example, c:\Program Files (x86)\Windows Kits\10\Tools\x64\TraceView.exe).

Start the msnmntr service

On the target computer, open a Command Prompt window as Administrator, and enter net start msnmntr. (To stop the driver, enter net stop msnmntr.)

Running the user-mode application

On the target computer, open a Command Prompt window as Administrator, and navigate to the folder that contains monitor.exe. Enter monitor.exe addcallouts. Then enter monitor.exe monitor TargetAppPath, where TargetAppPath is the path to the application that you want to monitor. Here is an example that initiates monitoring of Internet Explorer.

cmd
monitor.exe addcallouts
monitor.exe monitor "C:\Program Files (x86)\Internet Explorer\iexplore.exe"

Start a logging session in TraceView

On the target computer, open TraceView.exe as Administrator. On the File menu, choose Create New Log Session. Click Add Provider. Select PDB (Debug Information File), and enter the path to your PDB file, msnmntr.pdb. Click OK, and finish working through the setup procedure. Open Internet Explorer, and watch the communication patterns being displayed in the Traceview.exe tool.

Tracing for the sample driver can be started at any time before the driver is started or while the driver is already running.

For more information on creating a Windows Filtering Platform Callout Driver, see Windows Filtering Platform Callout Drivers.

Using MSBuild

As an alternative to building the WFP MSN Messenger Monitor Sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the Tools menu, choose Visual Studio Command Prompt. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, msnmntr.sln. Use the MSBuild command to build the solution. Here are some examples:

msbuild /p:configuration="Debug" /p:platform="x64" msnmntr.sln

msbuild /p:configuration="Release" /p:platform="Win32" msnmntr.sln

For more information about using MSBuild to build a driver package, see Building a Driver Using the Command Line (MSBuild).


Overview (`network/trans/stmedit/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Windows Filtering Platform Stream Edit Sample

This sample driver demonstrates replacing a string pattern for a Transmission Control Protocol (TCP) connection using the Windows Filtering Platform (WFP).

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

The sample consists of a kernel-mode Windows Filtering Platform (WFP) callout driver (Stmedit.sys) that can operate in one of the following modes:

  • Inline editing where all modification is done within the ClassifyFn callout function.

  • Out-of-band editing where all modification is done by a worker thread (the default).

The sample performs inspection for both Internet Protocol version 4 (IPv4) and Internet Protocol version 6 (IPv6) traffic.

Before experimenting with the sample, add an exception for the InspectionPort to your host firewall.

Automatic deployment

Before you automatically deploy a driver, you must provision the target computer. For instructions, see Provision a computer for driver deployment and testing.

After you have provisioned the target computer, continue with these steps:

  1. On the host computer, in Visual Studio, in Solution Explorer, right click package (lower case), and choose Properties. Navigate to Configuration Properties > Driver Install > Deployment.

  2. Check Enable deployment, and check Remove previous driver versions before deployment. For Target Computer Name, select the name of a target computer that you provisioned previously. Select Do not install. Click OK.

  3. On the Build menu, choose Build Solution.

  4. On the target computer, navigate to DriverTest\Drivers, and locate the file stmedit.inf. Right click stmedit.inf, and choose Install.

Manual deployment

Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the DevCon tool to the target computer. For instructions, see Preparing a Computer for Manual Driver Deployment.

After you have prepared the target computer for manual deployment, continue with these steps:

  1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpStreamEditSamplePackage).

  2. On the target computer, navigate to your driver package folder. Right click stmedit.inf, and choose Install

Create Registry values

  • On the target computer, open Regedit, and navigate to this key:

    HKLM\System\CurrentControlSet\Services\strmedit\Parameters

You can create and set values for the following registry entries.

  • StringToFind (REG_SZ, default = "rainy")

  • StringX (REG_SZ, default = "cloudy")

  • StringToReplace (REG_SZ, default = "sunny")

  • InspectionLocalPort (REG_DWORD, default = 8888)

  • InspectionRemotePort (REG_DWORD, default = 0)

    [!NOTE]
    For this sample, a local or remote port is mandatory. Both cannot be zero.

  • InspectioDirection (REG_DWORD, default = 2) Possible values : 2 (inbound + outbound), 0 (FWP_DIRECTION_OUTBOUND), 1 (FWP_DIRECTION_INBOUND)

  • MultipleCallouts (REG_DWORD, default = true/1) Controls registration of multiple callouts. Set 0 for false, other for TRUE

  • BusyThreshold (REG_DWORD, default = 16KB) BusyThreshold value is in KBs (e.g. a value of 5 means 5KB)

Start the stmedit service

On the target computer, open a Command Prompt window as Administrator, and enter net start stmedit. (To stop the driver, enter net stop stmedit.)

Remarks

For more information on creating a Windows Filtering Platform Callout Driver, see Windows Filtering Platform Callout Drivers.


Overview (`network/wlan/WDI/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

WDI samples

This sample demonstrates use of the WLAN WDI.


Overview (`network/wlan/ihvsampleui/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

IHV Sample UI

This sample demonstrates the WLAN IHV UI.


Overview (`network/wlan/wificx/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

WIFICX and NetAdapterCx Samples

This sample illustrates how to leverage WIFICX for control flow and NetAdapterCx for data flow. It supports both KMDF and UMDF(In Preview Stage) drivers.

How to Build

  1. Mount the EWDK ISO from a local drive (network share paths are not supported).
  2. Run LaunchBuildEnv.cmd.
  3. In the environment created in step 2, type SetupVSEnv and press Enter.
  4. Navigate to the current folder and open the solution file, for example:
    X:\Windows-driver-samples\network\wlan\WIFICX\wificxsampleclient.sln
  5. Build the solution from the Visual Studio UI.

Interfaces and Abstraction

The sample interacts with three OS components:

  • WDF
    driver.cpp, device.cpp, and adapter.cpp demonstrate proper registration for PnP and power event callbacks. WDF manages system PnP and power requests (e.g., power IRPs), so IHV drivers should follow the flow triggered through these callbacks.

  • WDF Wi-Fi Class Extension (WIFICX)
    wifixxxxx.cpp files implement the control path, handling commands sent to Wi-Fi firmware (e.g., scan access points, connect, disconnect).

  • WDF NetAdapter Class Extension (NetAdapterCx)
    netvxxxx files and classes implement the data path, managing network buffers and synchronizing with the control path for transfer start/stop operations.

Data Buffers from Firmware

The control path uses hardcoded data since this sample does not target real hardware. The data path uses Emulated Network Link (ENL), which connects two virtual network adapters directly. Packets sent over one adapter are delivered to the other and vice versa.

Supported Scenarios

  • Scan access points and report BSS entries to the Windows UI.
  • Connect to an open access point from the Windows UI.
  • Disconnect from the connected access point.
  • Transfer data between two Wi-Fi device instances (e.g., ping and throughput test).

🎥 Control & Data Path Demo Video

A walkthrough video demonstrating the Control & Data Path flow are available here:

▶ Watch Control Path Demo

▶ Watch Data Path Demo


Overview (`network/wsk/echosrv/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

WSK TCP Echo Server

This sample driver is a minimal driver meant to demonstrate the usage of the Winsock Kernel (WSK) programming interface.

The sample implements a simple kernel-mode application by using the Winsock Kernel (WSK) programming interface. The application accepts incoming TCP connection requests on port 40007 over both IPv4 and IPv6 and, on each connection, it echoes all received data back to the peer until the connection is closed by the peer. The application is designed to use a single worker thread to perform all of its processing. For better performance on a multi-processor computer, the sample can be enhanced to use more worker threads. This sample is designed such that operations on a given connection should always be processed by the same worker thread. This provides a simple form of synchronization that ensures proper socket closure in a setting where multiple operations might be outstanding and completed asynchronously on a given connection. For the sake of simplicity, this sample does not enforce any limit on the number of connections accepted (other than the natural limit imposed by the available system memory) or on the amount of time that a connection stays alive. A production server application should be designed with these security points in mind.

This sample is not intended for use in a production environment.

WPP SOFTWARE TRACING

This sample driver uses WPP Software Tracing in order to log its actions. You can find detailed information on WPP Software Tracing in the WDK documentation. Here is a quick overview of one way to collect trace logs from the sample driver by using the tracing tools that are available in the \tools\tracing directory in the WDK. All code for this sample is located in \network\WSK\echosrv directory.

  1. In a Command Prompt window, copy Echosrv.ctl and Echosrv.pdb into a directory and change to that directory (cd).

  2. Start software tracing for the sample driver by typing the following command:

    tracelog -start echosrvtrace -guid echosrv.ctl -f logfile.etl -flags 0x3

    The value that is provided for the -flags option determines which events will be logged by the sample driver. The sample currently has two event types denoted by the TRCERROR and TRCINFO macros where TRCERROR is 0x1 and TRCINFO is 0x2. Thus, a flag value of 0x3 (0x1 combined in a bitwise OR with 0x2) in the previous tracelog command tells the sample driver to log both TRCERROR and TRCINFO events.

  3. In order to stop tracing, type the following command:

    tracelog -stop echosrvtrace

  4. Convert the trace logs in Logfile.etl into a human-readable format by typing the following command:

    tracefmt -o logfile.txt -f logfile.etl -r . -i \full-path\ echosrv.sys

    where \full-path\ is the directory that contains the Echosrv.sys file.

  5. Open Logfile.txt to view the trace logs.

Be aware that tracing for the sample driver can be started at any time before the driver is started or while the driver is already running.

To run the sample

Install and run this sample driver by using the following steps:

  1. Copy the Echosrv.sys file to a directory on the test machine.

  2. In a Command Prompt window, type the following command:

    sc create echosrv type= kernel binpath= \full-path\ echosrv.sys

    where \full-path\ is the directory that contains the Echosrv.sys file.

  3. To start the driver, type:

    sc start echosrv

  4. To stop the driver, type:

    sc stop echosrv

After the driver is installed and started, it will listen for incoming TCP connection requests on port 40007 over both IPv4 and IPv6 protocols until the driver is stopped. On each connection, the driver will echo all the received data back to the peer until the connection is closed by the peer.

For more information on the usage of the Winsock Kernel (WSK) programming interface, see Winsock Kernel.


Overview (`network/wwan/cxwmbclass/README.md`)


page_type: sample
languages:

  • c
    products:
  • windows
  • windows-wdk

cxwmbclass samples

This sample demonstrates use of the cxwmbclass.


Overview (`pos/drivers/MagneticStripeReader/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Magnetic Stripe Reader Driver Sample

This sample serves as a template for creating a new Magnetic Stripe Reader driver.

This sample uses UMDF 2.0 and enables basic functionality such as claiming and enabling the device for exclusive access.

It serves as an example of how to include the libraries necessary to develop a PointOfService driver. Once a driver is developed using this template it can be compiled for, deployed, and used on x86, amd64, and ARM platforms.


Overview (`pos/drivers/barcodescanner/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Barcode Scanner Driver Sample

This sample serves as a template for creating a new Barcode Scanner driver.

This sample uses UMDF 2.0 and enables basic functionality such as claiming and enabling the device for exclusive access.

It serves as an example of how to include the libraries necessary to develop a PointOfService driver. Once a driver is developed using this template it can be compiled for, deployed, and used on x86, amd64, and ARM platforms.


Overview (`sd/miniport/sdhc/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Standard SD Host Controller Miniport

This is a sample for a Secure Digital (SD) Host Controller miniport driver. The driver works in conjunction with sdport.sys, which implements SD/SDIO/eMMC protocol and WDM interfaces, to provide the host register interface.

Universal Compliant

This sample builds a Windows Universal driver. It uses only APIs and DDIs that are included in Windows Core.

This driver, sdhc.sys, provides a functional miniport implementation for a standard SD host controller.

However, it does not have support for many more recent features such as:

  • UHS-I speed modes.

  • HS400

  • SD 4.0


Overview (`storage/class/classpnp/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

ClassPnP Storage Class Driver Library

This is the library for all storage drivers. It simplifies writing a storage class driver by implementing 90 percent of the code that you need to support Plug and Play (PnP), power management, and so on. This library is used by disk, CDROM, and the tape class drivers.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Installation and Operation

The storage class drivers are used to interact with mass storage devices along with appropriate port driver. The class drivers are layered above the port drivers and manage mass storage devices of a specific class, regardless of their bus type. The classpnp sample contains the common routines that are required for all storage class drivers such as PnP and power management. It also provides I/O and error handling support.

For more information, see Introduction to Storage Class Drivers in the storage technologies design guide.


Overview (`storage/class/disk/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

Disk Class Driver

The disk class driver sample is used for managing disk devices

You can build the sample in two ways: using Microsoft Visual Studio or the command line (MSBuild).

Building a Driver Using Visual Studio

You build a driver the same way you build any project or solution in Visual Studio. When you create a new driver project using a Windows driver template, the template defines a default (active) project configuration and a default (active) solution build configuration. When you create a project from existing driver sources or convert existing driver code that was built with previous versions of the WDK, the conversion process preserves the target version information (operating systems and platform).

The default Solution build configuration is Debug and Win32.

  1. Open the driver project or solution in Visual Studio (find samplename.sln or samplename.vcxproj).

  2. Right-click the solution in the Solutions Explorer and select Configuration Manager.

  3. From the Configuration Manager, select the Active Solution Configuration (for example, Debug or Release) and the Active Solution Platform (for example, Win32) that correspond to the type of build you are interested in.

  4. From the Build menu, click Build Solution (Ctrl+Shift+B).

Building a Driver Using the Command Line (MSBuild)

You can build a driver from the command line using the Visual Studio Command Prompt window and the Microsoft Build Engine (MSBuild.exe) Previous versions of the WDK used the Windows Build utility (Build.exe) and provided separate build environment windows for each of the supported build configurations. You can now use the Visual Studio Command Prompt window for all build configurations.

  1. Open a Visual Studio Command Prompt window at the Start screen. From this window you can use MsBuild.exe to build any Visual Studio project by specifying the project (.VcxProj) or solutions (.Sln) file.

  2. Navigate to the project directory and enter the MSbuild command for your target. For example, to perform a clean build of a Visual Studio driver project called filtername.vcxproj, navigate to the project directory and enter the following MSBuild command:

    msbuild /t:clean /t:build .\<samplename>.vcxproj

Installation and Operation

The disk class driver is used to interact with disk devices along with the appropriate port driver. The disk class driver is layered above the port driver and manages disk devices regardless of their bus type. This driver attaches to the disk devices that are enumerated by all of the storage port drivers. This driver exposes the required functionality to the file system drivers to access the disk devices.

For more information, see Introduction to Storage Class Drivers in the storage technologies design guide.


Overview (`storage/miniports/lsi_u3/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

LSI\_U3 StorPort Miniport Driver

The LSI_U3 sample is an adapter driver for use with Parallel SCSI Host Bus Adapters or on-motherboard solutions that use the LSI 53C1010 SCSI ASIC.

These sources are presented for your education and use with these generally available LSI SCSI-class adapters. The intended use of this sample driver is for this purpose only.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.

Installation and Operation

The operation of this sample requires one of the following hardware items:

  • Parallel SCSI Host Bus Adapter

  • On-motherboard solution that uses the LSI 53C1010 SCSI ASIC

For more information, see Storport Miniport Drivers in the storage technologies design guide.


Overview (`storage/miniports/storahci/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

StorAhci StorPort Miniport Driver

The StorAhci sample is a Storport ACHI miniport driver.

Universal Windows Driver Compliant

This sample builds a Universal Windows Driver. It uses only APIs and DDIs that are included in OneCoreUAP.


Overview (`storage/tools/spti/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

SCSI Pass-Through Interface Tool

The SCSI Pass Through Interface sample demonstrates how to communicate with a SCSI device from Microsoft Win32 applications by using the DeviceIoControl API.

Installation and Operation

The storage port drivers provide an interface for Win32 applications to send SCSI CBDs (Command Descriptor Block) to SCSI devices. The interfaces are IOCTL_SCSI_PASS_THROUGH and IOCTL_SCSI_PASS_THROUGH_DIRECT. Applications can build a pass-through request and send it to the device by using this IOCTL.

Two command line parameters can be used with SPTI.EXE. The first parameter is mandatory. It is the name of the device to be opened. Typical values for this are drive letters such as "C:", or device names as defined by a class driver such as Scanner0, or the SCSI port driver name, ScsiN:, where N = 0, 1, 2, etc. The second parameter is optional and is used to set the share mode (note that access mode and share mode are different things) and sector size. The default share mode is (FILE_SHARE_READ | FILE_SHARE_WRITE) and the default sector size is 512. A parameter of "r" changes the share mode to only FILE_SHARE_READ. A parameter of "w" changes the share mode to only FILE_SHARE_WRITE. A parameter of "c" changes the share mode to only FILE_SHARE_READ and also changes the sector size to 2048. Typically, a CD-ROM device would use the "c" parameter.


Overview (`video/archive/pixlib/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk

PixLib sample

The PixLib sample demonstrates how to implement the CPixel class for use by a display driver.

For more information, see the WDK documentation topic, CPixel Support Methods for Lightweight MIP Maps.


Overview (`audio/SoundWire/Samples/SdcaVad/README.md`)


page_type: sample
languages:

  • cpp
    products:
  • windows
  • windows-wdk
    urlFragment: sdcavad

SDCA Virtual Audio Device Driver Sample

Introduction

The Microsoft SDCA Virtual Audio Device Driver (SdcaVad) shows how to develop ACX/SDCA audio drivers that expose support for SDCA audio devices.

The following table shows the features that are implemented in the various subdirectories of this sample.

Directory Description
SdcaVCodec SDCA Virual Codec Driver.
SdcaVDsp SDCA Virual DSP Driver.
SdcaVXu SDCA Virtual XU Driver.
Apo\kws Sample APO that uses KSPROPERTY_INTERLEAVEDAUDIO_FORMATINFORMATION to determine if the keyword spotter pin is interleaving loopback audio with the microphone audio and identify which channels contain loopback audio. If it is interleaved the APO will strip out the loopback audio and deliver only the microphone audio upstream. Because channel data is removed, the APO negotiates an output format which is different than the input format.
EventDetectorAdapter Sample Event Detector Adapter.

Build the sample

If you simply want to build this sample driver and don't intend to run or test it, then you do not need a target computer (also called a test computer). If, however, you would like to deploy, run and test this sample driver, then you need a second computer that will serve as your target computer. Instructions are provided in the Run the sample section to show you how to set up the target computer - also referred to as provisioning a target computer.

Perform the following steps to build this sample driver.

1. Open the driver solution in Visual Studio

In Microsoft Visual Studio, Click File > Open > Project/Solution... and navigate to the folder that contains the sample files (for example, C:\Windows-driver-samples\audio\sdcavad). Double-click the sdcavad solution file.

In Visual Studio locate the Solution Explorer. (If this is not already open, choose Solution Explorer from the View menu.) In Solution Explorer, you can see one solution that has six projects.

2. Set the sample's configuration and platform

In Solution Explorer, right-click Solution 'sdcavad' (6 of 6 projects), and choose Configuration Manager. Make sure that the configuration and platform settings are the same for the six projects. Set the configuration to Debug, and the platform to x64 for all the projects. If you make any configuration and/or platform changes for one project, you must make the same changes for all the remaining projects.

3. Build the sample using Visual Studio

In Visual Studio, click Build > Build Solution.

4. Locate the built driver package

In File Explorer, navigate to the folder that contains the sample files. For example, you would navigate to C:\Windows-driver-samples\audio\sdcavad, if that's the folder you specified in the preceding Step 1.

In the folder, the location of the driver package varies depending on the configuration and platform settings that you selected in the Configuration Manager. For example, if you set Debug and x64, then the built driver package will be saved to a folder named Debug inside a folder named x64. Double-click the folder for the built driver package, and then double-click the folder named package.

The package should contain these files:

File Description
SdcaVCodec.sys The SDCA Virtual Codec Driver file.
SdcaVCodec.inf A information(INF) file that contians information needed to install the SDCA Virtual Codec Driver.
SdcaVDsp.sys The SDCA Virtual DSP Driver file.
SdcaVDsp.inf A information(INF) file that contians information needed to install the SDCA Virtual DSP Driver.
SdcaVXu.sys The SDCA Virtual XU Driver file.
SdcaVXu.inf A information(INF) file that contians information needed to install the SDCA Virtual XU Driver.
EventDetectorContosoAdapter.dll Sample Event detector adapter.
SdcaVKwsApo.dll The KWS APO.
SdcaVApo.inf A information (INF) file that installs an APO device.
sdcavad.cat A signed catalog file, which serves as the signature for the entire package.

Run the sample

The computer where you install the driver is called the target computer or the test computer. Typically this is a separate computer from the computer on which you develop and build the driver package. The computer where you develop and build the driver is called the host computer.

The process of moving the driver package to the target computer and installing the driver is called deploying the driver. You can deploy the SDCA sample driver automatically or manually.

Prepare the target computer

First of all, install the latest Windows Driver Kit (WDK) on the target computer, minimum version required for the WDK is 25926, which corresponds to the canary channel.

Before you manually deploy a driver, you must prepare the target computer by turning on test signing and by installing a certificate. You also need to locate the DevCon tool in your WDK installation. After that you're ready to run the built driver sample.

Open a Command Prompt window as Administrator. Then enter the following command:

bcdedit /set TESTSIGNING ON

and reboot the target computer.

[!IMPORTANT]
Before using BCDEdit to change boot information you may need to temporarily suspend Windows security features such as BitLocker and Secure Boot on the test PC.

Re-enable these security features when testing is complete and appropriately manage the test PC, when the security features are disabled.

After rebooting, navigate to the Tools folder in your WDK installation and locate the DevCon tool. For example, look in the following folder:

C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe

Copy devcon.exe to a folder on the target computer where it is easier to find. For example, create a C:\Tools folder and copy devcon.exe to that folder.

Create a folder on the target for the built driver package (for example, C:\SdcaVad). Copy all the files from the built driver package on the host computer to the folder that you created on the target computer.

Create a folder on the target computer for the certificate created by the build process. For example, you could create a folder named C:\Certificates on the target computer, and then copy package.cer to it from the host computer. You can find this certificate in the same folder on the host computer, as the package folder that contains the built driver files. On the target computer, right-click the certificate file, and click Install, then follow the prompts to install the test certificate.

If you need more detailed instructions for setting up the target computer, see Preparing a Computer for Manual Driver Deployment.

A note on signatures

Since most of these binary files are executed in kernel mode, it is important that they are signed and, optionally, to have a kernel debugger attached.

Without any signature or kernel debugger, the driver will not be installed in the target computer. With a kernel debugger attached, the driver can be installed and the driver files (.sys extension) would be loaded, but any user mode files (.dll files) will not be loaded.

The only way of installing and executing the whole driver sample is to have all the files (.sys, .dll and .cat) signed with a trusted certificate. This will allow the entire driver to be loaded even without a kernel debugger attached.

For more information on the subject, see Driver signing.

Install the driver

Single INF files

Each sample driver contains an INF file, which will install the sample driver.

On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter the following command:

devcon install SdcaVDsp.inf SOUNDWIRETEST\DSP
devcon install SdcaVCodec.inf Root\SDCAVCodec

Then, the XU INF (SdcaVXu.inf) and the APO INF (SdcaVApo.inf) can be installed - right-click the INF file and select Install to install it.

After successfully installing the sample drivers, you're now ready to test it.

Test the driver

On the target computer, in a Command Prompt window, enter devmgmt.msc to open Device Manager. In Device Manager, on the View menu, choose Devices by type. In the device tree, locate SDCA Virtual Dsp Audio Driver. This is typically under the Sound, video and game controllers node.

On the target computer, open Control Panel and navigate to Hardware and Sound > Manage audio devices. In the Sound dialog box, select the speaker icon labeled as SDCA Virtual Codec Audio Driver, then click Set Default, but do not click OK. This will keep the Sound dialog box open.

Locate an MP3 or other audio file on the target computer and double-click to play it. Then in the Sound dialog box, verify that there is activity in the volume level indicator associated with the SDCA Virtual Codec Audio Driver driver.

HLK testing

The sample uploaded here is tested using the latest HLK version available to make sure it passes all audio tests in the current playlist. However, since it is a virtual audio driver it does not implement audio mixing and simulates capture and loopback by generating a tone. Given these limitations, there are some HLK tests that are expected to fail because they rely on the described functionality.

In the case of audio tests, one of these exceptions is the Hardware Offload of Audio Processing Test. This test is aimed at devices that support offload capabilities and performs checks to make sure that the device complies with the appropiate requirements. In the particular case of SdcaVad, this test will fail for endpoints with offload and loopback.

For endpoints with offload, the test will fail because the driver includes offload pins but it does not implement a mixer with volume, mute and peak meter nodes, etc. For the case of endpoints with loopback, the test will fail because the driver simulates loopback by returning a sine tone instead of performing real mixing of streams in host and/or offload pins.

Besides, the current version of SdcaVad also failed the General Audio Test and the Device Po