Ignoring Notifications

Suppose you want to register for notifications on all the visible folders in a user’s mailbox. One option would be to walk the list of folders in the hierarchy tree and register for notifications. That would work, but would be very inefficient. It also wouldn’t be dynamic, since you wouldn’t catch new folders as they’re created. And if you register for too many notifications, you might run into this problem. A more elegant solution is to register for notifications at the message store level. This is what one customer did, but recently they ran into a problem with one of the new features in Outlook 2007.

Before Outlook 2007, if someone gave you permissions to see their Calendar, when you opened their Calendar Outlook would have to make a direct connection to their mailbox server, even if your profile was running in Cached mode. This was never an ideal experience for the user, as they would have to wait while Exchange built the views for the folder. And if too many people shared the same calendar, you could run into a scenario where each time a user looked at the folder, some other user’s views were deleted to make room, essentially meaning access for everyone, including the owner of the mailbox, was slow. This is a nasty scenario that isn’t fun to troubleshoot or resolve. Cached mode lessens the problem for the owner of the mailbox; their access will always be fast. But it doesn’t help the other users.

With Outlook 2007, we added the idea of caching these shared folders. You may have seen the option in your mailbox settings:

Mailbox settings dialog showing the "Download shared folders" option

This allows you to cache a copy of the other users Calendar, Contacts, Tasks and Notes folders in your own mailbox so you don’t have to connect to the Exchange server every time you want to look at them. The folders get updated periodically through the same incremental change synchronization (ISC) mechanism used to sync your own mailbox. (BTW – if you want to cache mail folders too, there’s a reg key for that.)

Since we’re caching these folders locally, the data has to live somewhere right? And where else but right there in your OST! Taking a look at my cached mode profile using MFCMAPI, we can see I have Jeff Garman’s Calendar cached:

Sgriffin's mailbox as seen in MFCMAPI, showing the Shared Data folder with Jeff's Calendar

This is where the customer ran into a problem. Remember they were registering for notifications store wide. In cached mode, that would include these folders under Shared Data, which they weren’t particularly interested in. Their question was how to identify which notifications were for these Shared Data folders so they could ignore them. Now, it turns out we haven’t documented many MAPI properties in this area, but there’s a way to approach this that doesn’t require any special knowledge. The key is recognizing that all the folders they do wish to monitor live under IPM_SUBTREE, and that folder is well documented. Here’s the approach we worked out:

  1. Maintain a cache of known folder entry IDs. Each entry would be accompanied by a Boolean indicating whether the folder is under IPM_SUBTREE or not.
  2. Seed the cache with the entry IDs for IPM_SUBTREE, marked as being under IPM_SUBTREE, and the root folder, marked as being not under IPM_SUBTREE.
  3. Implement a function, IsUnderIPMSubtree, which checks if the target entry ID is in the cache, and returns the value it finds. Comparisons should be done with CompareEntryIDs.
  4. If the entry ID is not in the cache, IsUnderIPMSubtree obtains the entry ID of the parent folder, and calls IsUnderIPMSubtree with that parent entry ID
  5. The result of this recursive IsUnderIPMSubtree call is cached with the target entry ID, and the value is then returned.
  6. Whenever a notification comes in, use the function IsUnderIPMSubtree to determine if the notification was interesting or not.

This algorithm makes the most sense to run in Cached mode, where CompareEntryIDs and OpenEntry will both be relatively cheap. Expected recursion level should be rather low, and the total number of folders opened over the lifetime of the algorithm is capped by the total number of folders in the store. In addition to filtering out notifications from the Shared Data folders, you’ll also eliminate any spurious notifications from any of the other non-visible folders.