Программирование драйверов Windows


Исполняемый код драйвера - часть 2


Функционально работу модифицированного драйвера можно описать следующим образом.

Драйвер получает IOCTL запрос IOCTL_SEND_TO_PORT от клиента (тестирующего приложения), откладывает запрос в системную очередь (см. описание механизма System Queuing в 6 главе) и завершает обработку IRP пакета, помечая его как завершенный в состоянии STATUS_PENDING, указывая на всякий случай процедуру CancelRoutine драйвера. Эта процедура получит управление, если клиент решит отменить запрос. Заметим, что такая ситуация возникает, когда тестирующее приложение запускается в отсутствие заглушки CheckIt в параллельном порту. Пакет не может быть завершен, и приложение простаивает в ожидании окончания синхронного вызова DeviceIoControl

&#8212 снятие приложения приводит к вызову CancelRoutine.

При извлечении IRP пакета из очереди Диспетчер ввода/вывода вызывает зарегистрированную в DriverEntry функцию StartIo, которая проверяет условия своего вызова, записывает в pIrpStack-&#62Parameters.DeviceIoControl.Type3InputBuffer ноль и планирует работу DPC функции DpcForIsr вызовом IoRequestDpc. Заметим, что это проходит вполне корректно (несмотря на то, что IoRequestDpc

необходимо вызывать на уровнях IRQL не ниже DISPATCH_LEVEL), поскольку сама функция StartIo работает на IRQL равном DISPATCH_LEVEL.

Работа DpcForIsr при первом вызове сводится к выводу первого байта (точнее половины байта) в порт и запуску первого прерывания, после чего срабатывает цепная реакция Isr-DpcForIsr-перенос/прерывание-Isr до полного переноса всей порции данных, поступивших по IOCTL запросу IOCTL_SEND_TO_PORT от клиента (тестирующего приложения). При выполнении переноса и при условии, что предварительно клиент запросил использование объекта события, процедура DpcForIsr выполняет установку объекта события в сигнальное состояние и таким образом сигнализирует клиенту, что перенос завершен. Тут следует обратить внимание, что, при условии регистрации объекта события, когда клиент решил отменить свой запрос на запись в порт и управление получает функция CancelRoutine, то ее код должен что-то сделать с объектом события.


Начало  Назад  Вперед