Поделиться через


Функция NtReadFile

Считывает данные из открытого файла.

Эта функция в пользовательском режиме эквивалентна функции ZwReadFile , описанной в пакете драйверов Windows (WDK).

Синтаксис

NTSTATUS NtReadFile(
  _In_     HANDLE           FileHandle,
  _In_opt_ HANDLE           Event,
  _In_opt_ PIO_APC_ROUTINE  ApcRoutine,
  _In_opt_ PVOID            ApcContext,
  _Out_    PIO_STATUS_BLOCK IoStatusBlock,
  _Out_    PVOID            Buffer,
  _In_     ULONG            Length,
  _In_opt_ PLARGE_INTEGER   ByteOffset,
  _In_opt_ PULONG           Key
);

Параметры

FileHandle [in]

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

Событие [в, необязательно]

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

ApcRoutine [in, необязательно]

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

ApcContext [in, необязательный]

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

IoStatusBlock [out]

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

Буфер [out]

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

Длина [in]

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

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, необязательный]

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

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

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

Комментарии

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

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

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 и с включенными специальными api ядрами.

Требования

Требование Значение
Минимальная версия клиента
Windows 2000 Professional [только классические приложения]
Минимальная версия сервера
Windows 2000 Server [только классические приложения]
Целевая платформа
Универсальное
Заголовок
Wdm.h (включая Wdm.h, Ntddk.h или Ntifs.h)
Библиотека
Ntdll.lib
DLL
Ntdll.dll (пользовательский режим)

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

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtSetInformationFile

NtWriteFile