PR_MAPPING_SIGNATURE and custom message stores

I was pulled into a neat little issue with a custom message store that didn't behave correctly with appointments in Outlook.  It seems that everything was created fine, and Outlook set all of the named properties correctly on appointments.  The custom store was supporting named properties correctly and exposing them in their contents tables, so Outlook was happy.  Different calendar views worked great.

However, things got weird once you started a new MAPI session.  For reasons specific to the custom store, it decided to change it's named property-to-proptag mapping.  Of course, this is perfectly legal, no reason they shouldn't be able to do that.  The thing is, it totally hosed Outlook's calendar views.  All of the sudden, appointments lost their start times, end times, etc!!

We started debugging Outlook, and the weird thing was that Outlook didn't seem to be calling GetIDsFromNames on these subsequent sessions.  The first time we logon to a new profile it does (and everything works), but subsequent times we don't.  So you see why changing the named property mappings breaks things: if Outlook believes that the named property for the start time is 0x8000, and it's been changed to 0x8001, then things break.  Everything would be great if Outlook just called GetIDsFromNames every time (or at least once every new session), but it doesn't.  So what gives?

It all comes down to PR_MAPPING_SIGNATURE.  Go read the MSDN notes on this property.  It doesn't have a section specifically regarding how to implement this property, so you kind of have to extrapolate.  The key nugget from this is: When two objects have the same PR_MAPPING_SIGNATURE value, the client does not need to translate name to identifier and identifier to name.   Can you guess where this custom store went wrong?  Exactly: they were using the same PR_MAPPING_SIGNATURE across sessions, even if they changed their named property mapping!

Outlook stores the value of PR_MAPPING_SIGNATURE for your store in a property in the profile.  Once that property is there, every time you open Outlook with that profile, it checks this value and compares to what it gets back from your store.  If the values match, then Outlook assumes that the named property mapping it got from the prior session is still valid to use, and skips the GetIDsFromNames call.  If the values don't match (or if the property isn't there in the profile) then Outlook discards it's old property mapping data and does a GetIDsFromNames call.

So, if your store provider supports PR_MAPPING_SIGNATURE, you need to make sure that you change its value when you change your named property mappings to ensure that everything works properly.