Удаление устройства в драйвере шины

При удалении дочернего устройства (дочернего PDO) драйвер родительской шины должен отменить все операции, выполненные для добавления и запуска устройства.

Водитель шины удаляет дочернее устройство с помощью следующей процедуры DispatchPnP :

  1. Обработал ли драйвер предыдущий запрос IRP_MN_SURPRISE_REMOVAL для этого PDO?

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

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

  2. Выполните все запросы, помещенные в очередь в драйвере.

  3. Отключите питание устройства, если драйвер шины способен сделать это, и уведомите диспетчер питания, вызвав PoSetPowerState.

    Водитель шины по возможности выключает дочернее устройство и уведомляет диспетчер питания об изменении состояния питания устройства. Водитель автобуса делает это в ответ на запрос IRP_MN_REMOVE_DEVICE ; владелец политики питания устройства не отправляет запрос IRP_MN_SET_POWER при удалении устройства. Дополнительные сведения см. в разделе Управление питанием.

  4. Если водитель шины сообщил об этом устройстве в своем последнем ответе на запрос IRP_MN_QUERY_DEVICE_RELATIONSbusRelations, устройство по-прежнему физически присутствует на компьютере. В этом случае водитель автобуса:

    • Сохраняет PDO для устройства, пока устройство не будет физически удалено.

    • Задает для Irp-IoStatus.Status> значение STATUS_SUCCESS.

    • Завершает IRP с помощью IoCompleteRequest.

    • Возвращает из подпрограммы DispatchPnP .

    Драйвер шины должен продолжать сообщать об этом устройстве в последующих перечислениях (IRP_MN_QUERY_DEVICE_RELATIONS для BusRelations), пока устройство не будет физически удалено. Диспетчер PnP отслеживает, было ли добавлено и запущено перечислимое устройство.

  5. Если устройство не было включено в последний ответ водителя автобуса на IRP_MN_QUERY_DEVICE_RELATIONS запрос busRelations, водитель автобуса считает устройство физически удаленным с компьютера. В этом случае водитель автобуса выполняет следующие действия:

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

    • Задает для Irp-IoStatus.Status> значение STATUS_SUCCESS.

    • Завершает IRP с помощью IoCompleteRequest.

    • Освобождает PDO с помощью IoDeleteDevice.

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

    • Возвращает из подпрограммы DispatchPnP .

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

Водитель шины должен иметь возможность обрабатывать IRP_MN_REMOVE_DEVICE для устройства, которое он уже удалил и чьи PDO помечены для удаления. В ответ на такой IRP водитель автобуса может успешно выполнить IRP или вернуть STATUS_NO_SUCH_DEVICE. PDO для устройства в этом случае еще не удалена, несмотря на предыдущий вызов водителя автобуса к IoDeleteDevice, так как некоторый компонент по-прежнему имеет ссылку на объект . Таким образом, водитель автобуса может получить доступ к PDO во время обработки второго удаления IRP. Водитель автобуса не должен повторно вызывать IoDeleteDevice для PDO; система ввода-вывода удаляет PDO, когда количество ссылок достигает нуля.

Драйвер шины не удаляет свои структуры данных для дочернего устройства, пока не получит запрос IRP_MN_REMOVE_DEVICE для устройства. Драйвер шины может обнаружить, что устройство было удалено, и вызвать IoInvalidateDeviceRelations, но он не должен удалять PDO устройства, пока диспетчер PnP не отправит IRP_MN_REMOVE_DEVICE запрос.