How To Change Address Book Sort Order with SetSearchPath (292590)



The information in this article applies to:

  • Microsoft Extended Messaging Application Programming Interface (MAPI)
  • Microsoft Visual C++, 32-bit Enterprise Edition 6.0
  • Microsoft Visual C++, 32-bit Professional Edition 6.0
  • Microsoft Visual C++, 32-bit Learning Edition 6.0

This article was previously published under Q292590

SUMMARY

This article provides a simple procedure to change the search order of address books within a MAPI profile.

MORE INFORMATION

You can change the search order of address books by using two functions that are provided by the IAddrBook interface: GetSearchPath and SetSearchPath. For example, you can set the search order so that addresses are resolved first against your Personal Address Book, and then against the Global Address List.

To change the search order of your address book, follow these steps:
  1. Initialize MAPI by using the MAPIInitialize function.
  2. Log on with the MAPI profile that you want to modify.
  3. Get a pointer to the address book from the Session pointer.
  4. Use GetSearchPath to get the current search path by using the following code:
    // Get the current search path.
    hRes = lpAddrBook->GetSearchPath(NULL, &pRows);
    					
    This returns an LPSRowSet that contains a row for each address book container that exists in the profile.

  5. Loop through the returned row set to find the address book containers that you want to use in your new search path. In the previous example, you look for the entry for the Personal Address Book (PAB) and the entry for the Global Address List (GAL).
  6. Create a new row set. Set the number of rows and copy the entry IDs for the address book containers that you want into this row set. Note that the new search order is determined by the order in which you place these entry IDs into the new row set. In the previous example, you place the entry ID for the Personal Address Book in the first row, and the entry ID for the Global Address List in the second row.
  7. Set the new search order by calling SetSearchPath with the new row set that you just created by using the following code:
    // Set the search path.
    hRes = lpAddrBook->SetSearchPath(0, pNewRows);
    					
  8. Log off from and uninitialize MAPI.

Full Sample

The following is a sample of code that changes the search order of an address book.
/************************************************************
                                                                        
 SetSearchPath.cpp                                                      
            
 This code pulls the search path for a profile's addressing 
 and replaces it with a specific search order: Personal Address 
 Book, then Global Address List.

 NOTE: This code is intended as a sample ONLY. It does 
 not do any error checking or memory cleanup. 
                                                                        
***********************************************************/ 

#include <mapix.h>
#include <mapiguid.h>
#include <mapiutil.h>
#include <stdio.h>
#include <conio.h>

// Forward declaration of helper function to copy binary data.
STDMETHODIMP CopySBinary(
               LPSBinary psbDest,
               const LPSBinary psbSrc, 
               LPVOID pParent);

