属性スコープクエリを実行する

属性スコープクエリは、オブジェクトの識別名値属性の検索を実行できるようにする検索設定です。 検索する属性は、単一または複数の値にすることができますが、 広告の _ DN _ 文字列 型である必要があります。 検索が実行されると、ADSI は属性の識別名の値を列挙し、識別名によって表されるオブジェクトの検索を実行します。 たとえば、グループオブジェクトの member 属性に対して属性スコープ検索を実行すると、ADSI によって メンバー 属性の識別名が列挙され、グループの各メンバーが指定された検索条件に一致するように検索されます。

属性スコープクエリが、 ADS _ DN _ STRING 型ではない属性に対して実行されると、検索は失敗します。 また、属性スコープクエリでは、 ads _ SEARCHPREF _ 検索 _ スコープ 設定を ads _ scope _ BASE に設定する必要があります。 Ads _ SEARCHPREF _ 検索 _ スコープ の設定は自動的に ads _ SCOPE _ BASE に設定されますが、 ads _ SEARCHPREF _ search _ スコープ 設定が他の値に設定されている場合、 idirectorysearch:: setsearchpreferenceは、 E _ ADS _ BAD _ PARAMETER で失敗します。

属性スコープクエリの結果は複数のサーバーにまたがることがあり、サーバーは返されたすべての行に対して要求されたすべてのデータを返すとは限りません。 この場合、 Idirectorysearch:: GetNextRowまたは Idirectorysearch:: getfirstrowを呼び出して最後の行を取得すると、ADSI は、広告が _ _ nomore _ 行 ではなく、 s _ ads _ errorfirstrow curred を返します。

属性スコープクエリを指定するには、 ads _ SEARCHPREF _ attribute _ クエリ 検索オプションを adstype ケースに設定し、属性の lDAPDisplayName に設定された _ _ _ 文字列 値を無視して、 idirectorysearch:: setsearchpreferenceメソッドに渡される ads _ SEARCHPREF _ INFO配列を検索します。 この操作を次のコード例に示します。

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 _ クエリ 検索オプションを使用する方法を示します。

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

    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 は、広告が _ _ nomore _ 行 ではなく、 s _ ads _ errorfirstrow curred を返します。