Udostępnij przez


Wstępne przetwarzanie i postprocessing IRPów

[Dotyczy tylko usługi KMDF]

Jeśli sterownik musi przechwycić pakiet żądania we/wy (IRP) przed lub po tym, jak struktura obsłuży protokół IRP, sterownik może wywołać WdfDeviceInitAssignWdmIrpPreprocessCallback, aby zarejestrować funkcję wywołania zwrotnego dla zdarzenia EvtDeviceWdmIrpPreprocess dla głównego kodu funkcji we/wy i opcjonalnie dla określonych pomocniczych kodów funkcji we/wy związanych z głównym kodem. Następnie struktura wywołuje funkcję wywołania zwrotnego EvtDeviceWdmIrpPreprocess za każdym razem, gdy sterownik otrzymuje IRP, który zawiera określony kod funkcji głównej i pomocniczej.

Funkcja EvtDeviceWdmIrpPreprocess wywołania zwrotnego może wykonać wszelkie czynności niezbędne do wstępnego przetwarzania IRP, a następnie wywołać WdfDeviceWdmDispatchPreprocessedIrp, aby zwrócić protokół IRP do struktury, chyba że sterownik jest obsługi IRP, że struktura nie obsługuje.

Po tym, jak sterownik wywoła WdfDeviceWdmDispatchPreprocessedIrp, framework przetwarza IRP w taki sam sposób, w jaki by to zrobił, gdyby sterownik nie dostarczył funkcji wywołania zwrotnego EvtDeviceWdmIrpPreprocess. Jeśli kod funkcji we/wy protokołu IRP jest taki, który platforma przekazuje do sterowników, sterownik otrzyma ponownie IRP jako obiekt żądania.

Jeśli sterownik musi przetworzyć IRP po ukończeniu IRP przez sterownik z warstwy niższej, funkcja wywołania zwrotnego EvtDeviceWdmIrpPreprocess może wywołać IoSetCompletionRoutine, aby ustawić routine IoCompletion przed wywołaniem WdfDeviceWdmDispatchPreprocessedIrp.

Po wywołaniu przez sterownik WdfDeviceInitAssignWdmIrpPreprocessCallback, struktura powoduje, że menedżer we/wy dodaje dodatkową lokalizację stosu we/wy do wszystkich IRP, aby funkcja wywołania zwrotnego EvtDeviceWdmIrpPreprocess mogła ustawić procedurę IoCompletion. Funkcja wywołania zwrotnego musi zaktualizować wskaźnik lokalizacji stosu we/wy protokołu IRP, zanim wywoła WdfDeviceWdmDispatchPreprocessedIrp.

Wywoływanie elementu WdfDeviceWdmDispatchPreprocessedIrp

Ponieważ menedżer we/wy dodaje dodatkowe miejsce stosu we/wy w IRP, funkcja wywołania zwrotnego EvtDeviceWdmIrpPreprocess musi wywołać funkcję IoSkipCurrentIrpStackLocation lub funkcję IoCopyCurrentIrpStackLocationToNext (w celu skonfigurowania następnej lokalizacji stosu we/wy w IRP) przed wywołaniem WdfDeviceWdmDispatchPreprocessedIrp.

Jeśli sterownik przetwarza wstępnie IRP, ale nie przetwarza IRP później, sterownik nie musi ustawiać procedury IoCompletion dla IRP i może wywołać IoSkipCurrentIrpStackLocation, jak pokazano w poniższym przykładzie kodu.

NTSTATUS
  EvtDeviceMyIrpPreprocess(
    IN WDFDEVICE Device,
    IN OUT PIRP Irp
    )
{
//
// Perform IRP preprocessing operations here.
//
...
//
// Deliver the IRP back to the framework. 
//
IoSkipCurrentIrpStackLocation(Irp);
return WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
}

Jeśli sterownik przetwarza protokół IRP po przetworzeniu, sterownik musi wywołać IoCopyCurrentIrpStackLocationToNext, a następnie wywołać IoSetCompletionRoutine, aby ustawić procedurę IoCompletion dla protokołu IRP, jak pokazano w poniższym przykładzie kodu.

NTSTATUS
  EvtDeviceMyIrpPreprocess(
    IN WDFDEVICE Device,
    IN OUT PIRP Irp
    )
{
//
// Perform IRP preprocessing operations here, if needed.
//
...
//
// Set a completion routine and deliver the IRP back to
// the framework. 
//
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(
                       Irp,
                       MyIrpCompletionRoutine,
                       NULL,
                       TRUE,
                       TRUE,
                       TRUE
                      );
return WdfDeviceWdmDispatchPreprocessedIrp(Device, Irp);
}

Sterownik nie może wywoływać IoCopyCurrentIrpStackLocationToNext (i dlatego nie może ustawić procedury IoCompletion), jeśli uchwyt obiektu urządzenia, który odbiera funkcja wywołania zwrotnego EvtDeviceWdmIrpPreprocess, reprezentuje obiekt urządzenia fizycznego (PDO), a główny kod funkcji IRP to IRP_MJ_PNP lub IRP_MJ_POWER. W przeciwnym razie Weryfikator Sterowników zgłosi błąd.

Aby uzyskać więcej informacji o tym, kiedy wywołać IoCopyCurrentIrpStackLocationToNext, IoSkipCurrentIrpStackLocationi IoSetCompletionRoutine, zobacz przekazywanie irps w dółstosu sterowników.