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.