在 UMDF 驱动程序中使用设备接口

警告

UMDF 2 是最新版本的 UMDF,取代了 UMDF 1。 所有新的 UMDF 驱动程序都应使用 UMDF 2 编写。 未向 UMDF 1 添加新功能,并且较新版本的 Windows 10 上对 UMDF 1 的支持有限。 通用 Windows 驱动程序必须使用 UMDF 2。

存档的 UMDF 1 示例可在 Windows 11 版本 22H2 - 2022 年 5 月驱动程序示例更新中找到。

有关详细信息,请参阅使用 UMDF 入门

设备接口是指向应用程序可用于访问设备的即插即用 (PnP) 设备的符号链接。 用户模式应用程序可以将接口的符号链接名称传递给 API 元素,例如 Microsoft Win32 CreateFile 函数。 若要获取设备接口的符号链接名称,用户模式应用程序可以调用 SetupDi 函数。 有关 SetupDi 函数的详细信息,请参阅 SetupDi 设备接口函数。

每个设备接口都属于一个 设备接口类。 例如,CD-ROM 设备的驱动程序堆栈可能会提供属于 GUID_DEVINTERFACE_CDROM 类的接口。 其中一个 CD-ROM 设备的驱动程序会注册 GUID_DEVINTERFACE_CDROM 类的实例,以通知系统和应用程序 CD-ROM 设备可用。 有关设备接口类的详细信息,请参阅 设备接口简介

注册设备接口

若要注册设备接口类的实例,基于 UMDF 的驱动程序可以从其 IDriverEntry::OnDeviceAdd 回调函数中调用 IWDFDevice::CreateDeviceInterface 。 如果驱动程序支持接口的多个实例,则可以为每个实例分配唯一的引用字符串。

启用和禁用设备接口

如果创建成功,框架将根据设备的 PnP 状态自动启用和禁用接口。

此外,驱动程序可以根据需要禁用和重新启用设备接口。 例如,如果驱动程序确定其设备已停止响应,则驱动程序可以调用 IWDFDevice::AssignDeviceInterfaceState 来禁用设备的接口并禁止应用程序获取接口的新句柄。 (接口的现有句柄不受影响。) 如果设备稍后变为可用,驱动程序可以再次调用 IWDFDevice::AssignDeviceInterfaceState 以重新启用接口。

接收访问设备接口的请求

当应用程序请求访问驱动程序的设备接口时,框架会调用驱动程序的 IQueueCallbackCreate::OnCreateFile 回调函数。 驱动程序可以调用 IWDFFile::RetrieveFileName 来获取应用程序正在访问的设备或文件的名称。 如果驱动程序在注册设备接口时指定了引用字符串,则操作系统会将引用字符串包含在 IWDFFile::RetrieveFileName 返回的文件或设备名称中。

创建设备事件

基于 UMDF 的驱动程序可以通过调用 IWDFDevice::P ostEvent 来创建设备特定的自定义事件 (称为设备事件) 。 已注册为使用任何设备接口的驱动程序可以接收设备自定义事件的通知。 基于 UMDF 的驱动程序通过提供 IRemoteInterfaceCallbackEvent::OnRemoteInterfaceEvent 回调函数来接收此类通知。

自定义事件对设备是唯一的。 创建事件的驱动程序的开发人员和接收事件的驱动程序的开发人员都必须了解事件的含义。

访问其他驱动程序的设备接口

如果希望基于 UMDF 的驱动程序将 I/O 请求发送到另一个驱动程序提供的设备接口,则可以创建表示设备接口的 远程 I/O 目标

首先,驱动程序必须注册才能在设备接口可用时接收通知。 请使用以下步骤:

  1. 当驱动程序调用 IWDFDriver::CreateDevice 时,驱动程序可以提供 IPnpCallbackRemoteInterfaceNotification 接口。 此接口的 IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival 回调函数在设备接口可用时通知驱动程序。

  2. 驱动程序调用 IWDFDriver::CreateDevice 后,可为驱动程序将使用的每个设备接口调用 IWDFDevice2::RegisterRemoteInterfaceNotification

随后,每次指定的设备接口可用时,框架都会调用驱动程序的 IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival 回调函数。 回调函数可以调用 IWDFRemoteInterfaceInitialize::GetInterfaceGuidIWDFRemoteInterfaceInitialize::RetrieveSymbolicLink 来确定到达的设备接口。

驱动程序的 IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival 回调函数通常应执行以下操作:

  1. 调用 IWDFDevice2::CreateRemoteInterface 来创建远程接口对象,可以选择提供 IRemoteInterfaceCallbackEventIRemoteInterfaceCallbackRemoval 接口。

  2. 调用 IWDFDevice2::CreateRemoteTarget 以创建远程目标对象,可以选择提供 IRemoteTargetCallbackRemoval 接口。

  3. 调用 IWDFRemoteTarget::OpenRemoteInterface 将设备接口连接到远程目标。

    如果设备接口是 SWENUM 软件设备枚举器创建的接口,驱动程序必须从工作项调用 OpenRemoteInterface 。 (例如,请参阅 Windows SDK 中的 QueueUserWorkItem 函数。)

现在,驱动程序可以格式化 I/O 请求并将其发送到远程 I/O 目标。

除了 IPnpCallbackRemoteInterfaceNotification::OnRemoteInterfaceArrival 回调函数外,基于 UMDF 的驱动程序还可以提供两个附加的回调函数来接收设备接口事件的通知: