Функция DsGetDcNameA (dsgetdc.h)

Функция DsGetDcName возвращает имя контроллера домена в указанном домене. Эта функция принимает дополнительные критерии выбора контроллера домена, чтобы указать предпочтение для контроллера домена с определенными характеристиками.

Синтаксис

DSGETDCAPI DWORD DsGetDcNameA(
  [in]  LPCSTR                   ComputerName,
  [in]  LPCSTR                   DomainName,
  [in]  GUID                     *DomainGuid,
  [in]  LPCSTR                   SiteName,
  [in]  ULONG                    Flags,
  [out] PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo
);

Параметры

[in] ComputerName

Указатель на строку, завершающуюся значением NULL, которая указывает имя сервера для обработки этой функции. Как правило, этот параметр имеет значение NULL, указывающее, что используется локальный компьютер.

[in] DomainName

Указатель на строку, завершающуюся нулевым значением, которая указывает имя домена или секции приложения для запроса. Это может быть имя в стиле DNS, например fabrikam.com, или имя в плоском стиле, например Fabrikam. Если указано имя стиля DNS, оно может быть указано с конечным периодом или без нее.

Если параметр Flags содержит флаг DS_GC_SERVER_REQUIRED , domainName должно быть именем леса. В этом случае dsGetDcName завершается сбоем, если DomainName указывает имя, которое не является корнем леса.

Если параметр Flags содержит флаг DS_GC_SERVER_REQUIRED , а domainName имеет значение NULL, DsGetDcName пытается найти глобальный каталог в лесу компьютера, определяемого именем компьютера, который является локальным компьютером, если ComputerName имеет значение NULL.

Если параметр DomainName имеет значение NULL , а параметр Flags не содержит флаг DS_GC_SERVER_REQUIRED , то для параметра ComputerName устанавливается доменное имя по умолчанию основного домена компьютера, определяемого параметром ComputerName.

[in] DomainGuid

Указатель на структуру GUID , указывающую GUID запрашиваемого домена. Если значение DomainGuid не равно NULL и не удается найти домен, указанный в параметре DomainName или ComputerName , DsGetDcName пытается найти контроллер домена в домене с идентификатором GUID, указанным в DomainGuid.

[in] SiteName

Указатель на строку, завершающуюся нулевым значением, которая указывает имя сайта, на котором должен физически существовать возвращенный контроллер домена. Если этот параметр имеет значение NULL, DsGetDcName пытается вернуть контроллер домена на сайте, ближайшем к сайту компьютера, указанному параметром ComputerName. По умолчанию этот параметр должен иметь значение NULL.

[in] Flags

Содержит набор флагов, предоставляющих дополнительные данные, используемые для обработки запроса. Этот параметр может быть сочетанием следующих значений.

DS_AVOID_SELF

При вызове из контроллера домена указывает, что возвращенное имя контроллера домена не должно быть текущим компьютером. Если текущий компьютер не является контроллером домена, данный флаг игнорируется. Этот флаг можно использовать для получения имени другого контроллера домена в домене.

DS_BACKGROUND_ONLY

Если флаг DS_FORCE_REDISCOVERY не указан, эта функция использует кэшированные данные контроллера домена. Если кэшированные данные устарели более 15 минут, кэш обновляется путем проверки связи с контроллером домена. Если этот флаг указан, обновление не выполняется, даже если срок действия кэшированных данных истек. Этот флаг следует использовать, если функция DsGetDcName вызывается периодически.

DS_DIRECTORY_SERVICE_PREFERRED

DsGetDcName пытается найти контроллер домена, поддерживающий функции службы каталогов. Если контроллер домена, поддерживающий службы каталогов, недоступен, DsGetDcName возвращает имя контроллера домена, не являющегося службой каталогов. Однако DsGetDcName возвращает контроллер домена, не относящегося к службе каталогов, только после того, как истекло время ожидания для поиска контроллера домена службы каталогов.

DS_DIRECTORY_SERVICE_REQUIRED

Требует, чтобы возвращенный контроллер домена поддерживал службы каталогов.

