Configurazione e uso di code di dispositivi
Un driver configura un oggetto coda di dispositivi chiamando KeInitializeDeviceQueue all'inizializzazione del driver o del dispositivo. Dopo aver avviato i dispositivi, il driver inserisce irPs in questa coda chiamando KeInsertDeviceQueue o KeInsertByKeyDeviceQueue. La figura seguente illustra queste chiamate.
Come illustrato nella figura, il driver deve fornire l'archiviazione per un oggetto coda del dispositivo, che deve essere residente. I driver che configurano un oggetto coda di dispositivi in genere forniscono l'archiviazione necessaria nell'estensione del dispositivo di un oggetto dispositivo creato dal driver, ma l'archiviazione può essere in un'estensione del controller se il driver usa un oggetto controller o in un pool non a pagina allocato dal driver.
Se il driver fornisce l'archiviazione per l'oggetto coda del dispositivo in un'estensione del dispositivo, chiama KeInitializeDeviceQueue dopo aver creato l'oggetto dispositivo e prima di avviare il dispositivo. In altre parole, il driver può inizializzare la coda dalla routine AddDevice o quando gestisce una richiesta di IRP_MN_START_DEVICE PnP. Nella chiamata a KeInitializeDeviceQueue, il driver passa un puntatore all'archiviazione fornito per l'oggetto coda del dispositivo.
Dopo aver avviato i dispositivi, il driver può inserire un'IRP nella coda del dispositivo chiamando KeInsertDeviceQueue, che posiziona l'IRP alla fine della coda o KeInsertByKeyDeviceQueue, che inserisce l'IRP nella coda in base a un valore SortKey determinato dal driver, come illustrato nella figura precedente.
Ognuna di queste routine di supporto restituisce un valore booleano che indica se l'IRP è stato inserito nella coda. Ognuna di queste chiamate imposta anche lo stato dell'oggetto coda del dispositivo su Occupato se la coda è attualmente vuota (Non occupato). Tuttavia, se la coda è vuota (non occupato), né la routine KeInsertXxxDeviceQueue inserisce l'IRP nella coda. Imposta invece lo stato dell'oggetto coda del dispositivo su Occupato e restituisce FALSE. Poiché l'IRP non è stato accodato, il driver deve passarlo a un'altra routine driver per un'ulteriore elaborazione.
Quando si configurano code di dispositivi supplementari, seguire questa linea guida di implementazione:
Quando una chiamata a KeInsertXxxDeviceQueue restituisce FALSE, il chiamante deve passare l'IRP che ha tentato di accodare per un'ulteriore elaborazione a un'altra routine driver. Tuttavia, la chiamata a KeInsertXxxDeviceQueue modifica lo stato dell'oggetto coda del dispositivo su Occupato, quindi l'IRP successivo da inserire nella coda, a meno che il driver non chiami prima KeRemoveXxxDeviceQueue .
Quando lo stato dell'oggetto coda del dispositivo è impostato su Occupato, il driver può dequeuere un'IRP per un'ulteriore elaborazione o reimpostare lo stato su Not-Busy chiamando una delle routine di supporto seguenti:
KeRemoveDeviceQueue per rimuovere l'IRP alla testa della coda
KeRemoveByKeyDeviceQueue per rimuovere un'IRP scelta in base a un valore SortKey determinato dal driver
KeRemoveEntryDeviceQueue per rimuovere un determinato IRP nella coda o per determinare se una determinata IRP si trova nella coda
KeRemoveEntryDeviceQueue restituisce un valore Boolean che indica se l'IRP era nella coda del dispositivo.
Chiamando una di queste routine per rimuovere una voce da una coda del dispositivo vuota, ma occupato modifica lo stato della coda in Non occupato.
Ogni oggetto coda del dispositivo è protetto da un blocco di spin esecutivo predefinito (non visualizzato nella figura Uso di un oggetto coda dispositivo ). Di conseguenza, un driver può inserire irP nella coda e rimuoverli in modo multiprocessore-sicuro da qualsiasi routine driver in esecuzione in modo minore o uguale a IRQL = DISPATCH_LEVEL. A causa di questa restrizione IRQL, un driver non può chiamare alcuna routine KeXxxDeviceQueue dalle routine ISR o SynchCritSection , che vengono eseguite in DIRQL.
Per altre informazioni, vedere Gestione delle priorità hardware e dei blocchi di spin . Per i requisiti IRQL per una routine di supporto specifica, vedere la pagina di riferimento della routine.