HOWTO: Modify Recipients of Exchange Global Address List

ID: Q197191

The information in this article applies to:

SUMMARY

This article describes the steps necessary to open the Exchange Global Address List (GAL) for modification. It also describes how to modify a property of a given recipient in an Exchange Global Address List.

MORE INFORMATION

The following steps are necessary for modifying a recipient in the GAL:

1. Open a MAPI session.

2. Find the entry id (PR_ENTRYID) of the Address Entry to modify.

3. Call OpenAddressBook from session object.

4. Open the root container of the Address book by calling

   IAddrbook::OpenEntry and passing NULL and 0 as the first two parameters.

5. Call IMAPIContainer::GetHierarchyTable to open the Hierarchy table of
   the root address book container.

6. Call HrQueryAllRows using a restriction for the only row that contains
   DT_GLOBAL as the PR_DISPLAY_TYPE property.

7. Call IAddrbook::OpenEntry using the PR_ENTRYID from the row
   returned from HrQueryAllRows to get back an IMAPIContainer object.

8. Call IMAPIContainer::OpenEntry using the entry id of the recipient you
   want to modify.

Now that you have the recipient wrapped in an IMAPIProp interface, you can make any modifications to it as long as you have the appropriate permissions.

The following code sample illustrates the above steps.

The following .lib files must be statically linked into your project for this code to compile and link correctly:

