Freigeben über


IRP_MJ_WRITE (FS- und Filtertreiber)

Sendeszenario

Der E/A-Manager oder ein Dateisystemtreiber sendet die IRP_MJ_WRITE-Anforderung. Diese Anforderung kann z. B. gesendet werden, wenn eine Anwendung im Benutzermodus eine Win32-Funktion wie WriteFile aufruft oder wenn eine Kernelmoduskomponente ZwWriteFile aufruft.

Vorgang: Dateisystemtreiber

Der Dateisystemtreiber sollte das Dateiobjekt extrahieren und decodieren, um die Parameter und den Hilfsfunktionscode zu bestimmen.

Bei MDL-Schreibanforderungen sollte das Dateisystem den Hilfsfunktionscode überprüfen, um zu ermitteln, welcher Vorgang angefordert wird. Im Folgenden sind die gültigen Hilfsfunktionscodes aufgeführt, die nur für zwischengespeicherte Datei-E/A verwendet werden können:

  • IRP_MN_COMPLETE
  • IRP_MN_COMPLETE_MDL
  • IRP_MN_COMPLETE_MDL_DPC
  • IRP_MN_COMPRESSED
  • IRP_MN_DPC
  • IRP_MN_MDL
  • IRP_MN_MDL_DPC
  • IRP_MN_NORMAL

Weitere Informationen zur Behandlung dieses IRP finden Sie im FASTFAT-Beispiel, das im Windows Driver Kit (WDK) enthalten ist.

Vorgang: Ältere Dateisystem-Filtertreiber

Der Filtertreiber sollte jede erforderliche Verarbeitung ausführen und je nach Art des Filters eine der folgenden Aktionen ausführen:

  • Abschließen oder Fehlschlagen des IRP oder
  • Das IRP wird an den nächstniedrigeren Treiber auf dem Stapel weitergegeben.

Parameter

Ein Dateisystem oder Filtertreiber ruft IoGetCurrentIrpStackLocation für das angegebene IRP auf, um einen Zeiger auf seine eigene Stapelposition im IRP abzurufen. In den folgenden Parametern verweist Irp auf die IRP- und IrpSp-Punkte auf die IO_STACK_LOCATION. Der Treiber kann die Informationen verwenden, die in den folgenden Elementen des IRP und des IRP-Stapelspeicherorts festgelegt sind, um eine Erstellungsanforderung zu verarbeiten:

  • DeviceObject ist ein Zeiger auf das Zielgerätobjekt.

  • Irp->AssociatedIrp.SystemBuffer verweist auf einen vom System bereitgestellten Puffer, der als Zwischensystempuffer verwendet werden soll, wenn das DO_BUFFERED_IO-Flag in DeviceObject->Flags festgelegt ist. Andernfalls wird dieser Member auf NULL festgelegt.

  • Irp->IoStatus verweist auf eine IO_STATUS_BLOCK-Struktur, die den endgültigen Abschlussstatus und Informationen zum angeforderten Vorgang empfängt. Wenn die IRP_MJ_WRITE-Anforderung fehlschlägt, gibt die Schreibroutine des Dateisystems einen NTSTATUS-Fehlerwert zurück, und der Wert von Irp->IoStatus.Information ist nicht definiert und sollte nicht verwendet werden.

  • Irp->MdlAddress ist die Adresse einer Speicherdeskriptorliste (MDL), die die Seiten beschreibt, in die die Daten geschrieben werden sollen.

  • IrpSp->FileObject verweist auf das Dateiobjekt, das DeviceObject zugeordnet ist. Wenn das FO_SYNCHRONOUS_IO-Flag in IrpSp->FileObject>-Flags festgelegt ist, wurde das Dateiobjekt für synchrone E/A geöffnet.

    Der Parameter IrpSp->FileObject enthält einen Zeiger auf das RelatedFileObject-Feld, das auch eine FILE_OBJECT-Struktur ist. Das RelatedFileObject-Feld der FILE_OBJECT-Struktur ist während der Verarbeitung von IRP_MJ_WRITE nicht gültig und sollte nicht verwendet werden.

  • IrpSp->Flags: Wenn das SL_FORCE_DIRECT_WRITE-Flag festgelegt ist, können Kernelmodustreiber in Volumebereiche schreiben, in die sie normalerweise aufgrund der direkten Schreibsperre nicht schreiben können. Die direkte Schreibsperre wurde aus Sicherheitsgründen in Windows Vista und späteren Betriebssystemen implementiert. Dieses Flag wird sowohl auf der Dateisystemebene als auch auf der Speicherstapelebene überprüft. Weitere Informationen zum blockieren von direkten Schreibvorgängen finden Sie unter Blockieren von direkten Schreibvorgängen auf Volumes und Datenträger. Das SL_FORCE_DIRECT_WRITE-Flag ist in Windows Vista und höheren Versionen von Windows verfügbar.

  • IrpSp->MajorFunction ist auf IRP_MJ_WRITE festgelegt.

  • IrpSp->MinorFunction gibt den angeforderten Vorgang an und enthält einen der folgenden Werte. Wenn kein Hilfsfunktionscode angegeben ist, ist der Vorgang ein Standardschreibvorgang (entspricht IRP_MN_NORMAL).

    MinorFunction Beschreibung
    IRP_MN_NORMAL Die Schreibanforderung ist für einen Standardschreibvorgang vorgesehen.
    IRP_MN_DPC Die Schreibanforderung stammt aus einer DPC-Routine.
    IRP_MN_MDL Gibt eine MDL zurück, die die zwischengespeicherten Daten der Datei in Irp->MdlAddress beschreibt. Der Aufrufer verwendet diese MDL, um Daten direkt in den Cache zu schreiben.
    IRP_MN_COMPLETE Nicht von sich selbst verwendet; tritt nur in Kombination mit mindestens IRP_MN_MDL auf. Siehe Hinweise.
    IRP_MN_COMPRESSED Die Schreibanforderung ist für eine komprimierte Datei.
    IRP_MN_MDL_DPC Die Schreibanforderung stammt aus einer DPC-Routine und gibt eine MDL zurück, die die zwischengespeicherten Daten der Datei in Irp->MdlAddress beschreibt.
    IRP_MN_COMPLETE_MDL Gibt an, dass der Aufrufer, der die MDL zum direkten Schreiben von Daten in den Cache verwendet hat, die Verwendung der MDL abgeschlossen hat.
    IRP_MN_COMPLETE_MDL_DPC Gibt an, dass der Aufrufer, der die MDL zum direkten Schreiben von Daten in den Cache verwendet hat, die Verwendung der MDL abgeschlossen hat; Die Schreibanforderung stammt aus einer DPC-Routine.
  • IrpSp->Parameters.Write.ByteOffset ist eine LARGE_INTEGER-Variable, die den Anfangsbyte-Offset in der Datei der zu schreibenden Daten angibt.

    Unter bestimmten Umständen kann dieser Parameter einen speziellen Wert enthalten. Bei „wahr” gibt die folgende Bedingung beispielsweise an, dass das aktuelle Ende der Datei anstelle eines expliziten Dateioffsetwerts verwendet werden soll: IrpSp->Parameters.Write.ByteOffset.LowPart == FILE_WRITE_TO_END_OF_FILE und IrpSp->Parameters.Write.ByteOffset.HighPart == -1

  • IrpSp->Parameters.Write.Key ist der Schlüsselwert, der einer Bytebereichssperre in der Zieldatei zugeordnet ist.

  • IrpSp->Parameters.Write.Length ist die Länge in Bytes der zu schreibenden Daten. Wenn der Schreibvorgang erfolgreich ist, wird die Anzahl der geschriebenen Bytes im Informationselement der IO_STATUS_BLOCK-Struktur zurückgegeben, auf die von Irp->IoStatus verwiesen wird.

