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

UptoLike

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

66
Рисунок 3.8 – Передача вниз с функцией завершения
Для применения этой стратегии необходимы два условия:
IRP может поступить на уровне DISPATCH_LEVEL в контексте
произвольного потока (то есть, блокировка во время обработки IRP
драйверами низшего уровня невозможна),
если необходимо, заключительная обработка может выполняться на
уровне DISPATCH_LEVEL (так как функции завершения могут
вызываться на этом уровне).
Код диспетчерской функции и функции завершения может выглядеть
примерно так:
NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)
{
PDEVICE_EXTENSION pdx =
(PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status = IoAcqureRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status);
IoCopyCurrentIrpStacklocationToNext(Irp);
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE) CompletionRoutine,
pdx, TRUE, TRUE, TRUE);
return IoCallDriver(pdx->LowerDeviceObject, Irp);
}
NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp,
                Рисунок 3.8 – Передача вниз с функцией завершения
     Для применения этой стратегии необходимы два условия:
     − IRP может поступить на уровне DISPATCH_LEVEL в контексте
        произвольного потока (то есть, блокировка во время обработки   IRP
        драйверами низшего уровня невозможна),
     − если необходимо, заключительная обработка может выполняться на
        уровне DISPATCH_LEVEL (так как функции завершения могут
        вызываться на этом уровне).
     Код диспетчерской функции и функции завершения может выглядеть
примерно так:
NTSTATUS DispatchSomething(PDEVICE_OBJECT fdo, PIRP Irp)
 {
 PDEVICE_EXTENSION pdx =
  (PDEVICE_EXTENSION) fdo->DeviceExtension;
 NTSTATUS status = IoAcqureRemoveLock(&pdx->RemoveLock, Irp);
 if (!NT_SUCCESS(status))
  return CompleteRequest(Irp, status);
 IoCopyCurrentIrpStacklocationToNext(Irp);
 IoSetCompletionRoutine(Irp,
  (PIO_COMPLETION_ROUTINE) CompletionRoutine,
  pdx, TRUE, TRUE, TRUE);
 return IoCallDriver(pdx->LowerDeviceObject, Irp);
 }
NTSTATUS CompletionRoutine(PDEVICE_OBJECT fdo, PIRP Irp,

                                       66