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


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

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

Синтаксис

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

Параметры

[in] FileHandle

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

[in, optional] Event

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

[in, optional] ApcRoutine

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

[in, optional] ApcContext

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

[out] IoStatusBlock

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

[in] Buffer

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

[in] Length

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

[in, optional] ByteOffset

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

Если при вызове NtCreateFile задан только флаг DesiredAccess FILE_APPEND_DATA, ByteOffset игнорируется. Данные в заданном буфере для байтов длины записываются начиная с текущего конца файла.

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

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

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

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

Можно также вызвать запуск операции записи в текущем конце файла, указав для ByteOffset указатель на LARGE_INTEGER значение, если Для Параметра HighPart задано значение -1, а для Параметра LowPart — значение FILE_WRITE_TO_END_OF_FILE. Это работает независимо от того, поддерживает ли диспетчер ввода-вывода текущую позицию файла.

[in, optional] Key

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

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

NtWriteFile возвращает STATUS_SUCCESS при успешном выполнении или соответствующий код ошибки NTSTATUS при сбое.

Комментарии

Вызывающие объект NtWriteFile должны уже вызывать NtCreateFile с флагом FILE_WRITE_DATA, FILE_APPEND_DATA или GENERIC_WRITE, установленным в параметре DesiredAccess . Обратите внимание, что наличие только FILE_APPEND_DATA доступа к файлу не позволяет вызывающему объекту выполнять запись в любом месте файла, за исключением текущей метки окончания файла, а наличие FILE_WRITE_DATA доступа к файлу не препятствует вызывающему объекту выполнять запись в конец файла или за его пределами.

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

NtWriteFile начинает операцию записи в файл в ByteOffset, в текущей позиции файла или в конце файла. Операция записи завершается при записи байтов длины из буфера. При необходимости он увеличивает длину файла и сбрасывает метку конца файла.

Если вызывающий объект открыл файл с установленным флагом DesiredAccess SYNCHRONIZE, вызывающий объект может подождать, пока эта подпрограмма присвоит заданному FileHandle состояние сигнала.

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

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

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

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

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

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

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

Для вызовов из драйверов режима ядра версии 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 HwStorPortProhibitedDIs, PowerIrpDDis

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

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile