教程:基于模板编写通用 Windows 驱动程序 (KMDF)

本文介绍如何使用 Kernel-Mode 驱动程序框架(KMDF)编写 通用 Windows 驱动程序 。 您可以从 Microsoft Visual Studio 模板开始使用,然后在单独的计算机上部署并安装您的驱动程序。

先决条件

  • 按照步骤安装 Windows 驱动程序工具包 (WDK)。 安装 WDK 时,需要包括 Windows 调试工具

  • 安装 Visual Studio 2022。 安装 Visual Studio 2022 时,选择使用 C++ 进行桌面开发工作负荷,然后在单独组件下添加:

    • MSVC v143 - VS 2022 C++ ARM64/ARM64EC Spectre 缓解库(最新版本)
    • MSVC v143 - VS 2022 C++ x64/x86 Spectre 缓解库(最新版本)
    • 带有 Spectre 缓解库的适用于最新 v143 生成工具的 C++ ATL (ARM64/ARM64EC)
    • 带有 Spectre 缓解库的适用于最新 v143 生成工具的 C++ ATL (x86 & x64)
    • 带有 Spectre 缓解库的适用于最新 v143 生成工具的 C++ MFC (ARM64/ARM64EC)
    • 适用于最新 v143 生成工具且带有 Spectre 漏洞缓解措施的 C++ MFC (x86 & x64)
    • Windows 驱动程序工具包 (WDK)

