Организация ввода-вывода. Драйверы WDM. Рощин А.В. - 52 стр.

UptoLike

Составители: 

52
IoCopyCurrentIrpStackLocationToNext копирует все поля
IO_STACK_LOCATION из текущей позиции в следующую. При этом не
копируются поля, связанные с функциями завершения ввода-вывода.
3.10 Постановка IRP в очередь для последующей обработки
Постановка IRP в очередь для последующей обработкитретий возможный
вариант поведения диспетчерской функции. Приведенный ниже фрагмент кода
предполагает, что для работы с
очередями IRP используется объект DEVQUEUE:
NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)
{
IoMarkIrpPending(Irp); //a
StartPacket(&pdx->dqSomething, fdo, Irp, CancelRoutine);//b
return STATUS_PENDING; //c
}
a. Эту функцию следует вызывать всегда, когда диспетчерская функция
возвращает STATUS_PENDING.
b. Если устройство в данный момент занято или остановлено из-за события
PnP или управления питанием, функция StartPacket помещает запрос в
очередь; в противном случае устройство помечается как занятое, и
вызывается функция StartIo.
c. Возврат STATUS_PENDING говорит о том, что
обработка IRP еще не
завершена.
Следует отметить, что после вызова StartPacket не следует обращаться к
IRP, так как к моменту возврата управления из этой функции IRP может
оказаться завершенным, а занимаемая им памятьосвобожденной.
3.11 Функция StartIo
Функция StartIo часто используется для обработки IRP в очередях. В
приведенном ниже примере собственно
обработка IRP изображена многоточием.
VOID StartIo(PDEVICE_OBJECT device, PIRP Irp)
     …
     IoCopyCurrentIrpStackLocationToNext        копирует         все   поля
IO_STACK_LOCATION из текущей позиции в следующую. При этом не
копируются поля, связанные с функциями завершения ввода-вывода.


     3.10 Постановка IRP в очередь для последующей обработки
     Постановка IRP в очередь для последующей обработки – третий возможный
вариант поведения диспетчерской функции. Приведенный ниже фрагмент кода
предполагает, что для работы с очередями IRP используется объект DEVQUEUE:
     NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)
     {
     …
     IoMarkIrpPending(Irp);      //a
     StartPacket(&pdx->dqSomething, fdo, Irp, CancelRoutine);//b
     return STATUS_PENDING;      //c
     }
     a. Эту функцию следует вызывать всегда, когда диспетчерская функция
         возвращает STATUS_PENDING.
     b. Если устройство в данный момент занято или остановлено из-за события
         PnP или управления питанием, функция StartPacket помещает запрос в
         очередь; в противном случае устройство помечается как занятое, и
         вызывается функция StartIo.
     c. Возврат STATUS_PENDING говорит о том, что обработка IRP еще не
         завершена.
     Следует отметить, что после вызова StartPacket не следует обращаться к
IRP, так как к моменту возврата управления из этой функции IRP может
оказаться завершенным, а занимаемая им память – освобожденной.


     3.11 Функция StartIo
     Функция StartIo часто используется для обработки IRP в очередях. В
приведенном ниже примере собственно обработка IRP изображена многоточием.
     VOID StartIo(PDEVICE_OBJECT device, PIRP Irp)
                                       52