Condividi tramite


Implementazione di una routine annulla

La gestione I/O chiama una routine Cancel fornita dal driver con un'IRP di input da annullare e un puntatore DeviceObject che rappresenta il dispositivo di destinazione per la richiesta di I/O.

L'IRP potrebbe essere uno che la routine DispatchReadWrite del driver ha accodato proprio come l'applicazione Win32 corrente viene chiusa dall'utente. L'IRP può anche essere uno che un driver di livello superiore ha annullato in modo esplicito, a seconda della natura del dispositivo sottostante.

Quando viene chiamata la routine Cancel , l'IRP di input potrebbe essere già CurrentIrp nell'oggetto dispositivo di destinazione o potrebbe essere già presente nella coda di dispositivi associata all'oggetto dispositivo di destinazione se il driver ha una routine StartIo . Se il driver non ha una routine StartIo , l'IRP potrebbe trovarsi in una coda interna gestita da driver di IRP quando viene chiamata la routine Cancel . In qualsiasi caso, prima che il gestore I/O chiami la routine Cancel per l'IRP in ingresso, il gestore I/O imposta il membro Cancel in questo IRP su TRUE e imposta il membro CancelRoutine in IRP su NULL.

La routine Annulla per un'IRP master che ha associato IoCancelIrp è responsabile della chiamata di IoCancelIrp per annullare tali ip associati.

Tutte le routine Annulla devono seguire queste linee guida:

  • Chiamare IoReleaseCancelSpinLock per rilasciare il blocco di spin spin annulla del sistema.

  • Impostare il membro Stato di I/O su STATUS_CANCELLED e impostare il membro Informazioni su zero.

  • Completare l'IRP specificato chiamando IoCompleteRequest.

  • Poiché una routine Cancel viene sempre chiamata con il blocco di spin di annullamento del sistema, questa routine non deve chiamare IoAcquireCancelSpinLock a meno che non chiami prima IoReleaseCancelSpinLock .

  • Una routine Annulla non può contenere il blocco di rotazione del sistema quando restituisce il controllo. Vale a dire, ogni routine Cancel deve chiamare IoReleaseCancelSpinLock almeno una volta prima che restituisca il controllo.

  • Se chiama IoAcquireCancelSpinLock, una routine Cancel deve effettuare la chiamata reciproca a IoReleaseCancelSpinLock il più rapidamente possibile.

  • Non chiamare mai IoCompleteRequest con un'IRP tenendo premuto un blocco di rotazione. Il tentativo di completare un'IRP mantenendo un blocco di rotazione può causare deadlock.