Hinweise

Dateisysteme runden Schreib- und Lesevorgänge am Ende der Datei auf ein Vielfaches der Sektorgröße des zugrunde liegenden Dateispeichergeräts ab. Wenn Filter Vor- oder Vorschreibvorgänge verarbeiten, müssen diese Filter, die Puffer zuordnen und austauschen, die Größe eines zugeordneten Puffers auf ein Vielfaches der Sektorgröße des zugeordneten Geräts aufrunden. Wenn dies nicht der Grund ist, überschreitet die Länge der vom zugrunde liegenden Dateisystem übertragenen Daten die zugewiesene Länge des Puffers. Weitere Informationen zum Austauschen von Puffern finden Sie im SwapBuffers Minifilter-Beispiel.

Die folgenden Aufzählungszeichen beschreiben einen Standardschreibfehler im Vergleich zu einem IRP-basierten MDL-Schreibzugriff:

  • So führen Sie einen Standardschreibvorgang aus:

    1. Der Aussteller erstellt ein IRP mit MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_NORMAL (d. h. 0) und stellt die Daten zum Schreiben in Irp-AssociatedIrp.SystemBuffer> bereit.
    2. Wenn sie das IRP an das Dateisystem senden, befinden sich die zu schreibenden Daten bereits im IRP. Der Schreibvorgang ist also abgeschlossen, wenn das Dateisystem die Verarbeitung des IRP abgeschlossen hat; Beispielsweise durch Kopieren der Daten aus dem Puffer in den Cache für einen zwischengespeicherten Schreibvorgang.
  • So führen Sie einen IRP-basierten MDL-Schreibvorgang aus:

    1. Der Aussteller erstellt ein IRP mit MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_MDL, stellt jedoch keinen Datenpuffer bereit. Sie senden dieses IRP an das Dateisystem.
    2. Das Dateisystem erstellt eine MDL, platziert sie im IRP und schließt das IRP ab.
    3. Der Aussteller verwendet diese MDL, um Daten direkt in den Cache der Datei zu kopieren.
    4. Wenn der Aussteller mit dem Kopieren von Daten in den Cache fertig ist, erstellen sie ein weiteres IRP mit MajorFunction = IRP_MJ_WRITE, MinorFunction = (IRP_MN_MDL | IRP_MN_COMPLETE) und senden sie an das Dateisystem.
    5. Das Dateisystem gibt die MDL frei, und der Schreibvorgang ist jetzt abgeschlossen.

Weitere Informationen

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE (WDK-Kernelreferenz)

ZwWriteFile