构建用于 Windows 的多个版本的 WDF 驱动程序Building a WDF driver for multiple versions of Windows

WDF 始终允许您一次生成一个驱动程序,并使用生成的二进制文件在多个版本的 Windows,但之前 Windows 10 版本 1803 (Redstone 4),这被限制为"基于较旧,更高版本上运行。"WDF has always allowed you to build a driver once and use the resulting binary on multiple versions of Windows, but before Windows 10 version 1803 (Redstone 4), this was limited to "build on older, run on newer." WDF 启动 Windows 10 版本 1803年中,添加"生成更高版本,运行更早版本,"有条件执行的其他优势。Starting in Windows 10 version 1803, WDF adds "build on newer, run on older," with the additional benefit of conditional execution. 总结:To summarize:

  • 现有:与较早版本的 framework 包括提供的主版本的框架的较新版本的 Windows 版本上运行生成的二进制文件匹配。Existing: Binaries built with older versions of the framework run on versions of Windows that include newer versions of the framework, provided major versions match. 例如,使用 KMDF 1.9 (Windows 7) 构建的驱动程序在 Windows 8 系统 (KMDF 1.11) 上运行。For example, a driver built with KMDF 1.9 (Windows 7) runs on a Windows 8 system (KMDF 1.11). 在示例中,该驱动程序被限制为 KMDF 1.9 的意大功能。In the example, the driver is limited to functionality of KMDF 1.9.
  • 添加项:从版本 1.25 KMDF 和 UMDF 上 Windows 10 版本 1803年的版本 2.25,可以构建与较新的 framework 版本的驱动程序和生成的驱动程序二进制文件在早期版本的 Windows (在最小的 Windows 10 版本 1803年) 上运行。Added: Starting in KMDF version 1.25 and UMDF version 2.25 on Windows 10 version 1803, you can build a driver with a newer framework version and the resulting driver binary runs on earlier versions of Windows (at minimum Windows 10 version 1803). 此外,驱动程序可以有条件地使用选项仅适用于更高版本的 framework 版本的功能。In addition, the driver can conditionally use functionality that is only available in newer framework versions.

这意味着,不仅不您的驱动程序运行在未来版本的 Windows,因为它始终都有,但它还返回到 Windows 10 版本 1803年运行有关以前版本。This means that not only does your driver run on future versions of Windows, as it always has, but it also runs on past versions, back to Windows 10 version 1803.

有两个步骤执行此操作: 在 Visual Studio 中,指定生成设置和执行 API 调用或访问的结构或可能或可能不会显示的字段之前运行时检查。There are two steps to doing this: specifying build settings in Visual Studio, and performing a runtime check before invoking an API or accessing a structure or field that may or may not be present.

注意:此功能是可选的它生成的驱动程序,同时保持可加载没有最新的 WDF 功能的 Windows 的早期版本上使用的最新的 WDF 功能,才应启用驱动程序。Note: This feature is optional and a driver should only enable it to build a driver that uses the latest WDF functionality while remaining loadable on earlier versions of Windows that do not have the latest WDF functionality.

如果未设置次要版本 (目标版本)次要版本 (最低要求),版本控制保持不变像以前一样。If you do not set Version Minor (Target Version) or Version Minor (Minimum Required), versioning remains the same as before.

指定所需的最小值Specifying Minimum Required

在 Visual Studio 中的新配置设置如下:The new configuration settings in Visual Studio are:

  • KMDF 版本次要 (最低要求)KMDF Version Minor (Minimum Required)
  • UMDF 版本次要 (最低要求)UMDF Version Minor (Minimum Required)

根据此更改后,更新了两个现有设置的名称:In accordance with this change, the names of two existing settings were updated:

  • KMDF 版本次要 -> KMDF 版本次要 (目标版本)KMDF Version Minor -> KMDF Version Minor (Target Version)
  • UMDF 版本次要 -> UMDF 版本次要 (目标版本)UMDF Version Minor -> UMDF Version Minor (Target Version)

如果未设置所需的最小,Visual Studio 生成目标版本和,并不提供低级支持。If you don't set Minimum Required, Visual Studio builds for Target Version and up, and does not provide downlevel support. 这与旧的行为一致次要版本属性。This matches the behavior of the old Version Minor properties.

如果设置所需的最小,必须满足以下要求:If you do set Minimum Required, the following requirements apply:

  • 25 < = 所需的最小值 < = 目标版本25 <= Minimum Required <= Target Version
  • 在中配置属性-> 驱动程序设置-> 常规,请设置_NT_TARGET_VERSION0x0A000005(RS4) 或更高版本。In Configuration Properties->Driver Settings->General, set _NT_TARGET_VERSION to 0x0A000005 (RS4) or later.

正在检查功能是否存在Checking if functionality is present

在每次使用 API、 结构或成员,可能会或可能不会显示之前, 必须调用 WdfFuncEnum.h 中定义的以下宏之一:Prior to every use of an API, structure, or member that may or may not be present, you must call one of the following macros, which are defined in WdfFuncEnum.h:

BOOLEAN
WDF_IS_FUNCTION_AVAILABLE (
    FunctionName
    );

BOOLEAN
WDF_IS_STRUCTURE_AVAILABLE (
    StructName
    );

BOOLEAN
WDF_IS_FIELD_AVAILABLE (
    StructName,
    FieldName
    );

请考虑下面的示例。Consider the following example. WDF v29 发布时,它将添加一个新的 API:WdfSomeNewFeatureWhen WDF v29 is released, it adds a new API: WdfSomeNewFeature. 如果您设置目标版本为 29 和最低要求为 25,25 到 29 从任何 framework 版本上加载该生成的驱动程序 (和更高版本,只要主版本不会更改),调用版本 25Api 一样,并使任何 v29 API 每次调用之前的以下检查:If you set Target Version to 29 and Minimum Required to 25, the resulting driver loads on any framework version from 25 through 29 (and beyond, as long as major version doesn't change), calls version 25 APIs like before, and makes the following check before each call of any v29 API:

if (WDF_IS_FUNCTION_AVAILABLE(WdfSomeNewFeature)) {
    WdfSomeNewFeature();
}

如果不执行条件检查,您可能会看到以下信息:If you don't do the conditional check, you might see the following:

  • 如果 API 返回 NTSTATUS,调用会返回失败代码。If the API returns NTSTATUS, the call returns a failure code.
  • 如果 API 返回 NTSTATUS 之外的任何内容:If the API returns anything other than NTSTATUS:
    • KMDF:机 bug 检查。KMDF: The machine bug checks.
    • UMDF:WudfHost 进程崩溃并出现 DriverStop 错误。UMDF: The WudfHost process crashes with a DriverStop error.
  • 如果启用了驱动程序验证程序,该驱动程序崩溃以及。If Driver Verifier is enabled, the driver crashes as well. 这有助于确定在测试环境中的问题。This helps to identify the problem in a test environment.
  • 无提示的内存损坏 (时访问的结构或字段)。Silent memory corruption (when accessing a structure or field).

驱动程序故障包含故障的驱动程序名称、 框架名称和失败的 API 索引。A driver crash contains the failed driver name, the framework name, and the failed API index. 可以通过查找 WDFFUNCENUM WdfFuncEnum.h 中的值来检索 API 的名称。You can retrieve the name of API by looking up the value of WDFFUNCENUM in WdfFuncEnum.h.

WDF 的 Visual Studio 属性的详细信息,请参阅驱动程序项目的驱动程序模型设置属性For more info about Visual Studio properties for WDF, see Driver Model Settings Properties for Driver Projects.