Synchronisieren des Abbruchs in Treiberroutinen, die IRPs verarbeiten
Jede Treiberroutine, die dequeues oder mit einem IRP aufgerufen wird, das in einem abbruchfähigen Zustand gehalten wird, einschließlich der StartIo-Routine eines Treibers, muss folgendes tun:
Rufen Sie IoAcquireCancelSpinLock auf.
Stellen Sie sicher, dass "Irp" dem Wert "DeviceObject-CurrentIrp>" entspricht. Andernfalls rufen Sie IoReleaseCancelSpinLock auf, und geben Sie die Steuerung zurück.
Wenn die beiden nicht identisch sind, wurde currentIrp möglicherweise zwischen dem Zeitpunkt abgebrochen, zu dem IoStartPacket die Drehungssperre freigegeben hat und diese Routine sie erworben hat.
Rufen Sie IoSetCancelRoutine mit einem NULL CancelRoutine-Zeiger auf, um das IRP aus dem abbruchfähigen Zustand zu entfernen.
Überprüfen Sie das Feld "Irp-Cancel>", um zu ermitteln, ob das IRP abgebrochen oder mit der Verarbeitung der E/A-Anforderung begonnen werden soll.
Wenn "Irp-Cancel>" auf "TRUE" festgelegt ist, gehen Sie wie folgt vor:
Rufen Sie IoReleaseCancelSpinLock auf.
Legen Sie "Irp-IoStatus.Status>" auf STATUS_CANCELLED fest.
Legen Sie Irp-IoStatus.Information> auf 0 fest.
Rufen Sie IoStartNextPacket (in einer StartIo-Routine) auf, um das nächste Paket zu starten.
Rufen Sie IoCompleteRequest mit einer Prioritätsverstärkung von IO_NO_INCREMENT auf, um das IRP abzuschließen.
Wenn "Irp-Cancel" auf FALSE festgelegt ist, rufen Sie IoReleaseCancelSpinLock auf, und starten Sie die angeforderte Verarbeitung der E/A-Anforderung>, oder übergeben Sie das IRP entsprechend an den nächsten niedrigeren Treiber.
Treiber, die ihre eigenen Warteschlangen von IRPs verwalten, anstatt die vom I/O-Manager bereitgestellte Gerätewarteschlange zu verwenden, müssen beim Aufrufen von IoSetCancelRoutine nicht die Abbruch-Spin-Sperre abrufen. Diese Treiber sollten jedoch den Cancel-Routinezeiger überprüfen, den IoSetCancelRoutine zurückgibt, um festzustellen, ob die Cancel-Routine bereits gestartet wurde.
In jedem Treiber, der abbrechbare IRPs verarbeitet, sollte jede Treiberroutine, die ein IRP verarbeitet, bevor das zugrunde liegende Gerät für den angeforderten E/A-Vorgang programmiert wurde, den abbruchfähigen Zustand aller eingehenden IRPs überprüfen. Insbesondere sollte ein Gerätetreiber auf höchster Ebene mit StartIo- und ControllerControl-Routinen eingehende IRPs in diesen beiden Treiberroutinen verarbeiten, wie bereits beschrieben.