创建和生成驱动程序

  1. 打开 Microsoft Visual Studio。 在“文件”菜单上,选择新建 > 项目

  2. 在“新建项目”对话框的左侧下拉列表中,选择“C++”,在中间下拉列表中,选择“Windows”,然后在右侧下拉列表中,选择“驱动程序”

  3. 从项目类型列表中选择 内核模式驱动程序(KMDF )。 选择“下一步”。

    “新建项目”对话框的屏幕截图,其中显示了已选择内核模式驱动程序。

    小窍门

    如果在 Visual Studio 中找不到驱动程序项目模板,则表示 WDK Visual Studio 扩展未正确安装。 若要解决此问题,请启动 Visual Studio Installer,选择 修改,在 单个组件 选项卡中添加 Windows 驱动程序工具包,然后选择 修改

  4. 在“ 配置新项目 ”对话框中,在 “项目名称 ”字段中输入“KmdfDriver”。

    注释

    在创建新的 KMDF 或 UMDF 驱动程序时,必须选择一个不多于 32 个字符的驱动程序名称。 此长度限制在 wdfglobals.h 中定义。  

  5. 在“位置”字段中,输入要在其中创建新项目的目录。

  6. 选中“将解决方案和项目置于同一目录中”,然后选择“创建”

    项目配置对话框的屏幕截图。

    Visual Studio 将创建一个项目和一个解决方案。 可以在“解决方案资源管理器”窗口中看到它们。 (如果“解决方案资源管理器”窗口不可见,请从“视图”菜单中选择“解决方案资源管理器”。该解决方案有一个名为 KmdfDriver 的驱动程序项目。 若要查看驱动程序源代码,请打开 源文件下的任何文件。 Driver.c 和 Device.c 是开始的好位置。

    解决方案资源管理器的屏幕截图,其中显示了驱动程序项目中的文件。

  7. “解决方案资源管理器” 窗口中,选择并按住(或右键单击) KmdfDriver,然后选择“ 属性”。 导航到配置属性>驱动程序设置常规>,并注意目标平台默认为通用。

  8. 若要生成驱动程序,请从“生成”菜单中选择“生成解决方案”。 Microsoft Visual Studio 在 “输出 ”窗口中显示生成进度。 (如果“输出”窗口不可见,请选择“视图”菜单中的“输出”。

    验证生成输出是否包括:

    >    Driver is 'Universal'.
    

    验证解决方案是否已成功生成时,可以关闭 Visual Studio。

  9. 若要查看生成的驱动程序,请在文件资源管理器中转到 KmdfDriver 文件夹,然后转到 x64\Debug\KmdfDriver。 该目录包括以下文件:

    • KmdfDriver.sys--内核模式驱动程序文件
    • KmdfDriver.inf--Windows 在安装驱动程序时使用的信息文件

部署驱动程序

通常在测试和调试驱动程序时,调试器和驱动程序在单独的计算机上运行。 运行调试程序的计算机称为“主计算机”,运行驱动程序的计算机称为“目标计算机”。 目标计算机也称为“测试计算机”。 有关调试驱动程序的详细信息,请参阅 适用于 Windows 的调试工具

到目前为止,你已使用 Visual Studio 在主计算机上生成驱动程序。 现在,你需要配置目标计算机。

  1. 按照预配计算机以便进行驱动程序部署和测试 (WDK 10) 中的说明进行操作。

    小窍门

    按照步骤使用网络电缆自动预配目标计算机时,请记下端口和密钥。 稍后会在调试步骤中使用它们。 在此示例中,我们使用 50000 作为端口,使用 1.2.3.4 作为密钥。

    在实际的驱动程序调试方案中,我们建议使用 KDNET 生成的密钥。 有关如何使用 KDNET 生成随机密钥的详细信息,请参阅 调试驱动程序 - 分步实验室(Sysvad 内核模式) 一文。

  2. 在主计算机上,在 Visual Studio 中打开你的解决方案。 可以在 KmdfDriver 文件夹中双击解决方案文件KmdfDriver.sln。

  3. “解决方案资源管理器” 窗口中,选择并按住 KmdfDriver 项目,然后选择“ 属性”。

  4. “KmdfDriver 包属性页” 窗口中的左窗格中,转到 “配置属性 > 驱动程序安装 > 部署”。

  5. 选中“部署前删除以前的驱动程序版本”

  6. 对于 远程计算机名称,请选择为测试和调试配置的计算机的名称。 在本练习中,我们使用名为 MyTestComputer 的计算机。

  7. 选择“硬件 ID 驱动程序更新”,然后输入驱动程序的硬件 ID。 在本练习中,硬件 ID 为 Root\KmdfDriver。 选择“确定”

    kmdfdriver 包属性页窗口的屏幕截图,其中显示了所选的部署驱动程序安装

    注释

    在本练习中,硬件 ID 并不标识真实的硬件设备。 它标识了虚构设备,该设备位于设备树中,作为根节点的子节点。 对于实际硬件,请勿选择 硬件 ID 驱动程序更新;而是选择“ 安装和验证”。 可在驱动程序的信息(INF)文件中看到硬件 ID。 在 “解决方案资源管理器” 窗口中,转到 KmdfDriver > 驱动程序文件 ,然后双击 KmdfDriver.inf。 硬件 ID 位于 [Standard.NT$ARCH$] 下。

    [Standard.NT$ARCH$]
    %KmdfDriver.DeviceDesc%=KmdfDriver_Device, Root\KmdfDriver
    
  8. 在“生成”菜单上,选择“部署解决方案”。 Visual Studio 会自动将安装和运行驱动程序所需的文件复制到目标计算机。

    部署驱动程序时,驱动程序文件将复制到测试计算机上的 %Systemdrive%\drivertest\drivers 文件夹。 如果部署期间发生错误,可以查看这些文件是否已复制到测试计算机。 请确认 .inf、.cat、测试证书和 .sys 文件以及其他任何必要的文件均位于 %systemdrive%\drivertest\drivers 文件夹中。

    有关部署驱动程序的详细信息,请参阅将驱动程序部署到测试计算机

安装驱动程序

将 KMDF 驱动程序部署到目标计算机后,现在安装驱动程序。 如果你之前使用“自动”选项通过 Visual Studio 预配了目标计算机,则在预配过程中,Visual Studio 会将目标计算机设置为运行测试签名驱动程序。 现在,你只需使用 DevCon 工具安装驱动程序即可。

  1. 在主计算机上,导航到 WDK 安装中的“Tools”文件夹,然后找到 DevCon 工具。 例如,在以下文件夹中查看:

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

    将 DevCon 工具复制到远程计算机。

  2. 在目标计算机上,导航到包含驱动程序文件的文件夹,然后运行 DevCon 工具,以安装驱动程序。

    1. 下面是用于安装驱动程序的 devcon 工具的一般语法:

      devcon 安装 <INF 文件><硬件 ID>

      安装此驱动程序所需的 INF 文件是 KmdfDriver.inf。 INF 文件包含用于安装驱动程序二进制文件的硬件 ID ,KmdfDriver.sys。 回想一下,位于 INF 文件中的硬件 ID 是 Root\KmdfDriver

    2. 以管理员身份打开命令提示符窗口。 导航到驱动程序包文件夹,然后输入以下命令:

      devcon install kmdfdriver.inf root\kmdfdriver

      如果收到一条关于 devcon 未被识别的错误消息,请尝试添加 devcon 工具的路径。 例如,如果已将其复制到目标计算机上名为 C:\Tools 的文件夹,则请尝试使用以下命令

      c:\tools\devcon install kmdfdriver.inf root\kmdfdriver

      此时会显示一个对话框,指示测试驱动程序是未签名的驱动程序。 选择“仍然安装此驱动程序”以继续

      驱动程序安装警告的屏幕截图。

调试驱动程序

在目标计算机上安装 KMDF 驱动程序后,请从主机远程附加调试器。

  1. 在主计算机上,以管理员身份打开命令提示符窗口。 切换到 WinDbg.exe 目录。 使用作为 Windows 工具包一部分安装的 Windows 驱动程序工具包(WDK)中的 x64 版本 WinDbg.exe。 下面是 WinDbg.exe 的默认路径:

    C:\Program Files (x86)\Windows Kits\10\Debuggers\x64

  2. 使用以下命令启动 WinDbg 以连接到目标计算机上的内核调试会话。 端口和密钥的值应该与你预配目标计算机所使用的值相同。 我们将 50000 用于端口, 1.2.3.4 用于密钥,即在部署步骤中使用的值。 K 标志指示这是内核调试会话。

    WinDbg -k net:port=50000,key=1.2.3.4

  3. 在“调试”菜单上,选择“中断”。 主计算机上的调试器闯入目标计算机。 在“调试程序命令”窗口中,你可以看到内核调试命令提示符:kd>

  4. 此时,可以通过在 kd-> 提示符处输入命令来试验调试器。 例如,可以尝试使用以下命令:

  5. 若要让目标计算机再次运行,请从“调试”菜单中选择“执行”,或者按“g”,然后按“Enter”。

  6. 若要停止调试会话,请从调试菜单中选择分离调试目标

    重要

    请确保使用“go”命令让目标计算机在退出调试器之前再次运行,或者目标计算机仍然对鼠标和键盘输入无响应,因为它仍在与调试器通信。

有关驱动程序调试过程的详细分步演练,请参阅调试通用驱动程序 - 分步实验室(回显内核模式)

有关远程调试的详细信息,请参阅使用 WinDbg 远程调试

使用驱动程序模块框架 (DMF)

驱动程序模块框架(DMF)是 WDF 的扩展,可为 WDF 驱动程序开发人员启用额外的功能。 它可帮助开发人员更好地更快地编写任何类型的 WDF 驱动程序。

DMF 作为框架允许创建称为 DMF 模块的 WDF 对象。 这些 DMF 模块的代码可以在不同的驱动程序之间共享。 此外,DMF 捆绑了我们为驱动程序开发的 DMF 模块库,感觉将为其他驱动程序开发人员提供价值。

DMF 不会替换 WDF。 DMF 是与 WDF 一起使用的第二个框架。 使用 DMF 的开发人员仍使用 WDF 及其所有基元来编写设备驱动程序。

有关详细信息,请参阅驱动程序模块框架(DMF)。