Pre-elaborazione e post-elaborazione dei runtime di integrazione

[Si applica solo a KMDF]

Se il driver deve intercettare un pacchetto di richiesta di I/O prima o dopo che il framework gestisce l'IRP, il driver può chiamare WdfDeviceInitAssignWdmIrpPreprocessCallback per registrare una funzione di callback di eventi EvtDeviceWdmIrpPreprocess per un codice di funzione I/O principale e, facoltativamente, per codici di funzione di I/O secondari specifici associati al codice principale. Successivamente, il framework chiama la funzione di callback EvtDeviceWdmIrpPreprocess del driver ogni volta che il driver riceve un IRP che contiene un codice di funzione principale e secondario specificato.

La funzione di callback EvtDeviceWdmIrpPreprocess può eseguire qualsiasi operazione necessaria per pre-elaborare l'IRP e quindi deve chiamare WdfDeviceWdmDispatchPreprocessedIrp per restituire l'IRP al framework a meno che il driver non gestisca un IRP che il framework non supporta.

Dopo che il driver chiama WdfDeviceWdmDispatchPreprocessedIrp, il framework elabora l'IRP nello stesso modo in cui avrebbe avuto se il driver non avesse fornito una funzione di callback EvtDeviceWdmIrpPreprocess . Se il codice della funzione I/O di IRP è uno che il framework passa ai driver, il driver riceverà di nuovo l'IRP come oggetto richiesta.

Se il driver deve eseguire la post-elaborazione di IRP dopo il completamento di un driver di livello inferiore, la funzione di callback EvtDeviceWdmIrpPreprocess del driver può chiamare IoSetCompletionRoutine per impostare una routine IoCompletion prima di chiamare WdfDeviceWdmDispatchPreprocessedIrp.

Dopo che il driver chiama WdfDeviceInitAssignWdmIrpPreprocessCallback, il framework fa sì che il gestore di I/O aggiunga un percorso dello stack di I/O aggiuntivo a tutti i provider di integrazione in modo che la funzione di callback EvtDeviceWdmIrpPreprocess possa impostare una routine IoCompletion . La funzione di callback deve aggiornare il puntatore alla posizione dello stack I/O di IRP prima di chiamare WdfDeviceWdmDispatchPreprocessedIrp.

Chiamata a WdfDeviceWdmDispatchPreprocessedIrp

Poiché il gestore di I/O aggiunge un percorso dello stack I/O aggiuntivo all'IRP, la funzione di callback EvtDeviceWdmIrpPreprocess deve chiamare IoSkipCurrentIrpStackLocation o IoCopyCurrentIrpStackLocationToNext (per configurare la posizione successiva dello stack di I/O in IRP) prima di chiamare WdfDeviceWdmDispatchPreprocessedIrp.

Se il driver esegue la pre-elaborazione di un IRP, ma non esegue la post-elaborazione di IRP, il driver non deve impostare una routine IoCompletion per IRP e può chiamare IoSkipCurrentIrpStackLocation, come illustrato nell'esempio di codice seguente.

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);
}

Se il driver esegue la post-elaborazione di IRP, il driver deve chiamare IoCopyCurrentIrpStackLocationToNext e quindi deve chiamare IoSetCompletionRoutine per impostare una routine IoCompletion per IRP, come illustrato nell'esempio di codice seguente.

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);
}

Il driver non deve chiamare IoCopyCurrentIrpStackLocationToNext (e pertanto non deve impostare una routine IoCompletion ) se l'handle dell'oggetto dispositivo che la funzione di callback EvtDeviceWdmIrpPreprocess del driver riceve rappresenta un oggetto dispositivo fisico (PDO) e se il codice della funzione principale di IRP è IRP_MJ_PNP o IRP_MJ_POWER. In caso contrario, Driver Verifier segnala un errore.

Per altre informazioni su quando chiamare IoCopyCurrentIrpStackLocationToNext, IoSkipCurrentIrpStackLocation e IoSetCompletionRoutine, vedere Passaggio di runtime di integrazione nello stack di driver.