Удержание входящих IRP при приостановке устройства
Драйверы для устройства должны приостанавливать работу устройства при повторной балансировке его ресурсов. Во время перебалансирования ресурсов некоторые драйверы приостанавливают устройство в ответ на запрос IRP_MN_QUERY_STOP_DEVICE , а другие драйверы задерживают приостановку устройства, пока не получат запрос IRP_MN_STOP_DEVICE . В любом случае устройство должно быть приостановлено при успешном IRP_MN_STOP_DEVICE .
Драйверы должны завершить выполнение всех irP на устройстве и воздерживаться от запуска любых новых IRP, которым требуется доступ к устройству.
Для хранения IRP во время приостановки устройства драйвер реализует следующую процедуру:
В процедуре AddDevice определите флаг в расширении устройства с именем, например HOLD_NEW_REQUESTS. Снимите флажок.
Создайте очередь FIFO для хранения IRP.
Если драйвер уже помещает в очередь IRP, он может повторно использовать ту же очередь, так как драйвер должен завершить все невыполненные запросы, прежде чем приостанавливать устройство.
Если у драйвера еще нет очереди IRP, он должен создать ее в своей процедуре AddDevice . Тип создаваемой очереди зависит от того, как драйвер очищает очередь. Драйвер может использовать переблокируемый, вдвойне связанный список и подпрограммы ExInterlockedXxxList .
В коде DispatchPnP для IRP_MN_QUERY_STOP_DEVICE (или IRP_MN_STOP_DEVICE) завершите все невыполненные запросы и установите флаг HOLD_NEW_REQUESTS.
В подпрограмме диспетчеризации, которая обращается к устройству, например DispatchWrite или DispatchRead, проверка, установлен ли флаг HOLD_NEW_REQUESTS. В этом случае драйвер должен пометить ожидающий IRP и поставить его в очередь.
Подпрограмма DispatchPnP драйвера должна продолжать обрабатывать PnP IRP, а не удерживать их, а подпрограмма DispatchPower должна продолжать обрабатывать IRP питания.
В DispatchPnP в ответ на запуск или отмену и остановку IRP снимите флаг HOLD_NEW_REQUESTS и запустите IRP в очереди хранения IRP.
Эти действия, вероятно, являются последними шагами для обработки этих PnP IRP. Например, в ответ на запуск IRP драйвер должен сначала выполнить любые операции для запуска устройства, а затем запустить IRP в очереди хранения IRP.
Ошибки при обработке IRP из очереди хранения IRP не влияют на состояние, возвращаемое для irPs запуска или отмены и остановки.