Platform SDK: Active Directory, ADSI, and Directory Services |
The following C++ code fragment contains a function that uses ranging to retrieve the members of a group using IDirectorySearch:
//////////////////////////////////////////////////////////////////////////////////////////////////// /* PrintAttributeWithRanging() - Uses IDirectorySearch to read an attribute with ADSI ranging Parameters IDirectoryObject * pDirObject - Object from which the attribute will be read LPOLESTR pwszAttribute - Name of the attribute int iScope - Scope of the search int iNumToDisplayAtATime - Number of Attributes to retrieve at a time */ HRESULT PrintAttributeWithRanging(IDirectoryObject * pDirObject,LPOLESTR pwszAttribute, int iScope,int iNumToDisplayAtATime) { HRESULT hr; ADS_SEARCH_COLUMN col; // Interface Pointers IDirectorySearch *pDSSearch=NULL; // Get an IDirectorySearch * from the passed IDirectoryObject hr = pDirObject->QueryInterface(IID_IDirectorySearch,(void**)&pDSSearch); if (FAILED(hr)) return hr; // The attribute which will come back from the search WCHAR pszAttr[512]; DWORD dwAttrNameSize = 1;//sizeof(pszAttr)/sizeof(LPWSTR); // Preferences on Search ADS_SEARCHPREF_INFO arSearchPrefs[1]; DWORD dwNumPrefs; // Set the scope to the passed value arSearchPrefs [0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE ; arSearchPrefs [0].vValue.dwType = ADSTYPE_INTEGER; arSearchPrefs [0].vValue.Integer = ADS_SCOPE_BASE; // Number of elements in arSearchPrefs dwNumPrefs = 1; ADS_SEARCH_HANDLE hSearch; // Handle for searching. ADSI uses this // to keep its place // Set the preferences for search hr = pDSSearch->SetSearchPreference( arSearchPrefs, dwNumPrefs); if (FAILED(hr)) return hr; // Do a series of Range searches, grabbing 10 at a time. int iRange = 0; DWORD dAttribsGotten = 0; while (SUCCEEDED(hr)) { LPWSTR pSrchFilter = (LPWSTR)&pszAttr; int iAttribsGottenLastSrch =0; // Build the Range String : ex: L"Member;Range=0-5" swprintf(pSrchFilter ,L"%s;Range=%d-%d",pwszAttribute,iRange,iRange+iNumToDisplayAtATime-1); // Display info to the user wprintf(L"\nPerforming a Range IDirectorySearch for the attribute '%s'\n" L"The search filter is %s\n\nEntries %d through %d:\n\n" ,pwszAttribute,pSrchFilter,iRange,iRange+iNumToDisplayAtATime-1); // Executing a BASE level search hr = pDSSearch->ExecuteSearch(L"(CN=*)",&pSrchFilter,dwAttrNameSize, &hSearch ); // Execute the Search if ( SUCCEEDED(hr) ) { while( pDSSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS ) { LPWSTR pszColumn; while(pDSSearch->GetNextColumnName( hSearch, &pszColumn )!= S_ADS_NOMORE_COLUMNS ) { //printf("%S ", pszColumn ); // Get the ADsPath and save it in the list hr = pDSSearch->GetColumn( hSearch, pszColumn, &col ); if ( SUCCEEDED(hr) ) { for (DWORD x = 0; x< col.dwNumValues; x++) { wprintf(L"%d: %s\n",dAttribsGotten,(col.pADsValues+x)->CaseIgnoreString); dAttribsGotten++; iAttribsGottenLastSrch++; } // Copy the BSTR // Free the column that GetColumn returns pDSSearch->FreeColumn( &col ); } FreeADsMem( pszColumn ); } } // Close the search handle and release the IDirectorySearch interface pDSSearch->CloseSearchHandle(hSearch); } if (FAILED(hr) || hr ==S_ADS_NOMORE_ROWS || iAttribsGottenLastSrch== 0 || iAttribsGottenLastSrch< iNumToDisplayAtATime ) break; iRange += iNumToDisplayAtATime; } pDSSearch->Release(); pDSSearch= NULL; return hr; }