属性スコープ クエリの実行
属性スコープ クエリは、オブジェクトの識別名値属性の検索を実行できるようにする検索設定です。 検索する属性は、単一値または複数値のいずれかですが、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::SetSearchPreference は E_ADS_BAD_PARAMETERで失敗します。
属性スコープ クエリの結果は複数のサーバーにまたがり、返されるすべての行に対して要求されたすべてのデータがサーバーから返されない場合があります。 これが発生した場合、IDirectorySearch::GetNextRowまたは IDirectorySearch::GetFirstRow呼び出して最後の行を取得すると、ADSI は S_ADS_NOMORE_ROWSの代わりに S_ADS_ERRORSOCCURRED を返します。
属性スコープ クエリを指定するには、IDirectorySearch::SetSearchPreference メソッドに渡された ADS_SEARCHPREF_INFO 配列で検索する属性の lDAPDisplayName に ADSTYPE_CASE_IGNORE_STRING 値を設定して、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を返します。