Функция ZwWriteFile (wdm.h)
Подпрограмма ZwWriteFile записывает данные в открытый файл.
Синтаксис
NTSYSAPI NTSTATUS ZwWriteFile(
[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
Дескриптор объекта файла. Этот дескриптор создается путем успешного вызова ZwCreateFile или ZwOpenFile.
[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 указывают операцию записи после текущей метки окончания файла, ZwWriteFile автоматически расширяет файл и обновляет метку конца файла; все байты, которые не записываются явным образом между такими старыми и новыми знаками окончания файла, определяются как нулевые.
Если вызов ZwCreateFile задает только флаг DesiredAccess FILE_APPEND_DATA, ByteOffset игнорируется. Данные в заданном буфере для байтов длины записываются начиная с текущего конца файла.
Если при вызове ZwCreateFile задан любой из флагов CreateOptions , FILE_SYNCHRONOUS_IO_ALERT или FILE_SYNCHRONOUS_IO_NONALERT, диспетчер ввода-вывода сохраняет текущую позицию файла. В этом случае вызывающий объект ZwWriteFile может указать, что вместо явного значения ByteOffset используется смещение текущей позиции файла. Эту спецификацию можно сделать с помощью одного из следующих методов:
Укажите указатель на LARGE_INTEGER значение с элементом HighPart , равным -1, а для элемента LowPart — системное значение FILE_USE_FILE_POINTER_POSITION.
Передайте указатель NULL для ByteOffset.
ZwWriteFile обновляет текущую позицию файла, добавляя количество байтов, записанных при завершении операции записи, если использует текущую позицию файла, поддерживаемую диспетчером ввода-вывода.
Даже если диспетчер ввода-вывода сохраняет текущую позицию файла, вызывающий объект может сбросить эту позицию, передав явное значение ByteOffsetв ZwWriteFile. Это автоматически изменяет текущую позицию файла на это значение ByteOffset, выполняет операцию записи, а затем обновляет позицию в соответствии с фактически записанным числом байтов. Этот метод предоставляет вызывающей объекту атомарную службу поиска и записи.
Можно также вызвать запуск операции записи в текущем конце файла, указав для ByteOffset указатель на LARGE_INTEGER значение, если Для Параметра HighPart задано значение -1, а для Параметра LowPart — значение FILE_WRITE_TO_END_OF_FILE. Это работает независимо от того, поддерживает ли диспетчер ввода-вывода текущую позицию файла.
[in, optional] Key
Драйверы устройств и промежуточных водителей должны задавать для этого указателя значение NULL.
Возвращаемое значение
ZwWriteFile возвращает STATUS_SUCCESS при успешном выполнении или соответствующий код ошибки NTSTATUS при сбое.
Комментарии
Вызывающие ZwWriteFile должны уже вызывать ZwCreateFile с флагом FILE_WRITE_DATA, FILE_APPEND_DATA или GENERIC_WRITE, установленным в параметре DesiredAccess . Обратите внимание, что наличие только FILE_APPEND_DATA доступа к файлу не позволяет вызывающему объекту выполнять запись в любом месте файла, за исключением текущей метки окончания файла, а наличие FILE_WRITE_DATA доступа к файлу не препятствует вызывающему объекту выполнять запись в конец файла или за его пределами.
Если в предыдущем вызове ZwCreateFile флаг CreateOptions FILE_NO_INTERMEDIATE_BUFFERING, параметры Length и ByteOffset значения ZwWriteFile должны быть неотъемлемой частью размера сектора. Дополнительные сведения см. в разделе ZwCreateFile.
ZwWriteFile начинает операцию записи в файл в ByteOffset, в текущей позиции файла или в конце файла. Операция записи завершается при записи байтов длины из буфера. При необходимости он увеличивает длину файла и сбрасывает метку конца файла.
Если вызывающий объект открыл файл с установленным флагом DesiredAccess SYNCHRONIZE, вызывающий объект может подождать, пока эта подпрограмма присвоит заданному FileHandle состояние сигнала.
Драйверы должны вызывать ZwWriteFile в контексте системного процесса в трех случаях:
Драйвер создает дескриптор файла, который передается в ZwWriteFile.
ZwWriteFile уведомляет драйвер о завершении ввода-вывода с помощью события, созданного драйвером.
ZwWriteFile уведомляет драйвер о завершении ввода-вывода с помощью процедуры обратного вызова APC, которую драйвер передает в ZwWriteFile.
Дескрипторы файлов и событий допустимы только в контексте процесса, в котором создаются дескрипторы. Поэтому, чтобы избежать брешей безопасности, драйвер должен создать любой файл или дескриптор события, который он передает в ZwWriteFile в контексте системного процесса, а не в контексте процесса, в который находится драйвер.
Аналогичным образом , ZwWriteFile должен вызываться в контексте системного процесса, если он уведомляет драйвер о завершении ввода-вывода с помощью APC, так как APC всегда активируются в контексте потока, отправляющего запрос ввода-вывода. Если драйвер вызывает ZwWriteFile в контексте процесса, отличного от системного процесса, APC может быть отложен на неопределенный срок или вообще не срабатывает, так как исходный поток может никогда не перейти в состояние ожидания с оповещениями.
Дополнительные сведения о работе с файлами см. в разделе Использование файлов в драйвере.
Вызывающие файлы ZwWriteFile должны выполняться в среде IRQL = PASSIVE_LEVEL и с включенными специальными ППК ядра.
Если вызов этой функции выполняется в пользовательском режиме, следует использовать имя "NtWriteFile" вместо "ZwWriteFile".
Для вызовов из драйверов режима ядра версии NtXxx и ZwXxx подпрограммы Собственные системные службы Windows могут вести себя по-разному, так как они обрабатывают и интерпретируют входные параметры. Дополнительные сведения о связи между версиями подпрограмм NtXxx и ZwXxx см. в разделе Использование версий NT и Zw подпрограмм собственных системных служб.
Требования
Требование | Значение |
---|---|
Целевая платформа | Универсальное |
Верхняя часть | wdm.h (включая Wdm.h, Ntddk.h, Ntifs.h) |
Библиотека | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL (см. раздел "Примечания") |
Правила соответствия DDI | HwStorPortProhibitedDIs(storport), PowerIrpDDis(wdm) |