Condividi tramite


Elaborazione di IRP in un driver di Intermediate-Level

I driver di livello superiore hanno un set diverso di routine standard rispetto ai driver di dispositivo di livello più basso, con un subset sovrapposto di routine standard comuni a entrambi i tipi di driver.

Il set di routine per i driver intermedi e di livello più alto varia anche in base ai criteri seguenti:

  • Natura del dispositivo fisico sottostante

  • Se un driver di dispositivo sottostante configura oggetti dispositivo per I/O diretto o memorizzato nel buffer

  • Progettazione del singolo driver di livello superiore

Nella figura seguente viene illustrato il percorso in cui potrebbe essere eseguito un'IRP nelle routine standard di un driver mirror intermedio a livelli sopra il driver di dispositivo di livello più basso descritto nella sezione precedente.

Il driver illustrato nella figura seguente presenta le caratteristiche seguenti:

  • Il driver viene stratiato su più di un dispositivo fisico e possibilmente su più di un driver di dispositivo.

  • Il driver a volte alloca altri IRP per i driver di livello inferiore, a seconda dell'operazione richiesta nell'IRP di input.

  • Il driver ha almeno un driver di file system a livelli sopra di esso e che il driver del file system potrebbe essere stratiato su altri driver intermedi a un livello superiore a questo.

diagramma che illustra un percorso irp attraverso routine del driver intermedio.

Come illustrato nella figura, il gestore I/O crea un'IRP e lo invia alla routine di invio del driver per il codice di funzione principale specificato. Supponendo che il codice della funzione sia IRP_MJ_WRITE, la routine di invio è DDDispatchWrite. La posizione dello stack I/O intermedio viene visualizzata al centro, con un numero illimitato di posizioni dello stack di I/O per driver di livello superiore e inferiore mostrati in ombreggiatura.

Allocazione di INDIRIZZI DI accesso

Lo scopo del driver mirror è inviare richieste di scrittura a diversi dispositivi fisici e inviare richieste di lettura in alternativa ai driver di questi dispositivi. Per le richieste di scrittura, il driver crea irP duplicati per ogni dispositivo in cui i dati devono essere scritti, presupponendo che i parametri nell'IRP di input siano validi.

La figura precedente mostra una chiamata a IoAllocateIrp ma i driver di livello superiore possono chiamare altre routine di supporto per allocare irP per i driver di livello inferiore. Vedere Creazione di IRP per i driver di Lower-Level.

Quando la routine di invio chiama IoAllocateIrp, specifica il numero di posizioni dello stack di I/O necessarie per l'IRP. Il driver deve specificare una posizione dello stack per ogni driver inferiore della catena, ottenendo il valore appropriato dagli oggetti dispositivo di ogni driver appena sotto il driver mirror. Facoltativamente, il driver può aggiungere uno a questo valore quando chiama IoAllocateIrp per ottenere una posizione dello stack personalizzata per ogni IRP allocata, come avviene nel driver nella figura precedente.

La routine di invio del driver intermedio chiama IoGetCurrentIrpStackLocation (non visualizzata) con l'IRP originale per controllare i parametri.

Chiama IoSetNextIrpStackLocation perché ha allocato la propria posizione dello stack in ogni nuova IRP e IoGetCurrentIrpStackLocation per creare un contesto per se stesso che viene usato più avanti nella routine IoCompletion .

Successivamente, chiama IoGetNextIrpStackLocation con ogni IRP appena creato in modo che possa configurare le posizioni dello stack I/O di livello inferiore successivo nei irP allocati. La routine di invio del driver mirror copia i codici e i parametri della funzione IRP (puntatore al buffer di trasferimento, lunghezza in byte da trasferire per IRP_MJ_WRITE) nelle posizioni dello stack di I/O per i driver inferiori successivi. Questi driver, a sua volta, configurano le posizioni dello stack di I/O per i driver appena sotto di essi, se presenti.

Chiamata di IoSetCompletionRoutine e IoCallDriver

La routine di invio nella figura precedente chiama IoSetCompletionRoutine per ogni IRP allocata. Poiché il driver nella figura precedente deve eliminare gli IRP allocati, questo driver imposta la routine IoCompletion da chiamare quando i driver inferiori completano i relativi IRP, se l'operazione di I/O è stata completata correttamente, non riuscita o annullata.

Poiché il driver nella figura precedente si specchia in parallelo, passa entrambi gli IP allocati ai driver di livello inferiore successivo chiamando IoCallDriver due volte, una volta per ogni oggetto dispositivo di destinazione che rappresenta una partizione con mirroring.

Elaborazione di IRP nella routine IoCompletion del driver

Quando un set di driver di livello inferiore completa l'operazione richiesta, il gestore I/O chiama la routine IoCompletion del driver mirror intermedio. Il driver mirror gestisce un conteggio nella propria posizione dello stack di I/O per l'IRP originale, per tenere traccia del completamento di tutti gli IR duplicati.

Supponendo che il blocco di stato I/O indica che un set di driver inferiori ha completato l'IRP duplicato mostrato nella figura precedente, la routine IoCompletion del driver mirror decrementa il conteggio, ma non può completare l'IRP originale fino a quando non decresce il conteggio su zero. Se il conteggio decrementato non è ancora zero, la routine IoCompletion chiama IoFreeIrp con il primo IRP (DupIRP1 nella figura precedente) che il driver allocato e restituisce STATUS_MORE_PROCESSING_REQUIRED.

Quando la routine IoCompletion del driver mirror viene chiamata di nuovo con la DupIRP2 illustrata nella figura precedente, la routine IoCompletion decrementa il conteggio nell'IRP originale e determina che entrambi i set di driver di livello inferiore hanno eseguito le operazioni richieste.

Supponendo che il blocco di stato I/O in DupIRP2 sia impostato anche con STATUS_SUCCESS, la routine IoCompletion copia il blocco di stato I/O da DupIRP2 nell'IRP originale e libera DupIRP2. Chiama IoCompleteRequest con l'IRP originale e restituisce STATUS_MORE_PROCESSING_REQUIRED. La restituzione di questo stato impedisce al gestore di I/O di tentare di eseguire ulteriori operazioni di completamento in DupIRP2; poiché l'IRP non è associato a un thread, l'elaborazione del completamento deve terminare con il driver che lo ha creato.

Se uno dei driver di livello inferiore non completa correttamente gli IRP del driver mirror, la routine IoCompletion del driver mirror deve registrare un errore e tentare il ripristino appropriato dei dati con mirroring. Per altre informazioni, vedere Registrazione degli errori.