Sample Code

    #define USES_IID_IABContainer
    #define USES_IID_IMailUser
    #define USES_IID_IAddrBook
    #define INITGUID

    #include <mapix.h>
    #include <mapiguid.h>
    #include <mapidefs.h>
    #include <mapiutil.h>

    HWND g_hWnd = NULL;  // Set g_hWnd to a window handle in your app.
                         // Specifically the window that will be the parent
                         // of the Address Book dialog.

    HRESULT Logon ( LPMAPISESSION *pSession )
    {
       HRESULT hRes = S_OK;
       LPMAPISESSION pLocalSession = NULL;
       ULONG ulFlags = 0L;

       if ( FAILED ( hRes = MAPIInitialize ( NULL ) ) )
          goto Quit;

       ulFlags = MAPI_EXTENDED |
                 MAPI_LOGON_UI |
                 MAPI_EXPLICIT_PROFILE |
                 MAPI_NEW_SESSION;

       if ( FAILED ( hRes = MAPILogonEx ( 0l,
                                          NULL,
                                          NULL,
                                          ulFlags,
                                          &pLocalSession ) ) )
          goto Quit;

       *pSession = pLocalSession;

    Quit:

    // TODO: Add code to release and free all memory allocated by MAPI.
       return hRes;
    }

    HRESULT ModifyGALRecipient( LPMAPISESSION pSession,
                                ULONG cbRecipEID,
                                LPBYTE lpbRecip )
    {

       HRESULT hRes = S_OK;
       ULONG ulFlags = 0L;
       ULONG ulObjType = 0L;
       ULONG cbEID = 0L;
       LPADRBOOK pAddrBook = NULL;
       LPMAPICONTAINER pGAL = NULL;
       LPMAPICONTAINER pIABRoot = NULL;
       LPMAPITABLE pHTable = NULL;
       LPMAILUSER pRecipient = NULL;
       LPSRowSet pRows = NULL;
       SRestriction sres;
       SPropValue spv;
       LPBYTE lpb = NULL;

       ZeroMemory ( (LPVOID) &sres, sizeof (SRestriction ) );

       // - Call OpenAddressBook from session object

       ulFlags = AB_NO_DIALOG;

       if ( FAILED ( hRes = pSession -> OpenAddressBook ( 0L,
                                                          NULL,
                                                          ulFlags,
                                                          &pAddrBook ) ) )
       goto Quit;
       else
       ulFlags = 0L;

       // - Open the root container of the Address book by calling
       //   IAddrbook::OpenEntry and passing NULL and 0 as the first 2
       //   params.

       ulFlags = MAPI_MODIFY;

       if ( FAILED ( hRes = pAddrBook -> OpenEntry ( NULL,
                                               0L,
                                               &IID_IABContainer,
                                               ulFlags,
                                               &ulObjType,
                                               (LPUNKNOWN *) &pIABRoot ) ))
          goto Quit;
       else
          ulFlags = 0L;

       // Make sure we have a Container object
       if ( MAPI_ABCONT == ulObjType )
       {
          // - Call IMAPIContainer::GetHierarchyTable to open the Hierarchy
          //   table of the root address book container.
          if ( FAILED ( hRes = pIABRoot -> GetHierarchyTable ( ulFlags,
                                                            &pHTable ) ) )
             goto Quit;
          else
             ulFlags = 0l;

          // - Call HrQueryAllRows using a restriction for the only row
          //   that contains DT_GLOBAL as the PR_DISPLAY_TYPE property.

          SizedSPropTagArray ( 2, ptaga ) = {2,PR_DISPLAY_TYPE,PR_ENTRYID};

          sres.rt                          = RES_PROPERTY;
          sres.res.resProperty.relop       = RELOP_EQ;
          sres.res.resProperty.ulPropTag   = PR_DISPLAY_TYPE;
          sres.res.resProperty.lpProp      = &spv;

          spv.ulPropTag = PR_DISPLAY_TYPE;
          spv.Value.l   = DT_GLOBAL;

          if ( FAILED ( hRes = HrQueryAllRows ( pHTable,
                                                (LPSPropTagArray) &ptaga,
                                                &sres,
                                                NULL,
                                                0L,
                                                &pRows ) ) )
             goto Quit;
          else
             ulFlags = 0L;

          // - Call IAddrbook::OpenEntry using the entry id (PR_ENTRYID)
          // from the row returned from HrQueryAllRows to get back an
          // IMAPIContainer object.

          ulFlags = MAPI_MODIFY;
          cbEID = pRows->aRow->lpProps[1].Value.bin.cb;
          lpb = pRows->aRow->lpProps[1].Value.bin.lpb;

          if ( FAILED ( hRes = pAddrBook -> OpenEntry ( cbEID,
                                                        (LPENTRYID)lpb,
                                                         NULL,
                                                         ulFlags,
                                                         &ulObjType,
                                                         (LPUNKNOWN *)&pGAL
                                                         ) ) )
             goto Quit;
          else
             ulFlags = 0L;

          // - Call IMAPIContainer::OpenEntry using the entry id of the
          //   recipient you want to modify.

          ulFlags = MAPI_MODIFY;
          ulObjType = 0;

          if ( FAILED ( hRes = pGAL -> OpenEntry ( cbRecipEID,
                                             (LPENTRYID)lpbRecip,
                                             NULL,
                                             ulFlags,
                                             &ulObjType,
                                             (LPUNKNOWN *)&pRecipient ) ) )
             goto Quit;

           // TODO: Add code here to set properties of recipient in GAL
        }
        else
           goto Quit;

    Quit:

    // TODO: Add code to release and free all memory allocated by MAPI

       return hRes;
    }

    HRESULT ModifyRecipient ( )
    {
       HRESULT hRes = S_OK;
       ULONG ulFlags = 0L;
       LPMAPISESSION pSession = NULL;
       LPADRBOOK pAddrBook = NULL;
       ADRPARM AdrParm;
       LPADRLIST pAddrList = NULL;
       ULONG cbEID = 0L;
       LPBYTE lpb = NULL;

       ZeroMemory ( (LPVOID) &AdrParm, sizeof ( ADRPARM ) );

       // set up the adrparm struct for Address
       AdrParm.ulFlags             = DIALOG_MODAL | AB_RESOLVE;
       AdrParm.cDestFields         = 1;
       AdrParm.nDestFieldFocus      = 0;
       AdrParm.lpszNewEntryTitle  = "Whatever";
       AdrParm.lpszDestWellsTitle = "";

       AdrParm.lpszCaption = "Browse Address Book";

       // - Open a MAPI session and pick an Address Entry to modify

       // Logon to MAPI session
       if ( FAILED ( hRes = Logon ( &pSession ) ) )
          goto Quit;

       // Pick a recipient

       if ( FAILED ( hRes = pSession -> OpenAddressBook ( 0L,
                                                          NULL,
                                                          ulFlags,
                                                          &pAddrBook ) ) )
          goto Quit;

       if ( FAILED ( hRes = pAddrBook -> Address ( (ULONG *) &g_hWnd,
                                                   &AdrParm,
                                                   &pAddrList) ) )
          goto Quit;

       cbEID = pAddrList->aEntries[0].rgPropVals[2].Value.bin.cb;
       lpb = pAddrList->aEntries[0].rgPropVals[2].Value.bin.lpb;

       // Modify the recipient

       if ( FAILED ( hRes = ModifyGALRecipient ( pSession, cbEID, lpb ) ) )
          goto Quit;

    Quit:
    // TODO: Add code to release and free all memory allocated by MAPI.
       return hRes;
    }

Additional query words: kbMAPI kbMsg kbXchge kbXchge400 kbXchge500 kbXchge550
Keywords          : kbcode kbXchge550 kbMAPI kbMsg 
Version           : WINDOWS:1.0; WINNT:4.0,5.0,5.5
Platform          : WINDOWS winnt
Issue type        : kbhowto

Last Reviewed: December 12, 1998