Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Драйвер класса или любой другой драйвер более высокого уровня может выделить IRPs для запросов управления вводом-выводом и отправить их следующему ниже расположенному драйверу следующим образом:
Выделение или повторное использование пакета запросов ввода-вывода (IRP) с основным кодом функции IRP_MJ_DEVICE_CONTROL или IRP_MJ_INTERNAL_DEVICE_CONTROL. Вы можете использовать процедуру IoBuildDeviceIoControlRequest специально для выделения IOCTL IRP. Вы также можете использовать подпрограммы создания и инициализации IRP общего назначения, например IoAllocateIrp, IoReuseIrpили IoInitializeIrp. Дополнительные сведения о выделении IRP см. в разделе Создание IRP для драйверов нижнего уровня.
Настройте расположение стека ввода-вывода нижнего драйвера для IRP с помощью кода IOCTL_XXX и соответствующих параметров.
Если запрос IOCTL выполняется асинхронно, вызовите процедуру KeInitializeEvent для инициализации объекта события в качестве события уведомления. Драйвер использует это событие для ожидания завершения операции ввода-вывода.
Вызовите IoSetCompletionRoutine с помощью IRP, чтобы верхний драйвер мог при необходимости предоставить подпрограмму IoCompletion для выполнения следующих действий:
Определите, как нижний драйвер обрабатывает заданный запрос.
Использовать повторно IRP для отправки другого запроса или утилизировать IRP, созданный драйвером, после завершения запрошенной операции нижним драйвером. Драйвер не может повторно использовать IRP, которые были созданы с помощью IoBuildDeviceIoControlRequest. Дополнительные сведения см. в разделе Повторное использование IRPs.
Вызовите IoCallDriver, чтобы передать запрос на более низкий драйвер.
Если IoCallDriver возвращает STATUS_PENDING, вызовите подпрограмму KeWaitForSingleObject, чтобы поместить текущий поток в состояние ожидания. Драйвер устанавливает параметр подпрограммы на адрес объекта события, который был инициализирован в вызове KeInitializeEvent.
Примечание Если драйвер вызывает KeWaitForSingleObject с параметром Timeout установленным в NULL или адрес переменной, содержащей ненулевое значение, драйвер должен выполняться на уровне IRQL <= APC_LEVEL в контексте непрозвольного потока. В противном случае драйвер должен работать в IRQL <= DISPATCH_LEVEL.
Событие сигнализирует о его процедуре IoCompletion при завершении запроса IOCTL. После сигнала события поток возобновляет выполнение.
Важно Если драйвер выделяет объект события в качестве локальной переменной в стеке, драйвер должен вызвать KeWaitForSingleObject с параметром WaitMode WaitMode, равным KernelMode. Это значение параметра предотвращает выгрузку стека в файл подкачки.
Чтобы избежать проблем синхронизации и возможных нарушений доступа, параметры для кодов управления ввода-вывода редко включают внедренные указатели. За исключением определённых запросов SCSI, в буферах Irp—>AssociatedIrp.SystemBuffer, в Irp->MdlAddress, а также в Parameters.DeviceIoControl.Type3InputBuffer в расположении стека ввода-вывода драйвера не содержатся указатели на другие буферы данных и не содержатся структуры, содержащие указатели для системно определённых кодов управления вводом-выводом. Дополнительные сведения о том, как буферы данных используются с IRPs, содержащими коды управления ввода-вывода, см. в разделе Описания буферов для кодов управления ввода-вывода.
Тем не менее, пара драйверов классов/портов, определяющих внутренние коды управления ввода-вывода, может передавать встроенный указатель на память, выделенную драйвером более высокого уровня, драйверу нижнего уровня. Такая пара драйверов класс/порт отвечает за обеспечение соблюдения следующих условий:
Доступ к данным может получить только один драйвер за раз.
Буферы частных данных доступны в произвольном контексте потока драйвером порта.
Драйверы отображения могут вызывать функцию GDI EngDeviceIoControl, чтобы отправлять как частные, определяемые устройством запросы управления вводом-выводом, так и публичные системные запросы, через системный драйвер видеопорта к соответствующим драйверам видеоминипортов .
Любой компонент пользовательского режима пакета драйвера может вызывать DeviceIoControl для отправки запросов управления ввода-вывода в стек драйверов. Диспетчер ввода-вывода создает запрос IRP_MJ_DEVICE_CONTROL и передает его драйверу высокого уровня.