Outlook Rules - At Least When You Tell It To

[This is now documented here: https://msdn.microsoft.com/en-us/library/ff960239.aspx ]

We just had a customer whose Wrapped PST based store wasn't getting rules to fire in Outlook 2007, when everything was working in 2003. In the course of figuring their issue out, we found a few flags that we should have documented before.

Suppose you built a message store based on the Wrapped PST provider. When your new messages are delivered to your backend database and you create matching messages in the PST, how do you inform Outlook that a new mail has arrived? In Outlook 2003, the way you solve this is to use the IMAPISupport object that was passed to you during logon. From there, you would call Notify, passing fnewNewMail and the details of the new message. When Outlook gets this new message notification, it passes the Entry ID over to the rules engine and everything is hunky dory.

Unfortunately, this doesn't work in Outlook 2007. You fire your notification, Outlook sees it, then Outlook decides not to run rules on the message. Why? Because when Outlook 2007 looked at PR_STORE_SUPPORT_MASK on the wrapped PST, it found the STORE_ITEMPROC flag was set. This means the wrapped PST is an "Item Proc" store, and handles rules differently. Without getting into too many details about "Item Proc", the general idea is that such stores will feed new items into a pipeline where rules, junk mail, and spam processing can happen before listening clients will get a notification. This concept was introduced in Outlook 2007 as a way to streamline the processing.

When an Item Proc store knows it has a new message, it calls a special callback function in Outlook to run it through the rules engine. In the PST, the concept of "newly delivered message" is handled through internal flags. These flags may be set or not set depending on how the message arrives in the PST. For instance, if the PST is being used as an OST and new mail is synchronized from an Exchange server, the flags will be set. Similarly, when the PST is being used as a back end POP3/IMAP, the flags will be set when a new mail is delivered.

For a wrapped PST, however, the way you set these flags is to pass ITEMPROC_FORCE in the SaveChanges call when the newly delivered message is committed to the store. This tells the PST to set its internal flags and mark the item as being eligible for the callback.

There's a twist though. If the mail being delivered to the PST came from Exchange, then rules would already have run on the server and the message has to be handled differently. And the default assumption is that the mail came from Exchange. So you have to indicate that Exchange was not the source of the mail by also passing the NON_EMS_XP_SAVE flag. When both flags are passed, the item will go through rules/junk/spam processing as soon as you call SaveChanges if Outlook is running, and shortly after Outlook starts if it wasn't.

Definitions of the new flags:

ITEMPROC_FORCE 0x00000800 A client can call IMAPIProp::SaveChanges setting the ITEMPROC_FORCE flag in the ulFlags parameter to indicate that a message is being delivered to a PST and should be eligible for rules processing. This flag is only available if the message is being saved to a PST. A wrapped PST store would use this flag to indicate new mail is being delivered through IMAPIFolder::CreateMessage and IMAPIProp::SaveChanges. If this flag is not passed in combination with NON_EMS_XP_SAVE when a message is delivered in this fashion rules will not fire.
NON_EMS_XP_SAVE 0x00001000 A client can call IMAPIProp::SaveChanges setting the NON_EMS_XP_SAVE flag in the ulFlags parameter to indicate that a message is being delivered to a PST and should be eligible for rules processing, and that the mail was not delivered from Exchange. This flag is only available if the message is being saved to a PST. A wrapped PST store would use this flag to indicate new mail is being delivered through IMAPIFolder::CreateMessage and IMAPIProp::SaveChanges. If this flag is not passed in combination with ITEMPROC_FORCE when a message is delivered in this fashion rules will not fire.
STORE_ITEMPROC 0x00200000 The message store implements Item Proc logic. Outlook 2007 will not fire rules on messages in this store when it receives an fnevNewMessage notification.