NtWriteFile-Funktion (ntifs.h)

Die ZwWriteFile-Routine schreibt Daten in eine geöffnete Datei.

Syntax

__kernel_entry NTSYSCALLAPI NTSTATUS NtWriteFile(
  [in]           HANDLE           FileHandle,
  [in, optional] HANDLE           Event,
  [in, optional] PIO_APC_ROUTINE  ApcRoutine,
  [in, optional] PVOID            ApcContext,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [in]           PVOID            Buffer,
  [in]           ULONG            Length,
  [in, optional] PLARGE_INTEGER   ByteOffset,
  [in, optional] PULONG           Key
);

Parameter

[in] FileHandle

Handle mit dem Dateiobjekt. Dieses Handle wird durch einen erfolgreichen Aufruf von NtCreateFile oder NtOpenFile erstellt.

[in, optional] Event

Optional ein Handle für ein Ereignisobjekt, das nach Abschluss des Schreibvorgangs auf den signalierten Zustand festgelegt werden soll. Geräte- und Zwischentreiber sollten diesen Parameter auf NULL festlegen.

[in, optional] ApcRoutine

Dieser Parameter ist reserviert. Geräte- und Zwischentreiber sollten diesen Zeiger auf NULL festlegen.

[in, optional] ApcContext

Dieser Parameter ist reserviert. Geräte- und Zwischentreiber sollten diesen Zeiger auf NULL festlegen.

[out] IoStatusBlock

Zeiger auf eine IO_STATUS_BLOCK-Struktur, die die endgültige Vervollständigung status und Informationen zum angeforderten Schreibvorgang empfängt. Das Information-Element empfängt die Anzahl der Bytes, die tatsächlich in die Datei geschrieben wurden.

[in] Buffer

Zeiger auf einen vom Aufrufer zugewiesenen Puffer, der die Daten enthält, die in die Datei geschrieben werden sollen.

[in] Length

Die Größe des Puffers in Bytes, auf den Puffer verweist.

[in, optional] ByteOffset

Zeiger auf eine Variable, die den Anfangsbyteoffset in der Datei zum Starten des Schreibvorgangs angibt. Wenn Length und ByteOffset einen Schreibvorgang über das aktuelle Dateiende hinaus angeben, erweitert NtWriteFile die Datei automatisch und aktualisiert die Markierung zum Ende der Datei. Alle Bytes, die nicht explizit zwischen diesen alten und neuen End-of-File-Markierungen geschrieben werden, werden als Null definiert.

Wenn beim Aufruf von NtCreateFile nur das DesiredAccess-Flag FILE_APPEND_DATA festgelegt wird, wird ByteOffset ignoriert. Daten im angegebenen Puffer für Längenbytes werden ab dem aktuellen Ende der Datei geschrieben.

Wenn der Aufruf von NtCreateFile eines der CreateOptions-Flags FILE_SYNCHRONOUS_IO_ALERT oder FILE_SYNCHRONOUS_IO_NONALERT festgelegt hat, behält der E/A-Manager die aktuelle Dateiposition bei. Wenn ja, kann der Aufrufer von NtWriteFile angeben, dass der aktuelle Dateipositionsoffset-Offset anstelle eines expliziten ByteOffset-Werts verwendet wird. Diese Spezifikation kann mit einer der folgenden Methoden vorgenommen werden:

  • *Geben Sie einen Zeiger auf einen LARGE_INTEGER Wert an, wobei der HighPart-Member auf -1 und der LowPart-Member auf den systemdefinierte Wert FILE_USE_FILE_POINTER_POSITION festgelegt ist.
  • Übergeben Sie einen NULL-Zeiger für ByteOffset.

NtWriteFile aktualisiert die aktuelle Dateiposition, indem die Anzahl der Bytes hinzugefügt wird, die beim Abschluss des Schreibvorgangs geschrieben werden, wenn die aktuelle Dateiposition verwendet wird, die vom E/A-Manager verwaltet wird.

Auch wenn der E/A-Manager die aktuelle Dateiposition behält, kann der Aufrufer diese Position zurücksetzen, indem er einen expliziten ByteOffset-Wert an NtWriteFile übergibt. Dadurch wird die aktuelle Dateiposition automatisch in diesen ByteOffset-Wertgeändert, der Schreibvorgang ausgeführt und dann die Position entsprechend der Anzahl der tatsächlich geschriebenen Bytes aktualisiert. Mit dieser Technik erhält der Aufrufer einen atomaren Such- und Schreibdienst.

Es ist auch möglich, einen Schreibvorgang am aktuellen Ende der Datei zu starten, indem für ByteOffset ein Zeiger auf einen LARGE_INTEGER Wert angegeben wird, wobei HighPart auf -1 und LowPart auf FILE_WRITE_TO_END_OF_FILE festgelegt ist. Dies funktioniert unabhängig davon, ob der E/A-Manager die aktuelle Dateiposition behält.

