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

UptoLike

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

75
ваша заключительная обработка этого IRP должна выполняться на
уровне PASSIVE_LEVEL.
Типичным примером ситуации, в которой необходимо использовать этот
сценарийобработка запросов PnP подвида IRP_MN_START_DEVICE.
Рисунок 3.14 – Синхронная передачи IRP вниз по стеку
Две вспомогательные функции, показанные ниже, сильно упростят
выполнение синхронной передачи.
Тот, кто вызывает эту функцию, должен вызвать IoCompleteRequest для
IRP, захватить и освободить блокировку удаления. Логику блокировки и удаления
не следует размещать в ForwardAndWait, потому что это может вызвать
конфликт с вызывающей стороной.
NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
{
KEVENT event;
KeInitialize(&event, NotificationRoutine, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&event, Executive, KernelMode,
FALSE, NULL);
status = Irp->IoStatus.Status;
      − ваша заключительная обработка этого IRP должна выполняться на
         уровне PASSIVE_LEVEL.
      Типичным примером ситуации, в которой необходимо использовать этот
сценарий – обработка запросов PnP подвида IRP_MN_START_DEVICE.




             Рисунок 3.14 – Синхронная передачи IRP вниз по стеку
      Две вспомогательные функции, показанные ниже, сильно упростят
выполнение синхронной передачи.
      Тот, кто вызывает эту функцию, должен вызвать IoCompleteRequest для
IRP, захватить и освободить блокировку удаления. Логику блокировки и удаления
не следует размещать в ForwardAndWait, потому что это может вызвать
конфликт с вызывающей стороной.
NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
 {
 KEVENT event;
 KeInitialize(&event, NotificationRoutine, FALSE);
 IoCopyCurrentIrpStackLocationToNext(Irp);
 IoCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
  ForwardAndWaitCompletionRoutine, &event, TRUE, TRUE, TRUE);
 NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
 if (status == STATUS_PENDING)
  {
  KeWaitForSingleObject(&event, Executive, KernelMode,
     FALSE, NULL);
  status = Irp->IoStatus.Status;

                                     75