DS_DIRECTORY_SERVICE_6_REQUIRED

Требуется, чтобы возвращенный контроллер домена работал под управлением Windows Server 2008 или более поздней версии.

DS_DIRECTORY_SERVICE_8_REQUIRED

Требует, чтобы возвращенный контроллер домена работал Windows Server 2012 или более поздней версии.

DS_FORCE_REDISCOVERY

Принудительно игнорирует кэшированные данные контроллера домена. Если флаг DS_FORCE_REDISCOVERY не указан, DsGetDcName может возвращать кэшированные данные контроллера домена. Если этот флаг указан, DsGetDcName не будет использовать кэшированные сведения (если таковые существуют), а выполняет обнаружение нового контроллера домена.

Этот флаг не следует использовать в обычных условиях, так как использование кэшированных сведений о контроллере домена имеет лучшие характеристики производительности и помогает обеспечить согласованное использование одного и того же контроллера домена всеми приложениями. Этот флаг следует использовать только после того, как приложение определит, что контроллер домена, возвращенный DsGetDcName (при вызове без этого флага), недоступен. В этом случае приложение должно повторить вызов DsGetDcName с этим флагом, чтобы убедиться, что неиспользоваемые кэшированные сведения (если таковые есть) игнорируются и обнаруживается доступный контроллер домена.

DS_GC_SERVER_REQUIRED

Требует, чтобы возвращенный контроллер домена был сервером глобального каталога для леса доменов, в котором данный домен является корневым. Если этот флаг установлен и параметр DomainName не равен NULL, domainName должен указать имя леса. Этот флаг нельзя сочетать с флагами DS_PDC_REQUIRED или DS_KDC_REQUIRED .

DS_GOOD_TIMESERV_PREFERRED

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

DS_IP_REQUIRED

Этот параметр указывает, что контроллер домена должен иметь IP-адрес. В этом случае DsGetDcName поместит ip-адрес протокола контроллера домена в элемент DomainControllerAddressобъекта DomainControllerInfo.

DS_IS_DNS_NAME

Указывает, что параметр DomainName является DNS-именем. Этот флаг нельзя объединить с флагом DS_IS_FLAT_NAME .

Укажите DS_IS_DNS_NAME или DS_IS_FLAT_NAME. Если не указан ни флаг, dsGetDcName может занять больше времени для поиска контроллера домена, так как ему может потребоваться поиск как в стиле DNS, так и по неструктурированному имени.

DS_IS_FLAT_NAME

Указывает, что параметр DomainName является неструктурированным именем. Этот флаг нельзя сочетать с флагом DS_IS_DNS_NAME .

DS_KDC_REQUIRED

Требует, чтобы на возвращенном контроллере домена в данный момент была запущена служба центра распространения ключей Kerberos. Этот флаг нельзя сочетать с флагами DS_PDC_REQUIRED или DS_GC_SERVER_REQUIRED .

DS_ONLY_LDAP_NEEDED

Указывает, чтобы возвращенный сервер был сервером LDAP. Возвращаемый сервер не обязательно является контроллером домена. На сервере не подразумевается наличие других служб. Возвращаемый сервер не обязательно имеет контейнер конфигурации , доступный для записи, или контейнер схемы , доступный для записи. Возвращаемый сервер не обязательно может использоваться для создания или изменения принципов безопасности. Этот флаг можно использовать вместе с флагом DS_GC_SERVER_REQUIRED для возврата сервера LDAP, на котором также размещен сервер глобального каталога. Возвращенный сервер глобального каталога не обязательно является контроллером домена. На сервере не подразумевается наличие других служб. Если этот флаг указан, флаги DS_PDC_REQUIRED, DS_TIMESERV_REQUIRED, DS_GOOD_TIMESERV_PREFERRED, DS_DIRECTORY_SERVICES_PREFERED, DS_DIRECTORY_SERVICES_REQUIRED и DS_KDC_REQUIRED игнорируются.

DS_PDC_REQUIRED

Требует, чтобы возвращенный контроллер домена был первичным контроллером домена. Этот флаг нельзя сочетать с флагами DS_KDC_REQUIRED или DS_GC_SERVER_REQUIRED .

