HOWTO: Adding a Delegate to the Exchange Server Messaging Service

ID: Q171636


The information in this article applies to:


SUMMARY

The following details the process of adding a Delegate to the Exchange Messaging Service. Delegates are the users that show up in the Additional Mailboxes section on the Advanced tab of the Exchange Server Properties.

This process is the programmatic equivalent to:

  1. Launching the mail program from the control panel.


  2. Selecting a profile that has the Microsoft Exchange Server service installed.


  3. Pulling up the Properties for Microsoft Exchange Server.


  4. Selecting the Advanced tab.


  5. Adding an additional mailbox to open.



MORE INFORMATION

To accomplish this programmatically, you need to do the following:

  1. Start a MAPI Session by calling MAPILogonEx.


  2. Call IMAPISession::AdminServices to get an IMsgServiceAdmin pointer for making changes to message services. The call should look something like the following:
    
    hr = m_lpSession->AdminServices(0, &m_lpServiceAdmin); 


  3. Call IMsgServiceAdmin::GetMsgServiceTable to provide access to the message service table, a listing of the message services in the profile. This call should look something like the following:
    
    hr = m_lpServiceAdmin->GetMsgServiceTable(0, &m_lpMsgSvcTable); 


  4. Now that you have a table of all of the Messaging Services, you need to find the Exchange Server Service. You do this by first calling SetColumns to specify that you only want to see PR_DISPLAY_NAME and PR_SERVICE_UID in the table. Next, you create a restriction that specifies
    
    PR_SERVICE_NAME = "MSEMS" 
    and call FindRow with this restriction. Then, you call QueryRows() to get a pointer to the returned SRowSet. At this point, you should have a single row that contains the Exchange Server PR_DISPLAY_NAME and PR_SERVICE_UID properties. You will need to store the PR_SERVICE_UID because you will need it later. Here is a sample of what this process looks like:
    
          HRESULT      hr = NOERROR;
          static       SRestriction sres;
          SPropValue     spv;
          LPSRowSet   lpRows = NULL;
    
          static SizedSPropTagArray(2, Columns) =   {2, {PR_DISPLAY_NAME,
                                                         PR_SERVICE_UID}};
    
    
          // Restrict the columns to just PR_DISPLAY_NAME & PR_ENTRYID
          hr = m_lpMsgSvcTable->SetColumns((LPSPropTagArray)&Columns, 0);
    
          if (FAILED(hr))
          {
               goto cleanup;
          }
    
          // Set up a restriction for the Exchange Server Service.
          sres.rt = RES_PROPERTY;
          sres.res.resProperty.relop = RELOP_EQ;
          sres.res.resProperty.ulPropTag = PR_SERVICE_NAME;
          sres.res.resProperty.lpProp = &spv;
    
          spv.ulPropTag = PR_SERVICE_NAME;
          spv.Value.lpszA = "MSEMS";
    
          // Call FindRow with that restriction
          hr = m_lpMsgSvcTable->FindRow(&sres, BOOKMARK_BEGINNING, 0);
    
          if (SUCCEEDED(hr))
          {
             // We have found the Service.  Go get it.
             LPSPropValue   lpProp  =   NULL;
    
             hr = m_lpMsgSvcTable->QueryRows(1, 0, &lpRows);
    
             if (FAILED(hr))
             {
                goto cleanup;
             }
    
             // It would not make sense to have more than one row returned in
             // this case.
             if (lpRows->cRows != 1)
             {
                hr = (E_FAIL);
                goto cleanup;
             }
    
             // We know that the 2nd row has the Service UID.
             // See SetColumns() (above).
             lpProp = &lpRows->aRow[0].lpProps[1];
    
             if (lpProp->ulPropTag != PR_SERVICE_UID)
             {
                hr = (E_FAIL);
                goto cleanup;
             }
    
             // Copy the UID into our member.
             memcpy(&m_ServiceUID.ab, lpProp->Value.bin.lpb,
                    lpProp->Value.bin.cb);
    
          }
          cleanup:
             return hr; 


  5. Using the Service UID obtained from step 4, call IMsgServiceAdmin::AdminProviders to obtain a pointer that will provide access to the Exchange Server Service administration object. This looks like the following:
    
    hr = m_lpServiceAdmin->AdminProviders(&m_ServiceUID,0,
                                                &m_lpProviderAdmin); 


  6. Now call the IProviderAdmin::CreateProvider method to add the "EMSDelegate" provider. You also need to specify an array of properties that you need to set for the newly added provider. In this case, you will need to add the following properties:
    PR_PROFILE_TYPE
    PR_DISPLAY_NAME
    PR_PROFILE_MAILBOX
    PR_PROFILE_SERVER
    PR_PROFILE_SERVER_DN


This process should look something like:

   {


      HRESULT      hr;


      UINT      cprops = 0;  // incremented by the MACRO SetLPSZ
      SPropValue   propT[5];       // Number of props
      const TCHAR   szSection[] = TEXT("EMSDelegate");


      // TODO: Change the hard-coded values that are used below to see
      // this work.
      SetLPUL(propT, cprops, PR_PROFILE_TYPE, PROFILE_DELEGATE);
      SetLPSZ(propT, cprops, PR_DISPLAY_NAME, "Mailbox - My Name");
      SetLPSZ(propT, cprops, PR_PROFILE_MAILBOX,
              "/o=MSGTEAM/ou=MSGSite1/cn=Recipients/cn=email");
      SetLPSZ(propT, cprops, PR_PROFILE_SERVER, "MYSERVER");
      SetLPSZ(propT, cprops, PR_PROFILE_SERVER_DN,
        "/o=MSGTEAM/ou=MSGSite1/cn=Configuration/cn=Servers/cn=MYSERVER");


      // Create the provider section
      hr = m_lpProviderAdmin->CreateProvider((LPTSTR)szSection, 5, propT,
                                             0, 0, &m_ServiceUID);

      return hr;

   } 

Additional query words: EMSDelegate Mailboxes


Keywords          : kbAPI kbEDK kbMsg kbEDK500 kbEDK550 kbMAPI100 
Version           : WINDOWS:1.0,5.0; winnt:4.0,5.0
Platform          : WINDOWS winnt 
Issue type        : kbhowto 

Last Reviewed: April 1, 1999