Platform SDK: Active Directory, ADSI, and Directory Services |
The ADsBuildEnumerator function builds an enumerator object for the specified ADSI container object.
HRESULT ADsBuildEnumerator( IADsContainer *pADsContainer, IEnumVARIANT **ppEnumVariant );
This method supports the standard HRESULT return values, including S_OK for a successful operation. For other return values, see ADSI Error Codes.
The ADsBuildEnumerator helper function 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 on the enumerator object. The general procedure to enumerate the available objects in a container is as follows:
The following code snippet illustrates how this and other related API functions can be used to delete all the objects in a container.
Void DeleteObject(IUnknown* pIUnknown) { IUnknown* pIChildUnk = NULL; IADsContainer* pIContainer = NULL; IEnumVARIANT* pIEnumVar = NULL; ULONG ulFetch = 0; VARIANT var; HRESULT hr; if(pIUnknown =NULL) return E_FAIL; // QI container interface. hr=pIUnknown->QueryInterface(IID_IADsContainer,(void**)&pIContainer); if (SUCCEEDED(hr)) { //Create an enumerator object in the container. hr=ADsBuildEnumerator(pIContainer, &pIEnumVar); while(SUCCEEDED(hr)) { //Get the next contained object. ulFetch = 0L; hr = ADsEnumerateNext(pIEnumvar, 1, &var, &ulFetch); if(!ulFetch) break; //Check if the retrieved object is another container. V_DISPATCH(%var)->QueryInterface(IID_IUnknown, (void**)&pIChildUnk); //Release the contained object. VariantClear(&var); //Call the function recursively on child containers. if(pIChildUnk != NULL) { DeleteObject(pIContainer, pIChildUnk); pIChildUnk->Release(); } pIChildUnk = NULL; } //Release the enumerator. if (pIEnumVar != NULL) { ADsFreeEnumerator(pIEnumVar); } //Release the container. pIContainer->Release(); }
If the server supports paged search and the client has specified the page limit that exceeds the maximum search results allowed on the server, the ADsBuildEnumerator function forwards errors and results from the server to the user in the following ways:
Here is another code snippet that uses the ADsBuildEnumerator function to enumerate Group Membership.
int main(int argc, char* argv[]) { IADs *pRoot=NULL; IADsContainer *pCont=NULL; IEnumVARIANT *pEnum=NULL,*pMbrEnum=NULL; IDispatch *pDisp,*pDispMem; IADs *pADs,*pADsMem; IADsGroup *pGrp; IADsMembers *pMbr; VARIANT varDSRoot; VARIANT varEnum,varEnumMem; ULONG ulFetch=0; BSTR bstrPath; TCHAR adspath[MAX_PATH]; HRESULT hr; hr = CoInitialize(NULL); //Get the name of the root container for this domain. //Read the Root DSE from the default DS, which will be the DS for //the local domain. This will get us the name of the schema //container, which is stored in the "defaultNamingContext" //operational attribute. hr = ADsGetObject(TEXT("LDAP://RootDSE"), IID_IADs, (void**)&pRoot); hr = pRoot->Get(TEXT("defaultNamingContext"),&varDSRoot); _tprintf(TEXT("\nDS Root :%s\n"),varDSRoot.bstrVal); pRoot->Release(); //Now bind to the builtin container. _tcscpy(adspath,TEXT("LDAP://")); _tcscat(adspath,TEXT("CN=Builtin,")); _tcscat(adspath,varDSRoot.bstrVal); hr = ADsGetObject(adspath,IID_IADsContainer,(void**)&pCont); //Enumerate the contents of the builtin container hr = ADsBuildEnumerator(pCont,&pEnum); while (hr == S_OK) { // //Fetch one element and place it in varEnum. ulFetch is the //number of elements actually returned. If there are no //objects to enumerate ulFetch will be zero and the call will //succeed. When an object is fetched, varEnum will contain //the dispinterface of the child object // hr = ADsEnumerateNext(pEnum,1,&varEnum,&ulFetch); if (ulFetch) { // //Use the dispinterface to QI for IADs. // pDisp = V_DISPATCH(&varEnum); hr = pDisp->QueryInterface( IID_IADs, (void**)&pADs); hr = pADs->get_ADsPath(&bstrPath); if SUCCEEDED(hr) { _tprintf(TEXT(" Builtin:%s\n"),bstrPath); //Enumerate the members of this group. Bind to the //group requesting IADsGroup // hr = ADsGetObject(bstrPath,IID_IADsGroup,(void**)&pGrp); //Retrieve the Members property - this is a container //that holds IADs objects for the members // hr = pGrp->Members(&pMbr); //Create another enumerator and enumerate the members //of the group. // hr = ADsBuildEnumerator((IADsContainer*)pMbr,&pMbrEnum); while (hr == S_OK) { hr = ADsEnumerateNext(pMbrEnum,1,&varEnumMem,&ulFetch); if (ulFetch) { // //For each member, read the ADsPath attribute //and display it. // pDispMem = V_DISPATCH(&varEnumMem); hr = pDispMem->QueryInterface( IID_IADs, (void**)&pADsMem); hr = pADsMem->get_ADsPath(&bstrPath); _tprintf(TEXT(" Member:%s\n"),bstrPath); pDispMem->Release(); pADsMem->Release(); } //Object Fetched. } //Member enumerator built. hr = ADsFreeEnumerator(pMbrEnum); pGrp->Release(); pMbr->Release(); pADs->Release(); pDisp->Release(); } //Group object bound } //Group fetched } // Group enumerator built hr = ADsFreeEnumerator(pEnum); if (pCont) pCont->Release(); return 0; }
Windows NT/2000: Requires Windows 2000 (or Windows NT 4.0 with DSClient).
Windows 95/98: Requires Windows 95 or later (with DSClient).
Header: Declared in Adshlp.h.
Library: Included as a resource in ActiveDs.dll.
ADSI Error Codes, ADSI Functions, ADsEnumerateNext, ADsFreeEnumerator, IADsContainer, IEnumVARIANT