Share via


Buscar con la interfaz IDirectorySearch

La interfaz IDirectorySearch proporciona una interfaz de alto nivel y de baja sobrecarga para consultar datos de un directorio o un catálogo global. La interfaz COM IDirectorySearch solo se puede usar con una vtable y, por tanto, no está disponible para entornos de desarrollo basados en Automatización.

Para realizar una búsqueda

  1. Enlazar a un objeto en el directorio .
  2. Llame a QueryInterface para obtener el puntero IDirectorySearch .
  3. Ejecute la búsqueda mediante el puntero IDirectorySearch . Llame al método IDirectorySearch::ExecuteSearch y pase un filtro de búsqueda, los nombres de atributo solicitados y otros parámetros.

Para obtener más información sobre la sintaxis del filtro de búsqueda, vea Sintaxis de filtro de búsqueda.

La ejecución de consultas es específica del proveedor. Con algunos proveedores, la ejecución real de la consulta no se produce hasta que se llama a IDirectorySearch::GetFirstRow o IDirectorySearch::GetNextRow . La interfaz IDirectorySearch funciona directamente con filtros de búsqueda. Ni el dialecto SQL ni el dialecto LDAP son necesarios.

La interfaz IDirectorySearch proporciona métodos para enumerar el conjunto de resultados, fila por fila. El método IDirectorySearch::GetFirstRow recupera la primera fila y IDirectorySearch::GetNextRow lo mueve a la siguiente fila de la fila actual. Cuando haya llegado a la última fila, al llamar a estos métodos se devuelve el código de error S_ADS_NOMORE_ROWS. Por el contrario, IDirectorySearch::GetPreviousRow le mueve una fila a la vez. Un valor devuelto S_ADS_NOMORE_ROWS indica que ha alcanzado la primera fila del conjunto de resultados. Estos métodos funcionan en el conjunto de resultados, residente en memoria, en el cliente. Por lo tanto, cuando se realizan búsquedas paginadas y asincrónicas y la opción _CACHE_RESULTS está desactivada, el desplazamiento hacia atrás puede tener consecuencias inesperadas.

Cuando haya localizado la fila adecuada, llame a IDirectorySearch::GetColumn para obtener elementos de datos, columna por columna. Para cada llamada, se pasa el nombre de la columna de interés. El elemento de datos devuelto es un puntero a una estructura ADS_SEARCH_COLUMN . GetColumn asigna esta estructura por usted, pero debe liberarla mediante FreeColumn. Llame a CloseSearchHandle para completar la operación de búsqueda.

Para realizar una búsqueda de directorios

  1. Enlace a un proveedor LDAP. Puede ser un controlador de dominio o un proveedor de catálogo global.

  2. Recupere la interfaz COM IDirectorySearch con una llamada a QueryInterface; Esta operación puede haberse realizado en el paso 1 durante el enlace inicial.

    Opcionalmente, llame a SetSearchPreference para seleccionar opciones para controlar los resultados de la búsqueda.

  3. Llame a ExecuteSearch. En función de las opciones establecidas en SetSearchPreference , es posible que, o no, comience la ejecución de la consulta.

  4. Llame a GetNextRow para mover el índice de fila (interno a IDirectorySearch) a la primera fila.

  5. Lea los datos de la fila mediante GetColumn y, a continuación, llame a FreeColumn para liberar la memoria asignada por GetColumn.

  6. Repita el paso 5 hasta que se recuperen todos los datos del resultado de búsqueda o hasta que GetNextRow devuelva S_ADS_NOMORE_ROWS.

  7. Llame a AbandonSearch y CloseSearchHandle cuando haya finalizado.

En el ejemplo de código siguiente se muestra este escenario. Para iniciar el enlace a ADSI, llame a la función 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);

Esto proporciona un puntero a la interfaz IDirectorySearch .

Ahora que hay una interfaz COM para una instancia de IDirectoryInterface, llame a IDirectorySearch::SetSearchPreference.

Cree una matriz de nombres de atributo para prepararse para llamar a la función IDirectorySearch::ExecuteSearch . Los nombres de atributo se definen dentro del esquema de Active Directory. Para obtener más información sobre la definición de esquema, vea Modelo de esquema ADSI. Los nombres de atributo enumerados se devuelven, si el objeto lo admite, como conjunto de resultados de la búsqueda.

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

Ahora, llame a la función ExecuteSearch . La búsqueda no se ejecuta hasta que se llama al método GetNextRow .

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

Llame a GetNextRow para iterar filas en el resultado. A continuación, se consulta cada fila para el atributo "description". Si se encuentra el atributo , se muestra.

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 finalizar la búsqueda, llame al método AbandonSearch .

Tenga en cuenta que si no se establece un tamaño de página, GetNextRow se bloquea hasta que se devuelve todo el conjunto de resultados al cliente. Si se establece el tamaño de página, GetNextRow se bloquea hasta que se devuelva la primera página (tamaño de página = número de filas de una página). Si se establece el tamaño de página y la consulta se va a ordenar y no busca al menos un atributo indizado, se omite el valor de tamaño de página y el servidor calcula todo el conjunto de resultados antes de devolver los datos. Esto tiene el efecto de bloquear GetNextRow hasta que se complete la consulta.

Nota

Para cambiar esta consulta de una búsqueda de directorio a una búsqueda de catálogo global, se cambia la llamada ADsOpenObject .

 

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