Compartilhar via


Pesquisando com a interface IDirectorySearch

A interface IDirectorySearch fornece uma interface de alto nível e baixa sobrecarga para consultar dados de um diretório ou catálogo global. A interface COM IDirectorySearch pode ser usada apenas com um vtable e, portanto, não está disponível para ambientes de desenvolvimento baseados em automação.

Para realizar uma pesquisa

  1. Vincular a um objeto no diretório.
  2. Chame QueryInterface para obter o ponteiro IDirectorySearch.
  3. Execute a pesquisa usando o ponteiro IDirectorySearch. Chame o método IDirectorySearch::ExecuteSearch e passe um filtro de pesquisa, os nomes de atributos solicitados e outros parâmetros.

Para obter mais informações sobre a sintaxe do filtro de pesquisa, consulte Sintaxe do filtro de pesquisa.

A execução da consulta é específica do provedor. Com alguns provedores, a execução de consulta real não ocorre até IDirectorySearch::GetFirstRow ou IDirectorySearch::GetNextRow é chamado. A interface IDirectorySearch funciona diretamente com filtros de pesquisa. Nem o dialeto SQL nem o dialeto LDAP são necessários.

A interface IDirectorySearch fornece métodos para enumerar o conjunto de resultados, linha por linha. O método IDirectorySearch::GetFirstRow recupera a primeira linha e IDirectorySearch::GetNextRow move você para a próxima linha da linha atual. Quando você tiver atingido a última linha, chamar esses métodos retorna o código de erro S_ADS_NOMORE_ROWS. Por outro lado, IDirectorySearch::GetPreviousRow move você para trás uma linha de cada vez. Um valor de retorno S_ADS_NOMORE_ROWS indica que você atingiu a primeira linha do conjunto de resultados. Esses métodos operam no conjunto de resultados, residente na memória, no cliente. Assim, quando pesquisas paginadas e assíncronas são realizadas e a opção _CACHE_RESULTS é desativada, a rolagem para trás pode ter consequências inesperadas.

Quando você tiver localizado a linha apropriada, chame IDirectorySearch::GetColumn para obter itens de dados, coluna por coluna. Para cada chamada, você passa o nome da coluna de interesse. O item de dados retornado é um ponteiro para uma estrutura ADS_SEARCH_COLUMN. GetColumn aloca essa estrutura para você, mas você deve liberá-la usando FreeColumn. Chame CloseSearchHandle para concluir a operação de pesquisa.

Para executar uma pesquisa de diretório

  1. Vincular a um provedor LDAP. Pode ser um controlador de domínio ou um provedor de catálogo global.

  2. Recupere a interface COM IDirectorySearch com uma chamada para QueryInterface, essa operação pode ter sido feita na Etapa 1 durante a associação inicial.

    Opcionalmente, chame SetSearchPreference para selecionar opções para manipular os resultados da sua pesquisa.

  3. Chame ExecuteSearch. Dependendo das opções definidas em SetSearchPreference , isso pode, ou não, iniciar a execução da consulta.

  4. Chame GetNextRow para mover o índice de linha (interno para IDirectorySearch) para a primeira linha.

  5. Leia os dados da linha usando GetColumn e chame FreeColumn para liberar a memória alocada por GetColumn.

  6. Repita a Etapa 5 até que todos os dados sejam recuperados do resultado da pesquisa ou até que GetNextRow retorne S_ADS_NOMORE_ROWS.

  7. Chame AbandonSearch e CloseSearchHandle quando concluir.

O exemplo de código a seguir mostra esse cenário. Para iniciar a vinculação ao ADSI, chame a função 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);

Isso fornece um ponteiro para a interface IDirectorySearch.

Agora que há uma interface COM para uma instância IDirectoryInterface, chame IDirectorySearch::SetSearchPreference.

Crie uma matriz de nomes de atributos para se preparar para chamar a função IDirectorySearch::ExecuteSearch . Os nomes de atributo são definidos dentro do esquema do Active Directory. Para obter mais informações sobre a definição de esquema, consulte Modelo de esquema ADSI. Os nomes de atributos listados são retornados, se suportados pelo objeto, como o conjunto de resultados da pesquisa.

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

Agora, chame a função ExecuteSearch . A pesquisa não é executada até que você chame o método GetNextRow.

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

Chame GetNextRow para iterar linhas no resultado. Cada linha é então consultada para o atributo "description". Se o atributo for encontrado, ele será exibido.

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();

Para encerrar a pesquisa, chame o método AbandonSearch .

Lembre-se de que, se um tamanho de página não estiver definido, GetNextRow bloqueará até que todo o conjunto de resultados seja retornado ao cliente. Se o tamanho da página estiver definido, GetNextRow bloqueará até que a primeira página (tamanho da página = número de linhas em uma página) seja retornada. Se o tamanho da página estiver definido e a consulta for classificada e você não estiver pesquisando em pelo menos um atributo indexado, o valor do tamanho da página será ignorado e o servidor calculará todo o conjunto de resultados antes de retornar os dados. Isso tem o efeito de bloqueio GetNextRow até que a consulta seja concluída.

Observação

Para alterar essa consulta de uma pesquisa de diretório para uma pesquisa de catálogo global, a chamada ADsOpenObject é alterada.

 

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