Monday, October 16th, 2017

Дело о задержке появления диалога открытия файла

Published on Март 4, 2009 by   ·   Комментариев нет

Предлагаем вашему вниманию прошлогоднюю статью Марка Руссиновича, которая, к сожалению, раньше осталась незамеченной. В данной статье Руссинович говорит о причине задержки открытия диалога Open в Windows Explorer и иных приложениях, поэтому она может оказаться поистине полезной.

Несколько недель назад я был на конференции TechEd/ITForum в Барселоне, где выступал с несколькими докладами. Конференция прошла очень хорошо и Windows Vista, которую я решил испробовать впервые, работала отлично. Однако, когда я просматривал демо перед одной из своих лекций, я заметил, что диалог открытия файлов, который является общим для всех Windows-приложений, появляется с интервалом 5-15 секунд после нажатия.

У меня не было времени разобраться с причиной до доклада, поэтому подобные задержки во время моего доклада «Изменения в ядре Windows Vista» (Windows Vista Kernel Changes) застали меня врасплох. Такое поведение ОС оставляло такое же странное впечатление, как и в том случае, который я описал в заметке «Причина задержки автоматически загружаемых процессов» (The Case of the Process Startup Delays). В том случае Windows Defender Remote Procedure Call (RPC) пытался соединиться с контроллером домена, что приводило к зависаниям, в случае если компьютер к домену не подключён. Я бормотал извинения от имени Windows Vista и пытался отвлечь аудиторию, переходя к следующим демонстрациям.

До тех пор, пока я не прилетел домой, у меня не было возможности взглянуть на эту проблему еще раз. Я совершил шаги, похожие на те, которые я делал, когда исследовал зависания Windows Defender. Я запустил инструмент Windbg из Debugging Tools for Windows, а из него блокнот, нажал Ctrl O для открытия диалога открытия файлов и, когда система начала тормозить, я посмотрел в стек основного потока в блокноте.
Если вы раньше не видели стек – то это список всех последних команд, вызванных потоком. Вы читаете их снизу вверх, и таким образом, можете прочитать, что блокнот загрузил Browseui.Dll, и вызвал её функцию CAddressBand::SetNavigationState. Эта функция вызвала CBreadcrumbBar::SetNavigationState, которая, в свою очередь, вызвала CBreadcrumbBar::SetIDList, и так далее.

Взгляд на названия функций в стеке сразу мне сказал, что же произошло: когда вы первый раз в приложении запускаете диалог открытия файлов, то он открывает вашу папку документов. В Windows Vista моя папка с документами это C:\Users\Markruss\Documents, но оболочка хочет сделать путь в новой панели «хлебных крошек» (от англ. «bread crumb») красивым, отображая его как «Mark Russinovich\Documents», и поэтому, вызывает [url= http://msdn2.microsoft.com/en-gb/library/ms724435.aspx]функцию GetUserNameEx[/url], чтобы посмотреть, как отображается имя моей учётной записи в объекте Пользователь в Active Directory. Я подтвердил свою теорию, проверив, что первый параметр SHGetUserDisplayName передает параметры команде GetUserNameEx, которая интерпретируется как перечень EXTENDED_NAME_FORMAT, и есть 3: NameDisplay.

Я установил контрольную точку на возвращении вызова и обратился к ней, когда зависание закончилось. Команда GetUserNameEx вернула код ошибки ERROR_NO_SUCH_DOMAIN, и прошла через SHGetUserDisplayName, показав, что это она снижает скорость передачи данных к команде GetUserName. Вместо того, чтобы искать отображаемое имя пользователя, эта функция просто получает идентификатор безопасности (SID) пользователя от маркера процесса (структура данных ядра, которая определяет владельца процесса), и вызывает LookupAccountName, чтобы перевести SID в имя учётной записи, которое, в моём случае, просто markruss. Таким образом, появившийся диалог выглядел таким образом.

Задержка открытия папок в Виндовс

В противоположность вот, что появилось, когда я пришёл на работу, и подключился к .
Я разобрался с проблемой, но мне стало интересно, где именно происходила задержка, и поэтому я продолжил исследование того, что же именно происходило по ту сторону вызова Secure32!CallSPM, который находится в начале листинга стека. Я знал, что процесс Local Security Authority (LSASS) ответственен за , включая взаимодействие с контроллерами домена и трансляторами имени учётной записи, так что, я прикрепил Windbg к процессу Lsass.exe (убедитесь, что вы открепили дебаггер от LSASS, иначе при его выключении с помощью команды qd отключится и процесс LSASS, и система перезагрузится через 30 секунд). Я определил, что Secur32.Dll связывается и с клиентом и с сервером, и подтвердил, что она загружается в процесс LSASS, но мне необходимо было определить определённую серверную функцию, которая отвечает за Secur32!SecpGetUserName. Я её определил брут-форсом (то есть перебором): я выгружал функции, осуществляемые Secur32.Dll, и искал какую-либо со словом «name» в ней.
Я установил контрольные точки на некоторых из них и, когда я заново вызвал подвисание, я запустил одну на SecpGetUserName, и переступил через неё, чтобы добраться до этого стека.

Ошибка задержка открытия файла

Функция DsGetDcName документирована как возвращающая имя контроллера домена в определённом домене. Очевидно, функции SecpTranslateName необходимо найти контроллер домена, которому она пошлёт запрос на отображаемое имя пользователя. Я проследовал далее и обнаружил, что LSASS кэширует результат поиска на 45 секунд, что объясняет, почему у меня не было задержки, если я запускал другое приложение и диалог открытия файла в нём сразу после этого зависания. После этого я попал в тупик, когда Netapi32!DsrGetDcNameEx2 выполняла RPC запрос.

Узнав, что Netapi32 работает и с клиентом и с сервером, я убрал её символы и установил точки на командах, содержащих «dc». Я позволил LSASS запускать процессы и к своему удивлению наткнулся на ту же самую функцию Netapi32!DsrGetDcNameEx2. Я проследил за запросом всё глубже и глубже, пока поток меня, наконец, не привёл в ядро (Ntdll!KiFastSystemCallRet).
Я был близок к окончанию своего расследования. Последний вопрос, который у меня был – что это за драйвер устройства Netlogon, делающий вызов на посылание дейтаграммы ? Я ответил на этот вопрос, посмотрев на первый параметр, который он передал NlBrowserDeviceIoControl, который, как я предположил, был обработчиком объекта файла. Потом я открыл Windbg в режиме Local Kernel Debugging (заметьте, что в Windows Vista вы должны загрузиться в режиме отладки, чтобы сделать это, что позволит вам посмотреть на живую структуру данных ядра) и убрал информацию обработчика. Это показало мне объект устройства, который подсказал мне, что драйвер Bowser.sys — это NT драйвер-получатель дейтаграммы менеджера локальных подключений (NT Lan Manager Datagram Receiver Driver).
Я думал, что моё исследование подошло к концу, но когда позже я пытался вызвать снова подвисание, у меня ничего не вышло. Я повторил свои шаги и узнал, что LsapGetUserNameForLogonSession кэширует отображаемое имя на 30 минут. Далее отображаемое имя кэшируется с кэшируемыми мандатами, так что вы не будете сталкиваться с задержками в течение 30 минут после подключения или отключения от корпоративной сети. Я подтвердил свои предположения, подождав 30 минут и вызвав зависание.

Итак, диалог открытия файлов пытается отобразить имя пользователя для панели «хлебных крошек» при отображении папки документов и в процессе пытается определить местоположение контроллера домена, отсылая дейтаграмму менеджера локальных подключений через драйвер устройства Bowser.sys. Я также узнал, что нет способов решения проблемы задержек, и что любой, у кого компьютер подключён к домену, но в данный момент отключённый от него, тоже будет сталкиваться с такими задержками, по крайней мере, до выхода Vista SP1.

Нет ли изменений после установки недавно выпущенного Vista SP1?

Источник: http://blogs.technet.com/markrussinovich







Смотрите также:

Tags: ,

Readers Comments (Комментариев нет)




Да человек я, человек! =)

