The January 2011 Release (build 6.0.0.1024) is live: http://mfcmapi.codeplex.com.
This round of work had two foci: Speed startup time of MFCMAPI and MrMAPI, and add features to MrMAPI.
I have been ignoring startup time of MFCMAPI for a while now, since it started up “fast enough”. But MrMAPI was designed to be run in batch scripts, and a slow startup time really adds up over multiple runs. They share the same code, so any work improving one improves the other. I found a number of opportunities to squeeze cycles out by sorting some arrays in the source and by improving the algorithms I use to shuffle them around when we’re starting. But the biggest improvement will happen if you happen to run MFCMAPI or MrMAPI from a directory with a lot of other files in it, such as a tools directory. We get a great speedup by remembering which files are and are not add-ins to MFCMAPI, so we don’t keep retrying them.
Other than the speed-up work, MrMAPI got most of the love. I added a host of new features: Error lookup, guid lookup, ACL and Rule table exports, and nickname cache parsing are the big ones. I’ve also uploaded a 64 bit version of MrMAPI since some of the features actually log in to a profile, and we need to support 64 bit Outlook.
When you download the new version of MFCMAPI, make sure to download MrMAPI for all of your property tag needs.
Here's a change list - see the Issue Tracker on Codeplex for more details, or look at the code:
Enjoy.
In Outlook 2007 and prior, a common pattern for solutions written using Exchange Client Extensions (ECE) involved intercepting when Outlook would open a message, so that the contents of the message could be modified. This technique was used in several solutions, from virus scanning to implementing e-mail archiving. The events available in ECEs made these sort of solutions possible and there were no comparable events to do similar work in the Outlook Object Model.
With Outlook 2010, we decided to cut ECEs completely. We anticipated that vendors who relied on ECEs as part of their solution would need additions to the object model to make it possible to migrate their code to Add-Ins. One of our additions was the BeforeRead event. The purpose of this event was to allow developers a chance to modify the MAPI message that Outlook was about to render before Outlook had done any work with the message. It worked well in our testing, and several vendors have already implemented solutions using it.
There’s a problem though: if you try to change the message class during BeforeRead to one of our secure message classes, such as “IPM.Note.SMIME”, Outlook acts as if you didn’t. You can do all the work to add the encrypted body type as an attachment, update all the attendant properties, and Outlook will still treat the message as if it were IPM.Note. It’s almost as if, despite what the documentation for BeforeRead says, Outlook was reading the properties on the message before handing it to the event.
Here’s what’s going on: The Outlook developers didn’t want to sprinkle special case code for encrypted messages all through their code base. Instead, they created a wrapper interface, IMAPISecureMessage, which implements IMessage and a few other functions. This wrapper interface handles most of the details of encrypted messages. The very first thing Outlook does when it opens a message from a store is to wrap it in this IMAPISecureMessage interface. This wrapped object is what you get when you ask for the MAPIOBJECT from the BeforeRead event.
One of the quirks of this object is that it postpones any initialization until you actually do something with it, such as call GetProps or SetProps. At this point, it runs through its initialization routine, one portion of which reads the message class of the message and makes decisions on whether and how to handle encryption. So the BeforeRead documentation was technically correct – Outlook hadn’t read any properties on the message when the event started. But using BeforeRead to update the message class still wouldn’t work since the first call to SetProps to update the message runs through code that reads the previous message class!
Fortunately, we anticipated this scenario and documented a way around it: IMAPISecureMessage::GetBaseMessage. This function, when called on a message which has been wrapped for security, returns the underlying wrapped message. This message can then be read from and written to without triggering the setup logic. As long as all of this work is done before anyone tries to read or write properties via the secure wrapper, any changes made will be fully reflected in what Outlook renders.
So, if you’re using BeforeRead in your Add-In solution and want to make sure all of your changes are reflected, you’ll need to do something like this:
Some notes about the documentation for IMAPISecureMessage and GetBaseMessage. This is brand new documentation and we’ve found a few errors in it, all of which are slated for correction in a future update to the MSDN: