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

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

通常,用户模式组件调用 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_DEVICEQUERYREMOVE 通知的情况下收到 CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED 通知。

    CM_NOTIFY_ACTION_DEVICEREMOVEPENDING

    调用 CM_Unregister_Notification 以取消注册句柄的通知。 必须通过延迟的例程执行此操作。 有关详细信息,请参阅CM_Unregister_Notification“备注”部分。 如果设备仍有打开的句柄,请调用 CloseHandle 以关闭设备句柄。

    CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE

    调用 CM_Unregister_Notification 以取消注册句柄的通知。 必须通过延迟的例程执行此操作。 有关详细信息,请参阅CM_Unregister_Notification“备注”部分。 如果设备仍有打开的句柄,请调用 CloseHandle 以关闭设备句柄。

  6. 使用完设备后,调用 CM_Unregister_Notification 以取消注册在步骤 1 中注册的接口通知回调。

如果在 UMDF 2 驱动程序中遵循此过程,请参阅 使用设备接口 获取代码示例。 UMDF 2 驱动程序可能会执行驱动程序的 EvtDevicePrepareHardware 回调例程中的步骤 1-4,在驱动程序的设备删除回调例程之一中执行步骤 6。

CM_Register_Notification

CM_Unregister_Notification

使用设备接口