I’ve updated the Outlook MAPI Samples and posted a new project up on Codeplex: Outlook 2010 MAPI Samples. We’ll get the MSDN updated to point at these samples soon. The goal of this update, of course, was to get these samples working with Outlook 2010, especially in 64 bit mode. Most of the changes were minor, swapping ULONG for ULONG_PTR, etc., but I did have to make a couple big changes:
I’m sure there are bugs in these samples. I didn’t get to test every possible scenario. So feedback is welcome – see the Help/Feedback section of the main page.
I got a bug report this morning that using Profile\Launch Profile Wizard in MFCMAPI returned MAPI_E_NO_SUPPORT in Outlook 2010. Further investigation showed it also failed on Outlook 2007. A quick debug revealed that the function had been rewritten before we shipped Outlook 2007, so that it always returns MAPI_E_NO_SUPPORT.
Why was it removed? During the development of Outlook 2007, the function was flagged as having some problems that were going to be costly to resolve. Outlook was no longer dependent on this function, and we weren’t aware of any third party code that used it, so it was decided to gut the function The fact that I didn’t learn that it no longer worked in MFCMAPI until nearly three years later illustrates how little this function is used.
It appears the Exchange implementation of this function is still intact, if it’s something you really want to use. However, for profile creation for MFCMAPI, the best method, which works with both versions of MAPI, is to just Session/Logon and Display Store Table, and hit New.
I’m in the process of updating the Outlook 2007 MAPI Samples for Outlook 2010 and ran into something that deserves some clarification. Suppose you have a 32 bit application which uses MAPI and which links in mapi32.lib. In preparation for 64 bit MAPI, you decide to try rebuilding as a 64 bit app. You install the updated MAPI headers, point your installer at them, then try building a 64 bit flavor. The 64 bit compiler might catch a few type casting errors, which you fix, then it’s time to link.
Now – if you do what I did a couple days ago, you don’t mess with the linked library settings and just let it build. And if you have the Microsoft SDK installed, it might succeed. How is this possible, when mapi32.lib is a 32 bit library?
We look at the SDK for copies of mapi32.lib:
C:\Program Files\Microsoft SDKs>dir /s mapi32.lib Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib 09/27/2007 03:20 PM 34,778 MAPI32.Lib 1 File(s) 34,778 bytes Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\x64 09/27/2007 03:20 PM 28,478 MAPI32.Lib 1 File(s) 28,478 bytes
C:\Program Files\Microsoft SDKs>dir /s mapi32.lib
Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib
09/27/2007 03:20 PM 34,778 MAPI32.Lib
1 File(s) 34,778 bytes
Directory of C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\x64
09/27/2007 03:20 PM 28,478 MAPI32.Lib
1 File(s) 28,478 bytes
This is why the link succeeded, and this is the problem I’m here to warn you about. That 64 bit build of mapi32.lib shouldn’t exist. To put it another way: The 64 bit build of mapi32.lib is bad and should be avoided! Basically, the SDK team built and shipped this library without the involvement of Office. There were a number of changes which should have been made to get it ready for 64 bit MAPI, but weren’t made. We’re still investigating if it would be possible for Office to ship a 64 bit version of this library. But for now, if you want to build a 64 bit MAPI application, you have to explicitly link to MAPI.
BTW – this isn’t a problem for MFCMAPI, which hasn’t linked with mapi32.lib for years. :)
I noticed something about downloading/installing the Outlook 2010 MAPI headers. I use Windows Server 2008 as my development machine, and when I ran the installer, which is really a self extracting zip file, it offered to copy the headers to “C:\Program Files\Microsoft SDKs\Office\14.0\Include”. However, when I looked there, the files weren’t there. Instead, after a bit of looking around, I found them here instead:
C:\Users\sgriffin\AppData\Local\VirtualStore\Program Files\Microsoft SDKs\Office\14.0\Include
If you’re just looking to get the files, and plan on copying them into your project, I guess this works, but if you want to depend on the path, you have to do a bit of work. What worked for me was to open an administrative command prompt and run the installer from there. When I did that, the headers were copied in to “C:\Program Files\Microsoft SDKs\Office\14.0\Include”, as expected.
When I finish working on the Outlook 2010 MAPI samples (coming soon!) they will depend on these MAPI headers being in the proper path. Without these updated headers, these samples will not compile for 64 bit.
Suppose you’ve scheduled an meeting and sent out meeting requests to a number of recipients. Some of those recipients don’t like the time you’ve scheduled for the meeting and decide to propose a new time. At this point, you will receive a message with message class "IPM.Schedule.Meeting.Resp.Tent". This message will contain information about the proposed new time, which Outlook will then tag on to the meeting when it processes the response.
Now – suppose you also have some CDO based code that also tries to process this meeting response using GetAssociatedAppointment and Update. CDO knows about this message type, so it can read the tentative response off of it and update the meeting. And here’s the problem – CDO doesn’t like proposals. Or, more accurately, CDO doesn’t know anything about the propose new time feature, so it doesn’t know anything about the properties used to implement it. So when CDO updates the meeting during the processing of the response, it ends up wiping out the properties that controlled the proposal feature! Before CDO touched the meeting, you could look at it in Outlook and see an Infobar indicating that new times were proposed. And switching over to the Scheduling Assistant, you could view and select the new time. After CDO’s done with the meeting, nothing indicating there was a proposal is left.
Some more technical details: The proposed new times are stored on the meeting on the recipient table, with a set of properties written to each recipient row indicating their proposal. To read about these properties, look for PidTagRecipientProposedStartTime in [MS-OXOCAL]. CDO isn’t deliberately wiping any properties. Instead, it knows it needs to add PidTagRecipientTrackStatus, also in [MS-OXOCAL], to the recipient. Not knowing about the proposal properties, the new row CDO constructs for ModifyRecipients doesn’t contain them. So the effect is, if the properties were there before, they’re not there now.
Other than avoiding CDO, no simple workaround for this issue is known. A savvy developer armed with [MS-OXOCAL] might try reading the recipient table off before allowing CDO to touch the meeting, then go in and fix it up.
The July 2009 Release (build 6.0.0.1014) is live: http://mfcmapi.codeplex.com.
Note that a 64 bit build is now included. Of course, to use it, you’ll need 64 bit Outlook 2010.
This time around I focused on performance. I've just discovered the built in profiler in Visual Studio and I’ve been using it to find bottlenecks in loading items and displaying their properties. It’s been enlightening to drill into the performance reports and find out just how much time some of the code paths took to execute. I was able to trim away a good bit of fat.
The biggest change I made in the name of performance was in the area of Named Properties. I found I was repeatedly calling GetNamesFromIDs to map property tags to their named prop names. Cutting down the number of calls meant implementing a cache. We still incur the initial hit to look up the mappings, but once we’ve looked up a tag, we won’t look it up again. Uncached profiles should load a bit faster now.
Here's a change list - see the Issue Tracker on Codeplex for more details, or look at the code:
Enjoy.
I had some extra time today, so I put together updates I’ve been working on for the GCReconnect sample/tool which we use to demonstrate/test referrals. The key addition here is an oft requested switch, –k, which requests that we keep the profile that GCReconnect built. I've posted the updated sample here.
C:\>gcreconnect Creates a profile, optionally enabling referral and reconnect logic, and tests name lookup.
Usage: GCReconnect [-?] -m mailbox -s server [-e] [-x] [-n name] [-l] [-r] [-w]
Options: -m mailbox Specifies the mailbox to log on to. -s server Specifies the Exchange server where the mailbox resides. -e Enable referral and reconnect If referral and reconnect are not enabled, MAPI will connect directly to the Exchange server for name lookup -x Enable additional referral and reconnect settings for Exchange 2007 Implies -e -a auth Use specificied auth. Default is 9 (RPC_C_AUTHN_GSS_NEGOTIATE). -n name Specifies a name to resolve with ResolveName If not specified, QueryIdentity will be used instead -l Loop over MAPILogonEx. Will log on and off repeatedly until key is hit -r Loop over ResolveName and OpenMsgStore. Will log on once and do name lookup and message store open repeatedly until key is hit Requires -n, not valid with -l -w Wait for keyboard input before and after creating and configuring profile -k Do not delete the profile when done. -? Displays this usage information.
Anybody think this is worth posting as a project up on Codeplex? Or would I be better off just incorporating all of this into MFCMAPI?
Up until today, the first rule of 64 bit MAPI was we don’t talk about 64 bit MAPI. But now we can talk about it. 64 bit MAPI has arrived!
We just released the Outlook 2010 MAPI Reference today. If you develop MAPI based applications, you’ll want to get the updated MAPI Headers that come with it. You’ll need these if you want to rebuild your application for 64 bit. We’ve also prepared an article on building MAPI applications for both 32 bit and 64 bit platforms. This article is based in part on my experience building MFCMAPI as a 64 bit application. Since we don’t provide a 64 bit mapi32.lib, to build a 64 bit MAPI application you’re going to have to use explicit linking, building on the documentation we included in the Outlook 2007 MAPI reference.
Oh yeah – that reminds me – MFCMAPI builds as a 64 bit application! Actually, it’s been possible to build MFCMAPI as 64 bit for years. I slipped those project types in a long time ago and have been quietly maintaining them, even before I had an actual 64 bit build of MAPI I could test against. The next release of MFCMAPI will include a 64 bit build of the project, but if you want a 64 build now, just download the source and build it yourself.
Enjoy!
Ever since I went to the new Vista style icon for MFCMAPI, it’s not been possible to compile in Visual Studio 6. I’ve spent some time looking at this, and it appears the only clean way to get VS 6 working again is to remove compression from the icon, something I really don’t want to do. So I’m considering dropping support for Visual Studio 6 altogether. While I’m at it, it’s been a while since I tried to compile in VS 2003 or 2005, so I was thinking about dropping support for those two as well. The only compiler I’d test would be Visual Studio 2008 (and 2010 whenever it comes out). Note that other than the known break in VS 6 I’m not planning on actively breaking compilation for 2003 or 2005. I just wouldn’t test them, so over time, I probably would break them.
Before I do this – I wanted to get feedback. Would anybody care if MFCMAPI no longer compiled in Visual Studios 6, 2003, or 2005?
Had a customer contact me recently asking why MAPIOpenFormMgr doesn’t work with the Exchange MAPI download. Actually, it wasn’t working in Exchange 2003 either. I’m not sure exactly when it last worked in Exchange’s implementation of MAPI. We might have to go all the way back to the Exchange Client to find a version of Exchange’s MAPI where it worked.
There was more to this story that I wanted to post. A few years ago, on a whim, I debugged why MAPIOpenFormMgr was broken. I found it was looking for a forms manager DLL that Exchange hadn’t shipped in a long long time. However, there was a mechanism for directing Exchange’s MAPI to use a different forms manager, and one of the DLLs Exchange shipped could act as a forms manager. Since this wasn’t likely supported, and no one was asking about it, I filed it away as an interesting tidbit.
Since I did get asked about it, my plan was to post the reg key that controls which forms manager is used with a warning that since it isn’t supported or tested, it’s quite possible it will break on you. However, when I went to try it out, I found that when you try it out with the Exchange MAPI download, you crash right away. This isn’t surprising considering no one’s run the code in 10+ years.
So there’s no point in posting the key, though someone who was really determined could figure it out pretty quickly, and with a little debugging even figure out which DLL to point at. I guess I’ll leave that as an exercise for the reader. The official answer here is that Exchange’s implementation of MAPI doesn’t include a functioning forms manager, so none of the forms management portions of MAPI, such as MAPIOpenFormMgr or MAPIOpenLocalFormContainer, are available.
Since I’ve got a few customers who were waiting on this update I figured I should announce it here. Yesterday we released the June Cumulative Update for Office 2007: http://support.microsoft.com/kb/972632. In there, you’ll find links to update packages for everything in Office 2007. We highlight two:
MAPI Profile Crash: Basically, SP2 caused MAPI to stumble over certain profiles because it didn’t like their names. This update fixes that.
The Big Rollup: This is the mother-load of fixes. In this one, you’ll find fixes for the following issues:
BTW – if you’re looking for a central place to monitor for the latest Cumulative Update, flag this article: http://support.microsoft.com/kb/953878. It’s updated with every Cumulative Update release to point at the latest one.