Implementieren einer Abbruchroutine
Der E/A-Manager ruft eine vom Treiber bereitgestellte Cancel-Routine mit einem eingabe-IRP auf, der abgebrochen werden soll, und einem DeviceObject-Zeiger , der das Zielgerät für die E/A-Anforderung darstellt.
Das IRP kann eine sein, die von der DispatchReadWrite-Routine des Treibers in die Warteschlange eingereiht wurde, während die aktuelle Win32-Anwendung vom Benutzer geschlossen wird. Die IRP kann auch eine sein, die ein Treiber auf höherer Ebene explizit abgebrochen hat, je nach Art des zugrunde liegenden Geräts.
Wenn die Cancel-Routine aufgerufen wird, ist die Eingabe-IRP möglicherweise bereits currentIrp im Zielgerätobjekt oder befindet sich bereits in der Gerätewarteschlange, die dem Zielgerätobjekt zugeordnet ist, wenn der Treiber über eine StartIo-Routine verfügt. Wenn der Treiber über keine StartIo-Routine verfügt, befindet sich der IRP möglicherweise in einer vom Treiber verwalteten internen Warteschlange von IRPs, wenn seine Cancel-Routine aufgerufen wird. In jedem Fall, bevor der E/A-Manager die Cancel-Routine für die eingehende IRP aufruft, legt der E/A-Manager das Cancel-Element in diesem IRP auf TRUE und das CancelRoutine-Element im IRP auf NULL fest.
Die Cancel-Routine für ein master IRP mit zugeordneten IRPs ist dafür verantwortlich, IoCancelIrp aufzurufen, um die zugeordneten IRPs abzubrechen.
Alle Cancel-Routinen müssen die folgenden Richtlinien befolgen:
Rufen Sie IoReleaseCancelSpinLock auf, um die Abbruch-Spin-Sperre des Systems freizugeben.
Legen Sie den Status-Member des E/A-status-Blocks auf STATUS_CANCELLED fest, und legen Sie dessen Information-Member auf 0 (null) fest.
Schließen Sie den angegebenen IRP ab, indem Sie IoCompleteRequest aufrufen.
Da eine Cancel-Routine immer aufgerufen wird, wobei die Spin-Sperre des Systemabbruchs erhalten bleibt, darf diese Routine IoAcquireCancelSpinLock erst aufrufen, wenn zuerst IoReleaseCancelSpinLock aufgerufen wird.
Eine Cancel-Routine kann die Systemrückbruch-Spin-Sperre nicht halten, wenn sie die Steuerung zurückgibt. Das heißt, jede Cancel-Routine muss IoReleaseCancelSpinLock mindestens einmal aufrufen, bevor die Steuerung zurückgegeben wird.
Wenn IoAcquireCancelSpinLock aufgerufen wird, muss eine Cancel-Routine den wechselseitigen Aufruf von IoReleaseCancelSpinLock so schnell wie möglich durchführen.
Rufen Sie niemals IoCompleteRequest mit einem IRP auf, während Sie eine Drehsperre halten. Der Versuch, eine IRP abzuschließen, während eine Drehsperre gedrückt wird, kann zu Deadlocks führen.