특성 범위 쿼리 수행

특성 범위 쿼리는 개체의 고유 이름 값 특성 검색을 수행할 수 있는 검색 기본 설정입니다. 검색할 특성은 단일 또는 다중 값일 수 있지만 ADS_DN_STRING 형식이어야 합니다. 검색이 수행되면 ADSI는 특성의 고유 이름 값을 열거하고 고유 이름이 나타내는 개체에 대해 검색을 수행합니다. 예를 들어 그룹 개체의 멤버 특성에 대해 특성 범위가 지정된 검색을 수행하는 경우 ADSI는 멤버 특성의 고유 이름을 열거하고 그룹의 각 멤버에서 지정된 검색 조건을 검색합니다.

특성 범위 쿼리가 ADS_DN_STRING 형식이 아닌 특성에 대해 수행되면 검색이 실패합니다. 특성 범위 쿼리를 사용하려면 ADS_SEARCHPREF_SEARCH_SCOPE 기본 설정을 ADS_SCOPE_BASE 합니다. ADS_SEARCHPREF_SEARCH_SCOPE 기본 설정은 자동으로 ADS_SCOPE_BASE 설정되지만 ADS_SEARCHPREF_SEARCH_SCOPE 기본 설정이 다른 값으로 설정된 경우 IDirectorySearch::SetSearchPreferenceE_ADS_BAD_PARAMETER 함께 실패합니다.

특성 범위 쿼리의 결과는 여러 서버에 걸쳐 있을 수 있으며 서버는 반환된 모든 행에 대해 요청된 모든 데이터를 반환하지 않을 수 있습니다. 이 경우 IDirectorySearch::GetNextRow 또는 IDirectorySearch::GetFirstRow를 호출하여 마지막 행을 검색하면 ADSI는 S_ADS_NOMORE_ROWS 대신 S_ADS_ERRORSOCCURRED 반환합니다.

특성 범위 쿼리를 지정하려면 ADSTYPE_CASE_IGNORE_STRING 값이 iDirectorySearch::SetSearchPreference 메서드에 전달된 ADS_SEARCHPREF_INFO 배열에서 검색할 특성의 lDAPDisplayName으로 설정된 ADS_SEARCHPREF_ATTRIBUTE_QUERY 검색 옵션을 설정합니다. 이 작업은 다음 코드 예제에 나와 있습니다.

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

다음 코드 예제에서는 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;
}

이 검색이 실행되고 결과가 열거되면 그룹의 구성원 특성 목록에 포함된 모든 사용자 개체의 이름, 전화 번호사무실 번호를 반환합니다.

오류 처리: 특성 범위 쿼리의 결과는 여러 서버에 걸쳐 있을 수 있으며 서버는 반환된 모든 행에 대해 요청된 모든 데이터를 반환하지 않을 수 있습니다. 이 경우 GetNextRow 또는 GetFirstRow를 호출하여 마지막 행을 검색할 때 ADSI는 S_ADS_NOMORE_ROWS 대신 S_ADS_ERRORSOCCURRED 반환합니다.