Удаление устройства в драйвере функции
При удалении устройства драйвер функции должен отменить все операции, выполненные для добавления и запуска устройства. Это обсуждение включает в себя драйверы функций для периферийных устройств и драйверы функций для устройств шины.
Драйвер функции удаляет устройство с помощью следующей процедуры в подпрограмме DispatchPnP :
Является ли это драйвером функции для устройства шины?
Если это так, возможно, удалите все неоплаченные дочерние 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 перед удалением устройства шины.
Уже ли драйвер выполнил предыдущий запрос IRP_MN_SURPRISE_REMOVAL для этого FDO?
Если это так, выполните все оставшиеся очистки и перейдите к шагу 8 IoCallDriver.
Драйвер обычно сохраняет флаг в расширении устройства, который указывает, обрабатывал ли драйвер запрос IRP_MN_SURPRISE_REMOVAL для устройства.
Если драйвер ранее включил пробуждение устройства, отмените запрос IRP_MN_WAIT_WAKE .
Убедитесь, что устройство неактивно.
Если устройство еще не неактивно в ответ на предыдущие IRP_MN_QUERY_REMOVE_DEVICE, драйвер должен пометить устройство как не принимающее новые запросы и выполнить все запросы, помещенные в очередь в этом драйвере. Драйвер должен завершить все невыполненные запросы, требующие доступа к устройству.
Драйвер может использовать подпрограммы IoXxxRemoveLockXxx для подсчета невыполненных операций ввода-вывода и установки события, указывающего, что обработка удаления может продолжаться.
Выполнение любых операций выключения питания.
При получении запроса на IRP_MN_REMOVE_DEVICE каждый драйвер устройства выполняет свои операции выключения питания, если таковые есть. Владелец политики питания для устройства, как правило, драйвер функции, не отправляет отдельный запрос IRP_MN_SET_POWER , чтобы установить для устройства состояние питания D3. Водитель родительского автобуса обычно отключает слот и уведомляет диспетчер питания с помощью PoSetPowerState , когда водитель автобуса получает удалив IRP. Дополнительные сведения см. в разделе Управление питанием.
Отключите все интерфейсы устройств, вызвав IoSetDeviceInterfaceState.
Освободите все аппаратные ресурсы для устройства, используемого драйвером.
Точные операции зависят от устройства и драйвера, но могут включать отключение прерывания с помощью IoDisconnectInterrupt, освобождение физических диапазонов адресов с помощью MmUnmapIoSpace и освобождение портов ввода-вывода.
Передайте запрос IRP_MN_REMOVE_DEVICE следующему драйверу.
Настройте расположение стека IRP для следующего нижнего драйвера с помощью IoSkipCurrentIrpStackLocation и передайте IRP следующему драйверу с помощью IoCallDriver.
Драйверу не требуется ждать завершения операций удаления базовых драйверов, прежде чем продолжить действия по удалению.
Удалите объект устройства из стека устройств с помощью IoDetachDevice.
Укажите указатель на следующий нижний объект устройства в качестве параметра TargetDevice . Драйвер получает такой указатель от вызова IoAttachDeviceToDeviceStack в процедуре AddDevice драйвера.
Очистите все выделения, память, события и т. д.
Освободите FDO с помощью IoDeleteDevice.
Возвращается из подпрограммы DispatchPnP , распространяя состояние возврата из IoCallDriver.
Драйвер функции не указывает подпрограмму IoCompletion для удаления IRP и не завершает IRP. Удаление irP выполняется драйвером родительского автобуса.