Функция FltCreateFile (fltkernel.h)
Драйверы минифильтра вызывают FltCreateFile , чтобы создать новый файл или открыть существующий.
Синтаксис
NTSTATUS FLTAPI FltCreateFile(
[in] PFLT_FILTER Filter,
[in, optional] PFLT_INSTANCE Instance,
[out] PHANDLE FileHandle,
[in] ACCESS_MASK DesiredAccess,
[in] POBJECT_ATTRIBUTES ObjectAttributes,
[out] PIO_STATUS_BLOCK IoStatusBlock,
[in, optional] PLARGE_INTEGER AllocationSize,
[in] ULONG FileAttributes,
[in] ULONG ShareAccess,
[in] ULONG CreateDisposition,
[in] ULONG CreateOptions,
[in, optional] PVOID EaBuffer,
[in] ULONG EaLength,
[in] ULONG Flags
);
Параметры
[in] Filter
Непрозрачный указатель фильтра для вызывающего объекта.
[in, optional] Instance
Указатель непрозрачного экземпляра для экземпляра драйвера минифильтра, в который должен быть отправлен запрос на создание. Экземпляр должен быть присоединен к тому, где находится файл или каталог. Этот параметр является необязательным и может иметь значение NULL. Если этот параметр имеет значение NULL, запрос отправляется объекту устройства в верхней части стека драйверов файловой системы для тома. Если значение не равно NULL, запрос отправляется только экземплярам драйвера минифильтра, присоединенным ниже указанного экземпляра.
[out] FileHandle
Указатель на переменную, выделенную вызывающим объектом, которая получает дескриптор файла в случае успешного вызова FltCreateFile .
[in] DesiredAccess
Битовая маска флагов, указывающая тип доступа к файлу или каталогу, которые требуются вызывающей системе. Дополнительные сведения об этом параметре и списке значений флагов см. в разделе Параметр DesiredAccessioCreateFileEx .
[in] ObjectAttributes
Указатель на непрозрачную структуру OBJECT_ATTRIBUTES , которая уже инициализирована с помощью InitializeObjectAttributes. Дополнительные сведения и описание каждого элемента структуры см. в разделе Параметр ObjectAttributesобъекта IoCreateFileEx .
[out] IoStatusBlock
Указатель на структуру IO_STATUS_BLOCK , которая получает окончательное состояние завершения и сведения о запрошенной операции. Дополнительные сведения об этом параметре см. в разделе Параметр IoStatusBlockобъекта IoCreateFileEx .
[in, optional] AllocationSize
При необходимости задает начальный размер выделения (в байтах) для файлового потока. Ненулевое значение не оказывает никакого влияния, если только файл не создается, не перезаписывается или не заменяет его.
[in] FileAttributes
Указывает один или несколько флагов FILE_ATTRIBUTE_XXX , которые представляют атрибуты файла, устанавливаемые при создании, замене или перезаписи файла. Дополнительные сведения и список флагов см. в параметре FileAttributesioCreateFileEx .
[in] ShareAccess
Указывает тип общего доступа к файлу, который требуется вызывающей организации, как ноль или единица, или сочетание флагов. Дополнительные сведения и список флагов см. в разделе Параметр ShareAccessIoCreateFileEx .
[in] CreateDisposition
Задает значение, определяющее выполняемое действие в зависимости от того, существует ли файл. Список возможных значений см. в разделе Параметр ЛиквидацияIoCreateFileEx .
[in] CreateOptions
Указывает параметры, применяемые при создании или открытии файла. Этот параметр является совместимым сочетанием флагов, перечисленных и описанных в параметре CreateOptionsобъекта IoCreateFileEx.
[in, optional] EaBuffer
Указатель на предоставленный вызывающим FILE_FULL_EA_INFORMATION структурированный буфер, содержащий сведения о расширенных атрибутах (EA), применяемые к файлу.
[in] EaLength
Длина EaBuffer в байтах.
[in] Flags
Указывает параметры, используемые во время создания запроса на создание. Список возможных параметров см. в разделе ПараметрыIoCreateFileEx .
Возвращаемое значение
FltCreateFile возвращает STATUS_SUCCESS или соответствующее значение NTSTATUS. Список возможных кодов возврата см. в разделе Возвращаемое значениеioCreateFileEx .
Примечание
FltCreateFile может возвращать STATUS_FILE_LOCK_CONFLICT в качестве возвращаемого значения или в элементе Status структуры IO_STATUS_BLOCK, на которую указывает параметр IoStatusBlock. Это происходит только в том случае, если файл журнала NTFS заполнен, а при попытке FltCreateFile справиться с этой ситуацией возникает ошибка.
Комментарии
В версиях Windows, предшествующих Microsoft клиентский компонент Центра обновления Windows Rollup для Windows 2000 с пакетом обновления 4 (SP4) и Windows Server 2003 с пакетом обновления 1 (SP1), драйверы минифильтра должны вызывать FltCreateFile вместо IoCreateFile, IoCreateFileSpecifyDeviceObjectHint или ZwCreateFile, чтобы получить дескриптор файла для использования с подпрограммами ввода-вывода ZwXxx, такими как ZwReadFile и ZwQueryInformationFile.
В накопительном пакете microsoft клиентский компонент Центра обновления Windows для Windows 2000 с пакетом обновления 4 (SP4), Windows Server 2003 с пакетом обновления 1 (SP1) и более поздних версий драйверы минифильтра могут использовать FltCreateFileEx для получения указателя объекта файла для использования с подпрограммами FltXxxFile, такими как FltReadFile и FltWriteFile. В более ранних версиях Windows дескриптор, полученный из FltCreateFile , можно преобразовать в указатель на объект файла, вызвав ObReferenceObjectByHandle следующим образом:
status = ObReferenceObjectByHandle(
handle, //Handle
0, //DesiredAccess
NULL, //ObjectType
KernelMode, //AccessMode
&handleFileObject, //Object
NULL); //HandleInformation</pre>
FltCreateFile отправляет запрос на создание только экземплярам, подключенным под указанным экземпляром драйвера минифильтра, и в файловую систему. Указанный экземпляр и экземпляры, присоединенные над ним, не получают запрос на создание. Если экземпляр не указан, запрос направляется в верхнюю часть стека и получается всеми экземплярами и файловой системой.
Существует два альтернативных способа указать имя файла, который будет создан или открыт с помощью FltCreateFile:
- В виде полного имени пути, указанного в элементе ObjectName входных атрибутов ObjectAttributes.
- В качестве пути относительно файла каталога, представленного дескриптором в элементе RootDirectory входного объекта ObjectAttributes.
Любой дескриптор, полученный из FltCreateFile , в конечном итоге должен быть освобожден путем вызова FltClose.
Подпрограммы драйвера, которые не выполняются в контексте системного процесса, должны задавать атрибут OBJ_KERNEL_HANDLE для параметра ObjectAttributesобъекта FltCreateFile. Установка этого атрибута ограничивает использование дескриптора, возвращаемого FltCreateFile , процессами, выполняющимися в режиме ядра. В противном случае дескриптор может получить доступ к процессу, в контексте которого выполняется драйвер.
Примечание
Не вызывайте эту подпрограмму со значением IRP верхнего уровня, отличном от NULL, так как это может привести к взаимоблокировке системы.
Не вызывайте эту подпрограмму с отключенными APC (необработанным FsRtlEnterFileSystem или KeEnterCriticalRegion, так как это может привести к взаимоблокировке потока).
Некоторые флаги DesiredAccess и их сочетания имеют следующие эффекты:
Чтобы вызывающий объект синхронизировать завершение ввода-вывода, ожидая, пока возвращенный ФайлHandle будет установлен в состояние Signaled, необходимо установить флаг SYNCHRONIZE.
Если заданы только флаги FILE_APPEND_DATA и SYNCHRONIZE, вызывающий объект может записывать данные только в конец файла, а любые сведения о смещении записей в файл игнорируются. Однако файл автоматически расширяется по мере необходимости для операций записи этого типа.
Установка флага FILE_WRITE_DATA для файла также позволяет выполнять операции записи за пределами конца файла. Файл также автоматически расширяется для этого типа записи.
Если заданы только флаги FILE_EXECUTE и SYNCHRONIZE, вызывающий объект не может использовать возвращенный файл FileHandle для непосредственного чтения или записи данных в файл или из файла. То есть все операции с файлом должны использовать системные операции ввода-вывода подкачки для чтения или записи данных файла.
Параметр ShareAccess определяет, могут ли отдельные потоки получать доступ к одному файлу, возможно, одновременно. Если оба средства открытия файлов имеют права доступа к файлу указанным способом, файл можно открыть и предоставить к ним общий доступ. Если исходный вызывающий объект FltCreateFile не указывает FILE_SHARE_READ, FILE_SHARE_WRITE или FILE_SHARE_DELETE, другие открытые операции с файлом выполняться невозможно, так как исходному вызывающему объекту предоставляется монопольный доступ к файлу.
Чтобы общий файл был успешно открыт, запрошенный desiredAccess к файлу должен быть совместим со спецификациями DesiredAccess и ShareAccess всех предыдущих открытий, которые еще не были выпущены с fltClose. Это значит, что значение DesiredAccess , указанное в параметре FltCreateFile для данного файла, не должно конфликтовать с доступом, запрещенным другими средствами открытия файла.
Примечание
Если IO_IGNORE_SHARE_ACCESS_CHECK указан в параметре Flags , диспетчер ввода-вывода игнорирует параметр ShareAccess . Однако файловая система может по-прежнему выполнять проверки доступа. Таким образом, важно указать режим общего доступа для параметра ShareAccess , даже если используется флаг IO_IGNORE_SHARE_ACCESS_CHECK. Кроме того, обратите внимание, что при указании IO_IGNORE_SHARE_ACCESS_CHECK файловая система не отслеживает требуемый или общий доступ для текущего открытия. Из-за этого последующие открытые вызовы в том же файле могут быть успешными.
Значение CreateDisposition FILE_SUPERSEDE требует, чтобы вызывающий объект был доступ DELETE к существующему объекту файла. Если это так, успешный вызов FltCreateFile с FILE_SUPERSEDE в существующем файле эффективно удаляет этот файл, а затем повторно создает его. Это означает, что если файл уже был открыт другим потоком, он открыл файл, указав параметр ShareAccess с флагом FILE_SHARE_DELETE. Обратите внимание, что этот тип ликвидации соответствует стилю POSIX для перезаписи файлов.
Значения CreateDisposition FILE_OVERWRITE_IF и FILE_SUPERSEDE похожи. Если fltCreateFile вызывается с существующим файлом и любое из этих значений CreateDisposition , файл заменяется.
Перезапись файла семантически эквивалентна операции замены, за исключением следующего:
- Вызывающий объект должен иметь доступ на запись к файлу, а не доступ к удалению. Это означает, что, если файл уже был открыт другим потоком, он открыл файл с флагом FILE_SHARE_WRITE, установленным во входном shareAccess.
- Указанные атрибуты файла логически являются ORed с атрибутами, уже имеющимися в файле. Это означает, что если файл уже открыт другим потоком, последующий вызывающий объект FltCreateFile не может отключить существующие флаги FileAttributes , но может включить дополнительные флаги для того же файла. Обратите внимание, что этот стиль перезаписи файлов согласуется с MS-DOS, Windows 3.1 и OS/2.
Значение FILE_DIRECTORY_FILE CreateOptions указывает, что создаваемый или открытый файл является файлом каталога. При создании файла каталога файловая система создает соответствующую структуру на диске, которая представляет пустой каталог для структуры на диске конкретной файловой системы. Если этот параметр был указан, а открываемый файл не является файлом каталога или если вызывающий объект указал несогласованное значение CreateOptions или CreateDisposition , вызов FltCreateFile завершается ошибкой.
Флаг FILE_NO_INTERMEDIATE_BUFFERING CreateOptions запрещает файловой системе выполнять промежуточную буферизацию от имени вызывающего объекта. Указание этого значения накладывает определенные ограничения на параметры вызывающего объекта на Zw.. Подпрограммы файлов , в том числе следующие:
- Любое значение смещения байтов, передаваемое в ZwReadFile или ZwWriteFile, должно быть кратным размеру сектора.
- Длина, передаваемая в ZwReadFile или ZwWriteFile, должна быть кратна размеру сектора. Обратите внимание, что указание операции чтения в буфере, длина которого точно равна размеру сектора, может привести к тому, что в этот буфер будет передано меньше байтов, если во время передачи был достигнут конец файла.
- Буферы должны быть выровнены в соответствии с требованиями выравнивания базового запоминающего устройства. Эти сведения можно получить, вызвав FltCreateFile , чтобы получить дескриптор для объекта файла, представляющего физическое устройство, а затем вызвав ZwQueryInformationFile с этим дескриптором, указав FileAlignmentInformation в качестве FileInformationClass. Дополнительные сведения о системных значениях FILE_XXX_ALIGNMENT, которые определены в ntifs.h, см. в разделе DEVICE_OBJECT и инициализация объекта устройства.
- Вызовы ZwSetInformationFile с параметром FileInformationClass, для параметра FileInformationClass , равным FilePositionInformation, должны указывать смещение, кратное размеру сектора.
FILE_SYNCHRONOUS_IO_ALERT и FILE_SYNCHRONOUS_IO_NONALERT CreateOptions , которые являются взаимоисключающими, как следует из их названий, указывают, что файл открывается для синхронного ввода-вывода. Это означает, что все операции ввода-вывода с файлом должны быть синхронными, если они выполняются через объект file, на который ссылается возвращенный FileHandle . Все операции ввода-вывода в таком файле сериализуются во всех потоках с помощью возвращенного дескриптора. Если любой из этих свойств CreateOptions задан, диспетчер ввода-вывода сохраняет текущее смещение положения файла в поле CurrentByteOffset объекта файла. Это смещение можно использовать в вызовах ZwReadFile и ZwWriteFile. Его также можно запросить или задать, вызвав ZwQueryInformationFile или ZwSetInformationFile.
Если флаг createOptions FILE_OPEN_REPARSE_POINT не указан и FltCreateFile пытается открыть файл с точкой повторного обработки, для файла выполняется обычная обработка точки повторного обработки. Если, с другой стороны, указан флаг FILE_OPEN_REPARSE_POINT, обычная обработка повторного обработки не выполняется и FltCreateFile пытается открыть файл точки повторного обработки напрямую. В любом случае, если операция открытия была успешной, FltCreateFile возвращает STATUS_SUCCESS; В противном случае подпрограмма возвращает код ошибки NTSTATUS. FltCreateFile никогда не возвращает STATUS_REPARSE.
Флаг createOptions FILE_OPEN_REQUIRING_OPLOCK исключает время между открытием файла и запросом блокировки операции, которая потенциально может позволить третьей стороне открыть файл и получить нарушение общего доступа. Приложение может использовать флаг FILE_OPEN_REQUIRING_OPLOCK в FltCreateFile , а затем запросить любую блокировку. Это гарантирует, что владелец oplock будет уведомлен о любом последующем открытом запросе, который приведет к нарушению общего доступа.
В Windows 7, если в файле существуют другие дескрипторы, когда приложение использует флаг FILE_OPEN_REQUIRING_OPLOCK, операция создания завершится сбоем с STATUS_OPLOCK_NOT_GRANTED. Это ограничение больше не существует, начиная с Windows 8.
Если эта операция создания приведет к прерыванию блокировки операции, которая уже существует в файле, установка флага FILE_OPEN_REQUIRING_OPLOCK приведет к сбою операции создания с STATUS_CANNOT_BREAK_OPLOCK. Существующая блокировка не будет нарушена этой операцией создания.
Приложение, использующее этот флаг, должно запросить блокировку после успешного вызова, иначе все последующие попытки открыть файл будут заблокированы без использования обычной обработки блокировки. Аналогичным образом, если этот вызов завершается успешно, но последующий запрос oplock завершается ошибкой, приложение, использующее этот флаг, должно закрыть свой дескриптор после обнаружения сбоя запроса oplock.
Примечание
Флаг FILE_OPEN_REQUIRING_OPLOCK доступен в операционных системах Windows 7, Windows Server 2008 R2 и более поздних версий. Файловые системы Майкрософт, реализующие этот флаг в Windows 7, — NTFS, FAT и exFAT.
Флаг CreateOptions FILE_RESERVE_OPFILTER позволяет приложению запрашивать oplock уровня 1, пакет или фильтр, чтобы другие приложения не получали нарушения общего доступа. Однако FILE_RESERVE_OPFILTER практически полезно только для блокировки фильтров. Чтобы использовать его, необходимо выполнить следующие действия.
Отправьте запрос на создание с помощью createOptions FILE_RESERVE_OPFILTER, DesiredAccess для точного FILE_READ_ATTRIBUTES и ShareAccess точно FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE.
- Если дескрипторы уже открыты, запрос на создание завершается ошибкой с STATUS_OPLOCK_NOT_GRANTED, а следующая запрошенная блокировка также завершается ошибкой.
- При открытии с большим доступом или меньшим общим доступом также произойдет сбой STATUS_OPLOCK_NOT_GRANTED.
Если запрос на создание выполнен успешно, запросите блокировку операции.
Откройте другой дескриптор файла для выполнения операций ввода-вывода.
Шаг 3 делает это практичным только для фильтров oplock. Дескриптор, открытый на шаге 3, может иметь desiredAccess, который содержит не более FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE | SYNCHRONIZE | READ_CONTROL и по-прежнему не прерывает блокировку фильтра. Однако любой объект DesiredAccess больше FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | Функция SYNCHRONIZE разорвёт блокировку на уровне 1 или пакетную блокировку и сделает флаг FILE_RESERVE_OPFILTER бесполезным для этих типов oplock.
NTFS — единственная файловая система Майкрософт, реализующая FILE_RESERVE_OPFILTER.
Драйверы минифильтра должны использовать FltSetInformationFile, а не ZwSetInformationFile для переименования файла.
Примечание
Если вы попытаетесь открыть том, указав только сочетание следующих флагов для параметра DesiredAccess , FltCreateFile откроет дескриптор, не зависящий от файловой системы, имеющий прямой доступ к устройству хранения тома.
- FILE_READ_ATTRIBUTES
- READ_CONTROL
- WRITE_DAC
- WRITE_OWNER
- SYNCHRONIZE
Вы не должны использовать FltCreateFile для открытия дескриптора с прямым доступом к устройству хранения тома, иначе произойдет утечка системных ресурсов. Если вы хотите открыть дескриптор с прямым доступом к устройству хранения, вызовите вместо этого функцию IoCreateFileEx, IoCreateFileSpecifyDeviceObjectHint или ZwCreateFile .
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Накопительный пакет обновления 1 для Windows 2000 с пакетом обновления 4 (SP4), Windows XP с пакетом обновления 2 (SP2), Windows Server 2003 с пакетом обновления 1 (SP1) |
Целевая платформа | Универсальное |
Верхняя часть | fltkernel.h (включая FltKernel.h) |
Библиотека | Fltmgr.lib |
IRQL | PASSIVE_LEVEL |