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

       

Случай 3: Работа через очереди IRP пакетов


Разумеется, простейший драйвер может инициализировать свое устройство в процедуре DriverEntry, в обработчике запросов IRP_MJ_READ сразу же считывать данные из устройства (например, LPT порта). Тем не менее, полномасштабный ритуал работы с подсистемой ввода/вывода Windows (то есть Диспетчером ввода/вывода) диктует иную последовательность действия. Рабочая процедура должна поместить пакет IRP в очередь для последующей обработки процедурой StartIO и сразу же возвратить Диспетчеру ввода/вывода сообщение о том, что обработка IRP не завершена, а именно:

  • Выполнить вызов IoMarkIrpPending &#8212 чтобы информировать Диспетчера ввода/вывода о том, что пакет IRP поставлен в очередь на обработку.
  • Выполнить вызов IoStartPacket, чтобы поместить пакет IRP в системную очередь для последующей его обработки процедурой StartIO. Драйвер может реализовывать и свои очереди IRP пакетов.
  • Возвратить управление из рабочей процедуры с кодом завершения STATUS_PENDING.
  • Фрагмент кода, приведенный ниже, демонстрирует, как рабочая процедура размещает IRP запрос в очереди на обработку.

    NTSTATUS ReadRequestHandler( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { : // IRP "в работе", но работа с ним будет происходить // через очередь пакетов (в данном случае - системную): IoMarkIrpPending( pIrp );

    // Четвертый параметр позволяет указывать процедуру удаления // CancelRoutine, что подробно обсуждается в конце главы 9. IoStartPacket( pDeviceObject, pIrp, 0, NULL );

    return STATUS_PENDING; }

    Некоторые источники указывают, что Диспетчер ввода/вывода автоматически завершает запросы, не помеченные кодом STATUS_PENDING, сразу же после получения управления из рабочей процедуры. Возможно, данный автоматически запускающийся механизм когда-то и работал именно так. Однако в доступных на сегодня версиях Windows это не подтверждается, то есть для нормального завершения обработки IRP пакета необходимо, чтобы текущий драйвер производил вызов IoCompleteRequest

    в конце обработки IRP пакета в своей рабочей процедуре (если только он не помечен как отложенный в системную очередь, STATUS_PENDING). К тому же, при этом условии будут запущены все процедуры завершения в вышестоящих драйверах, если таковые, конечно, имеются. Подробнее эти вопросы рассмотрены в главе 9.



    Содержание раздела