IDirectoryObject インターフェイスを使用した属性へのアクセス
IDirectoryObject インターフェイスは、C および C++ で記述されたクライアント アプリケーションに、ディレクトリ サービス オブジェクトへの直接アクセスを提供します。 このインターフェイスは、ADSI 属性キャッシュではなく、直接ネットワーク プロトコルを使用してアクセスできるようにします。 IADs インターフェイスでサポートされるプロパティの代わりに、IDirectoryObject オブジェクトのメンテナンスの重要なサブセットをサポートし、その属性へのアクセスを提供するメソッドを提供します。 IDirectoryObject では、クライアントは 1 つのメソッド呼び出しで任意の数のオブジェクト属性を取得または設定できます。 バッチ処理される対応する Automation メソッドとは異なり、IDirectoryObject メソッドは呼び出されたときに実行されます。 このインターフェイスのメソッドでは Automation ディレクトリ オブジェクトのインスタンスを作成する必要がないため、パフォーマンスのオーバーヘッドは小さくなります。
C や C++ などの言語で記述されたクライアントは、IDirectoryObject インターフェイスのメソッドを使用してパフォーマンスを最適化し、ネイティブ ディレクトリ サービス インターフェイスを利用する必要があります。 オートメーション クライアントは IDirectoryObject を使用できません。 代わりに、IADs インターフェイスを使用する必要があります。
IDirectoryObject::GetObjectAttributes メソッドは、単一の値と複数の値の両方を持つ属性を取得します。 このメソッドは、要求された属性の一覧を受け取り、ADS_ATTR_INFO 構造体を返します。 ADSI はこの構造体を割り当てます。呼び出し元は、FreeADsMem 関数を使用して、このメモリが不要になったときに解放する必要があります。
返される属性値の順序は、属性が要求された順序と必ずしも同じではありません。 したがって、ADSI から返される属性名を比較する必要があります。
Note
ADS_ATTR_INFO 構造体は、要求されたすべての属性を返すわけではありません。 返される構造体の一部は、値を含む属性だけです。
返される属性の数は、dwNumberAttributes パラメーター (IDirectoryObject::GetObjectAttributes メソッドに渡される) によって決まります。
次のコード例では、オブジェクトにバインドし、IDirectoryObject::GetObjectAttributes メソッドを使用してオブジェクトの属性を取得します。
HRESULT hr;
IDirectoryObject *pDirObject;
CoInitialize(NULL);
hr = ADsGetObject(
L"LDAP://CN=Jeff Smith,OU=Users,DC=Fabrikam,DC=com",
IID_IDirectoryObject,
(void**)&pDirObject);
if(SUCCEEDED(hr))
{
ADS_ATTR_INFO *pAttrInfo = NULL;
LPWSTR pAttrNames[] = {L"cn", L"title", L"otherTelephone"};
DWORD dwNumAttr = sizeof(pAttrNames)/sizeof(LPWSTR);
DWORD dwReturn;
//////////////////////////////////////////////////
// Get attribute values requested.
// Be aware that the order is not necessarily the
// same as requested using pAttrNames.
//////////////////////////////////////////////////
hr = pDirObject->GetObjectAttributes(pAttrNames,
dwNumAttr,
&pAttrInfo,
&dwReturn);
if(SUCCEEDED(hr))
{
for(DWORD idx = 0; idx < dwReturn; idx++)
{
if(_wcsicmp(pAttrInfo[idx].pszAttrName, L"cn") == 0)
{
if(pAttrInfo[idx].dwADsType == ADSTYPE_CASE_IGNORE_STRING)
{
wprintf(L"Common Name: %s\n",
pAttrInfo[idx].pADsValues[0].CaseIgnoreString);
}
}
else if(_wcsicmp(pAttrInfo[idx].pszAttrName, L"title") == 0)
{
if(pAttrInfo->dwADsType == ADSTYPE_CASE_IGNORE_STRING)
{
wprintf(L"Title: %s\n",
pAttrInfo[idx].pADsValues[0].CaseIgnoreString);
}
}
else if(_wcsicmp(pAttrInfo[idx].pszAttrName,
L"otherTelephone") == 0)
{
// Print the multi-valued property, "Other Telephones".
if(pAttrInfo[idx].dwADsType == ADSTYPE_CASE_IGNORE_STRING)
{
wprintf(L"Other Telephones:");
for(DWORD val = 0; val < pAttrInfo[idx].dwNumValues; val++)
{
wprintf(L" %s\n",
pAttrInfo[idx].pADsValues[val].CaseIgnoreString);
}
}
}
}
FreeADsMem(pAttrInfo);
}
pDirObject->Release();
}
CoUninitialize();