Introduction
This article will briefly describe how to use the IDirectoryObject
in your C++ ADSI application, instead of using the IADs objects intended for scripting clients
Why IDirectoryObject instead of IADs
ADSI (Active Directory Services Interface) is a nice collection of COM objects and gives you easy access to objects and attributes in Active Directory or other LDAP directories. Most programmers use the IADs, IDispatch
inherited, interface when programming but using the non-scripting interface IDirectoryObject
can improve performance and coding for C++ programmers (if you use scripting languages and/or Visual Basic you have no choice but to use the IADs interface). All ADSI providers must implement the IADs and IDirectoryInterface, so why not take advantage of the features of the IDirectoryObject
interface
The major differences between IADs and IDirectoryObject
is that the IDirectoryObject
will give you direct net access to the directory. IADs uses a property cache from which you read and write attributes using the Get()
, get_*
and put_*
methods and you have to put up with that all the data is delivered using the VARIANT
data type. The IDirectoryObject
lets you read and write directly through a single request to the object.
Example
Here are three code snippets doing almost the same thing; retrieving the distinguishedName
property of a user in Active Directory with a given GUID. The examples can be downloaded above.
IADs
The code in VBScript and in VC++
This first example shows a message box with the distinguishedName
and is written in VBScript.
Dim oObject As IADs
Dim vValue As Variant
Set oObject = GetObject("GC://<GUID=b74488fda7dc9c488de9b4bbcdde341f>")
vValue = oObject.Get("distinguishedName")
This example in C++ prints the distinguishedName
in a console.
IADs* pObject;
HRESULT hr;
VARIANT vValue;
hr = ADsGetObject(CComBSTR(
L"GC://<GUID=b74488fda7dc9c488de9b4bbcdde341f>"),
IID_IADs,
(void**)&pObject);
if(SUCCEEDED(hr)) {
hr = pObject->Get(CComBSTR(L"distinguishedName"), &vValue);
if(SUCCEEDED(hr)) {
USES_CONVERSION;
printf("distinguishedName is %s\n", W2A(vValue.bstrVal));
VariantClear(&vValue);
}
pObject->Release();
}
IDirectoryObject
This is the same as above but now using the IDirectoryObject
. More coding but slightly faster!
IDirectoryObject* pObject;
HRESULT hr;
PADS_ATTR_INFO pAttributeEntries;
LPWSTR ppAttributeNames[] = {L"distinguishedName"};
DWORD dwAttributesReturned = 0;
hr = ADsGetObject(CComBSTR(
L"GC://<GUID=b74488fda7dc9c488de9b4bbcdde341f>"),
IID_IDirectoryObject,
(void**)&pObject);
if(SUCCEEDED(hr)) {
hr = pObject->GetObjectAttributes(ppAttributeNames,
1,
&pAttributeEntries,
&dwAttributesReturned );
if(SUCCEEDED(hr)) {
if(dwAttributesReturned >0 ) {
printf("distinguishedName is %S\n",
pAttributeEntries->pADsValues[0].CaseIgnoreString);
}
FreeADsMem(pAttributeEntries);
}
pObject->Release();
}
Summary
Use IDirectoryObject
when programming in C++ (or plain C), especially if you are reading small or very large amount of attributes of the objects or when reading attributes that the IADs property cache does not cache by default.
Notes
The GUID used in the examples points to a user object in Active Directory, to retrieve the GUID get the objectGUID
property of the ADSI object.