Condividi tramite


Passaggio di runtime di integrazione nello stack di driver

Quando la routine dispatch di un driver riceve un IRP, deve chiamare IoGetCurrentIrpStackLocation in modo che possa controllare il proprio percorso dello stack di I/O e determinare che i parametri sono validi. Se il driver non può soddisfare e completare la richiesta stessa, può eseguire una delle operazioni seguenti:

  • Passare l'IRP per un'ulteriore elaborazione da parte dei driver di livello inferiore.

  • Creare uno o più nuovi runtime di integrazione e passarli ai driver di livello inferiore.

Un driver di livello superiore deve passare una richiesta di I/O a un driver inferiore successivo come indicato di seguito:

  1. Se il driver passerà l'IRP di input al driver di livello inferiore successivo, la routine dispatch deve chiamare IoSkipCurrentIrpStackLocation o IoCopyCurrentIrpStackLocationToNext per configurare il percorso dello stack di I/O del driver inferiore successivo.

    Se il driver chiama IoAllocateIrp per allocare uno o più IRP aggiuntivi per i driver inferiori, la routine dispatch deve inizializzare la posizione dello stack I/O del driver inferiore successivo seguendo i passaggi descritti in Elaborazione dei runtime di integrazione in un driver Intermediate-Level.

    La routine dispatch può modificare alcuni dei parametri nella posizione dello stack I/O del driver inferiore successivo per determinate richieste. Ad esempio, un driver di livello superiore potrebbe modificare i parametri per una richiesta di trasferimento di grandi dimensioni quando il dispositivo sottostante ha un limite noto nella capacità di trasferimento e riutilizzare l'IRP per inviare richieste di trasferimento parziale al driver di dispositivo sottostante.

  2. Chiamare IoSetCompletionRoutine.

    Se la routine dispatch passa un IRP ricevuto al driver inferiore successivo, l'impostazione di una routine IoCompletion è facoltativa ma utile, perché la routine può eseguire attività come determinare il modo in cui i driver inferiori hanno completato la richiesta, riusando l'IRP per trasferimenti parziali, aggiornando qualsiasi stato gestito dal driver se tiene traccia dei provider di integrazione e ritentando una richiesta restituita con un errore.

    Se la routine dispatch ha allocato nuovi runtime di integrazione, è necessaria l'impostazione di una routine IoCompletion perché la routine deve rilasciare ogni IRP dopo il completamento dei driver inferiori.

    Per altre informazioni sulle routine IoCompletion , vedere Completamento dei runtime di integrazione.

  3. Chiamare IoCallDriver con ogni IRP da elaborare con driver inferiori.

  4. Restituisce un valore NTSTATUS appropriato, ad esempio:

    • STATUS_PENDING

      Il driver restituisce in genere STATUS_PENDING se l'IRP di input è una richiesta asincrona, ad esempio IRP_MJ_READ o IRP_MJ_WRITE.

    • Risultato della chiamata a IoCallDriver

      Il driver restituisce spesso il risultato della chiamata a IoCallDriver se l'IRP di input è una richiesta sincrona, ad esempio IRP_MJ_CREATE.

Un driver di dispositivo di livello più basso passa qualsiasi IRP che non può completare nella routine dispatch su altre routine driver come indicato di seguito:

  1. Chiamare IoMarkIrpPending con l'IRP di input.

  2. Chiamare IoStartPacket per passare o accodare l'IRP alla routine StartIo del driver, a meno che il driver non gestisca il proprio accodamento IRP interno, come descritto in Code IRP gestite dal driver.

    Se il driver non dispone di una routine StartIo ma gestisce i runtime di integrazione annullabili, deve registrare una routine Cancel o implementare una coda IRP annullabile. Per altre informazioni sulle routine Cancel , vedere Annullamento dei runtime di integrazione.

  3. Restituisce STATUS_PENDING.