Suchen mit der IDirectorySearch-Schnittstelle

Die IDirectorySearch-Schnittstelle bietet eine Schnittstelle mit hohem und geringem Aufwand zum Abfragen von Daten eines Verzeichnisses oder eines globalen Katalogs. Die IDirectorySearch-COM-Schnittstelle kann nur mit einer vtable verwendet werden und steht daher nicht für automatisierungsbasierte Entwicklungsumgebungen zur Verfügung.

So führen Sie eine Suche aus

  1. Binden Sie an ein Objekt im Verzeichnis.
  2. Rufen Sie QueryInterface auf, um den IDirectorySearch-Zeiger abzurufen.
  3. Führen Sie die Suche mit dem IDirectorySearch-Zeiger aus. Rufen Sie die IDirectorySearch::ExecuteSearch-Methode auf, und übergeben Sie einen Suchfilter, die angeforderten Attributnamen und andere Parameter.

Weitere Informationen zur Suchfiltersyntax finden Sie unter Suchfiltersyntax.

Die Abfrageausführung ist anbieterspezifisch. Bei einigen Anbietern erfolgt die tatsächliche Abfrageausführung erst, wenn IDirectorySearch::GetFirstRow oder IDirectorySearch::GetNextRow aufgerufen wird. Die IDirectorySearch-Schnittstelle funktioniert direkt mit Suchfiltern. Weder der SQL-Dialekt noch der LDAP-Dialekt sind erforderlich.

Die IDirectorySearch-Schnittstelle bietet Methoden zum Auflisten des Resultsets Zeile für Zeile. Die IDirectorySearch::GetFirstRow-Methode ruft die erste Zeile ab, und IDirectorySearch::GetNextRow verschiebt Sie zur nächsten Zeile aus der aktuellen Zeile. Wenn Sie die letzte Zeile erreicht haben, gibt das Aufrufen dieser Methoden den S_ADS_NOMORE_ROWS Fehlercode zurück. Umgekehrt verschiebt IDirectorySearch::GetPreviousRow Sie jeweils um eine Zeile zurück. Ein S_ADS_NOMORE_ROWS Rückgabewert gibt an, dass Sie die erste Zeile des Resultsets erreicht haben. Diese Methoden arbeiten mit dem Resultset, das sich im Arbeitsspeicher befindet, auf dem Client. Wenn also seitenseitige und asynchrone Suchvorgänge ausgeführt werden und die Option _CACHE_RESULTS deaktiviert ist, kann rückwärts scrollen unerwartete Folgen haben.

Wenn Sie die entsprechende Zeile gefunden haben, rufen Sie IDirectorySearch::GetColumn auf, um Datenelemente Spalte für Spalte abzurufen. Für jeden Aufruf übergeben Sie den Namen der spalte von Interesse. Das zurückgegebene Datenelement ist ein Zeiger auf eine ADS_SEARCH_COLUMN-Struktur . GetColumn weist diese Struktur für Sie zu, aber Sie müssen sie mithilfe von FreeColumn freigeben. Rufen Sie CloseSearchHandle auf, um den Suchvorgang abzuschließen.

So führen Sie eine Verzeichnissuche aus

  1. Binden Sie an einen LDAP-Anbieter. Es kann sich um einen Domänencontroller oder einen globalen Kataloganbieter handeln.

  2. Rufen Sie die IDirectorySearch-COM-Schnittstelle mit einem Aufruf von QueryInterface ab. Dieser Vorgang wurde möglicherweise während der anfänglichen Bindung in Schritt 1 ausgeführt.

    Rufen Sie optional SetSearchPreference auf, um Optionen für die Behandlung der Suchergebnisse auszuwählen.

  3. Rufen Sie ExecuteSearch auf. Abhängig von den in SetSearchPreference festgelegten Optionen kann die Abfrageausführung beginnen oder nicht.

  4. Rufen Sie GetNextRow auf, um den Zeilenindex (intern in IDirectorySearch) in die erste Zeile zu verschieben.

  5. Lesen Sie die Daten aus der Zeile mit GetColumn, und rufen Sie dann FreeColumn auf, um den von GetColumn zugewiesenen Arbeitsspeicher freizugeben.

  6. Wiederholen Sie Schritt 5, bis alle Daten aus dem Suchergebnis abgerufen werden, oder bis GetNextRow S_ADS_NOMORE_ROWS zurückgibt.

  7. Rufen Sie AbandonSearch und CloseSearchHandle auf, wenn sie abgeschlossen sind.

