Удаление устройства в драйвере функции

При удалении устройства драйвер функции должен отменить все операции, выполненные для добавления и запуска устройства. Это обсуждение включает в себя драйверы функций для периферийных устройств и драйверы функций для устройств шины.

Драйвер функции удаляет устройство с помощью следующей процедуры в подпрограмме DispatchPnP :

  1. Является ли это драйвером функции для устройства шины?

    Если это так, возможно, удалите все неоплаченные дочерние PDO для устройств в шине.

    Если водитель автобуса обработал предыдущий запрос IRP_MN_SURPRISE_REMOVAL для дочернего устройства, но водитель еще не получил последующий запрос IRP_MN_REMOVE_DEVICE , водитель автобуса оставляет дочерний PDO нетронутым. Позже, когда все дескриптора дочернего устройства будут закрыты, диспетчер PnP отправит IRP удаления для дочернего устройства, а драйвер автобуса удалит дочернее PDO в это время.

    Если водитель автобуса обработал предыдущий запрос IRP_MN_REMOVE_DEVICE для устройства, а последующий запрос IRP_MN_SURPRISE_REMOVAL не был выполнен, водитель автобуса удаляет дочернее PDO. В этом случае диспетчер PnP гарантирует, что все функции и драйверы фильтров были удалены с дочернего устройства (FDO и DOS фильтра были удалены), прежде чем он отправит IRP удаления на родительское устройство шины. Дочерний PDO может по-прежнему присутствовать, поэтому водитель автобуса должен удалить дочернее PDO перед удалением устройства шины.

  2. Уже ли драйвер выполнил предыдущий запрос IRP_MN_SURPRISE_REMOVAL для этого FDO?

    Если это так, выполните все оставшиеся очистки и перейдите к шагу 8 IoCallDriver.

    Драйвер обычно сохраняет флаг в расширении устройства, который указывает, обрабатывал ли драйвер запрос IRP_MN_SURPRISE_REMOVAL для устройства.

  3. Если драйвер ранее включил пробуждение устройства, отмените запрос IRP_MN_WAIT_WAKE .

  4. Убедитесь, что устройство неактивно.

    Если устройство еще не неактивно в ответ на предыдущие IRP_MN_QUERY_REMOVE_DEVICE, драйвер должен пометить устройство как не принимающее новые запросы и выполнить все запросы, помещенные в очередь в этом драйвере. Драйвер должен завершить все невыполненные запросы, требующие доступа к устройству.

    Драйвер может использовать подпрограммы IoXxxRemoveLockXxx для подсчета невыполненных операций ввода-вывода и установки события, указывающего, что обработка удаления может продолжаться.

  5. Выполнение любых операций выключения питания.

    При получении запроса на IRP_MN_REMOVE_DEVICE каждый драйвер устройства выполняет свои операции выключения питания, если таковые есть. Владелец политики питания для устройства, как правило, драйвер функции, не отправляет отдельный запрос IRP_MN_SET_POWER , чтобы установить для устройства состояние питания D3. Водитель родительского автобуса обычно отключает слот и уведомляет диспетчер питания с помощью PoSetPowerState , когда водитель автобуса получает удалив IRP. Дополнительные сведения см. в разделе Управление питанием.

  6. Отключите все интерфейсы устройств, вызвав IoSetDeviceInterfaceState.

  7. Освободите все аппаратные ресурсы для устройства, используемого драйвером.

    Точные операции зависят от устройства и драйвера, но могут включать отключение прерывания с помощью IoDisconnectInterrupt, освобождение физических диапазонов адресов с помощью MmUnmapIoSpace и освобождение портов ввода-вывода.

  8. Передайте запрос IRP_MN_REMOVE_DEVICE следующему драйверу.

    Настройте расположение стека IRP для следующего нижнего драйвера с помощью IoSkipCurrentIrpStackLocation и передайте IRP следующему драйверу с помощью IoCallDriver.

    Драйверу не требуется ждать завершения операций удаления базовых драйверов, прежде чем продолжить действия по удалению.

  9. Удалите объект устройства из стека устройств с помощью IoDetachDevice.

    Укажите указатель на следующий нижний объект устройства в качестве параметра TargetDevice . Драйвер получает такой указатель от вызова IoAttachDeviceToDeviceStack в процедуре AddDevice драйвера.

  10. Очистите все выделения, память, события и т. д.

  11. Освободите FDO с помощью IoDeleteDevice.

  12. Возвращается из подпрограммы DispatchPnP , распространяя состояние возврата из IoCallDriver.

Драйвер функции не указывает подпрограмму IoCompletion для удаления IRP и не завершает IRP. Удаление irP выполняется драйвером родительского автобуса.