Подпрограммы DispatchPnP
Подпрограмма DispatchPnP драйвера поддерживает Plug and Play, обрабатывая IRP для кода функции ввода-вывода IRP_MJ_PNP. Код функции IRP_MJ_PNP связан с несколькими дополнительными кодами функций ввода-вывода (см. раздел Plug and Play Дополнительные irP), некоторые из которых должны обрабатываться всеми драйверами, а некоторые из них можно обрабатывать при необходимости. Диспетчер PnP использует эти дополнительные коды функций, чтобы направлять драйверы для запуска, остановки и удаления устройств, а также для запроса драйверов об их устройствах.
Все драйверы для устройства должны иметь возможность обрабатывать PnP IRP для устройства, за исключением нескольких случаев, когда драйвер функции или фильтра может завершать ошибку IRP.
Подпрограмма DispatchPnP каждого драйвера должна соответствовать следующим правилам:
Драйвер функции или фильтра должен передавать PnP IRP следующему драйверу в стеке устройств, если только драйвер функции или фильтра не обрабатывает IRP и не сталкивается с ошибкой (например, из-за нехватки ресурсов).
Все драйверы для устройства должны иметь возможность обрабатывать PnP IRP для устройства, если только один из драйверов не столкнется с ошибкой. Диспетчер PnP отправляет irP в верхний драйвер в стеке устройств. Драйверы функций и фильтров передают IRP следующему драйверу, а драйвер родительского автобуса завершает IRP. Дополнительные сведения см. в статье Передача PnP IRP в стек устройств .
Драйвер может завершиться ошибкой IRP, если он пытается обработать его и обнаруживает ошибку (например, нехватку ресурсов). Если драйвер получает IRP с кодом, который он не обрабатывает, драйвер не должен сбой IRP. Он должен передать такой IRP следующему драйверу без изменения состояния IRP.
Драйвер должен обрабатывать определенные PnP IRP и при необходимости может обрабатывать другие.
Каждый драйвер PnP требуется для обработки определенных irP, таких как IRP_MN_REMOVE_DEVICE, и при необходимости может обрабатывать другие. Сведения о том, какие irP являются обязательными и необязательными для каждого типа драйверов (драйверы функций, драйверы фильтров и драйверы автобусов), см. в Plug and Play.
Драйвер может завершиться ошибкой требуемого PnP IRP с соответствующим состоянием ошибки, но драйвер не должен возвращать STATUS_NOT_SUPPORTED для такого IRP.
Если драйвер успешно обрабатывает PnP IRP, драйвер устанавливает состояние IRP в состояние успешно. Установка состояния не зависит от другого драйвера в стеке.
Драйвер устанавливает Irp-IoStatus.Status> в значение STATUS_SUCCESS, чтобы сообщить диспетчеру PnP о том, что драйвер успешно обработал IRP. Для некоторых поставщиков интеграции водитель, не относящихся к шине, может полагаться на своего родительского водителя автобуса, чтобы задать состояние успешного выполнения. Тем не менее, это рискованной практики. Для обеспечения согласованности и надежности драйвер должен задать состояние IRP как успешное для каждой успешной обработки PnP IRP.
Если драйвер завершает ошибку IRP, драйвер завершает его с состоянием ошибки и не передает его следующему драйверу.
Для сбоя IRP, например IRP_MN_QUERY_STOP_DEVICE, драйвер устанавливает Irp-IoStatus.Status> в значение STATUS_UNSUCCESSFUL. Дополнительные значения состояния ошибки для других поставщиков irP включают STATUS_INSUFFICIENT_RESOURCES и STATUS_INVALID_DEVICE_STATE.
Драйверы не задают STATUS_NOT_SUPPORTED для irP, которые они обрабатывают. Это начальное состояние, заданное диспетчером PnP. Если IRP завершено с таким состоянием, это означает, что ни драйверы в стеке не обрабатывали IRP; все драйверы только что передали IRP следующему драйверу.
Драйвер должен обрабатывать PnP IRP в своей подпрограмме диспетчеризации (на пути IRP вниз по стеку устройств), в процедуре IoCompletion (на пути IRP резервное копирование стека устройств) или в обоих, как указано на справочной странице для IRP.
Некоторые PnP IRP, такие как IRP_MN_REMOVE_DEVICE, должны обрабатываться сначала драйвером в верхней части стека устройств, а затем каждым следующим ниже драйвером. Другие, такие как IRP_MN_START_DEVICE, должны обрабатываться сначала родительским водителем автобуса. Другие, такие как IRP_MN_QUERY_CAPABILITIES, можно обрабатывать как по пути вниз по стеку устройств, так и по пути резервного копирования. Правила, применимые к каждому PnP IRP, см. в разделе Plug and Play дополнительных irP. Сведения об обработке PnP IRP, которые должны быть обработаны в первую очередь родительским водителем автобуса, см. в статье Перенос обработки PnP IRP до завершения работы с более низкими драйверами .
Драйвер должен добавить сведения в IRP на пути IRP вниз по стеку устройств и изменить или удалить сведения о пути IRP.
При возврате сведений в ответ на IRP запроса PnP драйвер должен следовать этому соглашению, чтобы обеспечить упорядоченную передачу информации многоуровневые драйверы для устройства.
За исключением случаев, когда это явно задокументировано, драйвер не должен зависеть от PnP IRP, отправляемых в определенном порядке.
Когда драйвер отправляет PnP IRP, он должен отправить его в верхний драйвер в стеке устройств.
Большинство PnP IRP отправляются менеджером PnP, но некоторые могут быть отправлены драйверами (например, IRP_MN_QUERY_INTERFACE). Драйвер должен отправить PnP IRP драйверу в верхней части стека устройств. Вызовите IoGetAttachedDeviceReference , чтобы получить указатель на объект устройства для драйвера в верхней части стека устройств.