Das folgende Codebeispiel zeigt dieses Szenario. Um mit der Bindung an ADSI zu beginnen, rufen Sie die Funktion ADsOpenObject auf .

HRESULT hr = S_OK; // COM result variable
ADS_SEARCH_COLUMN col;  // COL for iterations
LPWSTR szUsername = NULL; // user name
LPWSTR szPassword = NULL; // password
 
// Interface Pointers.
IDirectorySearch     *pDSSearch    =NULL;
 
// Initialize COM.
CoInitialize(0);

// Add code to securely retrieve the user name and password or
// leave both as NULL to use the default security context.
 
// Open a connection with server.
hr = ADsOpenObject(L"LDAP://coho.salmon.Fabrikam.com", 
szUsername,
szPassword,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);

Dadurch wird ein Zeiger auf die IDirectorySearch-Schnittstelle bereitgestellt.

Nachdem nun eine COM-Schnittstelle für eine IDirectoryInterface-instance vorhanden ist, rufen Sie IDirectorySearch::SetSearchPreference auf.

Erstellen Sie ein Array von Attributnamen, um den Aufruf der Funktion IDirectorySearch::ExecuteSearch vorzubereiten. Die Attributnamen werden innerhalb des Schemas von Active Directory definiert. Weitere Informationen zur Schemadefinition finden Sie unter ADSI-Schemamodell. Die aufgeführten Attributnamen werden zurückgegeben, sofern vom Objekt unterstützt, als Resultset der Suche.

LPWSTR pszAttr[] = { L"description", L"Name", L"distinguishedname" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount = 0;
DWORD dwAttrNameSize = sizeof(pszAttr)/sizeof(LPWSTR);

Rufen Sie nun die ExecuteSearch-Funktion auf. Die Suche wird erst ausgeführt, wenn Sie die GetNextRow-Methode aufrufen.

// Search for all objects with the 'cn' property that start with c.
hr = pDSSearch->ExecuteSearch(L"(cn=c*)",pszAttr ,dwAttrNameSize,&hSearch );

Rufen Sie GetNextRow auf, um Zeilen im Ergebnis zu durchlaufen. Jede Zeile wird dann nach dem Attribut "description" abgefragt. Wenn das Attribut gefunden wird, wird es angezeigt.

LPWSTR pszColumn;
    while( pDSSearch->GetNextRow( hSearch) != S_ADS_NOMORE_ROWS )
    {
        // Get the property.
        hr = pDSSearch->GetColumn( hSearch, L"description", &col );
 
        // If this object supports this attribute, display it.
        if ( SUCCEEDED(hr) )
        { 
           if (col.dwADsType == ADSTYPE_CASE_IGNORE_STRING)
              wprintf(L"The description property:%s\r\n", col.pADsValues->CaseIgnoreString); 
           pDSSearch->FreeColumn( &col );
        }
        else
            puts("description property NOT available");
        puts("------------------------------------------------");
        dwCount++;
    }
    pDSSearch->CloseSearchHandle(hSearch);
    pDSSearch->Release();

Um die Suche zu beenden, rufen Sie die AbandonSearch-Methode auf .

Beachten Sie, dass GetNextRow blockiert wird, wenn eine Seitengröße nicht festgelegt ist, bis das gesamte Resultset an den Client zurückgegeben wird. Wenn die Seitengröße festgelegt ist, blockiert GetNextRow , bis die erste Seite (Seitengröße = Anzahl der Zeilen auf einer Seite) zurückgegeben wird. Wenn die Seitengröße festgelegt ist und die Abfrage sortiert werden soll und Sie nicht nach mindestens einem indizierten Attribut suchen, wird der Wert der Seitengröße ignoriert, und der Server berechnet das gesamte Resultset, bevor die Daten zurückgegeben werden. Dies hat zur Folge, dass GetNextRow blockiert wird, bis die Abfrage abgeschlossen ist.

Hinweis

Um diese Abfrage von einer Verzeichnissuche in eine globale Katalogsuche zu ändern, wird der ADsOpenObject-Aufruf geändert.

 

// Open a connection with the server.
hr = ADsOpenObject(L"GC://coho.salmon.Fabrikam.com", 
szUsername, 
szPassword, 
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);