Ricerca con l'interfaccia IDirectorySearch
L'interfaccia IDirectorySearch offre un'interfaccia di alto livello e basso sovraccarico per l'esecuzione di query sui dati di una directory o di un catalogo globale. L'interfaccia COM IDirectorySearch può essere usata solo con una tabella virtuale e pertanto non è disponibile per gli ambienti di sviluppo basati su Automazione.
Per eseguire una ricerca
- Eseguire il binding a un oggetto nella directory .
- Chiamare QueryInterface per ottenere il puntatore IDirectorySearch.
- Eseguire la ricerca usando il puntatore IDirectorySearch. Chiamare il metodo IDirectorySearch::ExecuteSearch e passare un filtro di ricerca, i nomi degli attributi richiesti e altri parametri.
Per altre informazioni sulla sintassi del filtro di ricerca, vedere sintassi del filtro di ricerca.
L'esecuzione della query è specifica del provider. Con alcuni provider, l'esecuzione effettiva della query non viene eseguita finché non viene chiamato IDirectorySearch::GetFirstRow o IDirectorySearch::GetNextRow. L'interfaccia IDirectorySearch funziona direttamente con i filtri di ricerca. Non è necessario né il dialetto SQL né il dialetto LDAP.
L'interfaccia IDirectorySearch fornisce metodi per enumerare il set di risultati, riga per riga. Il metodo IDirectorySearch::GetFirstRow recupera la prima riga e IDirectorySearch::GetNextRow sposta la riga successiva dalla riga corrente. Dopo aver raggiunto l'ultima riga, la chiamata a questi metodi restituisce il codice di errore S_ADS_NOMORE_ROWS. Viceversa, IDirectorySearch::GetPreviousRow ti sposta indietro di una riga alla volta. Un valore restituito S_ADS_NOMORE_ROWS indica che è stata raggiunta la prima riga del set di risultati. Questi metodi operano sul set di risultati, residente in memoria, sul client. Pertanto, quando vengono eseguite ricerche in pagine e asincrone e l'opzione _CACHE_RESULTS è disattivata, lo scorrimento indietro può avere conseguenze impreviste.
Quando si trova la riga appropriata, chiamare IDirectorySearch::GetColumn per ottenere elementi di dati, colonna per colonna. Per ogni chiamata si passa il nome della colonna di interesse. L'elemento di dati restituito è un puntatore a una struttura ADS_edizione StandardARCH_COLUMN. GetColumn alloca automaticamente questa struttura, ma è necessario liberarla usando FreeColumn. Chiamare CloseSearchHandle per completare l'operazione di ricerca.
Per eseguire una ricerca nella directory
Eseguire l'associazione a un provider LDAP. Può trattarsi di un controller di dominio o di un provider di catalogo globale.
Recuperare l'interfaccia COM IDirectorySearch con una chiamata a QueryInterface. Questa operazione potrebbe essere stata eseguita nel passaggio 1 durante l'associazione iniziale.
Facoltativamente, chiamare SetSearchPreference per selezionare le opzioni per la gestione dei risultati della ricerca.
Chiamare ExecuteSearch. A seconda delle opzioni impostate in SetSearchPreference , è possibile che l'esecuzione della query venga avviata o meno.
Chiamare GetNextRow per spostare l'indice di riga (interno a IDirectorySearch) alla prima riga.
Leggere i dati dalla riga usando GetColumn, quindi chiamare FreeColumn per rilasciare la memoria allocata da GetColumn.
Ripetere il passaggio 5 finché tutti i dati non vengono recuperati dal risultato della ricerca o fino a quando GetNextRow non restituisce S_ADS_NOMORE_ROWS.
Al termine, chiamare AbandonSearch e CloseSearchHandle.
L'esempio di codice seguente illustra questo scenario. Per avviare l'associazione ad ADSI, chiamare la funzione ADsOpenObject.
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);
In questo modo viene fornito un puntatore all'interfaccia IDirectorySearch .
Ora che è disponibile un'interfaccia COM per un'istanza IDirectoryInterface, chiamare IDirectorySearch::SetSearchPreference.
Compilare una matrice di nomi di attributo per preparare la chiamata alla funzione IDirectorySearch::ExecuteSearch . I nomi degli attributi vengono definiti all'interno dello schema di Active Directory. Per altre informazioni sulla definizione dello schema, vedere Modello di schema ADSI. I nomi degli attributi elencati vengono restituiti, se supportati dall'oggetto, come set di risultati della ricerca.
LPWSTR pszAttr[] = { L"description", L"Name", L"distinguishedname" };
ADS_SEARCH_HANDLE hSearch;
DWORD dwCount = 0;
DWORD dwAttrNameSize = sizeof(pszAttr)/sizeof(LPWSTR);
Chiamare ora la funzione ExecuteSearch . La ricerca non viene eseguita finché non si chiama il metodo GetNextRow.
// Search for all objects with the 'cn' property that start with c.
hr = pDSSearch->ExecuteSearch(L"(cn=c*)",pszAttr ,dwAttrNameSize,&hSearch );
Chiamare GetNextRow per scorrere le righe nel risultato. Ogni riga viene quindi eseguita una query per l'attributo "description". Se l'attributo viene trovato, viene visualizzato.
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();
Per terminare la ricerca, chiamare il metodo AbandonSearch.
Tenere presente che se le dimensioni di una pagina non sono impostate, GetNextRow si blocca fino a quando l'intero set di risultati non viene restituito al client. Se la dimensione della pagina è impostata, GetNextRow si blocca fino a quando non viene restituita la prima pagina (dimensione pagina = numero di righe in una pagina). Se la dimensione della pagina è impostata e la query deve essere ordinata e non si esegue la ricerca in almeno un attributo indicizzato, il valore delle dimensioni della pagina viene ignorato e il server calcola l'intero set di risultati prima di restituire i dati. Questo ha l'effetto del blocco GetNextRow fino al completamento della query.
Nota
Per modificare questa query da una ricerca di directory a una ricerca di catalogo globale, la chiamata ADsOpenObject viene modificata.
// Open a connection with the server.
hr = ADsOpenObject(L"GC://coho.salmon.Fabrikam.com",
szUsername,
szPassword,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);