Freigeben über


Zusammenfassung der Lese-/Schreib-Dispatchroutinen

Beachten Sie beim Implementieren einer DispatchRead-, DispatchWrite- oder DispatchReadWrite-Routine die folgenden Punkte:

  • Es liegt in der Verantwortung des Treibers der obersten Ebene in einer Kette von Mehrschichttreibern, die Parameter eingehender Lese-/Schreib-IRPs auf Ihre Gültigkeit zu überprüfen, bevor der Speicherort des E/A-Stapels des nächstniedrigen Treibers in einer IRP eingerichtet wird.

  • Treiber auf mittlerer und niedrigster Ebene können sich im Allgemeinen auf den Treiber der höchsten Ebene in ihrer Kette verlassen, um Übertragungsanforderungen mit gültigen Parametern zu übergeben. Jeder Treiber kann jedoch Integritätsprüfungen an den Parametern in seinem E/A-Stapelstandort eines IRP durchführen, und jeder Gerätetreiber sollte die Parameter auf Bedingungen überprüfen, die möglicherweise gegen die von seinem Gerät auferlegten Einschränkungen verstoßen.

  • Wenn eine DispatchReadWrite-Routine einen IRP mit einem Fehler abschließt, sollte sie das Element des E/A-Stapelspeicherorts Status mit einem entsprechenden NTSTATUS-Typwert festlegen, das Element Information auf 0 festlegen und IoCompleteRequest mit dem IRP und einem PriorityBoost von IO_NO_INCREMENT aufrufen.

  • Wenn ein Treiber gepufferte E/A-Vorgänge verwendet, muss er möglicherweise eine Struktur definieren, die daten enthält, die übertragen werden sollen, und muss möglicherweise einige dieser Strukturen intern puffern.

  • Wenn ein Treiber direkte E/A verwendet, muss er möglicherweise überprüfen, ob die MDL bei Irp-MdlAddress> einen Puffer beschreibt, der zu viele Daten (oder zu viele Seitenumbrüche) enthält, damit das zugrunde liegende Gerät in einem einzigen Übertragungsvorgang verarbeitet werden kann. Wenn ja, muss der Treiber die ursprüngliche Übertragungsanforderung in eine Sequenz kleinerer Übertragungsvorgänge aufteilen.

    Ein eng gekoppelter Klassentreiber kann eine solche Anforderung in seiner DispatchReadWrite-Routine für den zugrunde liegenden Porttreiber aufteilen. Hierzu sind Treiber der SCSI-Klasse erforderlich, insbesondere für Massenspeichergeräte. Weitere Informationen zu den Anforderungen für SCSI-Treiber finden Sie unter Speichertreiber.

  • Die DispatchReadWrite-Routine eines niedrigeren Gerätetreibers sollte das Aufteilen einer großen Übertragungsanforderung in Teilübertragungen verschieben, bis eine andere Treiberroutine die IRP dequediert, um das Gerät für die Übertragung einzurichten.

  • Wenn ein Gerätetreiber auf niedrigerer Ebene einen Lese-/Schreib-IRP für die weitere Verarbeitung durch seine eigenen Routinen in die Warteschlange stellt, muss er IoMarkIrpPending aufrufen, bevor er die IRP in die Warteschlange stellt. Die DispatchReadWrite-Routine muss unter diesen Umständen auch die Steuerung mit STATUS_PENDING zurückgeben.

  • Wenn die DispatchReadWrite-Routine einen IRP an niedrigere Treiber übergibt, muss sie den E/A-Stapelspeicherort für den nächstniedrigen Treiber im IRP einrichten. Ob der übergeordnete Treiber auch eine IoCompletion-Routine im IRP festlegt, bevor er sie mit IoCallDriver weitergibt, hängt vom Design des Treibers und der darunter stehenden Ebenen ab.

    Ein Treiber auf höherer Ebene muss jedoch IoSetCompletionRoutine aufrufen, bevor ioCallDriver aufgerufen wird, wenn er Ressourcen wie IRPs oder Arbeitsspeicher zuweist. Die IoCompletion-Routine muss alle vom Treiber zugewiesenen Ressourcen freigeben, wenn niedrigere Treiber die Anforderung abgeschlossen haben, aber bevor die IoCompletion-RoutineIoCompleteRequest mit dem ursprünglichen IRP aufruft.

  • Wenn ein Treiber auf höherer Ebene IRPs für niedrigere Treiber zuweist, die möglicherweise einen zugrunde liegenden Wechselmediengerätetreiber enthalten, muss der Zuweisungstreiber den Threadkontext in jedem zuzuordnenden IRP einrichten.