A new MAPI interface is available to let you force connections to go to a specific Exchange Server

[Edit: 1/23/2014 - This new interface did not ship in the December 2013 CU.  I was incorrect.  I am currently looking into it.]

[Edit: 4/23/2014 - This fix should've released in February]

[Edit: 11/21/2014 - This change was ported to Outlook 2013 in the April 2014 Cumlative Update for Outlook 2013.  support.microsoft.com/kb/2878323]

[Edit: 11/17/2016 - This change was ported to Outlook 2016 and should be available in this update https://support.microsoft.com/en-us/kb/3115440 for MSI builds. C2R builds should've had it before that.]

Introduction

When making a connection to an Exchange Server, Outlook's MAPI will use the server configured in the profile for any mailbox access attempt, even if it's a different mailbox on a different server.  Additionally, Outlook's MAPI will prefer to use a server that it has connected to in the past over one that it hasn't.  Therefore, even if you specify a different mailbox on a different Exchange Server in the call to IExchangeManageStore::CreateStoreEntryID(), Outlook's MAPI will still use the server configured for the profile.  This is not normally a problem.

When a MAPI client application attempts to connect to multiple mailboxes using a "hub and spoke" type approach wherein the MAPI application connects to an initial mailbox and then connects to additional mailboxes for some sort of processing, if the mailbox resides on a different server Outlook's MAPI will ignore the specified server in the EntryID and connect to the server configured for the profile (the "home server").  This results in a return code of ecWrongServer (0x478 / 1144) and the MAPI application is redirected to the correct server.  Outlook's MAPI recognizes this scenario and redirects to the corrected server.  Again , this is not normally a problem.

Enter Exchange 2013 where every mailbox is now given it's own server name.  This is called the personalized server name and is a GUID that represents the mailbox's home server.  This makes Outlook's MAPI go through the redirect logic for all mailbox connection attempts and causes a small performance hit for each mailbox the MAPI application attempts to connect to.  Previously, there was no way to tell Outlook's MAPI to ignore the "home server" and use the server specified in the EntryID.  However, as of the December 2013 Cumulative Update for Outlook 2010 there now is.

To do this, a new interface was created to provide the MAPI application a new public API that can produce the Store EntryID needed when calling IMAPISession::OpenMsgStore().  You can use the header defined below and the properties to instruct MAPI to create the Store EntryID that contains a special flag in the EntryID that Outlook's MAPI will know how to parse. When this flag is present, MAPI will prefer the server name contained in the EntryID.  When it's not, it will use the conventional logic discussed above.

First,  you will need to define the new properties PR_PROFILE_MDB_DN and PR_FORCE_USE_ENTRYID_SERVER

 // 0x7CFF001E 
#define PR_PROFILE_MDB_DN PROP_TAG(PT_STRING8, 0x7CFF)
// 0x7CFE000B 
#define PR_FORCE_USE_ENTRYID_SERVER PROP_TAG(PT_BOOLEAN, 0x7CFE)

Next, you will need to include a new header with the following information

 #include <MAPIX.h>
#include <EdkMdb.h>
/*------------------------------------------------------------------------ * * 
 "IExchangeManageStoreEx" Interface Declaration 
 * * Used for store management functions. 
 * *-----------------------------------------------------------------------*/

#define EXCHANGE_IEXCHANGEMANAGESTOREEX_METHODS(IPURE)                            \
       MAPIMETHOD(CreateStoreEntryID2)                                                                 \
              (THIS_ ULONG                                    cValues,                                 \
                           LPSPropValue                      lpPropArray,                      \
                           ULONG                                    ulFlags,                                 \
                           ULONG *                                         lpcbEntryID,                       \
                           LPENTRYID *                              lppEntryID) IPURE;

#undef        INTERFACE
#define              INTERFACE  IExchangeManageStoreEx
DECLARE_MAPI_INTERFACE_(IExchangeManageStoreEx, IUnknown)
{
       MAPI_IUNKNOWN_METHODS(PURE)
       EXCHANGE_IEXCHANGEMANAGESTORE_METHODS(PURE)
       EXCHANGE_IEXCHANGEMANAGESTOREEX_METHODS(PURE)
};
#undef IMPL
#define IMPL

DECLARE_MAPI_INTERFACE_PTR(IExchangeManageStoreEx, LPEXCHANGEMANAGESTOREEX);

DEFINE_GUID(IID_IExchangeManageStoreEx, 0x7fe3c629, 0x4d9a, 0x4510, 0xa4, 0x79, 0x56, 0x96, 0x2b, 0x24, 0x6d, 0xc6);

At the call site you will need to pass an array of SPropValues for the following properties

Property: PR_PROFILE_MAILBOX
Description: The DN of the target mailbox
Example: /o=Contoso/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Harris Smithfield9f
Autodiscover Node: Response/User/LegacyDN
Property: PR_PROFILE_MDB_DN
Description: The DN of the target server
Example: /o=Contoso/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=f43abcd7-674b-d43e-8cb5-30b0b2d88c38@contoso.com/cn=Microsoft Private MDB
Autodiscover Node: Response/Account/Protocol/MdbDN (type EXCH)
Property: PR_FORCE_USE_ENTRYID_SERVER
Description: True to indicate that Outlook’s MAPI should use the Server DN from the EntryID instead of the home server.
Example:   N/A

Here is some example code to show you how it could be used.

 LPSPropValue         lpspv = nullptr;
MAPIAllocateBuffer((sizeof(SPropValue) * 3), (LPVOID*)&lpspv);
ZeroMemory(lpspv, sizeof(SPropValue) * 3);

lpspv[0].ulPropTag = PR_PROFILE_MAILBOX;
lpspv[0].Value.lpszA = TargetMailboxDN;

lpspv[1].ulPropTag = PR_PROFILE_MDB_DN;
lpspv[1].Value.lpszA = TargetStoreDN;

lpspv[2].ulPropTag = PR_FORCE_USE_ENTRYID_SERVER;
lpspv[2].Value.b = true;

hres = m_pMsgPrivStore->QueryInterface(IID_IExchangeManageStoreEx,
                                                                     (LPVOID*)&pManageStoreEx);
if (FAILED(hRes) || pManageStoreEx == nullptr)
{
    // Handle the error
    goto Cleanup;
}

hRes = pManageStoreEx->CreateStoreEntryID2(3, 
                        lpspv, 
                        ulCreateStoreEIDFlags, 
                        &cbEID,
                        &lpEntryId);
MAPIFreeBuffer(lpsv);

More Information

The “Autodiscover Node” above indicates where in the Autodiscover response for the target mailbox you would find the value for this property.

This EntryID is only supported on the client, specifically Outlook's MAPI.

The EntryID should not be persisted anywhere except in the memory of the application.

If you don’t specify values for all the properties, the returned EntryID will be equal to what you would have received back in a call to IExchangeManageStore::CreateStoreEntryID(),