Регистрация для уведомления о получении интерфейса устройства и удалении устройств
В этом разделе описывается, как приложение или драйвер в пользовательском режиме регистрируется для уведомления о получении интерфейса устройства и удалении устройства.
Если вы используете эту процедуру в драйвере UMDF 2, ознакомьтесь с примером кода с помощью интерфейсов устройств.
Как правило, компонент пользовательского режима вызывает CM_Register_Notification для поиска интерфейса устройства, а затем отправляет запросы ввода-вывода в интерфейс. Для этого компонент регистрируется как для CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, так и для CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE для уведомления о поступлении интерфейса устройства и удалении устройств соответственно. Последовательность вызовов может выглядеть следующим образом.
Регистрация для уведомления о получении интерфейса устройства и удалении устройств
Вызовите CM_Register_Notification с CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE, чтобы зарегистрировать уведомления о прибытии интерфейса устройства. При поступлении будущих интерфейсов в указанном классе система уведомляет компонент.
Так как интерфейс, в который вы хотите отправить ввод-вывод, может уже присутствовать в системе, вызовите CM_Get_Device_Interface_List или SetupDiGetClassDevs, чтобы получить список существующих интерфейсов. Примечание. Если интерфейс поступает между шагом 1 и шагом 2, интерфейс отображается дважды из регистрации на шаге 1 и списке интерфейсов на шаге 2.
Найдя нужный интерфейс, вызовите CreateFile , чтобы открыть дескриптор устройства.
После успешного создания дескриптора устройства на шаге 3 вызовите CM_Register_Notification второй раз. На этот раз зарегистрируйтесь для уведомлений типа CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE и укажите новый дескриптор устройства в качестве дескриптора, для которого будут получать уведомления. Когда устройство, представленное интерфейсом, получает запрос на удаление запроса, система уведомляет ваш компонент.
Используйте эту таблицу при реализации обратного вызова уведомлений на устройстве.
Значение действия, которое получает обратный вызов | Что должен сделать компонент |
---|---|
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE | Вызов CloseHandle, чтобы закрыть дескриптор устройства. Если этого не сделать, открытый дескриптор предотвращает удаление запроса этого устройства. |
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED | Сбой удаления запроса, поэтому устройство и его интерфейс по-прежнему действительны. Чтобы продолжить отправку ввода-вывода в интерфейс, откройте новый дескриптор. Регистрация уведомлений на устройстве с помощью исходного дескриптора остается допустимой, даже если этот дескриптор был закрыт, поэтому нет необходимости отменить регистрацию этого уведомления и создать новую регистрацию под новым дескриптором интерфейса устройства. Обратите внимание, что если вы регистрируете уведомления на устройстве, которое находится в процессе удаления запроса после отправки уведомлений 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 , чтобы закрыть дескриптор устройства. |
- Завершив работу с устройством, вызовите CM_Unregister_Notification , чтобы отменить регистрацию обратного вызова уведомления интерфейса, зарегистрированного на шаге 1.
Драйвер UMDF 2 может выполнить шаги 1–4 в подпрограмме обратного вызова EvtDevicePrepareHardware драйвера и шаг 6 в одной из подпрограмм обратного вызова устройства драйвера.