Как искать информационный объект в файловых структурах Windows
Обновлено: 21.11.2024
Оболочка пространство имен организует файловую систему и другие объекты, управляемые оболочкой, в единую древовидную иерархию. Концептуально это более крупная и всеобъемлющая версия файловой системы.
- Введение
- Идентификация объектов пространства имен
- Идентификаторы элементов
- Списки идентификаторов элементов
- PIDL
- Распределение PIDL
Введение
Одной из основных обязанностей командной консоли является управление широким спектром объектов, составляющих систему, и предоставление доступа к ним. Наиболее многочисленными и знакомыми из этих объектов являются папки и файлы, находящиеся на жестких дисках компьютеров. Однако оболочка также управляет рядом нефайловых системных или виртуальных объектов. Вот некоторые примеры:
- Сетевые принтеры
- Другие сетевые компьютеры
- Приложения панели управления
- Корзина
Некоторые виртуальные объекты вообще не требуют физического хранения. Например, объект принтера содержит набор ссылок на сетевые принтеры. Другие виртуальные объекты, такие как корзина, могут содержать данные, хранящиеся на диске, но с ними нужно обращаться иначе, чем с обычными файлами. Например, виртуальный объект можно использовать для представления данных, хранящихся в базе данных. Что касается пространства имен, различные элементы базы данных могут отображаться в проводнике Windows как отдельные объекты, даже если все они хранятся в одном файле на диске.
Виртуальные объекты могут даже находиться на удаленных компьютерах. Например, для облегчения роуминга файлы документов пользователя могут храниться на сервере. Чтобы предоставить пользователям доступ к своим файлам с нескольких настольных ПК, папка «Мои документы» на настольном ПК, который они сейчас используют, будет указывать на сервер, а не на жесткий диск настольного ПК. Его путь будет включать либо сопоставленный сетевой диск, либо путь в формате UNC.
Как и файловая система, пространство имен включает два основных типа объектов: папки и файлы. Объекты папки — это узлы дерева; они являются контейнерами для файловых объектов и других папок. Файловые объекты — это листья дерева; это либо обычные файлы на диске, либо виртуальные объекты, такие как ссылки на принтеры. Папки, которые не являются частью файловой системы, иногда называют виртуальными папками.
Как и папки файловой системы, набор виртуальных папок обычно различается от системы к системе. Существует три класса виртуальных папок:
- Стандартные виртуальные папки, такие как корзина, которые есть во всех системах.
- Необязательные виртуальные папки со стандартными именами и функциями, но могут присутствовать не во всех системах.
- Нестандартные папки, устанавливаемые пользователем.
В отличие от папок файловой системы, пользователи не могут сами создавать новые виртуальные папки. Они могут устанавливать только программы, созданные сторонними разработчиками. Таким образом, количество виртуальных папок обычно намного меньше, чем количество папок файловой системы. Обсуждение того, как реализовать виртуальные папки, см. в разделе Расширения пространства имен.
Визуальное представление структуры пространства имен можно увидеть на панели проводника проводника Windows. Например, на следующем снимке экрана проводника Windows показано относительно простое пространство имен.
Конечным корнем иерархии пространств имен является рабочий стол. Непосредственно под корнем находится несколько виртуальных папок, таких как «Мой компьютер» и «Корзина».
Файловые системы различных дисковых накопителей можно рассматривать как подмножества более крупной иерархии пространств имен. Корни этих файловых систем — это подпапки папки «Мой компьютер». Мой компьютер также включает в себя корни всех подключенных сетевых дисков. Другие узлы в дереве, такие как Мои документы, являются виртуальными папками.
Идентификация объектов пространства имен
Прежде чем вы сможете использовать объект пространства имен, вы должны сначала найти способ его идентификации. Объект в файловой системе может иметь такое имя, как MyFile.htm. Поскольку в системе могут быть другие файлы с таким именем, для уникальной идентификации файла или папки требуется полный путь, например «C:\MyDocs\MyFile.htm». Этот путь представляет собой упорядоченный список всех папок на пути от корня файловой системы C:\ до файла.
В контексте пространства имен пути по-прежнему весьма полезны для идентификации объектов, расположенных в части файловой системы пространства имен. Однако их нельзя использовать для виртуальных объектов. Вместо этого командная консоль предоставляет альтернативные средства идентификации, которые можно использовать с любым объектом пространства имен.
Идентификаторы элементов
Член abID является идентификатором объекта.Длина abID не определена, а его значение определяется папкой, содержащей объект. Поскольку не существует стандартного определения того, как значения abID назначаются папкам, они имеют смысл только для связанного объекта папки. Приложения должны просто рассматривать их как токен, который идентифицирует объект в определенной папке. Поскольку длина abID варьируется, элемент cb содержит размер структуры SHITEMID в байтах.
Поскольку идентификаторы элементов бесполезны для целей отображения, папка, содержащая объект, обычно присваивает ему отображаемое имя. Это имя используется Проводником Windows при отображении содержимого папки. Дополнительную информацию о том, как обрабатываются отображаемые имена, см. в разделе Получение информации из папки.
Списки идентификаторов элементов
Идентификатор элемента редко используется сам по себе. Обычно он является частью списка идентификаторов элементов, который служит той же цели, что и путь к файловой системе. Однако вместо строки символов, используемой для путей, список идентификаторов элементов представляет собой структуру ITEMIDLIST. Эта структура представляет собой упорядоченную последовательность из одного или нескольких идентификаторов элементов, заканчивающуюся двухбайтовым NULL. Каждый идентификатор элемента в списке идентификаторов элементов соответствует объекту пространства имен. Их порядок определяет путь в пространстве имен, очень похожий на путь в файловой системе.
На следующем рисунке показано схематическое представление структуры ITEMIDLIST, соответствующей C:\MyDocs\MyFile.htm. Отображаемое имя каждого идентификатора элемента отображается над ним. Различная ширина членов abID произвольна; они иллюстрируют тот факт, что размер этого члена может варьироваться.
PIDL
Для Shell API объекты пространства имен обычно идентифицируются указателем на их структуру ITEMIDLIST или указателем на список идентификаторов элементов (PIDL). Для удобства термин PIDL в этой документации обычно относится к самой структуре, а не к указателю на нее.
Показанный на предыдущем рисунке PIDL называется полным или абсолютным PIDL. Полный PIDL начинается с рабочего стола и содержит идентификаторы элементов всех промежуточных папок в пути. Он заканчивается идентификатором элемента объекта, за которым следует завершающий двухбайтовый NULL. Полный PIDL аналогичен полному пути и однозначно идентифицирует объект в пространстве имен Shell.
Полные PIDL используются редко. Многие функции и методы ожидают относительный PIDL. Корнем относительного PIDL является папка, а не рабочий стол. Как и в случае с относительными путями, ряд идентификаторов элементов, составляющих структуру, определяет путь в пространстве имен между двумя объектами. Хотя они не однозначно идентифицируют объект, они обычно меньше, чем полный PIDL, и их достаточно для многих целей.
Наиболее часто используемые относительные PIDL, одноуровневые PIDL, относятся к родительской папке объекта. Они содержат только идентификатор элемента объекта и завершающий NULL. Многоуровневые PIDL также используются для многих целей. Они содержат два или более идентификатора элемента и обычно определяют путь от родительской папки к объекту через серию из одной или нескольких вложенных папок. Обратите внимание, что одноуровневый PIDL по-прежнему может быть полным PIDL. В частности, объекты рабочего стола являются дочерними элементами рабочего стола, поэтому их полные PIDL содержат только один идентификатор элемента.
Как обсуждалось в разделе Получение идентификатора папки, Shell API предоставляет несколько способов получения PIDL объекта. Получив его, вы обычно просто используете его для идентификации объекта при вызове других функций и методов Shell API. В этом контексте внутреннее содержимое PIDL непрозрачно и не имеет значения. Для целей этого обсуждения думайте о PIDL как о маркерах, представляющих определенные объекты пространства имен, и сосредоточьтесь на том, как их использовать для общих задач.
Распределение PIDL
Хотя PIDL имеют некоторое сходство с путями, их использование требует несколько иного подхода. Основное различие заключается в том, как выделять и освобождать для них память.
Как и строка, используемая для пути, память должна быть выделена для PIDL. Если приложение создает PIDL, оно должно выделить достаточно памяти для структуры ITEMIDLIST. В большинстве обсуждаемых здесь случаев оболочка создает PIDL и обрабатывает выделение памяти. Независимо от того, что выделило PIDL, приложение обычно несет ответственность за освобождение PIDL, когда он больше не нужен.
Используйте функцию CoTaskMemAlloc для выделения PIDL и функцию CoTaskMemFree для его освобождения.
Подпрограмма NtQueryInformationFile возвращает различные виды информации об объекте файла. См. также NtQueryInformationByName, который можно более эффективно использовать для нескольких классов информации о файлах.
Синтаксис
Параметры
Дескриптор файлового объекта.Дескриптор создается успешным вызовом NtCreateFile или NtOpenFile или эквивалентной процедуры создания или открытия файла.
Указатель на структуру IO_STATUS_BLOCK, которая получает окончательный статус завершения и информацию об операции. Член информации получает число байтов, которое эта подпрограмма фактически записывает в буфер FileInformation.
Указатель на выделенный вызывающей стороной буфер, в который подпрограмма записывает запрошенную информацию об объекте файла. Параметр FileInformationClass указывает тип информации, запрашиваемой вызывающей стороной.
Размер в байтах буфера, на который указывает FileInformation.
Указывает тип возвращаемой информации о файле в буфере, на который указывает FileInformation. Драйверы устройств и промежуточные драйверы могут указывать любое из следующих значений FILE_INFORMATION_CLASS (перечисляются от самого низкого до самого высокого значения перечисления):
Значение FILE_INFORMATION_CLASS Тип возвращаемой информации FileBasicInformation (4) Структура FILE_BASIC_INFORMATION. Вызывающий должен открыть файл с флагом FILE_READ_ATTRIBUTES, указанным в параметре DesiredAccess. FileStandardInformation (5) A Структура FILE_STANDARD_INFORMATION. Вызывающий может запрашивать эту информацию, пока файл открыт, без особых требований к DesiredAccess. FileInternalInformation (6) Структура FILE_INTERNAL_INFORMATION. Эта структура определяет 64-битный идентификатор файла, который однозначно идентифицирует файл в NTFS. В других файловых системах уникальный идентификатор файла не гарантируется. FileEaInformation (7) Структура FILE_EA_INFORMATION. Эта структура определяет размер блока расширенных атрибутов, связанного с файлом. FileAccessInformation (8) Структура FILE_ACCESS_INFORMATION. Эта структура содержит маску доступа. Дополнительные сведения о масках доступа см. в разделе ACCESS_MASK. FileNameInformation (9) Структура FILE_NAME_INFORMATION. Структура может содержать полный путь к файлу или только его часть. Вызывающий может запрашивать эту информацию, пока файл открыт, без особых требований к DesiredAccess. Дополнительные сведения о синтаксисе имени файла см. в разделе "Примечания" далее в этом разделе. FilePositionInformation (14) Структура FILE_POSITION_INFORMATION. Вызывающий должен открыть файл с флагом DesiredAccess FILE_READ_DATA или FILE_WRITE_DATA, указанным в параметре DesiredAccess, и с флагом FILE_SYNCHRONOUS_IO_ALERT или FILE_SYNCHRONOUS_IO_NONALERT, указанным в CreateOptions. FileModeInformation (16) Структура FILE_MODE_INFORMATION. Эта структура содержит набор флагов, определяющих режим доступа к файлу. Эти флаги являются подмножеством параметров, которые можно указать в параметре CreateOptions процедуры IoCreateFile. FileAlignmentInformation (17) Структура FILE_ALIGNMENT_INFORMATION. Вызывающий может запрашивать эту информацию, пока файл открыт, без особых требований к DesiredAccess. Эта информация полезна, если файл был открыт с флагом FILE_NO_INTERMEDIATE_BUFFERING, указанным в параметре CreateOptions. FileAllInformation (18) Структура FILE_ALL_INFORMATION. Объединяя несколько структур файловой информации в единую структуру, FILE_ALL_INFORMATION уменьшает количество запросов, необходимых для получения информации о файле. FileAlternateNameInformation (21) Структура FILE_ALL_INFORMATION, в которой возвращается информация об альтернативном имени для файла (его имя в формате 8.3). FileStreamInformation (22) Буфер из Структуры FILE_STREAM_INFORMATION, в которых перечисляются потоки данных файла или каталога. FileCompressionInformation (28) Структура FILE_COMPRESSION_INFORMATION, в которой возвращается информация о сжатии для файла. FileNetworkOpenInformation (34) Структура FILE_NETWORK_OPEN_INFORMATION. Вызывающий должен открыть файл с флагом FILE_READ_ATTRIBUTES, указанным в параметре DesiredAccess. FileAttributeTagInformation (35) A Структура FILE_ATTRIBUTE_TAG_INFORMATION. Вызывающий должен открыть файл с флагом FILE_READ_ATTRIBUTES, указанным в параметре DesiredAccess. FileIoPriorityHintInformation (43) A Структура FILE_IO_PRIORITY_HINT_INFORMATION.Вызывающий должен открыть файл с флагом FILE_READ_DATA, указанным в параметре DesiredAccess. FileSfioReserveInformation (44) A Структура FILE_SFIO_RESERVE_INFORMATION. FileHardLinkInformation (46) Структура FILE_LINKS_INFORMATION. FileNormalizedNameInformation (48) Структура FILE_NAME_INFORMATION, в которой возвращается нормализованное имя файла. FileIsRemoteDeviceInformation (51) Структура FILE_IS_REMOTE_DEVICE_INFORMATION. Вызывающий может запрашивать эту информацию, пока файл открыт, без особых требований к DesiredAccess. FileStandardLinkInformation (54) Структура FILE_STANDARD_LINK_INFORMATION. FileIdInformation (59) Структура FILE_ID_INFORMATION. FileDesiredStorageClassInformation (67) Структура FILE_DESIRED_STORAGE_CLASS_INFORMATION. < tr>FileStatInformation (68) FILE_STAT_INFORMATION FileStatLxInformation (70) FILE_STAT_LX_INFORMATION FileCaseSensitiveInformation (71) Структура FILE_CASE_SENSITIVE_INFORMATION. Вызывающий должен открыть файл с флагом FILE_READ_ATTRIBUTES, указанным в параметре DesiredAccess. Это значение доступно, начиная с Windows 10 версии 1803. < tr>FileStorageReserveIdInformation (74) Структура FILE_STORAGE_RESERVE_ID_INFORMATION. FileCaseSensitiveInformationForceAccessCheck (75) Структура FILE_CASE_SENSITIVE_INFORMATION. Вызывающий должен открыть файл с флагом FILE_READ_ATTRIBUTES, указанным в параметре DesiredAccess. Это специальная версия операции FileCaseSensitiveInformation, которая используется, чтобы заставить IOManager выполнять проверки доступа для драйвера режима ядра, аналогичные проверкам, которые применяются к вызывающей программе пользовательского режима. Эта операция распознается только IOManager, и файловая система никогда не должна ее получать. Это значение доступно, начиная с Windows 10 версии 1803. FileKnownFolderInformation (76) Структура FILE_KNOWN_FOLDER_INFORMATION. Доступно, начиная с Windows Server 2022. Возвращаемое значение
NtQueryInformationFile возвращает STATUS_SUCCESS или соответствующий код ошибки NTSTATUS.
Примечания
NtQueryInformationFile возвращает информацию об указанном файловом объекте. Обратите внимание, что он возвращает ноль в любом элементе структуры FILE_XXX_INFORMATION, который не поддерживается конкретным устройством или файловой системой.
Когда FileInformationClass = FileNameInformation, имя файла возвращается в структуре FILE_NAME_INFORMATION. Точный синтаксис имени файла зависит от ряда факторов:
Если вы открыли файл, отправив NtCreateFile полный путь, NtQueryInformationFile возвращает этот полный путь.
Если дескриптор ObjectAttributes->RootDirectory был открыт по имени при вызове NtCreateFile, а затем файл был открыт с помощью NtCreateFile относительно этого дескриптора корневого каталога, NtQueryInformationFile возвращает полный путь.
Если дескриптор ObjectAttributes->RootDirectory был открыт по идентификатору файла (с использованием флага FILE_OPEN_BY_FILE_ID) при вызове NtCreateFile, а затем файл был открыт с помощью NtCreateFile относительно этого дескриптора корневого каталога, NtQueryInformationFile возвращает относительный путь.< /p>
Однако, если у пользователя есть SeChangeNotifyPrivilege (описано в документации Microsoft Windows SDK), NtQueryInformationFile во всех случаях возвращает полный путь.
Если возвращается только относительный путь, строка имени файла не будет начинаться с обратной косой черты.
Если возвращаются полный путь и имя файла, строка будет начинаться с одной обратной косой черты, независимо от ее местоположения. Таким образом, файл C:\dir1\dir2\filename.ext будет отображаться как \dir1\dir2\filename.ext, а файл \server\share\dir1\dir2\filename.ext будет отображаться как \server\share\dir1\ dir2\filename.ext.
Если NtQueryInformationFile завершается ошибкой из-за переполнения буфера, драйверы, реализующие FileNameInformation, должны возвращать столько символов WCHAR имени файла, сколько поместится в буфере, и указывать необходимую полную длину в FileNameLength. параметр структуры FILE_NAME_INFORMATION. Вы должны повторить запрос, используя длину имени файла, чтобы можно было получить полное имя файла. Драйверам, которые не следуют этому шаблону, может потребоваться постепенное увеличение длины, пока они не получат полное имя файла. Дополнительные сведения о работе с файлами см. в разделе Использование файлов в драйвере.
Вызывающие NtQueryInformationFile должны работать с IRQL = PASSIVE_LEVEL и с включенными специальными APC ядра.
Если вызов этой функции происходит в пользовательском режиме, следует использовать имя "NtQueryInformationFile" вместо "ZwQueryInformationFile".
Для вызовов из драйверов режима ядра версии NtXxx и ZwXxx подпрограммы собственных системных служб Windows могут вести себя по-разному в том, как они обрабатывают и интерпретируют входные параметры. Дополнительную информацию о взаимосвязи между версиями подпрограммы NtXxx и ZwXxx см. в разделе Использование версий Nt и Zw собственных подпрограмм системных служб.
Структура FILE_OBJECTID_INFORMATION используется для запроса информации об идентификаторе объекта для файлов в каталоге на томе NTFS.
Синтаксис
Участники
16-байтовый идентификатор файлового объекта для файла. NTFS генерирует этот номер и присваивает его файлу по запросу драйвера или приложения. Идентификаторы файловых объектов гарантированно уникальны только в пределах тома, на котором находится файл.
Идентификатор объекта тома, на котором находился файл на момент создания идентификатора объекта, или ноль, если в то время у тома не было идентификатора объекта. После операций копирования, перемещения или других операций с файлами это может не совпадать с идентификатором объекта тома, на котором в данный момент находится объект.
Идентификатор объекта файла на момент его создания. После операций копирования, перемещения или других файловых операций это может не совпадать с текущим значением члена ObjectId.
Зарезервировано; должен быть равен нулю.
Данные, предоставленные пользователем. Вы можете использовать его для хранения элементов BirthVolumeID, BirthObjectID и DomainID или определить другую структуру данных.
Примечания
Эту информацию можно запросить одним из следующих способов:
Вызовите ZwQueryDirectoryFile, передав FileObjectIdInformation в качестве значения FileInformationClass и передав выделенный вызывающей стороной буфер со структурой FILE_OBJECTID_INFORMATION в качестве значения FileInformation.
Создайте IRP с основным кодом функции IRP_MJ_DIRECTORY_CONTROL и вспомогательным кодом функции IRP_MN_QUERY_DIRECTORY.
Для запроса этой информации не требуются специальные права доступа.
Поддержка ссылочных номеров файлов и идентификаторов файловых объектов зависит от файловой системы. Идентификаторы файловых объектов поддерживаются только на томах NTFS в Microsoft Windows 2000 и более поздних версиях. NTFS позволяет открывать файлы по идентификатору объекта, а также по номеру ссылки на файл.
Драйверы фильтров файловой системы, использующие идентификаторы файловых объектов, должны быть протестированы на совместимость с DFS, службой репликации и службой отслеживания распределенных ссылок, которые используют идентификаторы файловых объектов и манипулируют ими.
Подпрограмма NtQueryDirectoryFile возвращает различную информацию о файлах в каталоге, заданном данным дескриптором файла.
Синтаксис
Параметры
Описатель, возвращаемый NtCreateFile или NtOpenFile для файлового объекта, представляющего каталог, для которого запрашивается информация. Файловый объект должен быть открыт для асинхронного ввода-вывода, если вызывающая сторона указывает ненулевое значение для Event или ApcRoutine.
[in, необязательно] Событие
Необязательный дескриптор события, созданного вызывающей стороной. Если этот параметр указан, вызывающая сторона будет переведена в состояние ожидания до тех пор, пока запрошенная операция не будет завершена и данное событие не будет установлено в состояние Signaled. Этот параметр является необязательным и может иметь значение NULL. Оно должно быть равно NULL, если вызывающая сторона будет ждать, пока FileHandle перейдет в состояние Signaled.
[in, необязательно] ApcRoutine
Адрес дополнительной процедуры APC, предоставляемой вызывающей стороной, которая будет вызываться после завершения запрошенной операции. Этот параметр является необязательным и может иметь значение NULL. Если с файловым объектом связан объект завершения ввода-вывода, этот параметр должен иметь значение NULL.
[in, необязательно] ApcContext
Необязательный указатель на определяемую вызывающей стороной область контекста, если вызывающая сторона предоставляет APC или если объект завершения ввода-вывода связан с файловым объектом. Когда операция завершается, этот контекст передается в APC, если он был указан, или включается как часть сообщения о завершении, которое диспетчер ввода-вывода отправляет связанному объекту завершения ввода-вывода.
Этот параметр является необязательным и может иметь значение NULL. Он должен быть NULL, если ApcRoutine имеет значение NULL и нет объекта завершения ввода-вывода, связанного с файловым объектом.
Указатель на структуру IO_STATUS_BLOCK, которая получает окончательный статус завершения и информацию об операции. Для успешных вызовов, которые возвращают данные, количество байтов, записанных в буфер FileInformation, возвращается в информационном элементе структуры.
Указатель на буфер, который получает нужную информацию о файле. Структура информации, возвращаемой в буфер, определяется параметром FileInformationClass.
Размер в байтах буфера, на который указывает FileInformation. Вызывающий должен установить этот параметр в соответствии с заданным FileInformationClass.
Тип возвращаемой информации о файлах в каталоге. Тип возвращаемой информации о файлах в каталоге. Список возможных значений см. в параметре FileInformationClass NtQueryDirectoryFileEx.
Установите значение TRUE, если должна быть возвращена только одна запись, иначе FALSE. Если этот параметр имеет значение TRUE, NtQueryDirectoryFile возвращает только первую найденную запись.
[in, необязательно] FileName
Необязательный указатель на выделенную вызывающей стороне строку Unicode, содержащую имя файла (или нескольких файлов, если используются подстановочные знаки) в каталоге, указанном FileHandle. Этот параметр является необязательным и может иметь значение NULL.
Если FileName не равно NULL, в сканирование каталога включаются только файлы, имена которых совпадают со строкой FileName. Если FileName имеет значение NULL, включаются все файлы.
Имя файла используется в качестве выражения поиска и захватывается при самом первом вызове NtQueryDirectoryFile для данного дескриптора. Последующие вызовы NtQueryDirectoryFile будут использовать поисковое выражение, установленное при первом вызове. Параметр FileName, передаваемый последующим вызовам, будет игнорироваться.
Установите значение TRUE, если сканирование должно начинаться с первой записи в каталоге. Установите значение FALSE, если сканирование возобновляется с предыдущего вызова.
Когда процедура NtQueryDirectoryFile вызывается для определенного дескриптора, параметр RestartScan обрабатывается так, как если бы для него было установлено значение TRUE, независимо от его значения. При последующих вызовах NtQueryDirectoryFile учитывается значение параметра RestartScan.
Возвращаемое значение
Подпрограмма NtQueryDirectoryFileroutine возвращает STATUS_SUCCESS или соответствующий статус ошибки. Набор значений состояния ошибки, которые могут быть возвращены, зависит от файловой системы. NtQueryDirectoryFile также возвращает количество байтов, фактически записанных в заданный буфер FileInformation в элементе Information блока IoStatusblock. Список некоторых возможных кодов ошибок см. в NtQueryDirectoryFileEx.
Примечания
Подпрограмма NtQueryDirectoryFile возвращает информацию о файлах, содержащихся в каталоге, представленном FileHandle.
Если указано, значение параметра FileName определяет записи, которые включаются в сканирование каталога для всех последующих вызовов NtQueryDirectoryFile для данного FileHandle.
Если есть хотя бы одна совпадающая запись, NtQueryDirectoryFile создает структуру FILE_XXX_INFORMATION для каждой записи и сохраняет их в буфере.
Предположим, что хотя бы одна соответствующая запись каталога найдена, количество записей, для которых возвращается информация, равно *наименьшему из следующего:
- Одна запись, если значение ReturnSingleEntry равно TRUE, а имя файла равно NULL.
- Количество записей, соответствующих строке FileName, если FileName не равно NULL. (Обратите внимание: если строка не содержит подстановочных знаков, может быть не более одной совпадающей записи.)
- Количество записей, информация о которых помещается в указанный буфер.
- Количество записей, содержащихся в каталоге.
При первом вызове NtQueryDirectoryFile, если структура, созданная для первой найденной записи, слишком велика для размещения в выходном буфере, подпрограмма записывает фиксированную часть структуры в выходной буфер. Затем подпрограмма записывает в выходной буфер столько строки FileName, сколько поместится. (Фиксированная часть структуры состоит из всех полей, кроме последней строки FileName. При первом вызове, но не при последующих вызовах, система ввода-вывода гарантирует, что буфер достаточно велик для хранения фиксированной части соответствующего FILE_< em>XXX_INFORMATION.) Когда это происходит, NtQueryDirectoryFile возвращает соответствующее значение состояния, например STATUS_BUFFER_OVERFLOW.
При каждом вызове NtQueryDirectoryFile возвращает столько структур FILE_XXX_INFORMATION (по одной на запись каталога), сколько может полностью содержаться в буфере, на который указывает FileInformation. При первом вызове NtQueryDirectoryFile возвращает STATUS_SUCCESS, только если выходной буфер содержит хотя бы одну полную структуру. При последующих вызовах, если выходной буфер не содержит структур, NtQueryDirectoryFile возвращает STATUS_SUCCESS, но устанавливает IoStatusblock->Information = 0, чтобы уведомить вызывающую сторону об этом условии. В этом случае вызывающая сторона должна выделить больший буфер и снова вызвать NtQueryDirectoryFile. Никакой информации об оставшихся записях не сообщается. Таким образом, за исключением перечисленных выше случаев, когда возвращается только одна запись, NtQueryDirectoryFile необходимо вызывать как минимум дважды, чтобы перечислить содержимое всего каталога.
При вызове NtQueryDirectoryFile вы можете увидеть изменения, внесенные в каталог, которые происходят параллельно с вызовами NtQueryDirectoryFile. Это поведение зависит от реализации базовой файловой системы.
Последний вызов NtQueryDirectoryFile возвращает пустой выходной буфер и сообщает соответствующее значение состояния, например STATUS_NO_MORE_FILES.
Если NtQueryDirectoryFile вызывается несколько раз для одного и того же каталога, а какая-то другая операция изменяет содержимое этого каталога, любые изменения могут быть видны или не видны, в зависимости от времени выполнения операций.
NtQueryDirectoryFile возвращает ноль в любом элементе структуры FILE_XXX_INFORMATION, который не поддерживается файловой системой.
Вызывающие NtQueryDirectoryFile должны работать с IRQL = PASSIVE_LEVEL и с включенными специальными APC ядра.
Информацию о других процедурах запроса информации о файлах см. в разделе «Файловые объекты».
Если вызов функции NtQueryDirectoryFile происходит в пользовательском режиме, следует использовать имя "NtQueryDirectoryFile" вместо "ZwQueryDirectoryFile".
Для вызовов из драйверов режима ядра версии NtXXX и ZwXXX подпрограммы собственных системных служб Windows могут вести себя по-разному в том, как они обрабатывают и интерпретируют входные параметры. Дополнительную информацию о взаимосвязи между версиями подпрограмм NtXXX и ZwXXX см. в разделе Использование версий Nt и Zw собственных подпрограмм системных служб.
Читайте также: