Platform SDK: Active Directory, ADSI, and Directory Services

Example Program for Using IDirectorySearch

The following ADSI example shows a simple command-prompt program that uses the IDirectorySearch interface to query a directory service. This sample has been edited, primarily by removing error checking, to simplify the flow. The complete example code is included in the ADSI SDK in the samples/activeds/sampapp/cxx/dssrch directory.

Usage: dssrch /b <baseObject> /f <search_filter> [/f <attrlist>] [/p <preference>=value>]  [/u <UserName> <Password>] [/t <flagName>=<value> 
 
    where:
    baseObject     = ADsPath of the base of the search
    search_filter  = search filter string in LDAP format
    attrlist       = list of the attributes to display
    preference could be one of:
    Asynchronous, AttrTypesOnly, DerefAliases, SizeLimit, TimeLimit,
    TimeOut, PageSize, SearchScope
    flagName could be one of:
    SecureAuth or UseEncrypt
    value is yes/no for a Boolean and the respective integer for integers
    scope is one of "Base", "OneLevel", or "Subtree"
 
For Example: dssrch /b NDS://ntmarst/ms /f "(object Class=Group)"  /a  "ADsPath, name, description" /p searchScope=onelevel
 
#define INC_OLE2
#include <windows.h>
#include <stdlib.h>
#include <limits.h>
#include <io.h>
#include <stdio.h>
#define BAIL_ON_NULL(p) if (!(p)) {goto error;}
#define BAIL_ON_FAILURE(hr) if (FAILED(hr)) {goto error;}
 
#include "activeds.h"
#include "main.hxx"
// Globals representing parameters on IDirectorySearch.
LPWSTR pszSearchBase, pszSearchFilter, pszAttrNames[10], pszAttrList;
DWORD dwNumberAttributes = -1;
// Preference Values.
BOOL fASynchronous=FALSE, fDerefAliases=FALSE, fAttrsOnly=FALSE;
DWORD fSizeLimit, fTimeLimit, dwTimeOut, dwPageSize, dwSearchScope;
 
ADS_SEARCHPREF_INFO pSearchPref[10];
DWORD dwCurrPref = 0;
 
LPWSTR pszUserName=NULL, pszPassword=NULL;
DWORD dwAuthFlags=0;
DWORD cErr=0;
 
char *prefNameLookup[] = 
    {
    "ADS_SEARCHPREF_ASYNCHRONOUS", 
    "ADS_SEARCHPREF_DEREF_ALIASES",   
    "ADS_SEARCHPREF_SIZE_LIMIT",      
    "ADS_SEARCHPREF_TIME_LIMIT",      
    "ADS_SEARCHPREF_ATTRIBTYPES_ONLY",
    "ADS_SEARCHPREF_SEARCH_SCOPE",    
    "ADS_SEARCHPREF_TIMEOUT",         
    "ADS_SEARCHPREF_PAGESIZE",         
    "ADS_SEARCHPREF_PAGED_TIME_LIMIT",
    "ADS_SEARCHPREF_CHASE_REFERRALS"
    };
 
 
//+--------------------
//  Function:   main
//---------------------
INT _CRTAPI1
main(int argc, char * argv[])
{
 
    hr = CoInitialize(NULL);
    hr = ADsOpenObject(
        pszSearchBase,
        pszUserName,
        pszPassword,
        dwAuthFlags,
        IID_IDirectorySearch,
        (void **)&pDSSearch
        );
 
    if (dwCurrPref) {
        hr = pDSSearch->SetSearchPreference(
                pSearchPref,
                dwCurrPref
                );
        BAIL_ON_FAILURE(hr);
        }
 
    hr = pDSSearch->ExecuteSearch(
            pszSearchFilter,
            pszAttrNames,
            dwNumberAttributes,
            &hSearchHandle
            );    BAIL_ON_FAILURE(hr);
 
    hr = pDSSearch->GetNextRow(
            hSearchHandle
            );    BAIL_ON_FAILURE(hr);
 
    while (hr != S_ADS_NOMORE_ROWS) {
        nRows++;
 
        if (dwNumberAttributes == -1) {
            hr = pDSSearch->GetNextColumnName(
                    hSearchHandle,
                    &pszColumnName
                    );             BAIL_ON_FAILURE(hr);
    
            while (hr != S_ADS_NOMORE_COLUMNS) {
                hr = pDSSearch->GetColumn(
                        hSearchHandle,
                        pszColumnName,
                        &Column
                        );
    
                if (FAILED(hr)  && hr != E_ADS_COLUMN_NOT_SET) 
                    goto error;
    
                if (SUCCEEDED(hr)) {
                    PrintColumn(&Column, pszColumnName);
                    pDSSearch->FreeColumn(&Column);
                }
 
            if (pszColumnName)
            free(pszColumnName);
                hr = pDSSearch->GetNextColumnName(
                        hSearchHandle,
                        &pszColumnName
                        );    BAIL_ON_FAILURE(hr);
            }
            printf("\n");
        }
        else {
            for (unsigned int i=0; i<dwNumberAttributes; i++) {
                hr = pDSSearch->GetColumn(
                        hSearchHandle,
                        pszAttrNames[i],
                        &Column
                        );
    
                if (hr == E_ADS_COLUMN_NOT_SET) 
                    continue;
    
                BAIL_ON_FAILURE(hr);
    
                PrintColumn(&Column, pszAttrNames[i]);
    
                pDSSearch->FreeColumn(&Column);
            }
        printf("\n");
        }
 
        hr = pDSSearch->GetNextRow(
                hSearchHandle
                );
        BAIL_ON_FAILURE(hr);
    }
 
    wprintf (L"Total Rows: %d\n", nRows);
 
    if (cErr) {
        wprintf (L"%d warning(s) ignored", cErr);
    }
 
    if (hSearchHandle)
        pDSSearch->CloseSearchHandle(hSearchHandle);
 
    FREE_INTERFACE(pDSSearch);
 
    FREE_UNICODE_STRING(pszSearchBase) ;
    FREE_UNICODE_STRING(pszSearchFilter) ;
    FREE_UNICODE_STRING(pszAttrList) ;
 
    CoUninitialize();
 
    return(0) ;
 
error:
//  Error handling 
}