void main()
{
   HRESULT       hRes = S_OK;       // Result code returned from MAPI calls.
   LPMAPISESSION lpSession = NULL;  // Pointer to MAPI session.
   LPADRBOOK     lpAddrBook = NULL; // Pointer to Address Book.
   LPSRowSet     pRows = NULL;      // Pointer to row set.
   LPSRowSet     pNewRows = NULL;   // Pointer to new row set.
   SizedSRowSet  (2, NewRows);      // New row set.
   SPropValue    sProps[2];         // Property tag structure.
   ULONG         i = 0;             // Index counter.
   ULONG         j = 0;             // Index counter.
   ULONG         ulGALIndex = 0;    // Index for GAL.
   ULONG         ulPABIndex = 0;    // Index for PAB.
   ULONG         ulPR_ENTRYID = 0;  // Index for entry ID.

   // Initialize MAPI.
   hRes = MAPIInitialize(NULL);

   // Log on to MAPI and allow user to choose profile.
   // Note: This uses the current MAPI session if there is one.
   hRes = MAPILogonEx(NULL, NULL, NULL, MAPI_LOGON_UI, &lpSession);

   // Open the Address Book.
   hRes = lpSession->OpenAddressBook(0, NULL, 0, &lpAddrBook);

   // Get the current search path.
   hRes = lpAddrBook->GetSearchPath(NULL, &pRows);

   // Print out how many rows were in the search path.
   printf("GetSearchPath returned %d rows\n", pRows->cRows);

   // Loop through the rows and find the one for the GAL
   // and the one for the PAB.
   for (i = 0; i < pRows->cRows; i++)
   {
      // Just for informational purposes, 
      // print out how many properties are in the row.
      printf("Row #%d has %d properties\n", i+1, pRows->aRow[i].cValues);

      // Loop through these properties and find the Entry ID property.
      for (j = 0; j < pRows->aRow[i].cValues; j++)
      {
         if (pRows->aRow[i].lpProps[j].ulPropTag == PR_ENTRYID)
         {
            // Save the index for the PR_ENTRYID column.
            ulPR_ENTRYID = j;
         }

         if (pRows->aRow[i].lpProps[j].ulPropTag == PR_DISPLAY_NAME)
         {
            // Print out the display name.
            printf("   Display Name: %s\n",
                   pRows->aRow[i].lpProps[j].Value.lpszA);
            if (0 == strcmp(
                       "Global Address List",
                       (char*)pRows->aRow[i].lpProps[j].Value.lpszA))
            {
               // Save the row index of the GAL entry.
               ulGALIndex = i;
            }

            if (0 == strcmp(
                       "Personal Address Book",
                       (char*)pRows->aRow[i].lpProps[j].Value.lpszA))
            {
               // Save the row index of the PAB entry.
               ulPABIndex = i;
            }
         }
      }
   }

   // Set up the new row set.
   ZeroMemory(&NewRows, 2 * sizeof(SRow));
   pNewRows = (LPSRowSet)&NewRows;

   // Set the number of rows you are going to set (this is important).
   pNewRows->cRows = 2;

   // Set the pointers to the structures.
   pNewRows->aRow[0].lpProps = &sProps[0];
   pNewRows->aRow[1].lpProps = &sProps[1];

   // The count of values is 1. We're only giving it the entry ID.
   pNewRows->aRow[0].cValues = 1;
   // The property we are passing is PR_ENTRY_ID
   pNewRows->aRow[0].lpProps[0].ulPropTag = PR_ENTRYID;
   // Copy the binary data over.
   hRes = CopySBinary(
            &pNewRows->aRow[0].lpProps[0].Value.bin,
            &pRows->aRow[ulPABIndex].lpProps[ulPR_ENTRYID].Value.bin,
            NULL);

   // The count of values is 1. We're only giving it the entry ID.
   pNewRows->aRow[1].cValues = 1;
   // The property we are passing is PR_ENTRY_ID.
   pNewRows->aRow[1].lpProps[0].ulPropTag = PR_ENTRYID;
   // Copy the binary data over.
   hRes = CopySBinary(
            &pNewRows->aRow[1].lpProps[0].Value.bin,
            &pRows->aRow[ulGALIndex].lpProps[ulPR_ENTRYID].Value.bin,
            NULL);

   // Set the search path.
   hRes = lpAddrBook->SetSearchPath(0, pNewRows);

   // Log off from MAPI.
   hRes = lpSession->Logoff(NULL, NULL, 0);

   // Uninitialize MAPI.
   MAPIUninitialize();
}

///////////////////////////////////////////////////////////// 
//    CopySBinary()
// 
//    Parameters
//      
//    Purpose
//      Allocates a new SBinary and copies psbSrc into it
//      
STDMETHODIMP CopySBinary(
               LPSBinary psbDest,
               const LPSBinary psbSrc,
               LPVOID pParent)
{
   HRESULT     hRes = S_OK;
   
   psbDest->cb = psbSrc->cb;
   
   if (psbSrc->cb)
   {
      if (pParent)
         hRes = MAPIAllocateMore(
                  psbSrc->cb, 
                  pParent,
                  (LPVOID*) &psbDest->lpb);
      else
         hRes = MAPIAllocateBuffer(
                  psbSrc->cb, 
                  (LPVOID*) &psbDest->lpb);
      if (!FAILED(hRes))
         CopyMemory(psbDest->lpb,psbSrc->lpb,psbSrc->cb);
   }
   
   return hRes;
}
				

Modification Type:MinorLast Reviewed:8/25/2005
Keywords:kbhowto kbMsg KB292590