Platform SDK: Active Directory, ADSI, and Directory Services |
There are three enumerator helper functions which can be used from C/C++ to aid in the navigation of Active Directory objects. They are ADsBuildEnumerator, ADsEnumerateNext, and ADsFreeEnumerator.
The ADsBuildEnumerator helper function encapsulates the code required to create an enumerator object. It calls the IADsContainer::get__NewEnum method to create an enumerator object and then calls the QueryInterface method of IUnknown to get a pointer to the IEnumVARIANT interface for that object. The enumeration object is the Automation mechanism to enumerate over containers. Use the ADsFreeEnumerator function to release this enumerator object.
The ADsEnumerateNext helper function populates a VARIANT array with elements fetched from an enumerator object. The number of elements retrieved can be smaller than the number requested.
Frees an enumerator object previously created through the ADsBuildEnumerator function.
Here is an example function using the enumerator helper functions in C++:
/***************************************************************************** Function: TestEnumObject Arguments: pszADsPath - ADsPath of the container to be enumerated (WCHAR*). Return: S_OK Purpose: Example using ADsBuildEnumerator, ADsEnumerateNext and ADsFreeEnumerator. ******************************************************************************/ #define MAX_ENUM 100 HRESULT TestEnumObject( LPWSTR pszADsPath ) { ULONG cElementFetched = 0L; IEnumVARIANT * pEnumVariant = NULL; VARIANT VariantArray[MAX_ENUM]; HRESULT hr; IADsContainer * pADsContainer = NULL; DWORD dwObjects = 0, dwEnumCount = 0, i = 0; BOOL fContinue = TRUE; hr = ADsGetObject( pszADsPath, IID_IADsContainer, (void **)&pADsContainer ); if (FAILED(hr)) { printf("\"%S\" is not a valid container object.\n", pszADsPath) ; goto exitpoint ; } hr = ADsBuildEnumerator( pADsContainer, &pEnumVariant ); if( FAILED( hr ) ) { printf("ADsBuildEnumerator failed with %lx\n", hr ) ; goto exitpoint ; } fContinue = TRUE; while (fContinue) { IADs *pObject ; hr = ADsEnumerateNext( pEnumVariant, MAX_ENUM, VariantArray, &cElementFetched ); if (hr == S_FALSE) { fContinue = FALSE; } dwEnumCount++; for (i = 0; i < cElementFetched; i++ ) { IDispatch *pDispatch = NULL; BSTR bstrADsPath = NULL; pDispatch = VariantArray[i].pdispVal; hr = V_DISPATCH( VariantArray + i )->QueryInterface(IID_IADs, (void **) &pObject) ; if( SUCCEEDED( hr ) ) { pObject->get_ADsPath( &bstrADsPath ); printf( "%S\n", bstrADsPath ); } pObject->Release(); VariantClear( VariantArray + i ); SysFreeString( bstrADsPath ); } dwObjects += cElementFetched; } printf("Total Number of Objects enumerated is %d\n", dwObjects); ADsFreeEnumerator( pEnumVariant ); if (pADsContainer) { pADsContainer->Release(); } return(S_OK); exitpoint: return S_OK; }