More Exchange and Outlook Madness

I'm working on a followup to my memory management article and a writeup on a MAPI deleted profile bug I ran across recently, but this takes precedence.

Exchange and Outlook on the same machine is bad. In my last post I waved my hands about some scenarios which could lead to a crash. I got a dump today which illustrates one. The issue originally manifested as heap corruption in MFCMAPI while opening a message store. We enabled pageheap on the process to see what was corrupting the heap. Here's the stack we got:

0:000> kL ChildEBP RetAddr
0012f2bc 77fb44fb NTDLL!RtlpDphIsNormalHeapBlock+0x86
...
0012f4d0 35525bda NTDLL!RtlFreeHeap+0x85
0012f4e0 35525b6e MSMAPI32!LH_ExtHeapFree+0x19
0012f50c 62a5248b MSMAPI32!MAPIFreeBuffer+0x64
0012f778 62a530dd emsmdb32!HrSetupOffline+0x144
0012f834 62cd1755 emsmdb32!RMSP_Logon+0x2c4
0012f894 62cd1478 mapi32!HrIntDoOneClientLogon+0x8a
0012f8b0 62cd0f25 mapi32!HrIntClientStoreLogon+0x47
0012f920 62cd1422 mapi32!HrCommonOpenStore+0x3c3
0012f9a0 004310b6 mapi32!SESSOBJ_OpenMsgStore+0x56
0012f9d0 004321c7 MFCMapi!CallOpenMsgStore+0x66

I've trimmed the stack a little to get to the heart of the issue. We're corrupting the heap when we call RtlFreeHeap. Notice that mapi32 and msmapi32 both appear on this stack. Here's the versions of both (again, output is trimmed):

0:000> lmvm mapi32
Image path: C:WINNTsystem32mapi32.dll
Timestamp: Sat Jun 12 00:17:32 2004 (40CA83DC)
File version: 6.0.6603.0
ProductName: Microsoft Exchange
0:000> lmvm MSMAPI32
Image path: C:Program FilesCommon FilesSystemMapi1033MSMAPI32.DLL
Timestamp: Tue Dec 16 20:39:51 2003 (3FDFB3E7)
File version: 10.0.6515.0
ProductName: MAPI32

So what's the problem? We have two competing versions of MAPI loaded into the same process!

Emsmdb32.dll made a call to GetProps to get some properties on a profile. The resulting LPSPropTagArray was allocated using Exchange's MAPI32.dll. Later, Emsmdb32.dll calls MAPIFreeBuffer to clean up this memory. Somehow, Outlook's MSMAPI32.dll ended up handling this call. Since Outlook's MSMAPI32.dll doesn't know anything about the heaps created by Exchange's MAPI32.dll, we end up corrupting the heap during this free. Without pageheap enabled, this corruption is silent, and doesn't rear it's ugly head until later on when we try allocating some memory against the corrupted heap.

After removing Outlook from the box, this problem went away.