Well Behaved Store Providers

The first answer I give to customers asking for tips on making their store provider work with the latest versions of Outlook is "be well behaved". I've had a couple message store provider cases recently that illustrate this and give me an opportunity to expand on that statement and give some concrete guidance.

  • The case of the missing search folders

    The customer's message store wasn't working well in Outlook 2007. Outlook would recreate it's persisted search folders every time it booted. In fact, it would create them, then try to create them again and again, chewing up cycles. They had checked their code to ensure that the folders got created, and that every property Outlook set was available. Except - some properties weren't accessible through the hierarchy table.

    When Outlook loaded the hierarchy table for the message store, it looked for any folders with PR_EXTENDED_FOLDER_FLAGS stamped on them. Those that had this property, with the appropriate flags set in it, would be added to the list of known search folders. Later, when Outlook needed to access one of the search folder, it would consult the list it had built. Since this particular store didn't expose a number of properties through the hierarchy table, this list was empty. So Outlook concluded it needed to create the search folder.

    The first lesson we learn is this:

    Properties set on messages and folders should be accessible through contents tables and hierarchy tables

    This lesson was behind the PR_RECORD_KEY issues and it's been the source of countless other store providers issues I've debugged over the years. Outlook (and MFCMAPI and even Outlook Spy) expect most properties to come back the same regardless of whether they're requested through the table or through the object. The solution is not to special case properties you think Outlook might want, but instead to ensure the general case works. That's exactly what this customer did and his provider's working much better now.

  • The case of the tentatively accepted meeting

    Different customer this time. Their issue was a bit more complicated. A user would send a recurring meeting request to another user, both running their message store. The recipient would let Outlook create a tentative appointment on the calendar. If at this point, they open the series, the info bar would prompt "Please respond". If they then opened one instance of the meeting and accepted it, then went back and opened the series, the info bar now indicated "Tentatively accepted". When the same steps were performed with Exchange as the back end, both times the info bar would prompt "Please respond".

    Outlook's logic for determining which string to display hinges on two properties - dispidResponseStatus and dispidApptReplyTime. If the status is set to none or not responded, we display "Please respond". If it's set to tentative, we display "Tentatively accepted", but ONLY if the reply time is set. If the reply time isn't set, we display "Please respond" instead. When the recipient accepted a single instance of the meeting, Outlook changed the response status on the master to tentative, but didn't set a reply time. However, when Outlook then looked at the properties on the meeting, the reply time was set, so it displayed "Tentatively accepted".

    How did the reply time property get set? This leads to the second lesson:

    Message stores which manufacture Outlook's business logic properties do so at their own risk

    If Outlook didn't set a property, it's probably not a good idea to manufacture it. And if you do decide to go that route, you better be prepared to crack open the Exchange Protocol documentation and spend a good long time making sure you get everything right. In this case, the customer got out of the property manufacturing business and their meeting started working as expected.

In both cases, as in most message store cases (see this and this), the advice boils down to "if your store acts weird, so will Outlook". Hopefully though, these lessons will help a few of you identify the source of weird behavior in your own providers.