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.
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):
cmdwpr -start GnssUmdfSampleDriver.wprp -filemode <Reproduce the issue> wpr -stop MyLog.etlInspect 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.
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
Getting started with Windows drivers
Windows Driver Kit 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.
Related topics
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
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.
Right-click the solution in the Solution Explorer and select Configuration Manager.
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.
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)
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.
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.
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.exeneeded for PowerShell scripting via network.- Note: PuTTY terminal client GUI does not appear to work, so Tera Term client was used instead, but
Plink.exeis 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.
- If the PDU is not connected to a network with DHCP, then its default static IP address should be
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), theUSB 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
@Password123to match what thepdu.ps1PowerShell script uses.
- Default login is:
- Once logged in, type
show networkto 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
- IPv4:
- 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 LXweb 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
@Password123to match what thepdu.ps1PowerShell script uses.
- Default login is:
- Select
Loadtab on the left of screen to see all the loads on the 16 power ports. - Click on the
Stateslider to show the Load options,Turn Off LoadandCycle Load. - To enable SSH for PowerShell scripting later, select
Networktab, thenServices, then enableSSH Enabled.
Scripting
- The
Pdu.ps1PowerShell 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.ps1script 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
- Eaton Tripp Lite Switched PDU (PDUMH15NET): Manuals & User Guides
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:
In the Action menu, click Add Legacy Hardware, and the Add Hardware Wizard appears. Click Next and then Next again.
In the Add Hardware window, select Show All Devices.
In the Manufacturer list in the left pane, click Microsoft.
You should see the AVStream Simulated Hardware Sample in the Model pane on the right. Click this and then click Next.
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:
After installation has completed, access the driver through the Graphedt tool. Graphedt.exe is available in the tools directory of the WDK.
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.
On the command line, type regsvr32 proppage.dll. If the registration succeeds, you'll get a message, "DllRegisterServer in proppage.dll succeeded." Click OK.
In the Graphedt tool, click the Graph menu and click Insert Filters. The sample appears under "WDM Streaming Capture Devices" as "avshws Source."
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.
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
Copy AVssamp.inf to a directory, for example, C:\Avstream\.
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\.
Copy the processor-appropriate Avssamp.sys file to the objfre_* directory.
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.
Related topics
Concepts
Streaming media device driver design guide
Universal camera driver design guide for Windows 10
Samples
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.
Related topics
Concepts
Streaming media device driver design guide
Universal camera driver design guide for Windows 10
Samples
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):
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_0006Please 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
Open Visual Studio. From the File menu, select Open Project/Solution and open the bthecho.sln project file.
Right-click the solution in the Solution Explorer and select Configuration Manager.
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.
From the Build menu, click Build Solution (Ctrl+Shift+B).
Building the sample using the command line (MSBuild)
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.
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.
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
Copy BthEchoSampleSrv.Sys, BthEchoSampleSrv.inf and bthsrvinst.exe on a temporary directory on the target machine.
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).
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.
- 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.)
/* 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.
Copy BthEchoSampleCli.Sys, BthEchoSampleCli.inf and bthecho.exe on a temporary directory on the target machine.
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.
In the Bluetooth Devices window, click the Add a device button.
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'.
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.
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
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'
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:
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
^CYou 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:
ConnectFailed
^
|
|
| (connection failure)
Uninitialized ----> Connecting -------> Connected
| (disconnect) / ^
| / /
| / /
V V / (connection complete)
Disconnecting
| (disconnect complete)
|
|
V
DisconnectedOne 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
Open the driver project or solution in Visual Studio (find fastfat.sln or fastfat.vcxproj).
Right-click the solution in the Solutions Explorer and select Configuration Manager.
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.
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
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.
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 ofosrfx2_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_baseosrfx2_DCHU_extensionosrfx2_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
Build the solution.
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, andSimpleMediaSourceDriver.inf.Deploy the driver package with the following command:
devgen /add /bus ROOT /hardwareid root\SimpleMediaSource
pnputil /add-driver SimpleMediaSourceDriver.inf /installVerify 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 /driversOpen 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]
TheNumberOfThreadscommand-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:
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:
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
---------------------
| |
| 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.
Related topics
Human Input Devices Design Guide
Related technologies
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:
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.
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:
Open gpedit.msd.
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.
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.
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.
You may need to reboot.
Bring up the Device Manager (type devmgmt.msc in the Start/Run window and press enter).
Find the Microsoft Optical mouse under "Mice and other pointing devices"
Right click on the device and choose "Update Driver Software."
Select "Browse my computer for driver software."
Browse to the temporary folder you created earlier. Click Next. Click through the warning.
You will see "Windows has successfully updated your driver software" for the "Shiny Things Firefly Mouse" device.
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:
Copy the sauron.dll to the Windows Media player Visualization directory (C:\Program Files\Windows Media Player\Visualizations).
Register the DLL with COM by calling "regsvr32 sauron.dll" in command shell.
Run Windows Media Player as administrator.
Click on the "Switch to Now Playing" button in the lower right of the application.
Right click, select Visualizations, and you will see a menu item called "Sauron."
Choose either Firefly Bars or Firefly Flash and play some music.
You will see the mouse light dancing to the tune of the music.
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.
Related topics
Human Input Devices Design Guide
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.
Related topics
Human Input Devices Design Guide
Related technologies
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 | 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:
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.Plug in the device and follow these steps:
Launch Device Manager by executing command devmgmt.msc in a command window, or from the Hardware and Sound program group in Control Panel.
Select OSR USB-FX2 device from Other Devices category and select Update Driver Software... from the right-click menu.
Select Browse my computer for software and provide the location of the driver files.
Select Install this driver software anyway when the Windows Security dialog box appears.
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
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.
From the HID Device to examine menu, select the device that contains "UsagePage 0ff00, Usage 01" as a substring.
Click Modify Features. The Feature Data dialog box opens.
Click Modify Features. The Modify features dialog box opens.
In the input box, type 7 and click Send to Device. You'll see number 7 appear in the 7-segment display.
Type any number from 1-8, and you'll see the respective number displayed in the 7-segment display.
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
/* 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.
Related topics
Human Input Devices Design Guide
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.
; For XP and above
[DDK_Ex.Mfg.NT$ARCH$]
;%DDK_Ex% = kbfiltr, *PNP0BAAD
%DDK_Ex% = kbfiltr, ACPI\VEN_PNP&DEV_0303Build 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.
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.
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.
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\KbfiltrDriverPackage).
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
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.
Right-click the solution in the Solution Explorer and select Configuration Manager.
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.
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)
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.
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.
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
-
DriverEntry- Driver initialization.
-
DeviceContext::AddDevice- Device initialization, including initializing the NFC CX driver.DeviceContext::WriteNciPacket- The implementation of theEvtNfcCxWriteNciPacketcallback function.DeviceContext::ReadNciPacket- Demonstrates callingNfcCxNciReadNotification.
-
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
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.
Related technologies
KMDF Power Framework (PoFx) Sample.
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:
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.
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.
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:
Copy all of the files in your driver package to a folder on the target computer (for example, c:\PoFx).
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.
Related technologies
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.
Obtain the devcon.exe tool from the WDK
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.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.
Obtain the devcon.exe tool from the WDK
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.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:
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.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.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
Copy the signed elamsample.sys file to the %WINDIR%\System32\Drivers directory on your test machine.
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-LaunchEnable 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:
/* 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:
This sample does not support multi-function serial devices.
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.
; 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 PortOverview (`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
Open Visual Studio. From the File menu, select Open Project/Solution. Navigate to the DevCon sample folder and open the devcon.sln project file.
Right-click the solution in the Solution Explorer and select Configuration Manager.
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.
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)
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.
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.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
- This command demonstrates the use of SetupDiBuildClassInfoListEx to enumerate all device class GUIDs. The function SetupDiClassNameFromGuidEx and SetupDiGetClassDescriptionEx are used to obtain more information about each device class.
cmdListClass
- This command demonstrates the use of SetupDiClassGuidsFromNameEx to enumerate one or more class GUIDs that match the class name. This command also demonstrates the use of SetupDiGetClassDevsEx to list all the devices for each class GUID.
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
- Shows how to get the complete list of hardware ID's or compatible ID's for a device using SetupDiGetDeviceRegistryProperty.
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:
Ensure that the driver builds without errors.
Copy the SYS and INF files to a separate folder.
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:
Navigate to the directory that contains SpbTestTool.exe.
Type the following command in the command window:
SpbTestTool.exeBy 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>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.
Open the driver project or solution in Visual Studio (find samplename.sln or samplename.vcxproj).
Right-click the solution in the Solutions Explorer and select Configuration Manager.
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.
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.
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.
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.
;
; 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:
[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_mfgSubstitute all instances of "gendsm" with the proper name for your DSM. For example, "mydsm":
[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_addregThis 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:
;
; 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:
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:
/* Detailed source-code truncated for AI context efficiency. */Finally, modify the following strings:
[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:
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 = 0x00030003You should be aware of the following when you install the MPIO DSM sample:
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.
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
- Contains the implementations EVT_UCM_CONNECTOR_SET_DATA_ROLE and EVT_UCM_CONNECTOR_SET_POWER_ROLE. These are callbacks from UCM which ask the client driver to perform role swaps.
UcmNotifications.cpp
- Contains methods that communicate with UcmCx using the client driver support methods described in the USB Type-C connector driver programming reference.
Fdo.cpp
- FDO callbacks, functions, and types, most of which do not interface with UCM. However, the method
Fdo_EvtDeviceSelfManagedIoInitcontains the code segment which initializes the device with UCM.
- FDO callbacks, functions, and types, most of which do not interface with UCM. However, the method
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:
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 ClientSampleTraceOther 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)
Windows 10 IoT Core Insider Preview
Windows for Internet of Things
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:
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.
Plug in the OSR USB-FX-2 Learning Kit (must be version 2.00 or later).
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.
After the driver installs, verify that the device appears under the Sample Device node in Device Manager.
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.
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&08The 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:
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 64The preceding command reads 64 bytes to the bulk IN endpoint.
osrusbfx2.exe -w 64The preceding command writes 64 bytes to the bulk OUT endpoint.
osrusbfx2.exe -r 64 -w 64 -c 100 -vThe 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 -aThe 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:
/* 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
Start tracing by using the following command:
logman start sample -o osrusbfx2.etl -ets -p OSRUSBFX2Generate activity through the osrusbfx2 test application, such as
osrusbfx2.exe -a.Stop tracing by using the following command:
Logman stop sampleView the trace file using tracerpt:
tracerpt -of csv OSRUSBFX2.etl
To start/stop the trace by using Xperf (Windows Performance Toolkit)
Start tracing by using the following command:
xperf -start sample -f osrusbfx2.etl -on OSRUSBFX2Generate activity through the osrusbfx2 test application, such as
osrusbfx2.exe -a.Stop tracing by using the following command:
xperf -stop sampleView 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.
Related technologies
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).
Plug in the OSR USB-FX2 board to the target computer.
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.
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.
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\umdf2_fx2).
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.
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:
- OSR FX2 learning kit. You can get the kit from OSR Online. For more information, see the specification for the OSR USB FX-2 Learning Kit
- MUTT devices. To order those devices, see How to get MUTT devices.
- Intel 82930 USB test board.
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).
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.
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.
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\Usbsamp).
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:
`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,
In Visual Studio, choose Solution Explorer from the View menu. Locate the application project named usbsamp, under the Exe folder.
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.
Run the executable on the target machine.
To view all descriptors and endpoint information, use the following command.
usbsamp.exe -uYou 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 -vThe 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 65536The preceding command reads 65536 bytes from pipe 0.
usbsamp.exe -w 65536The preceding command writes 65536 bytes to pipe 1.
usbsamp.exe -r 65536 -i pipe02The preceding command reads 65536 bytes from pipe 2.
usbsamp.exe -w 65536 -o pipe03The 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 pipe04The preceding command reads 512 bytes from pipe 4.
usbsamp.exe -w 512 -o pipe05The preceding command writes 512 bytes to pipe 5.
usbsamp.exe -w 1024 -o pipe05 -r 1024 -i pipe04 -c 100 -vThe 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
Change Debugger to launch to Local Windows Debugger.
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,
Copy the executable to a folder on the remote computer.
Specify project properties as per the instructions given in Remote Debugging.
Change Debugger to launch to Remote Windows Debugger.
On the Debug menu, select Start debugging or hit F5.
View a USB device in Usbview
Attach a USB device to one of USB ports on the computer that has Usbview running.
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.
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:
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.
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.
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
Open the driver project or solution in Visual Studio 2013 (find filtername.sln or filtername.vcxproj).
Right-click the solution in the Solutions Explorer and select Configuration Manager.
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.
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.
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:
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 64The preceding command reads 64 bytes to the bulk IN endpoint.
osrusbfx2.exe -w 64The preceding command writes 64 bytes to the bulk OUT endpoint.
osrusbfx2.exe -r 64 -w 64 -c 100 -vThe 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 -aThe 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:
/* Detailed source-code truncated for AI context efficiency. */If the device is operating in low speed mode, you will get the following information:
/* 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
Direct3DDeviceclass- 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.
SwapChainProcessorclass- 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.
IndirectDeviceContextclass- Processes device callbacks from IddCx.
- Manages the creation and arrival of the sample monitor.
- Handles swap-chain arrival and departure by creating a
Direct3DDeviceand handing it off to aSwapChainProcessor.
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.
Add the following files to the directory given by ...\[x64]\C++\Package:
SampleDriver.cat
SampleDriver.inf
SampleDriver.sys
SampleDriver.cer
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.cerThen 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.
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:
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_0003This 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:
Include the contents of Device.asl to your ASL source and rebuild the DSDT. Update the operating system with the new DSDT through reflashing.
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.
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.
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
Open the driver project or solution in Visual Studio (find filtername.sln or filtername.vcxproj).
Right-click the solution in the Solutions Explorer and select Configuration Manager.
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.
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
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.
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:
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.In Windows Explorer, right-click filtername.inf, and click Install.
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:
- 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.
- 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.
- 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.
- 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.
Related technologies
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.
Related technologies
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.
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.
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.
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\umdf2echoPkg).
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:
Does some setup work.
Registers the callback routine.
Performs one or more registry operations.
Unregisters the callback routine.
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).
Related technologies
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.
In the Properties for the package project, navigate to Common Properties > References.
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.
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.
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.
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.
On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WdfSimplePackage).
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).
Related technologies
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.
In the Properties for the package project, navigate to Common Properties > References.
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.
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.
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.
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.
On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WdfSimplePackage).
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.
Related technologies
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.
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.
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.
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.
On the Build menu, choose Build Solution or Rebuild Solution (if you removed references).
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.
Copy all of the files in your driver package to a folder on the target computer (for example, c:\Umdf2toaster).
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
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.xmlInstalling 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.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.
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.etlTo 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.
To stop the trace session, run the following command:
tracelog -stop TestEventdrvTo display the traces collected in the Tracedrv.etl file, run the following command:
tracerpt Eventdrv.etlThis command creates two files: Summary.txt and Dumpfile.xml. Dumpfile.xml will contain the event information in an XML format.
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.
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).
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
- 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.
d58c126f-b309-11d1-969e-0000f875a5bc- 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.
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.
To stop the trace session, use the following Tracelog command.
tracelog -stop TestTracedrv
- 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:
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.
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.
On the Build menu, choose Build Solution.
On the target computer, open Control Panel. 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. If you have previously installed this sample, highlight it in the list.
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.Click Have Disk.
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:
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
Open Control Panel.
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.
If you have previously installed this sample, highlight it in the list.
Click Install, then Service, then Add, then Have Disk.
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:
NDISLWF: ===>DriverEntry...
NDISLWF: ===>FilterRegisterOptions
NDISLWF: <===FilterRegisterOptions
NDISLWF: ==>FilterRegisterDevice
NDISLWF: <==FilterRegisterDevice: 0
NDISLWF: <===DriverEntry, Status = 0
NDISLWF: ===>FilterAttach: NdisFilterHandle FFFFE00000F73650
NDISLWF: <===FilterAttach: Status 0What the Ndislwf sample driver does
During DriverEntry, the ndislwf driver registers as an NDIS 6 filter driver.
Later on, NDIS calls Ndislwf's FilterAttach handler, for each underlying NDIS adapter on which it is configured to attach.
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
NdisXxxfunctions.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.
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.
All indications arriving from an underlying NDIS driver are forwarded up by Ndislwf filter driver.
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.
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:
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).
On the desktop, right-click the My Network Places icon and choose Properties.
Right-click on the relevant Local Area Connection icon and choose Properties.
Click Install, then Protocol, then Add, then Have Disk.
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.
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:
NDIS_DEVICE_POWER_STATE MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
NDIS_DEVICE_POWER_STATE MinPatternWakeUp= NdisDeviceStateUnspecified;
NDIS_DEVICE_POWER_STATE MinLinkChangeWakeUp=NdisDeviceStateUnspecifiedSee 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:
Creates only one virtual miniport for every physical adapter the MUX protocol edge binds to.
Disables the property page to prevent adding of additional virtual miniports.
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:
Change the protocol name in file \ndis\passthru\passthru.c from PASSTHRU to MUXP.
Change the driver name from Passthru to MUX in the sources file.
Rebuild the driver to obtain a mux.sys driver binary.
Build the MUX notify object with PASSTHRU_NOTIFY defined.
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.
Related technologies
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.
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.
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.In Control Panel, in the Network and Internet group, open Network Connections, select an adapter, and then open Properties.
Click Install, and then click Protocol.
Click Add, and then click Have disk.
Point to the location of the INF file and driver, click Sample NDIS Protocol Driver, and then click OK.
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 -?.
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:
C:\prot>prottest -e
0. \DEVICE\{9273DA7D-5275-4B9A-AC56-68A49D121F1F}
- Intel-Based 10/100 Ethernet CardThe 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).
C:\prot>prottest -n 2 \DEVICE\{9273DA7D-5275-4B9A-AC56-68A49D121F1F}
DoWriteProc: finished sending 2 packets of 100 bytes each
DoReadProc finished: read 2 packetsFor 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'sUmdfLibraryVersion = 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:
build.cmd :: Debug x64 (defaults)
build.cmd Release x64A plain
msbuild netvadapter.slnor a Visual Studio IDE build will fail to link with an
unresolvedWdfFunctions_02035symbol, 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):
:: 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.catInstalling
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 withdevcon:
.\devcon.exe install .\netvadapterum.inf root\netvadapterumIf the command fails, inspect the device‑install log at:
C:\Windows\INF\setupapi.dev.logPairing two adapters
A working link requires two netvadapter instances. Create both by running the install
command twice:
.\devcon.exe install .\netvadapterum.inf root\netvadapterum
.\devcon.exe install .\netvadapterum.inf root\netvadapterumThen set the MACLastByte advanced keyword to 1 and 2 on both adapters via Device Manager → adapter → Advanced, or the network adapter
property pages.
⚠️
MACLastBytedefaults 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 as1and2for the pair to link correctly.
Managing the driver
List installed net‑class drivers (to find the oemNN.inf published name):
pnputil /enum-drivers /class netRemove the driver and prepare for a clean reinstall (substitute the oemNN.inf from the command
above):
pnputil /delete-driver oem2.inf /uninstall /forceOverview (`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:
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:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\RadioManagement\Misc\SampleRadioManager\SampleRadioX]
"RadioState"=dword:00000000
"Name"="SampleRadioX"
"IsMultiComm"=dword:00000000Editing 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:
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.
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.
In the Build menu, choose Build Solution.
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
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.
Enter WFPSamplerInstall.cmd to run the installation script.
[!NOTE]
If you need to uninstall a previous version of the driver, enterWFPSamplerInstall.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 WFPSamplerCalloutsnet 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:
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.
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.
On the Build menu, choose Build Solution.
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:
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpPacketModificationSamplePackage).
On the target computer, navigate to your driver package folder. Right click ddproxy.inf, and choose Install
Create Registry values
On the target computer, open Regedit, and navigate to this key:
HKLM\System\CurrentControlSet\Services\ddproxy\Parameters
Create a REG_SZ entry named DestinationAddressToIntercept and set it's value to an IPV4 or IPV6 address (example: 10.0.0.1).
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:
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.
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.
On the Build menu, choose Build Solution.
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:
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpTrafficInspectionSamplePackage).
On the target computer, navigate to your driver package folder. Right click inspect.inf, and choose Install
Create Registry values
On the target computer, open Regedit, and navigate to this key:
HKLM\System\CurrentControlSet\Services\inspect\Parameters
Create a REG_DWORD entry named BlockTraffic and set it's value to 0 for permit or 1 to block.
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:
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.
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.
On the Build menu, choose Build Solution.
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:
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpMsnMessengerMonitorSamplePackage).
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.
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
ClassifyFncallout 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:
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.
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.
On the Build menu, choose Build Solution.
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:
Copy all of the files in your driver package to a folder on the target computer (for example, c:\WfpStreamEditSamplePackage).
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
- Mount the EWDK ISO from a local drive (network share paths are not supported).
- Run
LaunchBuildEnv.cmd. - In the environment created in step 2, type
SetupVSEnvand press Enter. - Navigate to the current folder and open the solution file, for example:
X:\Windows-driver-samples\network\wlan\WIFICX\wificxsampleclient.sln - Build the solution from the Visual Studio UI.
Interfaces and Abstraction
The sample interacts with three OS components:
WDF
driver.cpp,device.cpp, andadapter.cppdemonstrate 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.cppfiles implement the control path, handling commands sent to Wi-Fi firmware (e.g., scan access points, connect, disconnect).WDF NetAdapter Class Extension (NetAdapterCx)
netvxxxxfiles 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:
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.
In a Command Prompt window, copy Echosrv.ctl and Echosrv.pdb into a directory and change to that directory (cd).
Start software tracing for the sample driver by typing the following command:
tracelog -start echosrvtrace -guid echosrv.ctl -f logfile.etl -flags 0x3The 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.
In order to stop tracing, type the following command:
tracelog -stop echosrvtrace
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.syswhere \full-path\ is the directory that contains the Echosrv.sys file.
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:
Copy the Echosrv.sys file to a directory on the test machine.
In a Command Prompt window, type the following command:
sc create echosrv type= kernel binpath= \full-path\ echosrv.syswhere \full-path\ is the directory that contains the Echosrv.sys file.
To start the driver, type:
sc start echosrvTo 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.
Open the driver project or solution in Visual Studio (find samplename.sln or samplename.vcxproj).
Right-click the solution in the Solutions Explorer and select Configuration Manager.
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.
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.
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.
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\DSPdevcon 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