DS_RETURN_DNS_NAME

Указывает, что имена, возвращаемые в элементах DomainControllerName и DomainNameобъекта DomainControllerInfo , должны быть DNS-именами. Если DNS-имя недоступно, возвращается ошибка. Этот флаг нельзя указать с помощью флага DS_RETURN_FLAT_NAME . Этот флаг подразумевает флаг DS_IP_REQUIRED .

DS_RETURN_FLAT_NAME

Указывает, что имена, возвращаемые в элементах DomainControllerName и DomainNameобъекта DomainControllerInfo , должны быть неструктурированными именами. Если неструктурированное имя недоступно, возвращается ошибка. Этот флаг нельзя указать с помощью флага DS_RETURN_DNS_NAME .

DS_TIMESERV_REQUIRED

Требует, чтобы на возвращенном контроллере домена в данный момент была запущена служба времени Windows.

DS_TRY_NEXTCLOSEST_SITE

Если этот флаг указан, DsGetDcName пытается найти контроллер домена на том же сайте, что и вызывающий объект. Если такой контроллер домена не найден, он найдет контроллер домена, который может предоставить сведения о топологии, и вызовет DsBindToISTG для получения дескриптора привязки, а затем вызовет DsQuerySitesByCost по протоколу UDP, чтобы определить "следующий ближайший сайт", и, наконец, кэширует имя найденного сайта. Если контроллер домена не найден на этом сайте, dsGetDcName возвращается к методу поиска контроллера домена по умолчанию.

Если этот флаг используется вместе со значением, не равным NULL, во входном параметре SiteName, возникает ERROR_INVALID_FLAGS .

Кроме того, тип поиска, используемый с DS_TRY_NEXT_CLOSEST_SITE , зависит от сайта, поэтому этот флаг игнорируется, если он используется в сочетании с DS_PDC_REQUIRED. Наконец, DS_TRY_NEXTCLOSEST_SITE игнорируется при использовании в сочетании с DS_RETURN_FLAT_NAME так как для разрешения имени используется NetBIOS, но домен найденного контроллера домена не обязательно будет соответствовать домену, к которому присоединен клиент.

Примечание Этот флаг групповая политика включен. Если включить параметр политики "Следующий ближайший сайт", для компьютера будет включена функция Следующее ближайшее расположение контроллера домена сайта для всех доступных, но не настроенных сетевых адаптеров. Если этот параметр политики отключен, по умолчанию для компьютера не будет использоваться следующее ближайшее расположение контроллера домена сайта для всех доступных, но не настроенных сетевых адаптеров. Однако если вызов указателя контроллера домена выполняется с помощью флага DS_TRY_NEXTCLOSEST_SITE явным образом, DsGetDcName учитывает поведение следующего ближайшего сайта. Если этот параметр политики не настроен, по умолчанию для компьютера не будет использоваться следующее ближайшее расположение контроллера домена сайта для всех доступных, но ненастроенных сетевых адаптеров. Если флаг DS_TRY_NEXTCLOSEST_SITE используется явно, будет использоваться поведение следующего ближайшего сайта.
 

DS_WRITABLE_REQUIRED

Требует, чтобы возвращенный контроллер домена был доступны для записи; то есть разместите копию службы каталогов, доступной для записи.

DS_WEB_SERVICE_REQUIRED

Требует, чтобы возвращенный контроллер домена в настоящее время запускал веб-службу Active Directory.

[out] DomainControllerInfo

Указатель на значение PDOMAIN_CONTROLLER_INFO , которое получает указатель на структуру DOMAIN_CONTROLLER_INFO , содержащую данные о выбранном контроллере домена. Эта структура выделяется с помощью DsGetDcName. Вызывающий объект должен освободить структуру с помощью функции NetApiBufferFree , когда она больше не требуется.

Возвращаемое значение

Если функция возвращает данные контроллера домена, возвращаемое значение будет ERROR_SUCCESS.

Если функция завершается ошибкой, возвращаемое значение может быть одним из следующих кодов ошибок.

