Udostępnij przez


Implementowanie procedury anulowania

Menedżer we/wy wywołuje dostarczoną przez sterownik procedurę Cancel z IRP do anulowania i wskaźnikiem DeviceObject, reprezentującym urządzenie docelowe dla żądania we/wy.

IRP może być takim, że procedura DispatchReadWrite sterownika została ustawiona w kolejce właśnie gdy aktualna aplikacja Win32 jest zamykana przez użytkownika. Protokół IRP może być również taki, który sterownik wyższego poziomu jawnie anulował, w zależności od charakteru urządzenia bazowego.

Po wywołaniu procedury Anuluj wejście IRP może już być CurrentIrp w obiekcie urządzenia docelowego lub może już znajdować się w kolejce urządzenia skojarzonej z obiektem urządzenia docelowego, jeśli sterownik ma routynę StartIo. Jeśli sterownik nie ma procedury StartIo , protokół IRP może znajdować się w wewnętrznej kolejce protokołu IRPs zarządzanej przez sterownik, gdy jest wywoływana procedura Anuluj . W każdym razie, zanim menedżer we/wy wywoła procedurę Cancel dla przychodzącego IRP, menedżer we/wy ustawia element członkowski Cancel w tym IRP na TRUE i ustawia element członkowski CancelRoutine w IRP na NULL.

Procedura Anulowania dla głównego IRP, który ma skojarzone IRPs, jest odpowiedzialna za wywołanie IoCancelIrp w celu anulowania tych skojarzonych IRPs.

Wszystkie procedury Anulowania muszą być zgodne z następującymi wytycznymi:

  • Wywołaj metodę IoReleaseCancelSpinLock , aby zwolnić blokadę anulowania spin systemu.

  • Ustaw członek Status bloku stanu I/O na wartość STATUS_CANCELLED, a członek Informacje na zero.

  • Ukończ określony protokół IRP, wywołując element IoCompleteRequest.

  • Ponieważ rutyna anulowania jest zawsze wywoływana z blokadą spinową anulowania systemu, ta rutyna nie może wywołać IoAcquireCancelSpinLock, chyba że najpierw wywoła IoReleaseCancelSpinLock.

  • Rutyna Anulowania nie może trzymać blokady obrotowej anulowania systemu, gdy zwraca kontrolę. Oznacza to, że każda rutyna Anuluj musi wywołać funkcję IoReleaseCancelSpinLock co najmniej raz, zanim zwróci kontrolę.

  • Jeśli wywołuje metodę IoAcquireCancelSpinLock, należy jak najszybciej wykonać wywołanie wzajemne do funkcji IoReleaseCancelSpinLock.

  • Nigdy nie wywołuj IoCompleteRequest z IRP, gdy trzymasz blokadę spin. Próba ukończenia protokołu IRP przy zachowaniu blokady spinu może spowodować zakleszczenia.