Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Получить Primary Domain Controller (PDC)

Delphi , Интернет и Сети , Сеть

Получить Primary Domain Controller (PDC)

Оформил: DeeCo
Автор: http://www.swissdelphicenter.ch

{ 
  The NetGetDCName function returns the name of the primary domain controller (PDC). 
  It does not return the name of the backup domain controller (BDC) for the specified domain. 
  Also, you cannot remote this function to a non-PDC server. 
  Windows 2000/XP: Applications that support DNS-style names should call the  function. 
  Domain controllers in this type of environment have a multi-master 
  directory replication relationship. 
  Therefore, it may be advantageous for your application to use a DC that is not the PDC. 
  You can call the DsGetDcName function to locate any DC in the domain; 
  NetGetDCName returns only the name of the PDC. 
}

 type
   EAccessDenied = Exception;
   EInvalidOwner = Exception;
   EInsufficientBuffer = Exception;
   ELibraryNotFound = Exception;

   NET_API_STATUS = Integer;

 const
   NERR_Success = 0;

 var
   NTNetGetDCName: function (Server, Domain: pWideChar; var DC: pWideChar): NET_API_STATUS; stdcall;
   NTNetGetDCNameA: function (Server, Domain: PChar; var DC: PChar): NET_API_STATUS; stdcall;
   NTNetApiBufferFree: function (lpBuffer: Pointer): NET_API_STATUS; stdcall;

 procedure NetCheck(ErrCode: NET_API_STATUS);
 begin
   if ErrCode <> NERR_Success then
   begin
     case ErrCode of
       ERROR_ACCESS_DENIED:
         raise EAccessDenied.Create('Access is Denied');
       ERROR_INVALID_OWNER:
         raise EInvalidOwner.Create('Cannot assign the owner of this object.');
       ERROR_INSUFFICIENT_BUFFER:
         raise EInsufficientBuffer.Create('Buffer passed was too small');
       else
         raise Exception.Create('Error Code: ' + IntToStr(ErrCode) + #13 +
           SysErrorMessage(ErrCode));
     end;
   end;
 end;

 function GetPDC(szSystem: string): string;
   { if szSystem = '' return the PDC else return DC for that domain }
 const
   NTlib = 'NETAPI32.DLL';
   Win95lib = 'RADMIN32.DLL';
 var
   pAnsiDomain: PChar;
   pDomain: PWideChar;
   System: array[1..80] of WideChar;
   ErrMode: Word;
   LibHandle: THandle;
 begin
   Result := '';
   LibHandle := 0;
   try
     if Win32Platform = VER_PLATFORM_WIN32_NT then
     begin
       ErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
       LibHandle := LoadLibrary(NTlib);
       SetErrorMode(ErrMode);
       if LibHandle = 0 then
         raise ELibraryNotFound.Create('Unable to map library: ' +
           NTlib); @NTNetGetDCName := GetProcAddress(Libhandle, 'NetGetDCName');
         @NTNetApiBufferFree       := GetProcAddress(Libhandle,
         'NetApiBufferFree');
       try
         if szSystem <> '' then
           NetCheck(NTNetGetDCName(nil, StringToWideChar(szSystem, @System, 80), pDomain))
         else
           NetCheck(NTNetGetDCName(nil, nil, pDomain));
         Result := WideCharToString(pDomain);
       finally
         NetCheck(NTNetApiBufferFree(pDomain));
       end;
     end
     else
     begin
       ErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
       LibHandle := LoadLibrary(Win95lib);
       SetErrorMode(ErrMode);
       if LibHandle = 0 then
         raise ELibraryNotFound.Create('Unable to map library: ' +
           Win95lib); @NTNetGetDCNameA := GetProcAddress(Libhandle, 'NetGetDCNameA');
         @NTNetApiBufferFree := GetProcAddress(LibHandle, 'NetApiBufferFree');
       try
         if szSystem <> '' then
           NetCheck(NTNetGetDCNameA(nil, PChar(szSystem), pAnsiDomain))
         else
           NetCheck(NTNetGetDCNameA(nil, nil, pAnsiDomain));
         Result := StrPas(pAnsiDomain);
       finally
         NetCheck(NTNetApiBufferFree(pAnsiDomain));
       end;
     end;
   finally
     if LibHandle <> 0 then
     begin
       FreeLibrary(Libhandle); // free handle if it has been allocated 
    end;
   end;
 end;

 // Example call, Beispielaufruf: 

procedure TForm1.Button1Click(Sender: TObject);
 begin
   try
     Screen.Cursor  := crHourGlass;
     label1.Caption := GetPDC('');
   finally
     Screen.Cursor := crDefault;
   end;
 end;

Перевод контента на русский язык:

Программа Delphi, которая извлекает основной контроллер домена (PDC) для указанного домена или возвращает PDC для локального компьютера, если не указан домен.

Расшифровка кода:

  1. Функция NTNetGetDCName вызывается для извлечения имени основного контроллера домена (PDC). Эта функция доступна в библиотеке NETAPI32.DLL на платформах Windows NT/2000/XP и в библиотеке RADMIN32.DLL на платформах Windows 95/98.
  2. Функция принимает три параметра: Server, Domain и DC. Server - указатель на строку, которая specifies серверное имя или IP-адрес; Domain - указатель на строку, которая specifies доменное имя или NetBIOS-имя; а DC - переменная типа WideChar, которая получает имя основного контроллера домена.
  3. Код использует две версии функции: NTNetGetDCName (для Windows NT/2000/XP) и NTNetGetDCNameA (для Windows 95/98). Это потому, что два платформы имеют разные библиотеки для NetAPI-функций.
  4. Если происходит ошибка при выполнении функции, она вызывает исключение с описывающим сообщением.
  5. Процедура NetCheck обрабатывает ошибки, проверяя возвращаемое значение функции и вызывая исключение, если необходимо.
  6. Функция GetPDC вызывает NTNetGetDCName (или NTNetGetDCNameA) для извлечения имени основного контроллера домена для указанного домена или возвращает PDC для локального компьютера, если не указан домен.
  7. В примере вызова, когда кнопка нажата, она извлекает имя PDC для локального компьютера и отображает его в лейбле.

Имproved версия кода:

function GetPDC(const Domain: string): string;
begin
  Result := '';
  if LoadLibrary(NTlib) = 0 then
    raise ELibraryNotFound.Create('Unable to map library: ' + NTlib);

  try
     @NTNetGetDCName := GetProcAddress(LibHandle, 'NetGetDCName');
    if szSystem <> '' then
      NetCheck(NTNetGetDCName(nil, StringToWideChar(Domain, System), pDomain))
    else
      NetCheck(NTNetGetDCName(nil, nil, pDomain));

    Result := WideCharToString(pDomain);
  finally
    NetCheck(NTNetApiBufferFree(pDomain));
    FreeLibrary(LibHandle);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    Screen.Cursor := crHourGlass;
    label1.Caption := GetPDC('');
  finally
    Screen.Cursor := crDefault;
  end;
end;

В этой improved версии функция GetPDC упрощается, а обработка ошибок улучшается. Вызов LoadLibrary перенесен в начало функции GetPDC, а вызов FreeLibrary перенесен в блок finally. Это обеспечивает то, что handle библиотеки всегда будет освобожден, даже если исключение было вызвано.

Функция NetGetDCName возвращает имя главного домена контроллера (Primary Domain Controller, PDC), а не имени резервного домена контроллера (Backup Domain Controller, BDC) для указанной области.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Сеть ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-07-06 02:34:15/0.0037219524383545/0