Комментарии

Функция DsGetDcName отправляется в службу Netlogon на удаленном компьютере, указанном в параметре ComputerName. Если аргумент ComputerName имеет значение NULL, функция обрабатывается на локальном компьютере.

DsGetDcName не проверяет, является ли возвращенное имя контроллера домена именем фактического контроллера домена или глобального каталога. Если требуется взаимная проверка подлинности, вызывающий объект должен выполнить проверку подлинности.

DsGetDcName не требует определенного доступа к указанному домену. По умолчанию эта функция не гарантирует, что возвращенный контроллер домена в настоящее время доступен. Вместо этого вызывающий объект должен попытаться использовать возвращенный контроллер домена. Если контроллер домена недоступен, вызывающий объект должен снова вызвать функцию DsGetDcName , указав флаг DS_FORCE_REDISCOVERY .

Время отклика

При использовании DsGetDcName следует учитывать следующие сведения о времени:
  • DsGetDcName выполняет сетевые вызовы и может занять от нескольких секунд до одной минуты в зависимости от сетевого трафика, топологии, нагрузки на контроллер домена и т. д.
  • Не рекомендуется вызывать DsGetDcName из пользовательского интерфейса или другого потока, критического для времени.
  • Указатель контроллера домена использует оптимизированную логику для предоставления сведений о контроллере домена как можно быстрее. Он также использует кэшированные сведения на сайте для связи с ближайшим контроллером домена.

Примечания о прилипчивости контроллера домена

В доменные службы Active Directory функция указателя контроллера домена разработана таким образом, что после того, как клиент найдет предпочтительный контроллер домена, клиент не будет искать другой, если этот контроллер домена не перестанет отвечать или клиент не перезапущен. Это называется "Залипание контроллера домена". Так как рабочие станции обычно работают в течение нескольких месяцев без проблем или перезапуска, одним из непреднамеренных последствий этого поведения является то, что если конкретный контроллер домена выходит из строя для обслуживания, все клиенты, которые были к нему подключены, переносят свои подключения к другому контроллеру домена. Но когда контроллер домена выполняет резервное копирование, клиенты никогда не подключались к нему повторно, так как клиенты не перезапускаются очень часто. Это может привести к проблемам с балансировкой нагрузки.

Ранее наиболее распространенным решением этой проблемы было развертывание скрипта на каждом клиентском компьютере, который периодически вызывал DsGetDcName с помощью флага DS_FORCE_REDISCOVERY . Это было несколько громоздким решением, поэтому в Windows Server 2008 и Windows Vista появился новый механизм, который вызывал проблемы с залипанием контроллера домена.

Всякий раз, когда DsGetDcName получает имя контроллера домена из своего кэша, он проверяет, истек ли срок действия этой кэшированной записи, и если да, удаляет это имя контроллера домена и пытается повторно обнаружить имя контроллера домена. Срок жизни кэшированных записей определяется значением в следующих разделах реестра.

HKEY_LOCAL_MACHINE\СИСТЕМЫ\CurrentControlSet\Услуги\Netlogon\Параметры\ForceRediscoveryInterval

и

HKEY_LOCAL_MACHINE\Программного обеспечения\Политики\Microsoft\Netlogon\Параметры\ForceRediscoveryInterval

Значения в этих разделах реестра имеют тип REG_DWORD. Они указывают продолжительность в секундах, прежде чем DsGetDcName попытается повторно обнаружить имя контроллера домена. Значение по умолчанию — 43200 секунд (12 часов). Если значение записи реестра ForceRediscoveryInterval равно 0, клиент всегда выполняет повторное обнаружение. Если задано значение 4294967295, срок действия кэша никогда не истечет, а кэшированный контроллер домена продолжает использоваться. Не рекомендуется задавать для записи реестра ForceRediscoveryInterval значение меньше 3600 секунд (60 минут).

