注册获取设备接口到达和设备删除通知

本主题介绍用户模式应用程序或驱动程序如何注册获取设备接口到达和设备移除的通知。

如果在 UMDF 2 驱动程序中遵循此过程,请参阅使用设备接口以获取代码示例。

通常,用户模式组件会调用 CM_Register_Notification 来查找设备接口,然后将 I/O 请求发送到接口。 为此,组件会注册 CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACECM_NOTIFY_FILTER_TYPE_DEVICEHANDLE,分别用于获取设备接口到达和设备删除的通知。 调用序列可能如下所示。

注册获取设备接口到达和设备删除通知

  1. 使用 CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE 调用 CM_Register_Notification 以注册设备接口到达通知。 当指定类中的未来接口到达时,系统会通知您的组件。

  2. 由于要将 I/O 发送到的接口可能已存在于系统上,因此,请调用 CM_Get_Device_Interface_ListSetupDiGetClassDevs 以检索现有接口的列表。 注意:如果接口在步骤 1 和步骤 2 之间到达,则会从步骤 1 中的注册和步骤 2 中的接口列表中列出两次接口。

  3. 找到所需的接口后,请调用 CreateFile 以打开设备的句柄。

  4. 在步骤 3 中成功创建设备句柄后,再次调用 CM_Register_Notification。 这次,注册 CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE 类型的通知,并提供新设备句柄作为接收通知的句柄。 当接口所代表的设备收到查询移除请求时,系统会通知你的组件。

  5. 在实现设备处理通知回调时使用此表。

回调接收的操作值 组件应执行的操作
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE 调用 CloseHandle 以关闭设备句柄。 如果不这样做,则打开的句柄会阻止此设备的查询删除成功。
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED 查询删除失败,因此设备及其接口仍然有效。 若要继续向接口发送 I/O,请打开一个新接口句柄。 首先,通过调用 CM_Unregister_Notification 来取消注册旧句柄的通知。 你必须从延迟的例程执行此操作,因为你无法从通知回调中对取消注册的通知句柄调用 CM_Unregister_Notification。 有关详细信息,请参阅 CM_Unregister_Notification备注部分。 然后,在延迟的例程中继续,或在通知回调中返回,调用 CreateFile 以创建新句柄。 然后,使用此新句柄和 CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE 调用 CM_Register_Notification。 请注意,如果在正在被查询的设备上注册通知,但发送 CM_NOTIFY_ACTION_DEVICEQUERYREMOVE 通知后删除了调查,那么,你可能会收到 CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED 通知,而不会事先收到 CM_NOTIFY_ACTION_DEVICEQUERYREMOVE 通知。
CM_NOTIFY_ACTION_DEVICEREMOVEPENDING 调用 CM_Unregister_Notification 以取消注册句柄通知。 你必须从延迟的例程中执行此操作。 有关详细信息,请参阅 CM_Unregister_Notification备注部分。 如果仍有打开的设备句柄,请调用 CloseHandle 以关闭设备句柄。
CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE 调用 CM_Unregister_Notification 以取消注册句柄通知。 你必须从延迟的例程中执行此操作。 有关详细信息,请参阅 CM_Unregister_Notification备注部分。 如果仍有打开的设备句柄,请调用 CloseHandle 以关闭设备句柄。
  1. 用完设备后,调用 CM_Unregister_Notification 以取消注册步骤 1 中注册的接口通知回调。

UMDF 2 驱动程序可能会在驱动程序的 EvtDevicePrepareHardware 回调例程中执行步骤 1-4,并在某个驱动程序的设备删除回调例程中执行步骤 6。

CM_Register_Notification

CM_Unregister_Notification

使用设备接口