Удержание входящих IRP при приостановке устройства

Драйверы для устройства должны приостанавливать работу устройства при повторной балансировке его ресурсов. Во время перебалансирования ресурсов некоторые драйверы приостанавливают устройство в ответ на запрос IRP_MN_QUERY_STOP_DEVICE , а другие драйверы задерживают приостановку устройства, пока не получат запрос IRP_MN_STOP_DEVICE . В любом случае устройство должно быть приостановлено при успешном IRP_MN_STOP_DEVICE .

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

Для хранения IRP во время приостановки устройства драйвер реализует следующую процедуру:

  1. В процедуре AddDevice определите флаг в расширении устройства с именем, например HOLD_NEW_REQUESTS. Снимите флажок.

  2. Создайте очередь FIFO для хранения IRP.

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

    Если у драйвера еще нет очереди IRP, он должен создать ее в своей процедуре AddDevice . Тип создаваемой очереди зависит от того, как драйвер очищает очередь. Драйвер может использовать переблокируемый, вдвойне связанный список и подпрограммы ExInterlockedXxxList .

  3. В коде DispatchPnP для IRP_MN_QUERY_STOP_DEVICE (или IRP_MN_STOP_DEVICE) завершите все невыполненные запросы и установите флаг HOLD_NEW_REQUESTS.

  4. В подпрограмме диспетчеризации, которая обращается к устройству, например DispatchWrite или DispatchRead, проверка, установлен ли флаг HOLD_NEW_REQUESTS. В этом случае драйвер должен пометить ожидающий IRP и поставить его в очередь.

    Подпрограмма DispatchPnP драйвера должна продолжать обрабатывать PnP IRP, а не удерживать их, а подпрограмма DispatchPower должна продолжать обрабатывать IRP питания.

  5. В DispatchPnP в ответ на запуск или отмену и остановку IRP снимите флаг HOLD_NEW_REQUESTS и запустите IRP в очереди хранения IRP.

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

    Ошибки при обработке IRP из очереди хранения IRP не влияют на состояние, возвращаемое для irPs запуска или отмены и остановки.