Menghitung Pengendali Domain
Di versi Windows sebelumnya, aplikasi hanya dapat memperoleh satu pengendali domain di domain dengan memanggil DsGetDcName. Tidak ada cara untuk memprediksi pengendali domain mana yang akan diambil atau untuk mendapatkan daftar pengendali domain. Windows memungkinkan aplikasi untuk mendaftar pengontrol domain di domain dengan menggunakan fungsi DsGetDcOpen, DsGetDcNext, dan DsGetDcClose.
Untuk menghitung pengendali domain, panggil DsGetDcOpen. Fungsi ini mengambil parameter yang menentukan domain untuk menghitung dan opsi enumerasi lainnya. DsGetDcOpen menyediakan handel konteks enumerasi domain yang digunakan untuk mengidentifikasi operasi enumerasi saat DsGetDcNext dan DsGetDcClose dipanggil.
Fungsi DsGetDcNext dipanggil dengan handle konteks enumerasi domain untuk mengambil pengontrol domain berikutnya dalam enumerasi. Pertama kali fungsi ini dipanggil, pengontrol domain pertama dalam enumerasi diambil. Saat fungsi ini dipanggil untuk kedua kalinya, pengontrol domain kedua dalam enumerasi diperoleh. Proses ini diulang hingga DsGetDcNext mengembalikan ERROR_NO_MORE_ITEMS, yang menunjukkan akhir enumerasi.
FungsiDsGetDcNext akan menghitung pengontrol domain dalam dua grup. Grup pertama berisi pengendali domain yang mencakup situs komputer tempat fungsi dijalankan dan grup kedua berisi pengendali domain yang tidak mencakup situs komputer tempat fungsi dijalankan. Jika bendera DS_NOTIFY_AFTER_SITE_RECORDS telah ditetapkan dalam parameter OptionFlags di fungsiDsGetDcOpen, fungsi DsGetDcNext akan mengirimkan ERROR_FILEMARK_DETECTED setelah semua pengontrol domain khusus situs telah berhasil diambil. DsGetDcNext kemudian akan mulai menghitung grup kedua, yang berisi semua pengendali domain di domain, termasuk pengendali domain khusus situs yang terkandung dalam grup pertama.
Pengendali domain yang menangani situs komputer tempat fungsi dijalankan dijumlahkan terlebih dahulu diikuti oleh pengendali domain yang tidak mencakup situs komputer tempat fungsi dijalankan. Pengendali domain dikatakan mencakup situs jika pengendali domain dikonfigurasi untuk berada di situs tersebut atau jika pengendali domain berada di situs yang terdekat dengan situs yang dimaksud dalam hal biaya tautan antar situs yang dikonfigurasi. Jika ada pengontrol domain dalam grup pengontrol domain yang mencakup situs komputer dan grup pengontrol domain yang tidak mencakup situs komputer, pengontrol domain akan dikembalikan dalam grup berdasarkan urutan prioritas dan bobot yang dikonfigurasi yang ditentukan dalam DNS. Pengendali domain yang memiliki prioritas numerik yang lebih rendah dikembalikan dalam grup terlebih dahulu. Jika dalam grup terkait situs ada subgrup beberapa pengontrol domain dengan prioritas yang sama, pengendali domain dikembalikan dalam urutan acak tertimbang di mana pengontrol domain dengan bobot yang lebih tinggi memiliki lebih banyak peluang untuk dikembalikan terlebih dahulu. Situs, prioritas, dan bobot dikonfigurasi oleh administrator domain untuk mencapai performa dan penyeimbangan beban yang efektif di antara beberapa pengontrol domain yang tersedia di domain. Karena itu, aplikasi yang menggunakan fungsi DsGetDcOpen/DsGetDcNext/DsGetDcClose secara otomatis memanfaatkan pengoptimalan ini.
Ketika enumerasi selesai atau tidak lagi diperlukan, enumerasi harus ditutup dengan memanggil DsGetDcClose dengan handle konteks enumerasi domain.
Untuk mengatur ulang enumerasi, perlu untuk menutup enumerasi saat ini dengan memanggil DsGetDcClose lalu membuka kembali enumerasi dengan memanggil DsGetDcOpen lagi.
Contoh
Contoh kode berikut menunjukkan cara menggunakan fungsi-fungsi ini untuk menghitung pengontrol domain di domain lokal.
DWORD dwRet;
PDOMAIN_CONTROLLER_INFO pdcInfo;
// Get a domain controller for the domain this computer is on.
dwRet = DsGetDcName(NULL, NULL, NULL, NULL, 0, &pdcInfo);
if(ERROR_SUCCESS == dwRet)
{
HANDLE hGetDc;
// Open the enumeration.
dwRet = DsGetDcOpen( pdcInfo->DomainName,
DS_NOTIFY_AFTER_SITE_RECORDS,
NULL,
NULL,
NULL,
0,
&hGetDc);
if(ERROR_SUCCESS == dwRet)
{
LPTSTR pszDnsHostName;
/*
Enumerate each domain controller and print its name to the
debug window.
*/
while(TRUE)
{
ULONG ulSocketCount;
LPSOCKET_ADDRESS rgSocketAddresses;
dwRet = DsGetDcNext(
hGetDc,
&ulSocketCount,
&rgSocketAddresses,
&pszDnsHostName);
if(ERROR_SUCCESS == dwRet)
{
OutputDebugString(pszDnsHostName);
OutputDebugString(TEXT("\n"));
// Free the allocated string.
NetApiBufferFree(pszDnsHostName);
// Free the socket address array.
LocalFree(rgSocketAddresses);
}
else if(ERROR_NO_MORE_ITEMS == dwRet)
{
// The end of the list has been reached.
break;
}
else if(ERROR_FILEMARK_DETECTED == dwRet)
{
/*
DS_NOTIFY_AFTER_SITE_RECORDS was specified in
DsGetDcOpen and the end of the site-specific
records was reached.
*/
OutputDebugString(
TEXT("End of site-specific domain controllers\n"));
continue;
}
else
{
// Some other error occurred.
break;
}
}
// Close the enumeration.
DsGetDcClose(hGetDc);
}
// Free the DOMAIN_CONTROLLER_INFO structure.
NetApiBufferFree(pdcInfo);
}