Using MAPI In An Installer

If you have an installer which uses MAPI, specifically, which calls MAPIInitialize, you should be aware of this. After calling MAPIInitialize from the installer, you may note that you can no longer start Outlook! This only happens with Outlook 2010 and higher.

This was initially reported here: https://social.msdn.microsoft.com/forums/office/en-US/4cd23859-c5f5-40b2-a294-48cfc24bdc99/mapiinitialize-cause-outlook-2010-to-not-start-up, but I didn’t see it until recently. What’s happening is a change we made in Outlook 2010 to prevent potential cross user security issues with data stored in the MAPI profile. Every time MAPI starts up, we set an ACL on the following key:

HKCUSoftwareMicrosoftWindows NTCurrentVersionWindows Messaging SubsystemProfiles

The exact path may vary on different systems. The ACL we set contains three entries in it: System, the Administrators group, and the current user. When you start MAPI normally, the current user is the user the application is running as, which is typically the desktop user, so everything is fine. But when you run MAPI from the context of the installer, the current user can end up NOT being the desktop user. In that case we end up setting an ACL that denies the desktop user access to the registry key!

When Outlook subsequently tries to run, it finds it has no access to the Profiles registry key, so it has no MAPI profiles. Without MAPI profiles, Outlook can’t function, so you get an error, “Cannot start Outlook”. If you then try to run Outlook elevated, and you happen to be in the Administrators group, MAPI can then access this key and reset the ACL to the usual ACL, fixing the problem.

As far as I’m aware, not many applications call in to MAPI from an installer context, so this is somewhat a corner case. Additionally, it’s difficult to detect from MAPI’s perspective that we’re running like this. But if you want to avoid causing this problem for your users, you can use the functions GetSecurityInfo and SetSecurityInfo to grab the ACL before you call MAPIInitialize and then set the ACL back afterwards. Specifically, call GetSecurityInfo with SE_REGISTRY_KEY and a NULL Owner and Group parameter. Save off the Dacl and Sacl you get, then supply these to the SetSecurityInfo call after MAPIInitialize completes. This will prevent MAPIInitialize from rewriting the ACL on the Profiles key. You should only do this when running in an Installer or any other context where you find MAPI is writing an ACL that ends up affecting the desktop user.