Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Wie der Name schon sagt, wird eine ControllerControl-Routine einem Controllerobjekt zugeordnet. Wenn die ControllerControl-Routine ausgeführt wird, ist die vom Controllerobjekt dargestellte Hardware frei, und die Controllererweiterung wird in der Regel nicht von einer anderen Treiberroutine aufgerufen, es sei denn, die Controllererweiterung enthält Kontext, der für den ISR des Treibers freigegeben ist.
In der Regel führt eine ControllerControl-Routine mindestens die folgenden Aktionen aus:
Aktualisiert oder initialisiert den Kontext, den der Treiber in der Geräteerweiterung des Zielgerätobjekts und in der Controllererweiterung verwaltet.
Wenn der Treiber DMA verwendet, ist die ControllerControl-Routine in der Regel dafür verantwortlich, zu bestimmen, ob eine bestimmte Übertragungsanforderung aufgrund von vom System auferlegten oder geräteaufzwingenden Beschränkungen der Größe jeder DMA-Übertragung in teilweise Übertragungen aufgeteilt werden muss. Unter diesen Umständen ist die ControllerControl-Routine auch für das Aufrufen von AllocateAdapterChannel verantwortlich, wenn der Treiber über eine AdapterControl-Routine verfügt.
Wenn der Treiber PIO verwendet, ist die ControllerControl-Routine auch für das Aufteilen von Übertragungsanforderungen verantwortlich, falls die Hardware sie benötigt, in Teilübertragungsbereiche und zum Aufrufen von MmGetSystemAddressForMdlSafe mit der MDL bei Irp-MdlAddress>.
Programmiert seine Hardware für den angeforderten E/A-Vorgang
Wenn über den ISR auf die Geräte- oder Controllererweiterung zugegriffen werden kann, muss die ControllerControl-Routine eine SynchCritSection-Routine verwenden, die durch Aufrufen von KeSynchronizeExecution aufgerufen wird. Weitere Informationen finden Sie unter Using Critical Sections.
Wenn der Treiber über eine Cancel-Routine verfügt, muss die ControllerControl-Routine auch das Feld "Irp-Cancel>" überprüfen, um zu ermitteln, ob das aktuelle IRP abgebrochen werden soll, und führen Sie eine der folgenden Aktionen aus:
Wenn "Irp-Cancel" auf "TRUE" festgelegt ist, muss die ControllerControl-Routine> Folgendes ausführen:
Legen Sie STATUS_CANCELLED für Status und null für Information im E/A-Statusblock des IRP fest.
Rufen Sie IoFreeController auf, um das Controllerobjekt freizugeben, damit der nächste Gerätevorgang umgehend gestartet werden kann.
Rufen Sie IoStartNextPacket auf, oder entfernen Sie das nächste IRP aus der Warteschlange, wenn der Treiber eine eigene Warteschlange verwaltet.
Schließen Sie das abgebrochene IRP mit IoCompleteRequest ab, und geben Sie die Steuerung zurück.
Wenn "Irp-Cancel" nicht auf "TRUE" festgelegt ist, muss die ControllerControl-Routine> stattdessen Folgendes ausführen:
Rufen Sie IoSetCancelRoutine auf, um den Cancel-Routineeinstiegspunkt für das IRP auf NULL zurückzusetzen. Rufen Sie die Drehungssperre für diesen Aufruf ab, wenn der Treiber die vom I/O-Manager bereitgestellte Gerätewarteschlange im Geräteobjekt verwendet.
Programmieren Sie die Hardware für den angeforderten E/A-Vorgang mithilfe einer SynchCritSection-Routine , die durch Aufrufen von KeSynchronizeExecution aufgerufen wird. Weitere Informationen finden Sie unter Verwenden kritischer Abschnitte
Weitere Informationen zum Behandeln von stornierbaren IRPs finden Sie unter Canceling IRPs.
Bei den meisten unterbrechungsgesteuerten E/A-Vorgängen mit Ausnahme überlappender Vorgänge auf verschiedenen Geräten, die an den physischen Controller/Adapter angeschlossen sind, sollte eine ControllerControl-RoutineKeepObject zurückgeben, da die DpcForIsr - oder CustomDpc-Routine den Vorgang und die IRP-Routine abgeschlossen.
Sobald die E/A-Vorgänge zum Erfüllen der aktuellen Anforderung abgeschlossen sind, sollte die Routine, die das IRP ausführt, IoFreeController und IoStartNextPacket aufrufen, damit die nächste Anforderung so schnell wie möglich verarbeitet werden kann.
Wenn die ControllerControl-Routine selbst ein IRP abschließt oder wenn ein Vorgang wie eine Datenträgersuche für ein Zielgerätobjekt (Datenträger) eingerichtet werden kann, das mit einem Vorgang für ein anderes Geräteobjekt überlappen könnte, sollte die ControllerControl-RoutineDeallocateObject zurückgeben.