Share via


NtReadFile-Funktion (ntifs.h)

Die NtReadFile-Routine liest Daten aus einer geöffneten Datei.

Syntax

__kernel_entry NTSYSCALLAPI NTSTATUS NtReadFile(
  [in]           HANDLE           FileHandle,
  [in, optional] HANDLE           Event,
  [in, optional] PIO_APC_ROUTINE  ApcRoutine,
  [in, optional] PVOID            ApcContext,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [out]          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 Lesevorgangs 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 Lesevorgang empfängt. Das Information-Element empfängt die Anzahl der Bytes, die tatsächlich aus der Datei gelesen werden.

[out] Buffer

Zeiger auf einen vom Aufrufer zugewiesenen Puffer, der die aus der Datei gelesenen Daten empfängt.

[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 angibt, in der der Lesevorgang beginnt. Wenn versucht wird, über das Ende der Datei hinaus zu lesen, gibt NtReadFile einen Fehler zurück.

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 NtReadFile angeben, dass anstelle eines expliziten ByteOffset-Werts der aktuelle Dateipositionsoffset 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.

NtReadFile aktualisiert die aktuelle Dateiposition, indem die Anzahl der gelesenen Bytes hinzugefügt wird, wenn der Lesevorgang abgeschlossen wird, 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 NtReadFile übergibt. Dadurch wird die aktuelle Dateiposition automatisch in diesen ByteOffset-Wert geändert, der Lesevorgang ausgeführt und dann die Position entsprechend der Anzahl der tatsächlich gelesenen Bytes aktualisiert. Mit dieser Technik erhält der Aufrufer einen atomaren Such- und Lesedienst.

[in, optional] Key

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

Rückgabewert

NtReadFile gibt entweder STATUS_SUCCESS oder den entsprechenden NTSTATUS-Fehlercode zurück.

Hinweise

Aufrufer von NtReadFile müssen bereits NtCreateFile aufgerufen haben, wobei der FILE_READ_DATA oder GENERIC_READ Wert im DesiredAccess-Parameter festgelegt ist.

Wenn der vorherige Aufruf von NtCreateFile das FILE_NO_INTERMEDIATE_BUFFERING-Flag im CreateOptions-Parameter auf NtCreateFile festgelegt hat, müssen die Parameter Length und ByteOffset auf NtReadFile ein Vielfaches der Sektorgröße sein.

NtReadFile beginnt, aus dem angegebenen ByteOffset oder der aktuellen Dateiposition in den angegebenen Puffer zu lesen. Der Lesevorgang wird unter einer der folgenden Bedingungen beendet:

  • Der Puffer ist voll, da die durch den Parameter Length angegebene Anzahl von Bytes gelesen wurde. Daher können keine weiteren Daten ohne Überlauf in den Puffer platziert werden.
  • Das Ende der Datei wird während des Lesevorgangs erreicht, sodass keine weiteren Daten in der Datei vorhanden sind, die in den Puffer übertragen werden sollen.

Wenn der Aufrufer die Datei mit dem in DesiredAccess festgelegten SYNCHRONIZE-Flag geöffnet hat, kann der aufrufende Thread mit dem Abschluss des Lesevorgangs synchronisiert werden, indem er auf das Dateihandle wartet. Der Handle wird jedes Mal signalisiert, wenn ein E/A-Vorgang abgeschlossen wird, der für den Handle ausgegeben wurde. Der Aufrufer darf jedoch nicht auf ein Handle warten, das für den synchronen Dateizugriff (FILE_SYNCHRONOUS_IO_NONALERT oder FILE_SYNCHRONOUS_IO_ALERT) geöffnet wurde. In diesem Fall wartet NtReadFile im Namen des Aufrufers und wird erst zurückgegeben, wenn der Lesevorgang abgeschlossen ist. Der Aufrufer kann nur dann sicher auf das Dateihandle warten, wenn alle drei der folgenden Bedingungen erfüllt sind:

  • Das Handle wurde für den asynchronen Zugriff geöffnet (d. FILE_SYNCHRONOUS_IO_ XXX-Flag wurde nicht angegeben).
  • Das Handle wird jeweils nur für einen E/A-Vorgang verwendet.
  • NtReadFile hat STATUS_PENDING zurückgegeben.

Ein Treiber sollte NtReadFile im Kontext des Systemprozesses aufrufen, wenn eine der folgenden Bedingungen vorliegt:

  • Der Treiber hat das Dateihandle erstellt, das er an NtReadFile übergibt.
  • NtReadFile benachrichtigt den Treiber über die E/A-Vervollständigung mithilfe eines vom Treiber erstellten Ereignisses.
  • NtReadFile benachrichtigt den Treiber über die E/A-Vervollständigung mithilfe einer APC-Rückrufroutine, die der Treiber an NtReadFile ü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 NtReadFile übergibt und nicht den Kontext des Prozesses, in dem sich der Treiber befindet.

Ebenso sollte NtReadFile 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 NtReadFile im Kontext eines anderen Prozesses als des Systemvorgangs aufruft, kann der APC auf unbestimmte Zeit verzögert oder gar nicht ausgelöst werden.

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

Aufrufer von NtReadFile 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 "NtReadFile" anstelle von "ZwReadFile" 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 BufAfterReqCompletedIntIoctlA, BufAfterReqCompletedIoctlA, BufAfterReqCompletedReadA, BufAfterReqCompletedWriteA, HwStorPortProhibitedDIs, PowerIrpDDis

Weitere Informationen

KeInitializeEvent

ZwCreateFile

NtQueryInformationFile

NtSetInformationFile

NtWriteFile