Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Только драйвер, отправивший IRP ожидания и пробуждения, может отменить этот IRP.
Драйвер может потребовать отмены ожидающего выполнения или пробуждения IRP в следующих обстоятельствах:
Драйвер получает запрос PnP IRP_MN_STOP_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE или IRP_MN_SURPRISE_REMOVAL устройства. После перезапуска устройства драйвер должен переоформить IRP ожидания и пробуждения (PoRequestPowerIrp).
Система будет спянуть, но устройство не должно быть включено для пробуждения системы.
Например, драйвер USB-концентратора может отправить запрос IRP_MN_WAIT_WAKE при запуске устройства, если позже он помещает одно из его устройств ввода в состояние спящего режима. Хотя система находится в рабочем состоянии, сигнал пробуждения от устройства возвращает устройство в рабочее состояние (но не влияет на состояние питания системы). Когда система готовится к завершению работы, драйвер USB-концентратора отменяет этот IRP, если устройству не разрешается пробуждать систему.
Система вводит состояние спящего режима, от которого устройство не может проснуться. То есть он переходит в состояние с меньшим энергопотреблением, чем значение SystemWake, указанное в структуре DEVICE_CAPABILITIES.
Устройство вводит состояние питания, из которого он не может реагировать на сигнал пробуждения. Это означает, что устройство входит в состояние с меньшим энергопотреблением, чем значение DeviceWake, указанное в структуре DEVICE_CAPABILITIES.
Чтобы отменить IRP ожидания и пробуждения, драйвер, который отправил IRP, вызывает функцию IoCancelIrp, передавая указатель на IRP, который ранее возвращался при вызове драйвера PoRequestPowerIrp.
Драйвер не должен отменить IRP ожидания и пробуждения, который он не отправил.
Отмена процедур ожидания и пробуждения irps
Многие драйверы функций и шины должны задавать подпрограммы отмены для ожидающих/пробуждающих IRP; следующие типы драйверов должны задавать такие подпрограммы:
Драйверы, изменяющие параметры устройства, чтобы включить или отключить пробуждение.
Драйверы, отправляющие IRP_MN_WAIT_WAKE запросы на драйверы родительских устройств.
Подпрограмма отмены позволяет драйверу отключить пробуждение для своего устройства и очистить любые данные, связанные с ожидающим IRP ожидания/пробуждения. Драйверы, запрашивающие IRP ожидания/пробуждения для родительских устройств, также могут отменять эти IRP.
В подпрограмме ожидания/прерывания Cancel драйвер должен выполнить следующие действия:
Вызовите IoSetCancelRoutine, чтобы сбросить подпрограмму Cancel для IRP до NULL.
Вызовите IoReleaseCancelSpinLock, передав CancelIRQL, указанное в IRP, чтобы освободить спиновую блокировку для IRP.
Сбросьте все соответствующие поля в расширении устройства. Например, когда ожидается IRP ожидания/пробуждения, большинство драйверов устанавливают флаг и сохраняют указатель на IRP в расширении устройства.
Обратите внимание, что драйвер может получить IRP ожидания и пробуждения во время отмены другого такого IRP. Драйвер должен проверить, есть ли у него уже IRP под защитой спин-блокировки (или его эквивалента). В этом случае драйвер должен тщательно синхронизировать свою обработку, чтобы убедиться, что он отменяет правильный IRP. Дополнительные сведения об использовании спинлоков в подпрограммах отмены см. в разделе "Отмена IRPs".
Измените все необходимые параметры устройства. Например, драйвер модема отключает параметр пробуждения устройства.
Задайте для состояния Irp-IoStatus.Status> значение STATUS_CANCELLED.
Вызовите IoCompleteRequest, чтобы завершить IRP ожидания и пробуждения, указав IO_NO_INCREMENT.
Если драйвер ранее запрашивал связанный IRP_MN_WAIT_WAKE для родительского устройства, драйвер должен отменить его в рамках процедуры Отмены. Драйвер должен освободить блокировку спина отмены, прежде чем отменить IRP родительского объекта.
Например, драйвер, который выступает в качестве водителя шины для устройства и владеет драйвером политики питания для своего родительского объекта, должен отменить связанный идентификатор ожидания и пробуждения, который он ранее отправил родительскому элементу. Вызов IoCancelIrp вызовет подпрограмму отмены родительского объекта и т. д. вниз по стеку устройств.