Что такое дескрипторы windows
Что такое дескриптор Windows?
Что такое «дескриптор» при обсуждении ресурсов в Windows? Как они работают?
Это абстрактное значение ссылки на ресурс, часто в память, открытый файл или канал.
Например, GetModuleHandle возвращает уникальный идентификатор для загруженного в данный момент модуля. Возвращенный дескриптор может использоваться в других функциях, которые принимают дескрипторы модуля. Это не может быть дано функциям, которые требуют других типов ручек. Например, вы не можете дать дескриптор, возвращенный из GetModuleHandle в, HeapDestroy и ожидать, что он сделает что-то разумное.
Сам по HANDLE себе просто интегральный тип. Обычно, но не обязательно, это указатель на некоторый базовый тип или область памяти. Например, HANDLE возвращаемое значение на GetModuleHandle самом деле является указателем на базовый адрес виртуальной памяти модуля. Но нет правила, утверждающего, что дескрипторы должны быть указателями. Дескриптор также может быть простым целым числом (которое может быть использовано некоторыми Win32 API в качестве индекса в массиве).
HANDLE Это намеренно непрозрачные представления, которые обеспечивают инкапсуляцию и абстрагирование от внутренних ресурсов Win32. Таким образом, Win32 API могли бы потенциально изменить базовый тип за HANDLE, без какого-либо влияния на пользовательский код (по крайней мере, в этом идея).
Оба эти последствия могут быть нежелательными.
Зачем переживать эту проблему? Рассмотрим этот четвертый пример более новой версии этого же API:
Обратите внимание, что интерфейс функции идентичен третьему примеру выше. Это означает, что пользовательский код может продолжать использовать эту новую версию API без каких-либо изменений, даже несмотря на то, что реализация «за кулисами» изменилась для использования NewImprovedWidget структуры вместо этого.
Общие сведения о дескрипторах
Дескрипторы создаются вызовами API и определяют ресурсы.
Данные дескриптора
Дескриптор — это относительно небольшой блок данных, который полностью описывает объект для GPU в непрозрачном формате, характерном для GPU. Существует несколько различных типов дескрипторов — отрисовки целевых представлений (RTVs), представлений трафаретов глубины (DSV), представлений ресурсов шейдера (СРВС), неупорядоченных представлений доступа (уавс), представлений постоянного буфера (КБВС) и проб.
Дескрипторы имеют разный размер в зависимости от оборудования GPU. Можно запросить размер SRV, UAV или CBV, вызвав ID3D12Device:: жетдескрипторхандлеинкрементсизе. Дескрипторы показаны в этой документации как неделимые единицы. Ниже приведен пример.
Дескрипторы создаются вызовами API и будут включать такие сведения, как ресурс и MIP-карты, которые должен содержать дескриптор.
Драйвер не следит за ссылками на дескрипторы и не хранит ссылки на них. это приложение позволяет убедиться в том, что используется правильный тип и что информация актуальна. Существует одно небольшое исключение для этого; драйвер проверяет привязки целевых объектов прорисовки, чтобы обеспечить правильную работу цепочек обмена.
Дескрипторы объектов не обязательно должны освобождаться или освобождаться. Драйверы не присоединяют выделения для создания дескриптора. Дескриптор, однако, может кодировать ссылки на другие выделения, для которых приложение владеет временем существования. Например, дескриптор для SRV должен содержать виртуальный адрес ресурса D3D (например, текстуру), на который ссылается SRV. Это обязанность приложения, чтобы убедиться, что он не использует дескриптор SRV, когда базовый ресурс D3D, от которого он зависит, был уничтожен или изменен (например, объявлен как нерезидентный).
Основной способ использования дескрипторов заключается в помещении их в кучу дескрипторов, которые являются резервными копиями памяти для дескрипторов.
Дескрипторы дескрипторов
Дескриптор дескриптора — это уникальный адрес дескриптора. Он похож на указатель, но является непрозрачным, так как его реализация зависит от оборудования. Дескриптор уникален для кучи дескрипторов, поэтому, например, массив дескрипторов может ссылаться на дескрипторы в нескольких кучах.
Дескрипторы ЦП предназначены для немедленного использования, например для копирования, где должны быть идентифицированы источник и назначение. Сразу после использования (например, вызов ID3D12GraphicsCommandList:: омсетрендертаржетс) они могут быть использованы повторно, или их базовая куча может быть удалена.
Чтобы создать дескриптор дескриптора для запуска кучи, после создания самой кучи дескрипторов вызовите один из следующих методов.
Эти методы возвращают следующие структуры:
Поскольку размер дескрипторов зависит от оборудования, для получения инкремента между каждым дескриптором в куче используется:
Для копирования дескрипторов и передачи дескрипторов в вызовы API можно легко смещать начальное расположение с числом инкрементов. Разыменование маркера необязательно, как если бы он был допустимым указателем ЦП, а также для анализа битов в пределах маркера.
Некоторые вспомогательные структуры были добавлены с элементами инициализации, чтобы упростить управление дескрипторами.
Дескрипторы null
При создании дескрипторов с помощью вызовов API приложения передают значение NULL для указателя ресурса в определении дескриптора, чтобы при доступе к нему не приходилось обращаться к результату, связанному с шейдером.
Оставшаяся часть дескриптора должна быть заполнена как можно больше. Например, в случае с представлениями ресурсов шейдера (СРВС) дескриптор можно использовать для различения типа представления (Texture1D, Texture2D и т. д.). Числовые параметры в дескрипторе представления, например число MIP-карты, должны быть заданы для значений, допустимых для ресурса.
Во многих случаях существует определенное поведение для доступа к несвязанному ресурсу, например СРВС, возвращающего значения по умолчанию. Они будут учитываться при доступе к дескриптору NULL, если тип доступа шейдера совместим с типом дескриптора. Например, если шейдер ожидает Texture2D SRV и обращается к NULL SRV, определенному как Texture1D, поведение не определено и может привести к сбросу устройства.
В сводке, чтобы создать дескриптор null, передайте null параметр предварительного источника при создании представления с такими методами, как креатешадерресаурцевиев. В параметре описания представления пдеск Задайте конфигурацию, которая будет работать, если ресурс не равен null (в противном случае может произойти сбой на определенном оборудовании).
Однако корневые дескрипторы не должны иметь значение null.
На 1 класса оборудовании (см. раздел уровни оборудования), все дескрипторы, которые привязаны (посредством таблиц дескрипторов), должны быть инициализированы либо как реальные дескрипторы, либо как дескрипторы null, даже если нет доступа к оборудованию, в противном случае поведение не определено.
На партнеров оборудовании это относится к привязанным дескрипторам CBV и UAV, но не к дескрипторам SRV.
На Tier3 оборудовании нет ограничений на это, при условии, что неинициализированные дескрипторы никогда не обращаются.
Дескрипторы по умолчанию
Дескрипторы по умолчанию нельзя использовать с представлением структуры ускорения райтраЦинг, так как предоставленный параметр предварительного источника должен иметь значение NULL, а расположение должно передаваться через [D3D12_RAYTRACING_ACCELERATION_STRUCTURE_SRV]/Windows/Win32/API/d3d12/NS-d3d12-d3d12_raytracing_acceleration_structure_srv).
Что такое дескриптор Windows?
Что такое “Handle” при обсуждении ресурсов в Windows? Как они работают?
Это абстрактное опорное значение к ресурсу, часто памяти или открытого файла, или трубы.
Правильно, в Windows (и вообще в вычислениях) дескриптор представляет собой абстракцию, которая скрывает реальный адрес памяти от пользователя API, позволяя системе прозрачно преобразовывать физическую память в программу. Разрешение дескриптора на указатель блокирует память, а высвобождение дескриптора делает недействительным указатель. В этом случае подумайте об этом как о индексе в таблице указателей… вы используете индекс для вызовов API системы, и система может по желанию изменить указатель в таблице.
Альтернативно, реальный указатель может быть задан как дескриптор, когда автор API намеревается, чтобы пользователь API был изолирован от специфики того, на что указывает адрес, на который указывает; в этом случае следует учитывать, что то, что указывает дескриптор, может измениться в любой момент (от версии API до версии или даже от вызова к вызову API, который возвращает дескриптор) – поэтому дескриптор следует рассматривать как просто непрозрачное значение имеет смысл только для API.
Я должен добавить, что в любой современной операционной системе даже так называемые “настоящие указатели” по-прежнему непрозрачны в пространстве виртуальной памяти процесса, что позволяет O/S управлять и переупорядочивать память без аннулирования указателей в процессе.
A HANDLE – уникальный для контекста идентификатор. В контексте контекста я имею в виду, что дескриптор, полученный из одного контекста, не обязательно может использоваться в любом другом произвольном контексте, который также работает на HANDLE s.
HANDLE представляют собой преднамеренно непрозрачные представления, которые обеспечивают инкапсуляцию и абстрагирование от внутренних ресурсов Win32. Таким образом, API Win32 может потенциально изменить базовый тип за ручкой, без какого-либо влияния на код пользователя (по крайней мере, на эту идею).
Оба эти последствия могут быть нежелательными.
Зачем переживать эту проблему? Рассмотрим этот четвертый пример более новой версии этого же API:
A HANDLE в программировании Win32 – это токен, представляющий ресурс, управляемый ядром Windows. Ручкой может быть окно, файл и т.д.
Ручки – это просто способ идентификации ресурса частиц, с которым вы хотите работать с использованием API Win32.
Так, например, если вы хотите создать окно и показать его на экране, вы можете сделать следующее:
В приведенном выше примере HWND означает “дескриптор окна”.
Если вы привыкли к объектно-ориентированному языку, вы можете придумать РУЧКУ как экземпляр класса без каких-либо методов, которые заявляют, что они могут быть изменены только другими функциями. В этом случае функция ShowWindow изменяет состояние окна HANDLE.
Дескриптор является уникальным идентификатором для объекта, управляемого Windows. Это похоже на указатель, но не указатель на то, что он не является адресом, который может быть разыменован кодом пользователя, чтобы получить доступ к некоторым данным. Вместо этого дескриптор должен быть передан в набор функций, которые могут выполнять действия над объектом, который идентифицирует дескриптор.
Таким образом, на самом базовом уровне РУЧКА любого типа является указателем на указатель или
Теперь о том, почему вы хотели бы использовать его
Позволяет выполнить настройку:
Итак, поскольку obj передается по значению (сделайте копию и передайте его функции) в foo, printf напечатает исходное значение 1.
Теперь, если мы обновим foo до:
Есть вероятность, что printf напечатает обновленное значение 2. Но есть также вероятность того, что foo приведет к некоей форме повреждения или исключения памяти.
Причина в том, что, пока вы используете указатель для передачи obj в функцию, которую вы также выделяете 2 мегабайта памяти, это может заставить ОС перемещать память вокруг обновления местоположения obj. Поскольку вы передали указатель по значению, если obj перемещается, ОС обновляет указатель, но не копирует в функцию и потенциально вызывает проблемы.
Последнее обновление для foo:
Это всегда будет печатать обновленное значение.
См., когда компилятор выделяет память для указателей, он маркирует их как неподвижные, поэтому любое повторное перетасовка памяти, вызванное тем, что большой объект выделяется значением, переданным функции, укажет на правильный адрес, чтобы узнать конечное местоположение в памяти для обновления.
Любые конкретные типы HANDLE (hWnd, FILE и т.д.) являются специфичными для домена и указывают на определенный тип структуры для защиты от повреждения памяти.
дескриптор как первичное значение ключа записи в базе данных.
edit 1: ну, почему downvote, первичный ключ уникально идентифицирует запись базы данных, а дескриптор в системе Windows однозначно идентифицирует окно, открытый файл и т.д. Это то, что я говорю.
Подумайте о том, что окно в Windows является структурой, которая его описывает. Эта структура является внутренней частью Windows, и вам не нужно знать ее детали. Вместо этого Windows предоставляет typedef для указателя на struct для этой структуры. Это “дескриптор”, по которому вы можете ухватиться за окно.
Объект – это структура данных, представляющая системный ресурс, такой как файл, поток или графическое изображение. Приложение не может напрямую обращаться к данным объекта или к системному ресурсу, который представляет объект. Вместо этого приложение должно получить дескриптор объекта, который он может использовать для проверки или изменения системного ресурса. Каждый дескриптор имеет запись во внутренней таблице. Эти записи содержат адреса ресурсов и средства для идентификации типа ресурса.
Дескрипторы объекта и таблица дескрипторов процесса Windows
Когда процесс создает или открывает объект по его имени, он получает дескриптор, дающий ему доступ к объекту. Ссылаться на объект по его дескриптору быстрее, чем использовать его имя, поскольку диспетчер объектов может не заниматься поиском по имени и находить объект напрямую.
Процессы могут также получать дескрипторы объектов путем наследования дескрипторов во время создания процесса (когда создатель устанавливает флаг наследования дескрипторов при вызове функции CreateProcess, и дескриптор помечен как наследуемый либо в процессе своего создания, либо после создания путем использования Windows-функции SetHandleInformation) или путем получения продублированного дескриптора от другого процесса (см. Windows-функцию DuplicateHandle).
Все процессы пользовательского режима должны иметь дескриптор объекта, прежде чем их потоки смогут использовать объект. Использование дескрипторов для управления системными ресурсами — идея не новая.
Например, библиотеки времени выполнения C и Pascal (более старого языка программирования, аналогичного Delphi) возвращают дескрипторы открытых файлов. Дескрипторы служат в качестве косвенных указателей на ресурсы системы; эта косвенность не дает прикладным программам напрямую манипулировать структурами системных данных.
ПРИМЕЧАНИЕ. Компоненты исполняющей системы и драйверы устройств могут обращаться к объектам непосредственно, поскольку они запущены в режиме ядра и поэтому имеют доступ к структурам объекта в системной памяти. Но они должны объявить о своем использовании объекта, увеличив значение счетчика ссылок, чтобы объект не мог быть удален из памяти, пока он все еще используется.
Однако для успешного использования объекта драйверы устройств должны знать определение внутренней структуры объекта, а для многих объектов она не предоставляется. Взамен драйверам устройств рекомендуется использовать соответствующие API-функции ядра для изменения или чтения информации из объекта. Например, хотя драйверы устройств могут получить указатель на объект типа «процесс» (EPROCESS), его структура им не известна, и должны быть использованы API-функции вида Ps*.
Для других объектов непрозрачен сам тип (это касается большинства объектов исполняющей системы, в которые заключен диспетчер объектов, в качестве примеров можно привести события или мьютексы). Для таких объектов драйверы должны использовать такие же системные вызовы, которые в конечном итоге используются приложениями пользовательского режима (такие как ZwCreateEvent), и использовать дескрипторы, а не указатели на объекты.
Дескрипторы объектов дают дополнительные преимущества. Во-первых, за исключением того, к чему они относятся, нет никакой разницы между дескрипторами файла, события и процесса. Эта схожесть обеспечивает единый интерфейс для ссылки на объекты, независимо от их типа. Во-вторых, диспетчер объектов имеет исключительное право на создание дескрипторов и на определение местоположения объекта, который относится к дескриптору. Это означает, что диспетчер объектов может проверять каждое действие в пользовательском режиме, влияющее на объект, чтобы убедиться в том, что профиль безопасности вызывающей программы разрешает проводить запрашиваемую операцию над данным объектом.
Просмотр открытых дескрипторов.
Затем измените текущий каталог с помощью команды cd и нажмите клавишу F5, чтобы обновить отображаемую информацию. Вы увидите в Process Explorer, что дескриптор предыдущего текущего каталога закрыт и открыт новый дескриптор для нового текущего каталога. Предыдущий дескриптор выделен красным цветом, а новый дескриптор выделен зеленым цветом.
Свойство выделения разным цветом, имеющееся в Process Explorer, делает заметнее изменения в таблице дескрипторов. Например, если процесс допускает утечку дескрипторов, просмотр таблицы дескрипторов с помощью Process Explorer может быстро показать, какой дескриптор или какие дескрипторы были открыты, но не были закрыты. (Обычно виден длинный список дескрипторов для одного и того же объекта.) Эта информация поможет программисту обнаружить утечку дескрипторов.
Монитор ресурсов также показывает открытые (именованные) дескрипторы для процессов, выбранных путем установки флажков напротив их имен. Вот как выглядят дескрипторы открытого окна командной строки.
Таблицу открытых дескрипторов можно также вывести, используя средство командной строки Handle из серии программных продуктов Sysinternals.
Посмотрите, к примеру, на следующий, частично показанный вывод, полученный с помощью средства Handle при изучении дескрипторов файловых объектов, находящихся в таблице дескрипторов для процесса Cmd.exe до и после изменения каталога. По умолчанию Handle отфильтровывает нефайловые дескрипторы, пока не будет использован ключ –a, который приводит к выводу всех дескрипторов в процессе, аналогично Process Explorer.
Copyright (C) 1997-2011 Mark Russinovich
cmd.exe pid: 5124 Alex-Laptop\Alex Ionescu
3C: File (R-D) C:\Windows\System32\en-US\KernelBase.dll.mui
Copyright (C) 1997-2011 Mark Russinovich
cmd.exe pid: 5124 Alex-Laptop\Alex Ionescu
3C: File (R-D) C:\Windows\System32\en-US\KernelBase.dll.mui
40: File (RW-) C:\Windows
Дескриптор объекта является индексом в таблице дескрипторов, относящейся к конкретному процессу. Этот индекс указывается исполнительным блоком процесса (EPROCESS). Первый индекс дескриптора имеет значение 4, второй — 8 и т. д. Таблица дескрипторов процесса содержит указатели на все объекты, которые процесс открыл для своей работы.
Таблицы дескрипторов реализованы по древовидной схеме, подобной той, которую реализует блок управления памятью x86 для перевода виртуальных адресов в физические, которая дает максимальное значение, превышающее 16 000 000 дескрипторов на процесс.
ПРИМЕЧАНИЕ. В древовидной схеме таблиц таблица верхнего уровня может содержать страницу, заполненную указателями на таблицы среднего уровня, что позволяет иметь более половины миллиарда дескрипторов. Но чтобы поддержать совместимость со схемой дескрипторов, имевшейся в Windows 2000, и унаследовать ограничение в 16 777 216 дескрипторов, таблица верхнего уровня содержит не более 32 указателей на таблицы среднего уровня, устанавливая для более новых версий Windows тот же предел.
При создании процесса выделяется только таблица дескрипторов самого низкого уровня, другие уровни создаются по мере необходимости. Таблица дескрипторов нижнего уровня состоит из такого количества записей, которое может поместиться на странице минус одна запись, которая используется для контроля дескрипторов.
Например, для систем x86 страница составляет 4096 байт и поделена на записи таблицы дескрипторов размером 8 байт, которых получается 512 минус 1, то есть всего 511 записей в таблице дескрипторов самого низкого уровня. Таблица дескрипторов среднего уровня содержит полную страницу указателей на таблицы нижнего уровня, поэтому количество таблиц дескрипторов нижнего уровня зависит от размера страницы и размера указателя для платформы. Схема таблицы дескрипторов в системе Windows показана на следующем рисунке.
Создание максимального количества дескрипторов.
Тестовая программа Testlimit из коллекции Sysinternals предоставляет возможность открывать дескрипторы объекта до тех пор, пока она не сможет больше открыть ни одного дополнительного дескриптора. Этим можно воспользоваться, чтобы посмотреть, сколько дескрипторов может быть создано отдельно взятым процессом на вашей системе. Поскольку под таблицы дескрипторов выделяется место в выгружаемом пуле памяти, до достижения максимального количества дескрипторов, доступного для создания в рамках отдельно взятого процесса, вы можете выйти за рамки выгружаемого пула.
Чтобы увидеть, сколько дескрипторов можно создать на вашей системе, выполните следующие действия:
Чтобы показать максимальный размер пула, Process Explorer должен быть правильно настроен на доступ к символам образа ядра, Ntoskrnl.exe. Оставьте это отображение системной информации работающим, чтобы можно было следить за использованием пула при запуске программы Testlimit.
Как показано на следующем рисунке, на системах x86 каждая запись дескриптора состоит из структуры с двумя 32-разрядными элементами: указателем на объект (с флагами) и маской предоставленных прав доступа. На 64-разрядных системах запись таблицы дескрипторов имеет длину 12 байт: 64-разрядный указатель на заголовок объекта и 32-разрядная маска доступа.
Просмотр таблицы дескрипторов с помощью отладчика ядра.
Флаги можно указать в виде поразрядной маски, где разряд 0 означает «показать только информацию в записи дескриптора», разряд 1 означает «показать свободные (то есть неиспользуемые) дескрипторы, а разряд 2 означает «показать информацию об объекте, на который ссылается дескриптор». Следующая команда приводит к показу всех подробностей о таблице дескрипторов для процесса с идентификатором 0x62C:
processor number 0, process 000000000000062c
Searching for Process with Cid == 62c
SessionId: 1 Cid: 062c Peb: 7fffffdb000 ParentCid: 0558
DirBase: 7e401000 ObjectTable: fffff8a00381fc80 HandleCount: 111.
Handle table at fffff8a0038fa000 with 113 Entries in use
0000: free handle, Entry address fffff8a0038fa000, Next Entry 00000000fffffffe
0004: Object: fffff8a005022b70 GrantedAccess: 00000003 Entry: fffff8a0038fa010
Object: fffff8a005022b70 Type: (fffffa8002778f30) Directory
ObjectHeader: fffff8a005022b40fffff8a005022b40 (new version)
HandleCount: 25 PointerCount: 63
Directory Object: fffff8a000004980 Name: KnownDlls
0008: Object: fffffa8005226070 GrantedAccess: 00100020 Entry: fffff8a0038fa020
Object: fffffa8005226070 Type: (fffffa80027b3080) File
ObjectHeader: fffffa8005226040fffffa8005226040 (new version)
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \Program Files\Debugging Tools for Windows (x64)
Первым флагом является бит блокировки, показывающий, что запись в настоящее время используется. Вторым флагом является указатель на возможность наследования, то есть он показывает, получат ли процессы, созданный данным процессом, копию этого дескриптора в свои таблицы дескрипторов. Как уже отмечалось, наследование дескрипторов может быть указано при создании дескриптора или после него с помощью функции SetHandleInformation.
Третий флаг показывает, должно ли закрытие объекта генерировать контрольное сообщение (флаг не показывается в Windows, диспетчер объектов использует его для внутренних нужд). Бит защиты от закрытия хранится в неиспользованной части маски доступа и показывает, разрешено ли вызывающей программе закрыть этот дескриптор (флаг может быть установлен с помощью системного вызова NtSetInformationObject).
Системным компонентам и драйверам устройств зачастую нужно открывать дескрипторы объектов, к которым не должны иметь доступ приложения пользовательского режима. Это делается путем создания дескрипторов в таблице дескрипторов ядра (внутренняя ссылка на которую осуществляется по имени ObpKernelHandleTable).
Дескрипторы в этой таблице доступны только из режима ядра и в контексте любого процесса. Это означает, что функция режима ядра может сослаться на дескриптор в контексте любого процесса, не оказывая отрицательного влияния на производительность системы. Диспетчер объектов распознает ссылки на дескрипторы из таблицы дескрипторов ядра, когда установлен старший бит дескриптора, то есть когда ссылки на дескрипторы из таблицы дескрипторов ядра имеют значение, больше чем 0x80000000.
Таблица дескрипторов ядра также служит в качестве таблицы дескрипторов для процесса System, и все дескрипторы, созданные процессом System (например, кодом, запущенным в системных потоках), автоматически помечаются как дескрипторы ядра, поскольку они размещаются в таблице дескрипторов ядра по определению.
Поиск открытых файлов с помощью отладчика ядра.
Хотя для поиска дескрипторов открытых файлов можно воспользоваться такими средствами, как Process Explorer, Handle и OpenFiles.exe, они недоступны при просмотре аварийного дампа или удаленном анализе системы.
Object: fffff8a00016ea40 Type: (fffffa8000c38bb0) SymbolicLink
ObjectHeader: fffff8a00016ea10 (new version)
HandleCount: 0 PointerCount: 1
Directory Object: fffff8a000008060 Name: C:
Target String is ‘\Device\HarddiskVolume1’
Drive Letter Index is 3 (C:)
Device для нужного имени тома:
Object: fffffa8001bd3cd0 Type: (fffffa8000ca0750) Device
Checking handle table for process 0xfffffa8000c819e0
Kernel handle table at fffff8a000001830 with 434 entries in use
SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000
DirBase: 00187000 ObjectTable: fffff8a000001830 HandleCount: 434.
0048: Object: fffffa8001d4f2a0 GrantedAccess: 0013008b Entry: fffff8a000003120
Object: fffffa8001d4f2a0 Type: (fffffa8000ca0360) File
ObjectHeader: fffffa8001d4f270 (new version)
HandleCount: 1 PointerCount: 19
Directory Object: 00000000 Name: \Windows\System32\LogFiles\WMI\