MapiHTTP and Autodiscover – How to open shared mailboxes in a MAPI application No ratings yet.


Opening shared mailboxes in a MAPI application has been an easy thing in the past.
Simply query the primary mailbox for the IID_IExchangeManageStore interface and create an EntryID for the shared mailbox by calling CreateStoreEntryID.
This is a V2 Exchange Store Entry ID, as outlined here:

Here’s a simple code snippet on how to use the IID_IExchangeManageStore interface:

//Now try to open additional mailboxes
IExchangeManageStore * pManagedStore = NULL;

hRes = lpMDB->QueryInterface(IID_IExchangeManageStore, (void**)&pManagedStore);
if (hRes != S_OK)
//error handling and quit

ULONG cbeid = 0L;

“/o=ContosoOrg/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=ContosoSrv1/cn=Microsoft Private MDB”,
“/o=ContosoOrg/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=ContosoUsr1”,

IMsgStore * pMsgStore = NULL;
hRes = lpSession->OpenMsgStore(0, cbeid, lpEID, NULL, MDB_NO_DIALOG | MDB_NO_MAIL | MDB_TEMPORARY | MAPI_BEST_ACCESS, &pMsgStore);

This code works when connecting with RPC_via_TCP, or when using Outlook_Anywhere.


With the Exchange Server 2013 and 2016, a third communication protocol has been implemented – MAPI_HTTP, which will be the preferred communication protocol between modern Outlook clients and Exchange.
MAPI_HTTP has a strong dependency on Autodiscover, which is an Exchange service to gather mailbox information.

MAPI_HTTP is documented here:

As soon as an Outlook client connects via MAPI_HTTP, this information is stamped into the email profile.
And every MAPI application, which uses this email profile, is using MAPI_HTTP too.

When using the above code snippet to open shared mailboxes, the OpenMsgStore will fail, if that mailbox is unknown to the MAPI subsystem.
It will only work, if this shared mailbox has been opened at least once in an Outlook session by using this email profile, or of this mailbox has been added as ‘additional mailbox’ to the email profile.
This makes opening shared mailboxes for an external MAPI application when using MAPI_HTTP complicated.
The “April 5, 2016, update for Outlook 2013 (KB3114941)” has a solution for that, as it offers a new way for external MAPI applications to use AutoDiscover under the hood to open shared mailboxes.

  • First of all, that Outlook 2013 update KB3114941 has to be installed.
  • Second, a registry entry (“AllowAutoDiscoverForNonOutlook“) needs to be set to enable that new functionality.
    This is mentioned here:
    3114974 Update adds ability for non-Outlook MAPI applications to use the Autodiscover service in Outlook 2013
  • Third, a new interface and a new Entry_ID generator call needs to be used in your code.
    This new Entry_ID generator call requires two additional parameters/MAPI properties.
    PR_FORCE_USE_ENTRYID_SERVER and PR_PROFILE_USER_SMTP_EMAIL_ADDRESS_W, which is used by the emsmdb provider to call AutoDiscover (under the hood) to gather the required information to be abel to open that shared mailbox.

This interface is documented here:
Here’s a code snippet which demonstrates the new interface:

//Now try to open additional mailboxes
IExchangeManageStoreEx * pManagedStore = NULL;

hRes = lpMDB->QueryInterface(IID_IExchangeManageStoreEx, (LPVOID*)&pManagedStore);
if (hRes != S_OK)
//error handling and quit

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

lpspv[0].ulPropTag = PR_PROFILE_MAILBOX;
lpspv[0].Value.lpszA = “/o=ContosoOrg/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=ContosoUsr1”;

lpspv[1].ulPropTag = PR_PROFILE_MDB_DN;
lpspv[1].Value.lpszA = “/o=ContosoOrg/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=ContosoSrv1/cn=Microsoft Private MDB”;

lpspv[2].Value.b = false;

lpspv[3].Value.lpszW = L””;

ULONG  cbEID = 0L;

hRes = pManagedStore->CreateStoreEntryID2(4, lpspv, OPENSTORE_HOME_LOGON | OPENSTORE_TAKE_OWNERSHIP, &cbEID, &lpEID);

IMsgStore * pMsgStore = NULL;
hRes = lpSession->OpenMsgStore(0, cbEID, lpEID, NULL, MDB_NO_DIALOG | MDB_NO_MAIL | MDB_TEMPORARY | MAPI_BEST_ACCESS, &pMsgStore);


Please rate this

Leave a Reply