[in, optional] Key

Geräte- und Zwischentreiber sollten diesen Zeiger auf NULL festlegen.

Rückgabewert

NtWriteFile gibt STATUS_SUCCESS bei Erfolg oder den entsprechenden NTSTATUS-Fehlercode bei Einem Fehler zurück.

Hinweise

Aufrufer von NtWriteFile müssen bereits NtCreateFile aufgerufen haben, wobei das flag FILE_WRITE_DATA, FILE_APPEND_DATA oder GENERIC_WRITE im DesiredAccess-Parameter festgelegt ist. Beachten Sie, dass nur FILE_APPEND_DATA Zugriff auf eine Datei dem Aufrufer nicht erlaubt, an einer beliebigen Stelle in der Datei zu schreiben, außer am aktuellen Ende der Datei, während FILE_WRITE_DATA Zugriff auf eine Datei nicht verhindert, dass der Aufrufer an oder darüber hinaus an das Ende einer Datei schreibt.

Wenn der vorherige Aufruf von NtCreateFile das CreateOptions-Flag FILE_NO_INTERMEDIATE_BUFFERING festgelegt hat, müssen die Parameter Length und ByteOffset auf NtWriteFile ein Integral der Sektorgröße sein. Weitere Informationen finden Sie unter NtCreateFile.

NtWriteFile beginnt den Schreibvorgang in die Datei bei ByteOffset, an der aktuellen Dateiposition oder am Ende der Dateimarke. Der Schreibvorgang wird beendet, wenn Längenbytes aus Puffer geschrieben wurden. Bei Bedarf wird die Länge der Datei erweitert und die Markierung am Dateiende zurückgesetzt.

Wenn der Aufrufer die Datei mit dem DesiredAccess SYNCHRONIZE-Flag geöffnet hat, kann der Aufrufer warten, bis diese Routine das angegebene FileHandle auf den signalierten Zustand festgelegt hat.

Treiber sollten NtWriteFile im Kontext des Systemprozesses in drei Fällen aufrufen:

  • Der Treiber erstellt das Dateihandle, das er an NtWriteFile übergibt.
  • NtWriteFile benachrichtigt den Treiber der E/A-Vervollständigung mithilfe eines vom Treiber erstellten Ereignisses.
  • NtWriteFile benachrichtigt den Treiber der E/A-Vervollständigung mithilfe einer APC-Rückrufroutine, die der Treiber an NtWriteFile übergibt.

Datei- und Ereignishandles sind nur im Prozesskontext gültig, in dem die Handles erstellt werden. Um Sicherheitslücken zu vermeiden, sollte der Treiber daher ein beliebiges Datei- oder Ereignishandle erstellen, das er im Kontext des Systemprozesses an NtWriteFile übergeben wird, anstelle des Prozesskontexts, in dem sich der Treiber befindet.

Ebenso sollte NtWriteFile im Kontext des Systemprozesses aufgerufen werden, wenn der Treiber der E/A-Vervollständigung mithilfe eines APC benachrichtigt wird, da APCs immer im Kontext des Threads ausgelöst werden, der die E/A-Anforderung ausgibt. Wenn der Treiber NtWriteFile im Kontext eines anderen Prozesses als des Systemprozesses aufruft, kann der APC auf unbestimmte Zeit verzögert werden, oder er wird überhaupt nicht ausgelöst, da der ursprüngliche Thread möglicherweise nie in einen warnbaren Wartezustand wechselt.

Weitere Informationen zum Arbeiten mit Dateien finden Sie unter Verwenden von Dateien in einem Treiber.

Aufrufer von NtWriteFile müssen unter IRQL = PASSIVE_LEVEL und mit aktivierten speziellen Kernel-APCs ausgeführt werden.

Wenn der Aufruf dieser Funktion im Benutzermodus erfolgt, sollten Sie den Namen "NtWriteFile" anstelle von "ZwWriteFile" verwenden.

Bei Aufrufen von Kernelmodustreibern können sich die NtXxx - und ZwXxx-Versionen einer Windows Native System Services-Routine anders verhalten, da sie Eingabeparameter verarbeiten und interpretieren. Weitere Informationen zur Beziehung zwischen den Nt Xxx- und ZwXxx-Versionen einer Routine finden Sie unter Verwenden von Nt- und Zw-Versionen der Systemdienstroutinen.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows 2000
Zielplattform Universell
Header ntifs.h (einschließlich Wdm.h, Ntddk.h, Ntifs.h)
Bibliothek NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL (siehe Abschnitt Hinweise)
DDI-Complianceregeln HwStorPortProhibitedDIs, PowerIrpDDis

Weitere Informationen

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile