HOWTO: Modifying Settings of MS Exchange Transport Provider

Last reviewed: December 2, 1997
Article ID: Q170225
The information in this article applies to:
  • Extended Messaging Application Programming Interface (MAPI), version 1.0

SUMMARY

This article explains how to programmatically change the values of the Microsoft Exchange Transport Provider and review those changes after they have been committed.

MORE INFORMATION

Changing the settings for the Microsoft Exchange Server service provider can be broken into two phases: creating and configuring a profile and modifying some or all of the settings of the Microsoft Exchange Server service provider.

Creating and Configuring a Profile

First follow the steps listed below to create and configure a profile. (These steps can be found on the Microsoft Developer Network (MSDN) in the article "Creating and Configuring a Profile.")

  1. Read the header file for each service. Understand what properties you need to configure and what values you will use.

  2. Call the MAPIAdminProfiles function to obtain an IProfAdmin interface. Call the CreateProfile method to create your profile, and the AdminServices method to obtain an IMsgServiceAdmin interface.

  3. Add message services to the profile. Refer to the previous guidelines for the order you should use. For each service, use the IMsgServiceAdmin interface to do the following :

        a. Call the CreateMsgService method.
        b. Obtain the MAPIUID structure of the service you just created:
           1. Call the GetMsgServiceTable method to obtain an IMAPITable
    
              interface.
           2. Call the HrQueryAllRows function to retrieve all rows from the
              table.
           3. Get the PR_SERVICE_UID column from the last row. This is the
              MAPIUID structure of the last service added. You may wish to
              check with an assertion that other properties of the service are
              as you expect.
        c. Call the ConfigureMsgService method, passing the MAPIUID structure
           of the service you just created and a property value array with its
           configuration properties.
           - If you must make configuration calls that require an IMAPISession
           interface, such as IMAPISession::SetDefaultStore, IAddrBook::SetPAB,
           or IAddrBook::SetABSearchPath, pass the MAPI_NO_MAIL flag to the
           MAPILogonEx function.
           - To make your profile temporary, call the IProfAdmin::DeleteProfile
           method immediately after logging on to the profile. It will be
           deleted after you log off, and will not be visible to other
           applications in the meantime.
    
    

Modifying Settings of Service Provider

The steps above helped you to create and configure a generic profile. In the second phase you will modify some or all of the settings of the Microsoft Exchange Server service provider. (These steps can also be found on MSDN in the article "Creating a Profile through MAPI.")

When you reach the step in which the MAPI IMsgServiceAdmin::ConfigureMsgService method is called, specify the following information in the lpProps parameter. This parameter is a pointer to an SPropValue structure containing the values of the properties to display to the user in the property sheet.

  • Home Server of the application's mailbox. Use the property tag PR_PROFILE_HOME_SERVER. This property is defined in EDKMDB.H.
  • Name of the application's mailbox, using the property tag PR_PROFILE_MAILBOX. This property is defined in EDKMDB.H.

Summary

Following the steps above you should have code that is comparable to the pseudo-code below.

(NOTE: The following pseudo-code uses PR_UNRESOLVE_XXX properties to configure the profile. Using the properties mentioned above generally fail to configure the service as expected.)

  • Get IProfAdmin interface pointer with MAPIAdminProfiles()
  • Create a new profile with IProfAdmin::CreateProfile()
  • Get IMsgServiceAdmin interface pointer with IProfAdmin::AdminServices()
  • Add a message service to the newly created profile with IMsgServiceAdmin::CreateMsgService()
  • Get the message service table of the Message service with IMsgServiceAdmin::GetMsgServiceTable()
  • Get the row from the message service table which represents the Microsoft Exchange Server service provider (MSEMS) with HrQueryAllRows()
  • Set the values for PR_PROFILE_UNRESOLVED_NAME and PR_PROFILE_UNRESOLVED_SERVER with IMSgServiceAdmin::ConfigureMsgService()
  • Logon to a new MAPI session using the new profile with MAPILogonEx()
  • Release and reuse IMsgService and IMAPITable objects
  • Get new IMsgServiceAdmin interface pointer
  • Get the Message service table
  • Find the row that represents the MSEMS message service
  • Open the property sheet for the service with IMsgServiceAdmin::ConfigureMsgService

Sample Code

