This was discussed a while back in one of the newsgroups. I figured I'd document it a little more permanently here.
Outlook 2007's version of the Exchange provider, emsmdb32, doesn't automatically add the Public Folder store to the message store table of a new profile. Instead, it waits until a successful connection has been made to the Exchange server. If it then detects that the public folders are available, it updates the profile and sends a table notification indicating the availability of Public Folders. This is a change from previous versions of Outlook and from Exchange's version of the provider. We made this change to better support Exchange 2007's Public Folder-less environments.
This mechanism of using a table notification has caused some confusion though. Many have observed that the table doesn't appear to be updated at all, yet if they log off the profile and log back on, Public Folders are now suddenly listed. The problem is that for notifications to be processed, messages have to be pumped, and a lot of console or service based MAPI applications don't pump messages. This is where HrDispatchNotifications comes in.
Most MAPI developers probably aren't familiar with this function, but they should be. It does exactly what it says it's going to do: it makes sure all pending notifications have been dispatched. It does this by grabbing the internal table of pending notifications, then pumping messages until the table is empty. As the documentation for the function notes, you could implement this yourself using PeekMessage and DispatchMessage, but not nearly as efficiently.
Here's the general algorithm for logging on to Public Folders using Outlook 2007's version of MAPI:
Exercise for the reader 1: Keeping the above in mind, what happens when you use a dynamic profile in CDO?
Exercise for the reader 2: Suppose you create a dynamic profile with CDO, then before closing, it, you Logon again, using the name of the first profile as the first parameter to the second Logon? Hint: remember that deleted profiles aren't really deleted.
Raymond and Matt just posted their own thoughts on e-mail etiquette, especially as it applies here at Microsoft. I figure this is a good point for me to highlight my own pet peeve:
Please include me in your reply as I am not a member of this DL
Please include me in your reply as I am not a member of this DL
To understand why this phrase both amuses and annoys me, you have to understand what a DL is. A DL, or Distribution List, is a list of e-mail addresses used for mail routing in Exchange (and I'm sure, just about everywhere else). This way you can spam ask a bunch of people a question at the same time. When you send a mail to a DL, everybody on the DL gets a copy of the message. The To line is the alias of the DL, and the From line is the person who sent the message.
So, for example, if MAPINeophyte@microsoft.com sends a mail to MAPIRocks@microsoft.com, a DL I'd be a member of, then I'd get a mail in my inbox that's to MAPIRocks, and from MAPINeophyte.
Guess what happens if I Reply to this message? It's addressed to MAPINeophyte! What if I Reply All? Then it's addressed to MAPINeophyte and MAPIRocks. In other words, I'd have to take extra steps to make sure that my reply doesn't go to the guy that sent the mail!
So why do people think they need to ask that they be included on the reply? Perhaps they came from the newsgroup world, where messages and replies get posted to a central list, but not to individuals unless extra steps are taken? Or maybe they're so insecure as to think that anyone who got a mail from them would be certain to remove their name from it before replying? I don't know - some times folk are just weird.
I'm sure this will get comments. Please be sure to include me on them as I don't subscribe to this blog. :)
[This is now documented here: http://msdn.microsoft.com/en-us/library/dd188684.aspx ]
Development just gave me permission to document this.
Exchange 2007 and Outlook 2007 introduce the concept of a Freebusy access rights to user mailboxes. This is part of the push to eliminate the dependency on Public Folders. Previous versions of Exchange and Outlook depended on a special Public Folder where user's Freebusy information would be published. Other users could then access this folder to determine if someone was free for a meeting.
This system had many drawbacks: Public Folder replication, stale data, incomplete data, etc. It also can't work at all if there are no Public Folders.
So a new system was developed. In the new system, the client would not rely on possibly incorrect data published in a Public Folder. Instead, it uses the new Availability Service to get Freebusy information. In addition, two new rights were exposed on the permissions tab in Outlook 2007, "Free/Busy time" and "Free/Busy time, subject, location".
The use of these permissions is documented elsewhere. Here's how to get at and set them programmatically.
Like other permissions on MAPI folders, these are accessed through PR_ACL_TABLE (see this and this for some sample code). However, suddenly returning new rights in the table was likely to break existing code, so to see/set these rights, you have to request them. This is done by passing ACLTABLE_FREEBUSY as a flag in GetTable. Once this is done the new free busy rights, frightsFreeBusySimple and frightsFreeBusyDetailed, will show in PR_MEMBER_RIGHTS. ACLTABLE_FREEBUSY also needs to be passed in ModifyTable when setting these new rights.
Additionally, we introduced a new security descriptor property, PR_FREEBUSY_NT_SECURITY_DESCRIPTOR, which you will find on the Calendar folder. This property is of the same format as PR_NT_SECURITY_DESCRIPTOR and can be read with similar code (see this to get started, or borrow the CMySecInfo class from MFCMAPI). The access mask will also show the new permissions, as fsdrightFreeBusySimple and fsdrightFreeBusyDetailed. The effective permissions read via this property are the same as those set through the ACL table, so changes made to one will be reflected in the other.
Finally, ACLTABLE_FREEBUSY and the new property PR_FREEBUSY_NT_SECURITY_DESCRIPTOR can only be accessed using MAPI from Outlook 2007 or the MAPI download. Outlook and Exchange 2003's versions of MAPI do not understand them.
Without further ado, here are the constants you'll need:
#define ACLTABLE_FREEBUSY ((ULONG) 0x00000002)
#define frightsFreeBusySimple 0x0000800L
#define frightsFreeBusyDetailed 0x0001000L
#define fsdrightFreeBusySimple 0x00000001
#define fsdrightFreeBusyDetailed 0x00000002
#define PR_FREEBUSY_NT_SECURITY_DESCRIPTOR (PROP_TAG(PT_BINARY,0x0F00))
Believe it or not, we're still getting calls on the recent Daylight Saving Time changes. Most of the time it just turns out to be an unpatched server somewhere, but this last one I got had most everybody stumped. The customer was reporting that meeting requests sent from their Sharepoint server showed up an hour off when they were received in Outlook, but only if the meeting was scheduled for the first week of November. They also noted that meeting requests "received from the Internet" were also an hour off.
Now - that's the classic description of an unpatched machine, but an inventory of their Exchange and Sharepoint servers showed that all were patched correctly. Same for all the client machines.
I picked up the issue as it got escalated up the chain. First thing I did was to ask them what they meant by requests "received from the Internet". They explained that if you set up a Gmail account with a calendar, then exported it as ICS and imported it to Outlook, the meetings in the first week of November would be off by an hour. I figured there's really only two scenarios to consider here:
Ok - so this was simple enough to test out. I signed up for a Gmail account, created some appointments, and shared my calendar out so I could grab the ICS. And sure enough, when I imported it into Outlook, the appointments were wrong.
Here's the URL to my Gmail calendar: http://www.google.com/calendar/ical/mfcmapi%40gmail.com/public/basic.ics
When I first downloaded this ics file, it contained the following (truncated of course):
BEGIN:VTIMEZONE ... RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU ... RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU ... END:VTIMEZONE
The first RRULE there roughly translates to "Yearly on the last Sunday in October" and the second to "Yearly on the first Sunday in April". That's the old Eastern timezone definition. So of course the meeting looks funny when read in to Outlook.
If you look at my Gmail calendar now though, you'll find the correct RRULEs. This happened when I switched my Gmail timezone to another timezone and then back to Eastern. I don't know if anyone else is having problems with .ics exported from Gmail, but if you are it's worth trying this.
Back to the customer's issue - maybe they were having the same problem? After all, Sharepoint isn't really MAPI aware, so any meeting request it sends is likely to be iCalendar. I asked them to include me on one of their meeting requests. Here's what I found in the .ics they sent out:
PRODID:-//Advanced Intellect//aspNetEmail Calender Writer(v126.96.36.199)//EN ... RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=10;BYDAY=-1SU ... RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=4;BYDAY=1SU
Whaddya know? There's those old timezone rules again. Most interestingly, that PRODID indicates it's not even Sharepoint that created this .ICS, but instead a component called aspNetEmail, created by a company called Advanced Intellect. A little digging on their site finds their post concerning DST. Double checking their change log confirmed that they took a fix for DST in build 188.8.131.52. As soon as the customer applies the update to aspNetEmail, they should be back in business!
BTW - In all fairness to the guy that called the problem in - he didn't know that his Sharepoint guys were using this component. He accepted at face value that when they said they "sent the meeting request with Sharepoint" it meant Sharepoint was really sending the meeting request.