Finding Information About a User in the Address Book

You can find a user in the address book given a name, part of a name, or other information about the user; retrieve information from that entry; and search for several users at a time.

Design Tasks

  1. Decide whether you're searching the entire address book, one or more containers belonging to a specific message service, or a particular type of container such as a personal or global address list.
  2. Decide what properties are in your search criteria. The only property you can rely on searching with acceptable performance is PR_DISPLAY_NAME. If you want to use another property such as an account name, employee identification number, or organization name, you must experiment with the address book providers you expect to use to verify that searching on those properties is supported and the performance is acceptable.
  3. Understand whether or not the information you are given should identify each user uniquely. If it can be ambiguous — if it can match more than one entry in the address book — then decide whether your program should:

Implementation Tasks

    To search the entire address book by display name for one or more entries
    To open the user's personal address book (PAB)
  1. Retrieve its entry identifier by calling the IAddrBook::GetPAB method.
  2. Call the IAddrBook::OpenEntry method passing the PAB's entry identifier.
    To open a specific container other than the PAB
  1. Open the address book's root container by calling the IAddrBook::OpenEntry method with a NULL entry identifier. The root container is constructed by MAPI and contains the top-level containers of all the address book providers in the profile.
  2. Get the list of top-level containers by calling the IMAPIContainer::GetHierarchyTable method.
  3. If you want a specific container type such as the global address list, restrict the table on PR_DISPLAY_TYPE:
    1. Create a property restriction to match PR_DISPLAY_TYPE with the value for the particular type of container you want to open. For example, to open the global address book, build a property restriction that matches PR_DISPLAY_TYPE with the DT_GLOBAL value.
    2. Create an SPropTagArray including PR_ENTRYID, PR_DISPLAY_TYPE, and any other columns of interest.
    3. Call the HrQueryAllRows function passing your property tag array and restriction. Ordinarily, there will be a single global address list, but the call can return zero, one, or more rows depending on the address book providers in your profile. Be prepared to handle all these cases, not just one row.
    4. Call the IAddrBook::OpenEntry method with the PR_ENTRYID column from the row you want to open the container.
  4. If you want a container belonging to a specific address book provider, restrict the table on PR_AB_PROVIDER_ID:
    1. Create a property restriction to match PR_AB_PROVIDER_ID with the value that represents the target address book provider. You will find this property value in a header file created by the service provider. In the Platform SDK, for instance, the value for the flat file address book sample is SAB_PROVIDER_ID in SMPAB.H.
    2. Create an SPropTagArray structure including PR_ENTRYID, PR_AB_PROVIDER_ID, and any other columns of interest.
    3. Call the HrQueryAllRows function passing your property tag array and restriction. The call will return zero rows if the provider you want is not in the profile. It can return one or more rows depending on the provider's containers are organized, but it will only return the top-level rows.
    4. Call the IAddrBook::OpenEntry method with the PR_ENTRYID column from the row you want to open the container. If the container you want is not a top-level container, you will then have to navigate down through the latter's hierarchy table.
    To search in a specific address book container
  1. Open its contents table by calling its GetContentsTable method.
  2. Use IMAPITable::FindRow, IMAPITable::SortTable, and IMAPITable::Restrict to search the contents table just as you can any MAPI table. See Table Positioning and About Restrictions. These methods are subject to limitations in the provider's implementation, and their speed is unpredictable; careful testing against any providers you expect to use is indispensible. In addition to the normal IMAPITable methods, there are two search techniques specific to address book containers:
  3. After applying any of the restriction methods listed above, call the IMAPITable::QueryRows method to retrieve any rows that match the restriction. You may get back zero, one, or more rows that match.
  4. Retrieve additional information for a single address book entry by calling the IAddrBook::OpenEntry method passing its entry identifier, then call GetProps on the resulting IMAPIProp interface. To retrieve additional properties for multiple address book entries, you can of course call OpenEntry for each one, but it is usually much more efficient to call the IAddrBook::PrepareRecips method. PrepareRecips requires an ADRLIST structure.