Freigeben über


Zusammenfassung der Lese-/Schreibdispatch-Routinen

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

  • Es liegt in der Verantwortung des Treibers der höchsten Ebene in einer Kette von mehrschichtigen Treibern, die Parameter eingehender Lese-/Schreibzugriffs-IRPs auf ihre Gültigkeit zu überprüfen, bevor der E/A-Stapelspeicherort des nächsten Treibers auf niedrigerer Ebene in einem IRP eingerichtet wird.

  • Treiber auf mittlerer und niedrigster Ebene können sich in der Regel auf den Treiber der höchsten Ebene in ihrer Kette verlassen, um Übertragungsanforderungen mit gültigen Parametern zu übergeben. Jeder Treiber kann jedoch eine Integritätsüberprüfung der Parameter an seiner I/O-Stapelposition eines IRP durchführen, und jeder Gerätetreiber sollte die Parameter auf Bedingungen überprüfen, die gegen einschränkungen verstoßen könnten, die von seinem Gerät auferlegt werden.

  • Wenn eine DispatchReadWrite-Routine ein IRP mit einem Fehler abschließt, sollte das I/O-Stapelpositionsstatuselement mit einem entsprechenden NTSTATUS-Typwert festgelegt werden, das Information-Element auf Null festgelegt und IoCompleteRequest mit dem IRP und einem PriorityBoost von IO_NO_INCREMENT aufgerufen werden.

  • Wenn ein Treiber gepufferte E/A verwendet, muss möglicherweise eine Struktur definiert werden, die die zu übertragenden Daten enthält, und einige dieser Strukturen intern gepuffert werden.

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

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

  • Die DispatchReadWrite-Routine eines Gerätetreibers auf niedrigerer Ebene sollte das Aufteilen einer großen Übertragungsanforderung in Teilübertragungen verschieben, bis eine andere Treiberroutine das IRP zum Einrichten des Geräts für die Übertragung dequeuet.

  • Wenn ein Gerätetreiber auf niedrigerer Ebene ein Lese-/Schreib-IRP für die weitere Verarbeitung durch seine eigenen Routinen in die Warteschlange stellt, muss er IoMarkIrpPending aufrufen, bevor das IRP in die Warteschlange gestellt wird. Die DispatchReadWrite-Routine muss auch die Kontrolle mit STATUS_PENDING in diesen Fällen zurückgeben.

  • Wenn die DispatchReadWrite-Routine ein IRP an niedrigere Treiber übergibt, muss sie die I/O-Stapelposition für den nächsten niedrigeren Treiber im IRP einrichten. Ob der Treiber auf höherer Ebene auch eine IoCompletion-Routine im IRP festlegt, bevor er es mit IoCallDriver übergibt, hängt vom Design des Treibers und von diesen ab, die unter ihr angeordnet sind.

    Ein Treiber auf höherer Ebene muss jedoch IoSetCompletionRoutine aufrufen, bevor er IoCallDriver aufruft, wenn er Ressourcen wie IRPs oder Speicher 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 einen zugrunde liegenden Wechselmediengerätetreiber enthalten können, muss der Treiber, der die Zuweisung vornimmt, den Threadkontext in jedem von ihm zugewiesenen IRP einrichten.