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


Функция 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

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

[in, optional] ByteOffset

Указатель на переменную, указывающую начальное смещение байтов в файле для начала операции записи. Если длина и 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 задать FILE_NO_INTERMEDIATE_BUFFERING флаг CreateOptions, параметр Length и ByteOffset значением NtWriteFile должен быть неотъемлемой частью размера сектора. Дополнительные сведения см. в NtCreateFile.

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

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

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

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

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

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

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

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

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

Для вызовов драйверов в режиме ядра NtXxx и ZwXxx версии подпрограммы Windows Native System Services могут вести себя по-разному в том, как они обрабатывают и интерпретируют входные параметры. Дополнительные сведения о связи между NtXxx и ZwXxx версиями подпрограммы см. в разделе Using Nt and Zw Versions of the Native System Services Routines.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows 2000
целевая платформа Всеобщий
заголовка ntifs.h (включая Wdm.h, Ntddk.h, Ntifs.h)
библиотеки NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL (см. раздел "Примечания")
правил соответствия DDI HwStorPortProhibitedDDIs, PowerIrpDDis

См. также

KeInitializeEvent

NtCreateFile

NtQueryInformationFile

NtReadFile

NtSetInformationFile