Riepilogo delle routine dispatch di lettura/scrittura
Quando si implementa una routine DispatchRead, DispatchWrite o DispatchReadWrite , tenere presente quanto segue:
È responsabilità del driver di livello più alto in una catena di driver a più livelli controllare i parametri dei runtime di integrazione di lettura/scrittura in ingresso per la validità prima di configurare la posizione dello stack I/O del driver di livello inferiore successivo in un IRP.
I driver intermedi e di livello più basso in genere possono basarsi sul driver di livello più alto nella catena per passare le richieste di trasferimento con parametri validi. Tuttavia, qualsiasi driver può eseguire controlli di integrità sui parametri nel percorso dello stack I/O di un IRP e ogni driver di dispositivo deve controllare i parametri per le condizioni che potrebbero violare eventuali restrizioni imposte dal dispositivo.
Se una routine DispatchReadWrite completa un IRP con un errore, deve impostare il membro Status della posizione dello stack I/O con un valore di tipo NTSTATUS appropriato, impostare il membro Information su zero e chiamare IoCompleteRequest con IRP e PriorityBoost di IO_NO_INCREMENT.
Se un driver usa operazioni di I/O memorizzate nel buffer, potrebbe essere necessario definire una struttura per contenere dati da trasferire e potrebbe essere necessario memorizzare nel buffer un certo numero di queste strutture internamente.
Se un driver usa operazioni di I/O dirette, potrebbe essere necessario verificare se MDL in Irp-MdlAddress> descrive un buffer contenente troppi dati (o troppe interruzioni di pagina) per il dispositivo sottostante da gestire in una singola operazione di trasferimento. In tal caso, il driver deve suddividere la richiesta di trasferimento originale in una sequenza di operazioni di trasferimento più piccole.
Un driver di classe strettamente accoppiato potrebbe suddividere tale richiesta nella routine DispatchReadWrite per il driver di porta sottostante. A tale scopo, sono necessari driver di classe SCSI, in particolare per i dispositivi di archiviazione di massa. Per altre informazioni sui requisiti per i driver SCSI, vedere Driver di archiviazione.
La routine DispatchReadWrite di un driver di dispositivo di livello inferiore deve posticipare la suddivisione di una richiesta di trasferimento di grandi dimensioni in trasferimenti parziali fino a quando un altro driver non accoda l'IRP per configurare il dispositivo per il trasferimento.
Se un driver di dispositivo di livello inferiore accoda un IRP di lettura/scrittura per un'ulteriore elaborazione in base alle proprie routine, deve chiamare IoMarkIrpPending prima di accodare l'IRP. Anche la routine DispatchReadWrite deve restituire il controllo con STATUS_PENDING in queste circostanze.
Se la routine DispatchReadWrite passa un IRP ai driver inferiori, è necessario configurare la posizione dello stack di I/O per il driver inferiore successivo in IRP. Se il driver di livello superiore imposta anche una routine IoCompletion in IRP prima di passarla con IoCallDriver dipende dalla progettazione del driver e da quelle sovrapposte al suo interno.
Tuttavia, un driver di livello superiore deve chiamare IoSetCompletionRoutine prima di chiamare IoCallDriver se alloca risorse, ad esempio IRP o memoria. La routine IoCompletion deve liberare tutte le risorse allocate dal driver quando i driver inferiori hanno completato la richiesta, ma prima che la routine IoCompletion chiami IoCompleteRequest con l'IRP originale.
Se un driver di livello superiore alloca i provider di integrazione per driver inferiori che potrebbero includere un driver di dispositivo rimovibile sottostante, il driver di allocazione deve stabilire il contesto del thread in ogni IRP allocato.