How To Break The MAPI Stub Library

Well, that didn't take long. We just released the latest MAPI download this weekend and yesterday we got a case from a customer who's application no longer functioned when they upgraded. The issue was quickly resolved, and I was asked to communicate some of the details in case anyone else runs in to it.

The important detail here is that in order to get Exchange's MAPI to work on Vista and Windows Server 2008, we had to make it work with the MAPI Stub Library. So we installed our binaries under Program Files and set the following registry keys*:

-

<table>
<tbody>
<tr class="odd">
<td>Key</td>
<td>Value</td>
</tr>
<tr class="even">
<td>HKEY_LOCAL_MACHINESOFTWAREClientsMailExchangeMAPI::DLLPathEx</td>
<td>&lt;path to exmapi32.dll&gt;</td>
</tr>
<tr class="odd">
<td>HKEY_LOCAL_MACHINESOFTWAREClientsMail::Default</td>
<td>ExchangeMAPI</td>
</tr>
</tbody>
</table>

The first key tells the stub library where to find an Extended MAPI implementation called ExchangeMAPI, and the second key tells the stub library that when an application loads it, the default MAPI implementation to which all calls should be directed is ExchangeMAPI. In other words, when you load the stub library, it will in turn load exmapi32.dll.

This is the same as what Outlook does when it's installed - it registers itself and sets the Default key to "Microsoft Outlook".

Now, this customer had a product which had worked for years with either Outlook's or Exchange's implementation of MAPI. Apparently, they had had problems in the past with systems where Outlook was installed, but the default mail client had been set to something else, such as Hotmail. So, to work around this problem, following the advice given in Explicitly Mapping MAPI Calls to MAPI DLLs they wrote a key under HKLMSoftwareMicrosoftWindows Messaging SubsystemMSMapiApps mapping their application to the "Microsoft Outlook" implementation of MAPI. This worked on machines where Outlook was installed, since there would be a Microsoft Outlook key from which to read DLLPathEx. And on a machine where Exchange's MAPI was installed, since Exchange overwrote the stub library nothing written in any of those keys mattered.

Now, of course, it matters. When they set their application to use "Microsoft Outlook", but Outlook isn't installed, the stub doesn't know where to turn. It can't find the default mail client. It can't just start loading random MAPI binaries, so it turns to it's fallback mechanism, which is to look for MAPI32x.dll. Since that's not there either, it gives up and fails the call to MAPIInitialize.

There's not a perfect workaround here - there's no way to tell the stub that there are two MAPI implementations your application can work with and just use whichever one is available. The simplest solution here is probably to not use the MSMapiApps key and either accept whatever MAPI implementation is the default or load MAPI binaries manually and bypass the stub. The latter is what MFCMAPI does. You could also do some runtime detection of whether "Microsoft Outlook" or "ExchangeMAPI" are listed under the Mail key and set the MSMapiApps key appropriately before loading MAPI. Or, depending on where your application is meant to be installed, pick an implementation of MAPI and insist that it be the one installed with your app. No matter what you choose, this issue illustrates why I stressed to the commenter of my previous post on this update: "The move from system32 to program files is a fairly large and potentially destabilizing move though. You should definitely test your applications with this update."

*64 bit complicates this a bit by redirecting the registry keys. So for those of you playing along at home on a 64 bit box, look under HKEY_LOCAL_MACHINESOFTWAREWow6432NodeClientsMail