Ricerca con l'interfaccia IDirectorySearch
L'interfaccia IDirectorySearch fornisce 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 IDirectorySearch COM può essere usata solo con una tabella virtuale e pertanto non è disponibile per gli ambienti di sviluppo basati su automazione.
Per eseguire una ricerca
- Associare 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 fino a quando 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'interfacciaIDirectorySearchfornisce metodi per enumerare il set di risultati, riga per riga. Il metodo IDirectorySearch::GetFirstRow recupera la prima riga e IDirectorySearch::GetNextRow passa alla 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 sposta indietro 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 sull'insieme di risultati, residente in memoria, sul lato 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_SEARCH_COLUMN. GetColumn alloca automaticamente questa struttura, ma è necessario liberarla usando FreeColumn. Chiamare CloseSearchHandle per completare l'operazione di ricerca.
Per eseguire una ricerca di directory
Collegarsi 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 può 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 questo potrebbe, o meno, iniziare l'esecuzione della query.
Chiamare GetNextRow per spostare l'indice di riga (interno a IDirectorySearch) alla prima riga.
Leggi i dati dalla riga usando GetColumn, quindi chiama 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 restituisce S_ADS_NOMORE_ROWS.
Chiamare AbandonSearch e CloseSearchHandle al termine.
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'interfacciaIDirectorySearch.
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);
Ora, chiamare 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 iterare sulle righe del risultato. Ogni riga viene quindi interrogata per ottenere 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 della pagina non sono impostate, GetNextRow blocca fino a quando l'intero set di risultati non viene restituito al client. Se la dimensione della pagina è impostata, getNextRow 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 di GetNextRow bloccare fino al completamento della query.
Nota
Per modificare questa query da una ricerca di directory a una ricerca di catalogo globale, viene modificata la chiamataADsOpenObject.
// Open a connection with the server.
hr = ADsOpenObject(L"GC://coho.salmon.Fabrikam.com",
szUsername,
szPassword,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void **)&pDSSearch);