Methoden für den Zugriff auf Datenpuffer

Eine der Hauptaufgaben von Treiberstapeln ist die Übertragung von Daten zwischen Anwendungen im Benutzermodus und den Geräten eines Systems. Das Betriebssystem bietet die folgenden drei Methoden für den Zugriff auf Datenpuffer:

Gepufferte E/A-Vorgänge
Das Betriebssystem erstellt einen nicht ausgestellten Systempuffer, der der Größe des Anwendungspuffers entspricht. Bei Schreibvorgängen kopiert der E/A-Manager Benutzerdaten in den Systempuffer, bevor er den Treiberstapel aufruft. Bei Lesevorgängen kopiert der E/A-Manager Daten aus dem Systempuffer in den Puffer der Anwendung, nachdem der Treiberstapel den angeforderten Vorgang abgeschlossen hat.

Weitere Informationen finden Sie unter Verwenden von gepufferten E/A-Vorgängen.

Direkte E/A
Das Betriebssystem sperrt den Puffer der Anwendung im Arbeitsspeicher. Anschließend wird eine Speicherdeskriptorliste (Memory Descriptor List, MDL) erstellt, die die gesperrten Speicherseiten identifiziert, und die MDL an den Treiberstapel übergeben. Treiber greifen über die MDL auf die gesperrten Seiten zu.

Weitere Informationen finden Sie unter Verwenden von direkten E/A-Vorgängen.

Weder gepufferte noch direkte E/A-Vorgänge
Das Betriebssystem übergibt die virtuelle Startadresse und Größe des Anwendungspuffers an den Treiberstapel. Auf den Puffer kann nur über Treiber zugegriffen werden, die im Threadkontext der Anwendung ausgeführt werden.

Weitere Informationen finden Sie unter Verwenden von weder gepufferten noch direkten E/A-Vorgängen.

Für IRP_MJ_READ - und IRP_MJ_WRITE-Anforderungen geben Treiber die E/A-Methode mithilfe von Flags in jeder DEVICE_OBJECT-Struktur an. Weitere Informationen finden Sie unter Initialisieren eines Geräteobjekts.

Für IRP_MJ_DEVICE_CONTROL - und IRP_MJ_INTERNAL_DEVICE_CONTROL-Anforderungen wird die E/A-Methode durch den TransferType-Wert bestimmt, der in jedem IOCTL-Wert enthalten ist. Weitere Informationen finden Sie unter Definieren von E/A-Steuerungscodes.

Alle Treiber in einem Treiberstapel müssen für jede Anforderung die gleiche Pufferzugriffsmethode verwenden, mit Ausnahme möglicherweise des Treibers der höchsten Ebene (der unabhängig von der Von niedrigeren Treibern verwendeten Methode die Methode "weder" verwenden kann).