Функция NtReadFile (ntifs.h)

Подпрограмма NtReadFile считывает данные из открытого файла.

Синтаксис

__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
);

Параметры

[in] FileHandle

Дескриптор объекта файла. Этот дескриптор создается путем успешного вызова NtCreateFile или NtOpenFile.

[in, optional] Event

При необходимости — дескриптор объекта события, который будет установлен в состояние сигнала после завершения операции чтения. Драйверы устройства и промежуточные драйверы должны задать для этого параметра значение NULL.

[in, optional] ApcRoutine

Этот параметр зарезервирован. Драйверы устройства и промежуточные драйверы должны задавать для этого указателя значение NULL.

[in, optional] ApcContext

Этот параметр зарезервирован. Драйверы устройства и промежуточные драйверы должны задавать для этого указателя значение NULL.

[out] IoStatusBlock

Указатель на структуру IO_STATUS_BLOCK , которая получает окончательное состояние завершения и сведения о запрошенной операции чтения. Элемент Information получает количество байтов, фактически считанных из файла.

[out] Buffer

Указатель на буфер, выделенный вызывающим объектом, который получает данные, считываемые из файла.

[in] Length

Размер буфера в байтах, на который указывает buffer.

[in, optional] ByteOffset

Указатель на переменную, указывающую начальное смещение байтов в файле, с которого начнется операция чтения. Если предпринята попытка чтения за пределами конца файла, NtReadFile возвращает ошибку.

Если при вызове NtCreateFile задан один из флагов CreateOptions FILE_SYNCHRONOUS_IO_ALERT или FILE_SYNCHRONOUS_IO_NONALERT, диспетчер ввода-вывода сохраняет текущую позицию файла. Если это так, вызывающий объект NtReadFile может указать, что вместо явного значения ByteOffset используется смещение текущей позиции файла. Эту спецификацию можно сделать одним из следующих методов:

  • Укажите указатель на значение LARGE_INTEGER, если для элемента HighPart задано значение -1, а для элемента LowPart — системное значение FILE_USE_FILE_POINTER_POSITION.
  • Передайте указатель NULL для ByteOffset.

NtReadFile обновляет текущую позицию файла, добавляя количество байтов, прочитанных по завершении операции чтения, если использует текущую позицию файла, поддерживаемую диспетчером ввода-вывода.

Даже если диспетчер ввода-вывода сохраняет текущую позицию файла, вызывающий объект может сбросить эту позицию, передав явное значение ByteOffsetв NtReadFile. При этом текущая позиция файла автоматически изменяется на это значение ByteOffset , выполняет операцию чтения, а затем обновляет позицию в соответствии с фактическим числом прочитанных байтов. Этот метод предоставляет вызывающей объекту атомарную службу поиска и чтения.

[in, optional] Key

Драйверы устройства и промежуточные драйверы должны задавать для этого указателя значение NULL.

Возвращаемое значение

NtReadFile возвращает либо STATUS_SUCCESS, либо соответствующий код ошибки NTSTATUS.

Комментарии

Вызывающие ntReadFile должны уже вызывать NtCreateFile с FILE_READ_DATA или GENERIC_READ значением, заданным в параметре DesiredAccess .

Если в предыдущем вызове NtCreateFile для флага FILE_NO_INTERMEDIATE_BUFFERING в параметре CreateOptions задано значение NtCreateFile, параметры Length и ByteOffsetзначения NtReadFile должны быть кратными размеру сектора.

NtReadFile начинает чтение из заданного byteOffset или текущей позиции файла в данный буфер. Операция чтения завершается при одном из следующих условий:

  • Буфер заполнен, так как число байтов, указанное параметром Length , было считано. Таким образом, данные больше не могут быть помещены в буфер без переполнения.
  • Конец файла достигается во время операции чтения, поэтому в файле больше нет данных для передачи в буфер.

Если вызывающий объект открыл файл с флагом SYNCHRONIZE, установленным в DesiredAccess, вызывающий поток может синхронизироваться с завершением операции чтения, ожидая дескриптора файла FileHandle. Дескриптор получает сигнал каждый раз, когда операция ввода-вывода, выполненная для дескриптора, завершается. Однако вызывающий объект не должен ждать дескриптора, который был открыт для синхронного доступа к файлам (FILE_SYNCHRONOUS_IO_NONALERT или FILE_SYNCHRONOUS_IO_ALERT). В этом случае NtReadFile ожидает от имени вызывающей стороны и не возвращается до завершения операции чтения. Вызывающий объект может безопасно ждать дескриптора файла, только если выполняются все три из следующих условий:

  • Дескриптор был открыт для асинхронного доступа (то есть не указан флаг FILE_SYNCHRONOUS_IO_XXX ).
  • Дескриптор используется только для одной операции ввода-вывода одновременно.
  • NtReadFile вернул STATUS_PENDING.

Драйвер должен вызывать NtReadFile в контексте системного процесса, если существует одно из следующих условий:

  • Драйвер создал дескриптор файла, который он передает в NtReadFile.
  • NtReadFile уведомит драйвер о завершении ввода-вывода с помощью события, созданного драйвером.
  • NtReadFile уведомит драйвер о завершении ввода-вывода с помощью процедуры обратного вызова APC, которую драйвер передает в NtReadFile.

Дескрипторы файлов и событий допустимы только в контексте процесса, в котором создаются дескрипторы. Таким образом, чтобы избежать брешей в системе безопасности, драйвер должен создать любой файл или дескриптор события, который он передает в NtReadFile в контексте системного процесса, а не в контексте процесса, в который находится драйвер.

Аналогичным образом ntReadFile следует вызывать в контексте системного процесса, если он уведомляет драйвер о завершении ввода-вывода с помощью APC, так как APC всегда активируются в контексте потока, который выдает запрос ввода-вывода. Если драйвер вызывает NtReadFile в контексте процесса, отличного от системного, APC может быть отложена на неопределенный срок или может вообще не сработать.

Дополнительные сведения о работе с файлами см. в разделе Использование файлов в драйвере.

Вызывающие функции NtReadFile должны выполняться в среде IRQL = PASSIVE_LEVEL и с включенными специальными APC ядра.

Если вызов этой функции происходит в пользовательском режиме, следует использовать имя NtReadFile вместо ZwReadFile.

Для вызовов из драйверов режима ядра версии NtXxx и ZwXxx подпрограммы собственных системных служб Windows могут вести себя по-разному, так как они обрабатывают и интерпретируют входные параметры. Дополнительные сведения о связи между версиями процедуры NtXxx и ZwXxx см. в разделе Использование версий Nt и Zw для процедур собственных системных служб.

Требования

Требование Значение
Минимальная версия клиента Windows 2000
Целевая платформа Универсальное
Верхняя часть ntifs.h (включая Wdm.h, Ntddk.h, Ntifs.h)
Библиотека NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL (см. раздел "Примечания")
Правила соответствия DDI BufAfterReqCompletedIntIoctlA, BufAfterReqCompletedIoctlA, BufAfterReqCompletedReadA, BufAfterReqCompletedWriteA, HwStorPortProhibitedDDIs, PowerIrpDDis

См. также раздел

KeInitializeEvent

ZwCreateFile

NtQueryInformationFile

NtSetInformationFile

NtWriteFile