IRP_MJ_WRITE (FS и драйверы фильтров)

При отправке

Диспетчер ввода-вывода или драйвер файловой системы отправляет запрос IRP_MJ_WRITE. Этот запрос можно отправить, например, когда приложение в пользовательском режиме вызывает функцию Win32, например WriteFile или когда компонент режима ядра вызывает ZwWriteFile.

Операция: драйверы файловой системы

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

Для запросов на запись MDL файловая система должна проверить дополнительный код функции, чтобы определить, какая операция запрашивается. Ниже приведены допустимые коды дополнительных функций, которые можно использовать только для кэшированных операций ввода-вывода файлов:

  • IRP_MN_COMPLETE
  • IRP_MN_COMPLETE_MDL
  • IRP_MN_COMPLETE_MDL_DPC
  • IRP_MN_COMPRESSED
  • IRP_MN_DPC
  • IRP_MN_MDL
  • IRP_MN_MDL_DPC
  • IRP_MN_NORMAL

Дополнительные сведения о том, как обрабатывать этот IRP, изучите пример FASTFAT, включенный в комплект драйверов Windows (WDK).

Операция: устаревшие драйверы фильтров файловой системы

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

  • Завершение или сбой IRP или
  • Передайте IRP вниз к следующему нижнему драйверу в стеке.

Параметры

Файловая система или драйвер фильтра вызывает IoGetCurrentIrpStackLocation для заданного IRP, чтобы получить указатель на собственное расположение стека в IRP. В следующих параметрах Irp указывает на IRP и IrpSp указывает на IO_STACK_LOCATION. Драйвер может использовать сведения, заданные в следующих элементах IRP и расположении стека IRP для обработки запроса на создание:

  • DeviceObject — это указатель на целевой объект устройства.

  • Irp-AssociatedIrp.SystemBuffer> указывает на системный буфер, используемый в качестве промежуточного буфера системы, если флаг DO_BUFFERED_IO установлен в DeviceObject-Flags>. В противном случае для этого элемента задано значение NULL.

  • Irp-IoStatus> указывает на структуру IO_STATUS_BLOCK, которая получает окончательное состояние завершения и сведения о запрошенной операции. Если запрос IRP_MJ_WRITE завершается ошибкой, подпрограмма отправки записи файловой системы возвращает значение NTSTATUS ошибки, а значение Irp-IoStatus.Information> не определено и не должно использоваться.

  • Irp-MdlAddress> — это адрес списка дескриптора памяти (MDL), описывающего страницы, на которые записываются данные.

  • IrpSp-FileObject> указывает на объект файла, связанный с DeviceObject. Если флаг FO_SYNCHRONOUS_IO задан в IrpSp-FileObject-Flags>>, объект файла был открыт для синхронного ввода-вывода.

    Параметр IrpSp-FileObject> содержит указатель на поле RelatedFileObject, которое также является FILE_OBJECT структурой. Поле RelatedFileObject структуры FILE_OBJECT недопустимо во время обработки IRP_MJ_WRITE и не должно использоваться.

  • IrpSp-Flags>: если установлен флаг SL_FORCE_DIRECT_WRITE, драйверы режима ядра могут записывать в области тома, в которые они обычно не могут записываться из-за прямого блокировки записи. Прямая блокировка записи была реализована по соображениям безопасности в Windows Vista и более поздних операционных системах. Этот флаг проверяется как на уровне файловой системы, так и на уровне стека хранилища. Дополнительные сведения о прямой блокировке записи см. в разделе "Блокировка прямых операций записи на томах и дисках". Флаг SL_FORCE_DIRECT_WRITE доступен в Windows Vista и более поздних версиях Windows.

  • Для IrpSp-MajorFunction> задано значение IRP_MJ_WRITE.

  • IrpSp-MinorFunction> указывает запрашиваемую операцию и содержит одно из следующих значений. Если дополнительный код функции не указан, операция является стандартной записью (эквивалентной IRP_MN_NORMAL).

    ДополнительныйFunction Description
    IRP_MN_NORMAL Запрос на запись предназначен для стандартной операции записи
    IRP_MN_DPC Запрос на запись выполняется из подпрограммы DPC
    IRP_MN_MDL Возвращает MDL, описывающий кэшированные данные файла в Irp-MdlAddress>; вызывающий объект использует этот MDL для записи данных непосредственно в кэш.
    IRP_MN_COMPLETE Не используется сами по себе; только в сочетании с по крайней мере IRP_MN_MDL. См. заметки.
    IRP_MN_COMPRESSED Запрос на запись предназначен для сжатого файла
    IRP_MN_MDL_DPC Запрос на запись выполняется из подпрограммы DPC и возвращает MDL, описывающий кэшированные данные файла в Irp-MdlAddress>
    IRP_MN_COMPLETE_MDL Указывает, что вызывающий объект, который использовал MDL для записи данных непосредственно в кэш, закончил работу с помощью MDL
    IRP_MN_COMPLETE_MDL_DPC Указывает, что вызывающий объект, который использовал MDL для записи данных непосредственно в кэш, завершен с помощью MDL; Запрос на запись выполняется из подпрограммы DPC
  • IrpSp-Parameters.Write.ByteOffset> — это LARGE_INTEGER переменная, указывающая начальное смещение байтов в файле записываемых данных.

    В определенных обстоятельствах этот параметр может содержать специальное значение. Например, если значение true, то следующее условие указывает, что текущий конец файла должен использоваться вместо явного значения смещения файла: IrpSp-Parameters.Write.ByteOffset.LowPart> == FILE_WRITE_TO_END_OF_FILE и IrpSp-Parameters.Write.ByteOffset.HighPart> == -1

  • IrpSp-Parameters.Write.Key> — это значение ключа, связанное с блокировкой диапазона байтов в целевом файле.

  • IrpSp-Parameters.Write.Length> — это длина в байтах записываемых данных. Если операция записи выполнена успешно, число записанных байтов возвращается в элементе information структуры IO_STATUS_BLOCK, на которую указывает Irp-IoStatus>.

Замечания

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

Следующие маркеры описывают стандартную запись и запись MDL на основе IRP:

  • Чтобы выполнить стандартную запись:

    1. Издатель создает IRP с MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_NORMAL (то есть 0) и предоставляет данные для записи в Irp-AssociatedIrp.SystemBuffer>.
    2. При отправке IRP в файловую систему данные для записи уже есть в IRP. Поэтому запись завершается, когда файловая система завершает обработку IRP; Например, путем копирования данных из буфера в кэш для кэша для кэшируемой записи.
  • Для выполнения записи MDL на основе IRP:

    1. Издатель создает IRP с MajorFunction = IRP_MJ_WRITE, MinorFunction = IRP_MN_MDL, но не предоставляет буфер данных. Они отправляют этот IRP в файловую систему.
    2. Файловая система создает MDL, помещает его в IRP и завершает IRP.
    3. Издатель использует MDL для копирования данных непосредственно в кэш файла.
    4. Когда издатель выполняет копирование данных в кэш, они создают другой IRP с MajorFunction = IRP_MJ_WRITE, MinorFunction = (IRP_MN_MDL | IRP_MN_COMPLETE) и отправьте его в файловую систему.
    5. Файловая система освобождает MDL, а операция записи завершена.

См. также

CcMdlWriteComplete

CcPrepareMdlWrite

FLT_IO_PARAMETER_BLOCK

IO_STACK_LOCATION

IO_STATUS_BLOCK

IoGetCurrentIrpStackLocation

IRP

IRP_MJ_READ

IRP_MJ_WRITE (справочник по ядрам WDK)

ZwWriteFile