Поделиться через


Подпрограммы DispatchPnP

Подпрограмма DispatchPnP драйвера поддерживает Plug and Play, обрабатывая IRP для кода функции ввода-вывода IRP_MJ_PNP. Связанные с кодом функции IRP_MJ_PNP являются несколько дополнительных кодов функций ввода-вывода (см. Plug and Play Minor IRPs), некоторые из которых должны обрабатываться всеми драйверами, а некоторые могут обрабатываться по желанию. Диспетчер PnP использует эти дополнительные коды функций для направления драйверов для запуска, остановки и удаления устройств, а также для запроса драйверов о своих устройствах.

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

Подпрограмма DispatchPnP каждого драйвера должна соответствовать следующим правилам:

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

    Все драйверы для устройства должны иметь возможность обрабатывать PnP IRP для устройства, если только один из драйверов не сталкивается с ошибкой. Диспетчер PnP отправляет IRP в верхний драйвер в стеке устройств. Функциональные драйверы и фильтрующие драйверы передают IRP следующему драйверу, а родительский драйвер шины завершает IRP. Дополнительные сведения см. в статье об передаче PnP IRP вниз по стеку устройств .

    Драйвер может завершить IRP с ошибкой, если он пытается обработать IRP и обнаруживает проблему (например, недостаточно ресурсов). Если драйвер получает IRP с кодом, который он не обрабатывает, он не должен помечать IRP как ошибочный. Он должен передать такой IRP следующему драйверу, не изменив статус IRP.

  • Драйвер должен обрабатывать определенные PnP IRPs и может также обрабатывать другие, если это необходимо.

    Каждый драйвер PnP требуется для обработки определенных IRP, таких как IRP_MN_REMOVE_DEVICE, и может при необходимости обрабатывать другие. Дополнительные сведения о необходимых и необязательных IRP для каждого типа драйверов (драйверов функций, драйверов фильтров и драйверов автобусов) см. в разделе Минорные IRP Plug and Play.

    Драйвер может завершить выполнение требуемого PnP IRP с соответствующим кодом ошибки; однако драйвер не должен возвращать STATUS_NOT_SUPPORTED для такого запроса.

  • Если драйвер успешно обрабатывает IRP PnP, он устанавливает состояние IRP как успешное. Он не зависит от другого драйвера в стеке, чтобы задать состояние.

    Драйвер задает для Irp-IoStatus.Status> значение STATUS_SUCCESS, чтобы сообщить диспетчеру PnP, что драйвер успешно обработал IRP. Для некоторых IRPs не драйвер шины может полагаться на родительский драйвер шины, чтобы установить статус на успех. Однако это рисконая практика. Для обеспечения согласованности и надежности драйвер должен устанавливать статус IRP на "успешно" для каждого успешно обработанного IRP PnP.

  • Если драйвер не проходит IRP, он завершает IRP с состоянием ошибки и не передает IRP следующему драйверу.

    Чтобы вызвать ошибку в IRP, например IRP_MN_QUERY_STOP_DEVICE, драйвер устанавливает Irp->IoStatus.Status в STATUS_UNSUCCESSFUL. Дополнительные значения состояния ошибки для других IRPs включают STATUS_INSUFFICIENT_RESOURCES и STATUS_INVALID_DEVICE_STATE.

    Драйверы не задают STATUS_NOT_SUPPORTED для IRP, которые они обрабатывают. Это начальное состояние, заданное диспетчером PnP. Если IRP завершен с этим состоянием, это означает, что драйверы в стеке не обрабатывали IRP; все драйверы только что передали IRP следующему драйверу.

  • Драйвер должен обрабатывать PnP IRP в подпрограмме обработки (на пути IRP вниз по стеку устройств), в подпрограмме IoCompletion (на пути обратно вверх по стеку устройства), или в обоих, как указано на справочной странице для IRP.

    Некоторые IRP PnP, такие как IRP_MN_REMOVE_DEVICE, должны обрабатываться сначала драйвером на вершине стека устройства, а затем каждым последующим нижестоящим драйвером. Другие, такие как IRP_MN_START_DEVICE, должны обрабатываться в первую очередь драйвером родительской шины. Тем не менее, другие, такие как IRP_MN_QUERY_CAPABILITIES, могут обрабатываться как при спуске вниз по стеку устройств, так и при возврате назад. См. небольшие IRP Plug and Play для получения правил, которые применяются к каждому PnP IRP. Сведения об обработке PnP iRP см. в разделе "Отложенная обработка IRP" до тех пор, пока нижние драйверы не завершают обработку PnP IRP, которые должны обрабатываться первым водителем родительской шины.

  • Драйвер должен добавлять информацию в IRP на его пути вниз по стеку устройств и изменять или удалять информацию, когда он возвращается вверх.

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

  • За исключением случаев, когда это явно задокументировано, драйвер не должен зависеть от того, что PnP IRP отправляются в каком-либо конкретном порядке.

  • Когда драйвер отправляет PnP IRP, он должен отправить IRP в драйвер верхнего уровня в стеке устройств.

    Большинство PnP IRP отправляются диспетчером PnP, но некоторые из них могут отправляться драйверами (например, IRP_MN_QUERY_INTERFACE). Драйвер должен отправить PnP IRP находящемуся на вершине стека устройств драйверу. Вызовите IoGetAttachedDeviceReference, чтобы получить указатель на объект устройства для драйвера в вершине стека устройств.