Condividi tramite


Uso di Rimuovi blocchi

Le routine di rimozione dei blocchi consentono di tenere traccia del numero di operazioni di I/O in sospeso in un dispositivo e di determinare quando è sicuro scollegare ed eliminare l'oggetto dispositivo di un driver. Il sistema fornisce queste routine ai writer di driver come alternativa all'implementazione del proprio meccanismo di rilevamento.

Un driver può usare questo meccanismo per due scopi:

  1. Per assicurarsi che la routine DispatchPnP del driver non completi una richiesta di IRP_MN_REMOVE_DEVICE mentre il blocco viene mantenuto (ad esempio, mentre un'altra routine driver accede al dispositivo).

  2. Per contare il numero di motivi per cui il driver non deve eliminare l'oggetto dispositivo e impostare un evento quando tale conteggio diventa zero.

Per inizializzare un blocco di rimozione, un driver deve allocare una struttura IO_REMOVE_LOCK nella relativa estensione del dispositivo e quindi chiamare IoInitializeRemoveLock. Un driver chiama in genere IoInitializeRemoveLock nella routine AddDevice , quando il driver inizializza il resto dell'estensione del dispositivo per un oggetto dispositivo.

Il driver deve chiamare IoAcquireRemoveLock ogni volta che avvia un'operazione di I/O. Il driver deve chiamare IoReleaseRemoveLock ogni volta che termina un'operazione di I/O. Un driver può acquisire il blocco più volte. Le routine di blocco di rimozione mantengono un conteggio delle acquisizioni in sospeso del blocco. Ogni chiamata a IoAcquireRemoveLock incrementa il conteggio e IoReleaseRemoveLock decrementa il conteggio.

Il driver deve anche chiamare IoAcquireRemoveLock quando passa un riferimento al codice (per timer, CONTROLLER di dominio, callback e così via). Il driver deve quindi chiamare IoReleaseRemoveLock quando l'evento è stato restituito.

Nel codice di invio per IRP_MN_REMOVE_DEVICE, il driver deve acquisire il blocco ancora una volta e quindi chiamare IoReleaseRemoveLockAndWait. Questa routine non restituisce fino a quando non vengono rilasciate tutte le acquisizioni in sospeso del blocco. Per consentire il completamento delle operazioni di I/O in coda, ogni driver deve chiamare IoReleaseRemoveLockAndWait dopo aver superato la richiesta di IRP_MN_REMOVE_DEVICE al driver inferiore successivo e prima di rilasciare memoria, chiama IoDetachDevice o chiama IoDeleteDevice. Dopo che IoReleaseRemoveLockAndWait è stato chiamato per un blocco di rimozione specifico, tutte le chiamate successive a IoAcquireRemoveLock per lo stesso blocco di rimozione avranno esito negativo.

Dopo la restituzione di IoReleaseRemoveLockAndWait , il driver deve considerare il dispositivo in uno stato in cui è pronto per essere rimosso e non può eseguire operazioni di I/O. Pertanto, il driver non deve chiamare IoInitializeRemoveLock per inizializzare nuovamente il blocco di rimozione. La violazione di questa regola mentre il driver viene verificato da Driver Verifier genererà un controllo dei bug.

Poiché un driver archivia una struttura IO_REMOVE_LOCK nell'estensione del dispositivo di un oggetto dispositivo, il blocco di rimozione viene eliminato quando il driver elimina l'estensione del dispositivo durante l'elaborazione di una richiesta di IRP_MN_REMOVE_DEVICE .