Примечание Параметры реестра ForceRediscoveryInterval включены в групповую политику. Если этот параметр политики отключен, принудительное повторное обнаружение будет использоваться по умолчанию для компьютера каждые 12 часов. Если этот параметр политики не настроен, принудительное повторное обнаружение будет использоваться по умолчанию для компьютера каждые 12 часов, если только параметр локального компьютера в реестре не имеет другое значение.
 
Обратите внимание, что если указан флаг DS_BACKGROUND_ONLY , DsGetDcName никогда не будет пытаться повторно обнаружить имя контроллера домена, так как этот флаг заключается в том, чтобы принудить DsGetDcName использовать кэшированное имя контроллера домена, даже если срок его действия истек.

Трассировка ETW в DsGetDcName

Чтобы включить трассировку ETW для DsGetDcName, создайте следующий раздел реестра:

HKEY_LOCAL_MACHINE\Системы\CurrentControlSet\Услуги\DCLocator\Трассировки

Ключ будет иметь следующую структуру:

String ProcessName
  DWORD  PID <optional>

ProcessName должно быть полным именем, включая расширение процесса, для которого требуется получить сведения о трассировки. PID требуется только в том случае, если существует несколько процессов с одинаковым именем. Если он определен, трассировка будет включена только для процесса с этим PID. Невозможно отследить только 2 из 3 (или более) процессов с тем же именем. Можно включить один или все экземпляры (если существует несколько экземпляров с одинаковым именем процесса, а PID не указан, все экземпляры будут включены для трассировки).

Например, будет выполняться трассировка всех экземпляров App1.exe и App2.exe, но только экземпляра App3.exe с PID 999:

App1.exe 
App2.exe
App3.exe
     PID 999

Выполните следующую команду, чтобы запустить сеанс трассировки:

tracelog.exe -start <sessionname> -guid #cfaa5446-c6c4-4f5c-866f-31c9b55b962d -f <имя> файла -flag <traceFlags>

sessionname — это имя сеанса трассировки. Guid для поставщика трассировки DCLocator — cfaa5446-c6c4-4f5c-866f-31c9b55b962d. filename — это имя файла журнала, в который записываются события. traceFlags — это один или несколько из следующих флагов, обозначающие области трассировки:

Flag Шестнадцатеричное значение Описание
DCLOCATOR_MISC 0x00000002 Прочие отладки
DCLOCATOR_MAILSLOT 0x00000010 Сообщения почтового слоя
DCLOCATOR_SITE 0x00000020 Сайты
DCLOCATOR_CRITICAL 0x00000100 Важные ошибки
DCLOCATOR_SESSION_SETUP 0x00000200 Обслуживание доверенного домена
DCLOCATOR_DNS 0x00004000 Регистрация имени
DCLOCATOR_DNS_MORE 0x00020000 Подробная регистрация имени
DCLOCATOR_MAILBOX_TEXT 0x02000000 Подробные сообщения почтового ящика
DCLOCATOR_SITE_MORE 0x08000000 Подробные сайты
 

Выполните следующую команду, чтобы остановить сеанс трассировки:

tracelog.exe -stop <sessionname>

имя_сеанса совпадает с именем, которое использовалось при запуске сеанса.

Примечание Раздел реестра для процесса трассировки должен присутствовать в реестре во время запуска сеанса трассировки. При запуске сеанса процесс проверит, следует ли создавать сообщения трассировки (на основе наличия или отсутствия раздела реестра для этого имени процесса и необязательного PID). Процесс проверяет реестр только в начале сеанса. Любые изменения в реестре, происходящие после этого, не повлияют на трассировку.
 

Примечание

Заголовок dsgetdc.h определяет DsGetDcName в качестве псевдонима, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Использование псевдонима, не зависящий от кодирования, с кодом, который не является нейтральным для кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или времени выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.

Требования

Требование Значение
Минимальная версия клиента Windows Vista
Минимальная версия сервера Windows Server 2008
Целевая платформа Windows
Header dsgetdc.h
Библиотека NetApi32.lib
DLL NetApi32.dll

См. также раздел

DOMAIN_CONTROLLER_INFO

Функции службы каталогов

DsGetSiteName

DsValidateSubnetName

GUID

NetApiBufferFree

Служба времени Windows