Following is one possible implementation of the pseudo-code. It is only a sample, but it meets the design goals of changing various settings of the Microsoft Exchange Service Provider and displaying the results of those changes:

    HRESULT ChangeMSESPSettings ( LPSTR lpszProfile, HWND hWnd )
    {
      HRESULT hRes = S_OK;

      LPPROFADMIN       pProfAdmin = NULL;
      LPSERVICEADMIN    pSvcAdmin = NULL;
      LPMAPITABLE       pMsgSvcTable = NULL;
      LPSRowSet         pRows = NULL;
      SPropValue        rgval[2];
      LPMAPISESSION     pSession = NULL;
      SRestriction      sres;
      SPropValue        pSvcProps;

      enum {iSvcName, iSvcUID, cptaSvc};
      SizedSPropTagArray (cptaSvc, sptCols) = { cptaSvc,
                                                PR_SERVICE_NAME,
                                                PR_SERVICE_UID };

      for ( int i = 0; i < 2; i++)
         ZeroMemory ( &rgval[i], sizeof ( SPropValue ) );

      //  Get IProfAdmin interface pointer
      if ( FAILED ( hRes = MAPIAdminProfiles ( 0L, &pProfAdmin ) ) )
         goto Quit;

      //   Create a new profile -- IProfAdmin::CreateProfile()
      //   If the attempt to create the profile fails, remove the profile
      if ( FAILED ( hRes = pProfAdmin -> CreateProfile ( lpszProfile,
                                                         "",
                                                         (ULONG)hWnd,
                                                         0L ) ) )
      {
         hRes = pProfAdmin -> DeleteProfile ( lpszProfile, 0L );
         goto Quit;
      }
      // Get IMsgServiceAdmin interface pointer
      if ( FAILED ( hRes = GetAdminService ( &pSvcAdmin, NULL ) ) )
         goto Quit;

      // Add a message service to the newly created profile
      if (FAILED(hRes = pSvcAdmin->CreateMsgService ( "MSEMS",
                                                      "Microsoft Exchange",
                                                      (ULONG)hWnd,
                                                      0L ) ) )
         goto Quit;

      // Get the message service table of the Message service
      if ( FAILED ( hRes = pSvcAdmin->GetMsgServiceTable(0L,
                                                         &pMsgSvcTable) ) )
         goto Quit;

      // Get the row from the message service table which represents the
      // Microsoft Exchange Server service provider

      sres.rt = RES_CONTENT;
      sres.res.resContent.ulFuzzyLevel = FL_FULLSTRING;
      sres.res.resContent.ulPropTag = PR_SERVICE_NAME;
      sres.res.resContent.lpProp = &pSvcProps;

      pSvcProps.ulPropTag = PR_SERVICE_NAME;
      pSvcProps.Value.lpszA = "MSEMS";

      if ( FAILED ( hRes = HrQueryAllRows ( pMsgSvcTable,
                                            (LPSPropTagArray)&sptCols,
                                            &sres,
                                            NULL,
                                            0,
                                            &pRows ) ) )
         goto Quit;

      // Set the values for PR_PROFILE_UNRESOLVED_NAME and
      // PR_PROFILE_UNRESOLVED_SERVER

      rgval[0].ulPropTag = PR_PROFILE_UNRESOLVED_NAME;
      rgval[0].Value.lpszA = "<user name>";

      rgval[1].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER;
      rgval[1].Value.lpszA = "<server name>";

      if ( FAILED ( hRes = pSvcAdmin -> ConfigureMsgService(
           (LPMAPIUID) pRows -> aRow->lpProps[iSvcUID].Value.bin.lpb,
           0, NULL, 2, rgval ) ) )
      hRes = pProfAdmin -> DeleteProfile ( lpszProfile, 0L );

      // Logon to a new MAPI session using new profile -- MAPILogonEx()
      if ( SUCCEEDED ( hRes = MAPILogonEx ( ( ULONG )hWnd,
                                            lpszProfile,
                                            "",
                                            MAPI_NEW_SESSION |
                                            MAPI_NO_MAIL, &pSession ) ) )
      {
         // Release and reuse IMsgService and IMAPITable
         // objects.
         pSvcAdmin -> Release ( );
         pMsgSvcTable -> Release ( );
         FreeProws ( pRows );

         pSvcAdmin = NULL;
         pMsgSvcTable = NULL;
         pRows = NULL;

         // Get new IMsgServiceAdmin interface pointer
         hRes = pSession -> AdminServices ( 0L, &pSvcAdmin );

         // Get the Message service table
         if(FAILED(hRes = pSvcAdmin->GetMsgServiceTable ( 0L,
                                                       &pMsgSvcTable ) ) )
             goto Quit;

         // Find the row that represents the MSEMS message service
         if ( FAILED ( hRes = HrQueryAllRows (pMsgSvcTable,
                                              (LPSPropTagArray)&sptCols,
                                              &sres,
                                              NULL,
                                              0,
                                              &pRows ) ) )
             goto Quit;

         // Open the property sheet for the service
         if ( FAILED ( hRes = pSvcAdmin -> ConfigureMsgService(
           (LPMAPIUID) pRows -> aRow -> lpProps[iSvcUID].Value.bin.lpb,
            0,
            SERVICE_UI_ALLOWED |
            SERVICE_UI_ALWAYS,
            5,
            rgval) ) )

             goto Quit;
    }

    Quit:
      if ( hRes )
        hRes = pProfAdmin -> DeleteProfile ( lpszProfile, 0L );

      if ( pMsgSvcTable )
      {
         FreeProws( pRows );
         pRows = NULL;
         pMsgSvcTable -> Release ( );
         pMsgSvcTable = NULL;
      }

      if ( m_pProfAdmin )
      {
         if ( hRes == MAPI_E_NO_ACCESS )
            pProfAdmin -> DeleteProfile ( lpszProfile, 0L );
      }

      if ( pSvcAdmin )
      {
         pSvcAdmin -> Release ( );
         pSvcAdmin = NULL;
      }

      if ( pSession )
      {
         pSession -> Logoff ( (ULONG)m_hWnd, MAPI_LOGOFF_SHARED, 0L );
         pSession -> Release ( );
         pSession = NULL;
      }

      return hRes;
    }
     STDMETHODIMP GetAdminService ( LPSERVICEADMIN * lppSvcAdmin,
        LPMAPISESSION m_pSession)
     {
        HRESULT hRes = S_OK;
        LPSERVICEADMIN lpSvcAdmin = NULL;

        If(NULL!=m_pSession)
        hRes = m_pSession -> AdminServices ( 0L, &lpSvcAdmin );
        else
        hRes = MAPIAdminProfiles(0L, &lpSvcAdmin)

        if ( SUCCEEDED ( hRes ) )
           *lppSvcAdmin = lpSvcAdmin;

        return hRes;
     }


This code results in the messaging service property sheet for Microsoft Exchange Server service provider being displayed with the server and mailbox properties set for the profile.

Keywords          : kbcode EMAPI ExchExt MAPIIXP
Version           : WINDOWS:1.0
Platform          : WINDOWS
Issue type        : kbhowto


================================================================================


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: December 2, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.