Melakukan Kueri Cakupan Atribut

Kueri cakupan atribut adalah preferensi pencarian yang memungkinkan pencarian atribut bernilai nama khusus objek yang akan dilakukan. Atribut untuk pencarian dapat berupa tunggal atau multinilai, tetapi harus dari jenis ADS_DN_STRING . Ketika pencarian dilakukan, ADSI akan menghitung nilai nama khusus atribut dan melakukan pencarian pada objek yang diwakili oleh nama khusus. Misalnya, jika pencarian tercakup atribut dilakukan dari atribut anggota objek grup, ADSI akan menghitung nama khusus dalam atribut anggota dan mencari setiap anggota grup untuk kriteria pencarian yang ditentukan.

Jika kueri tercakup atribut dilakukan pada atribut yang bukan tipe ADS_DN_STRING, pencarian akan gagal. Kueri terlingkup atribut juga mengharuskan preferensi ADS_SEARCHPREF_SEARCH_SCOPE diatur ke ADS_SCOPE_BASE. Preferensi ADS_SEARCHPREF_SEARCH_SCOPE akan secara otomatis diatur ke ADS_SCOPE_BASE, tetapi jika preferensi ADS_SEARCHPREF_SEARCH_SCOPE diatur ke nilai lain, IDirectorySearch::SetSearchPreference akan gagal dengan E_ADS_BAD_PARAMETER.

Hasil kueri lingkup atribut dapat mencakup beberapa server dan server mungkin tidak mengembalikan semua data yang diminta untuk semua baris yang dikembalikan. Jika ini terjadi, ketika baris terakhir diambil dengan memanggil IDirectorySearch::GetNextRow atau IDirectorySearch::GetFirstRow, ADSI akan mengembalikan S_ADS_ERRORSOCCURRED alih-alih S_ADS_NOMORE_ROWS.

Untuk menentukan kueri cakupan atribut, atur opsi pencarian ADS_SEARCHPREF_ATTRIBUTE_QUERY dengan nilai ADSTYPE_CASE_IGNORE_STRING diatur ke lDAPDisplayName atribut untuk mencari dalam array ADS_SEARCHPREF_INFO yang diteruskan ke metode IDirectorySearch::SetSearchPreference. Operasi ini ditampilkan dalam contoh kode berikut.

ADS_SEARCHPREF_INFO SearchPref;
SearchPref.dwSearchPref = ADS_SEARCHPREF_ATTRIBUTE_QUERY;
SearchPref.vValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
SearchPref.vValue.Boolean = L"member";

Contoh kode berikut menunjukkan cara menggunakan opsi pencarian ADS_SEARCHPREF_ATTRIBUTE_QUERY .

/***************************************************************************

    SearchGroupMembers()

    Searches the members of a group that are of type user and prints each 
    user's cn and distinguishedName values to the console.

    Parameters:

    pwszGroupDN - Contains the distinguished name of the group whose 
    members will be searched.

***************************************************************************/

HRESULT SearchGroupMembers(LPCWSTR pwszGroupDN)
{
    HRESULT hr;
    CComPtr<IDirectorySearch> spSearch;
    CComBSTR sbstrADsPath;
 
    // Bind to the group and get the IDirectorySearch interface.
    sbstrADsPath = "LDAP://";
    sbstrADsPath += pwszGroupDN;
    hr = ADsOpenObject(sbstrADsPath,
        NULL,
        NULL,
        ADS_SECURE_AUTHENTICATION,
        IID_IDirectorySearch,
        (void**)&spSearch);
    if(FAILED(hr))
    {
        return hr;
    }
 
    ADS_SEARCHPREF_INFO SearchPrefs[1];

    // Set the ADS_SEARCHPREF_ATTRIBUTE_QUERY search preference.
    SearchPrefs[0].dwSearchPref = ADS_SEARCHPREF_ATTRIBUTE_QUERY;
    SearchPrefs[0].vValue.dwType = ADSTYPE_CASE_IGNORE_STRING;
    SearchPrefs[0].vValue.CaseIgnoreString = L"member";

    // Set the search preferences.
    hr = spSearch->SetSearchPreference(SearchPrefs, sizeof(SearchPrefs)/sizeof(ADS_SEARCHPREF_INFO));
    if(FAILED(hr))
    {
        return hr;
    }

    ADS_SEARCH_HANDLE hSearch;
    
    // Create the search filter.
    LPWSTR pwszSearchFilter = L"(&(objectClass=user))";
 
    // Set attributes to return.
    LPWSTR rgpwszAttributes[] = {L"cn", L"distinguishedName"};
    DWORD dwNumAttributes = sizeof(rgpwszAttributes)/sizeof(LPWSTR);
 
    // Execute the search.
    hr = spSearch->ExecuteSearch(pwszSearchFilter,
        rgpwszAttributes,
        dwNumAttributes,
        &hSearch);
    if(FAILED(hr))
    {
        return hr;
    }

    // Get the first result row.
    hr = spSearch->GetFirstRow(hSearch);
    while(S_OK == hr)
    {
        ADS_SEARCH_COLUMN col;

        // Enumerate the retrieved attributes.
        for(DWORD i = 0; i < dwNumAttributes; i++)
        {
            hr = spSearch->GetColumn(hSearch, rgpwszAttributes[i], &col);
            if(SUCCEEDED(hr))
            {
                switch(col.dwADsType)
                {
                case ADSTYPE_DN_STRING:
                    wprintf(L"%s: %s\n\n", rgpwszAttributes[i], col.pADsValues[0].DNString);
                    break;

                case ADSTYPE_CASE_IGNORE_STRING:
                    wprintf(L"%s: %s\n\n", rgpwszAttributes[i], col.pADsValues[0].CaseExactString);
                    break;

                default:
                    break;
                }
                
                // Free the column.
                spSearch->FreeColumn(&col);
            }
        }
        
        // Get the next row.
        hr = spSearch->GetNextRow(hSearch);
    }

    // Close the search handle to cleanup.
    hr = spSearch->CloseSearchHandle(hSearch);

    return hr;
}

Ketika pencarian ini dijalankan dan hasilnya dijumlahkan, pencarian akan mengembalikan nama, nomor telepon, dan nomor kantor semua objek pengguna yang terkandung dalam daftar atribut anggota grup.

Penanganan kesalahan: Hasil kueri lingkup atribut dapat mencakup beberapa server dan server mungkin tidak mengembalikan semua data yang diminta untuk semua baris yang dikembalikan. Jika ini terjadi, ketika baris terakhir diambil dengan memanggil GetNextRow atau GetFirstRow, ADSI akan mengembalikan S_ADS_ERRORSOCCURRED, bukan S_ADS_NOMORE_ROWS.