Exchange 2007

Проведение мониторинга Exchange 2007 с помощью диспетчера System Center Operations Manager 2007 (часть 3)

Если вы хотите прочитать предыдущие части этой серии статей, перейдите по ссылкам: Проведение мониторинга Exchange 2007 с помощью диспетчера System ... [+]

Практическое рассмотрение перехода с Exchange 2003 на Exchange 2007 (часть 1)

Введение В этой статье из нескольких частей я хочу показать вам процесс, который недавно использовал для перехода с существующей среды Exchange 2003 ... [+]

Использование инструмента Exchange Server Remote Connectivity Analyzer Tool (часть 2)

Если вы пропустили первую часть этой серии, пожалуйста, прочтите ее по ссылке Использование инструмента Exchange Server Remote Connectivity Analyzer Tool (Часть ... [+]

Мониторинг Exchange 2007 с помощью диспетчера System Center Operations Manager 2007 (часть 2)

Если вы пропустили предыдущую часть этой серии статей, перейдите по ссылке Мониторинг Exchange 2007 с помощью диспетчера System Center Operations ... [+]

Подробное рассмотрение подготовки Active Directory для Exchange 2007 (часть 5)

Если вы пропустили предыдущие части этой серии статей, перейдите по ссылкам: Подробное рассмотрение подготовки Active Directory для Exchange 2007 (часть 1) ... [+]

Установка и настройка Exchange 2007 из командной строки (Часть 3)

If you missed the previous parts in this article series please read: Exchange 2007 Install and Configuration from the command line (Part ... [+]

Использование инструмента Exchange Server Remote Connectivity Analyzer Tool (часть 1)

Инструмент ExRCA Текущий выпуск инструмента предоставляется только в целях тестирования и оснащен 5 опциями: Тест подключения Outlook 2007 Autodiscover Тест подключения Outlook 2003 RPC ... [+]

Развертывание сервера Exchange 2007 Edge Transport (часть 5)

Если вы хотите прочитать предыдущие части этой серии статей, перейдите по ссылкам: Развертывание сервера Exchange 2007 Edge Transport (часть 1) Развертывание ... [+]

Установка и настройка Exchange 2007 из командной строки (часть 2)

Если вы пропустили первую статью данного цикла, пожалуйста, перейдите по ссылке: Exchange 2007 Install and Configuration from the command line (Part ... [+]

Использование интегрированных сценариев Using Exchange Server 2007 – часть 2: генерирование отчетов агента Transport AntiSpam Agent

Если вы пропустили предыдущую часть этой серии статей, перейдите по ссылке Использование интегрированных сценариев Using Exchange Server 2007 – часть ... [+]