Unable to read other user's calendar

Mar 25, 2013 at 12:30 AM
This is presumably not an MFCMAPI error as such, but I hope someone has a suggestion.

The MFCMAPI sequence which previously has worked to read another user's calendar has been this:

MDB - Open other mailboxes - From GAL
  • select a user who has shared their calendar with the current user
  • in the dialog "Open Other User's Message Store" specify 0x0000000C (OPENSTORE_HOME_LOGON + OPENSTORE_TAKE_OWNERSHIP)
  • a new dialog is displayed showing this user's message store
    Actions - Open special folder - Calendar
This usually works, but for one specific installation I am getting the following error at this point:

Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function OpenDefaultFolder(ulFolder, lpMDB, &lpFolder)
File MsgStoreDlg.cpp
Line 197

I think the relevant lines from the MFCMAPI log file are these:

0x0634 04:15:37.214PM 03-24-2013 0x00000001: GetSpecialFolderEID: getting 0x36D00102 from 0359B1EC
0x0634 04:15:37.214PM 03-24-2013 0x00000001: GetInbox: getting Inbox from 0359B1EC
0x0634 04:15:37.214PM 03-24-2013 0x00000001: GetInbox: getting Inbox from 0359B1EC
0x0634 04:15:37.214PM 03-24-2013 0x40000000: Function call: MAPIFunctions.cpp@1058: lpMDB->GetReceiveFolder( (LPTSTR) _T("IPM.Note"), fMapiUnicode, &cbInboxEID, &lpInboxEID, NULL)
0x0634 04:15:37.214PM 03-24-2013 0x00000001: CallOpenEntry: Calling OpenEntry on MDB with ulFlags = 0x10
0x0634 04:15:37.229PM 03-24-2013 0x40000000: Function call: MAPIFunctions.cpp@81: lpMDB->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
0x0634 04:15:37.229PM 03-24-2013 0x00000040: Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function lpMDB->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
File MAPIFunctions.cpp
Line 81

This is an Outlook 2010 32-bit MAPI communicating with an Exchange Server 2010 SP2.

Thanks in advance for any suggestions.
Coordinator
Mar 25, 2013 at 1:52 PM
In order to open someone else's calendar when you don't have full permissions to their hierarchy, you have to use certain tricks to locate the calendar. One of these tricks is that Outlook will record the location (entry ID) of the calendar in a special property located on the Inbox folder. Delegates trying to open this user's calendar will look for this entry ID, then try to open it. If the entry ID happens to be incorrect, then we can't find the folder.

I bet you see a similar failure if you try to use Outlook to open this particular user's calendar folder.

Most likely, if this user runs Outlook with the /resetfolders or /resetfoldernames switch, Outlook will rewrite the Calendar pointer and you should be able to then open it.
Mar 25, 2013 at 2:24 PM
Thank you very much for your reply.
I bet you see a similar failure if you try to use Outlook to open this particular user's calendar folder.
No, Outlook is showing these other users' calendars just fine.
Most likely, if this user runs Outlook with the /resetfolders or /resetfoldernames switch, Outlook will rewrite the Calendar pointer and you should be able to then open it.
I've now tried starting Outlook with these two options, but there is no change for MFCMAPI - it still produces the same error.

Do you have any more precise information, for example a link to a code sample, about how to read other users' calendars via the "special property located in the Inbox folder" you mention?

Thanks again.
Coordinator
Mar 25, 2013 at 2:35 PM
I just looked at the log again - you're actually failing to open the Inbox. This puts the problem earlier in the process. We get the entry ID for the Inbox from the Receive Folder table. You'll find this here:
MDB/Display/Receive folder table...
Specifically, we try the entry IPM. I'd try that and see what happens when you click on the IPM entry.
Mar 25, 2013 at 4:07 PM
Thank you very much for your time - I really appreciate it.

Yes, it is correct that these users' Inboxes are not available. If I try to open them with Outlook then I get the message "Cannot display the folder. The Inbox folder cannot be found."

But Outlook is able to display the calendars, and it is only the calendars that I am interested in.

Here is what I experience with MFCMAPI:

MDB - Open other mailboxes - From GAL, and setting option bits to 0x0000000C

This displays a dialog with the person's name on the title bar and "Root Container" in the left column. (The fact that it displays "Root Container" - is that significant? On the systems where things are working as expected MFCMAPI ususally displays the person's name in the left column.)

MDB - Display - Receive folder table

This displays a dialog with four lines: no message class, "IPC", "IPM" and "REPORT.IPM".

When I click on the IPM line it displays six properties in the lower half of the dialog, the first of which is marked with the error icon. But that's typical, isn't it?

Does this clarify things at all?

My knowledge of MAPI is rather limited. My policy is usually "if Outlook can do it, then MFCMAPI should be able to do it, and if MFCMAPI can do it, then my program should be able to do it." But right now the first part of that policy is not working.

Thanks again for your time.
Coordinator
Mar 25, 2013 at 4:10 PM
The number of properties isn't what matters here. What matters is the source of the properties. If you succeeded in opening an object, the status bar should say the properties came from an object. If not, it'll say they came from the table. In this case, with just 6 properties, I'm guessing they came from the table.

Have you tried just navigating to the Calendar folder? There's more than one way to get to that folder. The option you're trying in MFCMAPI is just one way to get there.
Mar 25, 2013 at 4:36 PM
If you succeeded in opening an object, the status bar should say the properties came from an object. If not, it'll say they came from the table.
The colored bar at the bottom of the dialog says "Properties retrieved from row".
Have you tried just navigating to the Calendar folder? There's more than one way to get to that folder.
Ah, that sounds good. Except for the fact that I don't know what the other ways are. You are talking about something that can be done via MFCMAPI, I hope?

Thanks again.
Coordinator
Mar 25, 2013 at 6:28 PM
Yes - try expanding the Root Container folder and see if you can drill down to the Calendar. Or try looking at the Root Container object and locate the PR_IPM_APPOINTMENT_ENTRYID property. You can right click on that property and pick "Open as entry ID of object".
Mar 25, 2013 at 11:06 PM
Edited Mar 25, 2013 at 11:06 PM
Thanks for bearing with me ...
try expanding the Root Container folder and see if you can drill down to the Calendar.
I assume you mean double-click on "Root Container", or use Actions - Open contents table. Doing this results in two error dialogs:

Error:
Code: MAPI_E_NO_ACCESS == 0x80070005
Function lpContentsTable->GetRowCount( NULL, &ulTotal)
File ContentsTableListCtrl.cpp
Line 647

Error:
Code: MAPI_E_NO_ACCESS == 0x80070005
Function lpContentsTable->QueryRows( (ulThrottleLevel)?ulThrottleLevel:NUMROWSPERLOOP, NULL, &pRows)
File ContentsTableListCtrl.cpp
Line 701
Or try looking at the Root Container object and locate the PR_IPM_APPOINTMENT_ENTRYID property. You can right click on that property and pick "Open as entry ID of object".
The good news is that there is indeed a PR_IPM_APPOINTMENT_ENTRYID property in the root container. The bad news is that if I do what you say then I get this error:

Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function CallOpenEntry( MyEID.GetCheck(1)?lpMDB:0, MyEID.GetCheck(2)?lpAB:0, NULL, MyEID.GetCheck(3)?lpMAPISession:0, (ULONG) cbBin, lpEntryID, NULL, (MyEID.GetCheck(4)?MAPI_MODIFY:MAPI_BEST_ACCESS) | (MyEID.GetCheck(5)?MAPI_NO_CACHE:0) | (MyEID.GetCheck(6)?MAPI_CACHE_ONLY:0), &ulObjType, &lpUnk)
File BaseDialog.cpp
Line 805

I think these are the relevant lines from the log file:

0x0cac 10:45:07.190PM 03-25-2013 0x00000001: CallOpenEntry: Calling OpenEntry on MDB with ulFlags = 0x10
0x0cac 10:45:07.206PM 03-25-2013 0x40000000: Function call: MAPIFunctions.cpp@81: lpMDB->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
0x0cac 10:45:07.206PM 03-25-2013 0x00000040: Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function lpMDB->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
File MAPIFunctions.cpp
Line 81
0x0cac 10:45:07.206PM 03-25-2013 0x00000001: CallOpenEntry: Calling OpenEntry on AB with ulFlags = 0x10
0x0cac 10:45:07.206PM 03-25-2013 0x40000000: Function call: MAPIFunctions.cpp@112: lpAB->OpenEntry( cbEntryID, lpEntryID, NULL, ulFlags, &ulObjType, &lpUnk)
0x0cac 10:45:07.206PM 03-25-2013 0x00000040: Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function lpAB->OpenEntry( cbEntryID, lpEntryID, NULL, ulFlags, &ulObjType, &lpUnk)
File MAPIFunctions.cpp
Line 112
0x0cac 10:45:07.206PM 03-25-2013 0x00000001: CallOpenEntry: Calling OpenEntry on Session with ulFlags = 0x10
0x0cac 10:45:07.221PM 03-25-2013 0x40000000: Function call: MAPIFunctions.cpp@176: lpMAPISession->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
0x0cac 10:45:07.221PM 03-25-2013 0x00000040: Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function lpMAPISession->OpenEntry( cbEntryID, lpEntryID, lpInterface, ulFlags, &ulObjType, &lpUnk)
File MAPIFunctions.cpp
Line 176
0x0cac 10:45:07.221PM 03-25-2013 0x00000040: Error:
Code: MAPI_E_NOT_FOUND == 0x8004010F
Function CallOpenEntry( MyEID.GetCheck(1)?lpMDB:0, MyEID.GetCheck(2)?lpAB:0, NULL, MyEID.GetCheck(3)?lpMAPISession:0, (ULONG) cbBin, lpEntryID, NULL, (MyEID.GetCheck(4)?MAPI_MODIFY:MAPI_BEST_ACCESS) | (MyEID.GetCheck(5)?MAPI_NO_CACHE:0) | (MyEID.GetCheck(6)?MAPI_CACHE_ONLY:0), &ulObjType, &lpUnk)
File BaseDialog.cpp
Line 805

Should I be specifying some options on that right-click menu?

Thanks for your help.
Coordinator
Mar 26, 2013 at 12:34 PM
What you've confirmed by looking at PR_IPM_APPOINTMENT_ENTRYID is that it is definitely wrong on that user's mailbox. It's very unclear how you would ever be able to access this user's calendar folder using Outlook. Here's one more command line switch that might reset the property: \CleanFreeBusy. Keep in mind that the owner of the target mailbox is the one that needs to run this, as their mailbox is the one which is broken.
Mar 26, 2013 at 2:17 PM
Thank you for your reply.
It's very unclear how you would ever be able to access this user's calendar folder using Outlook.
Outlook has no problems showing these other users' calendars. (I can send you a screen shot...)

I doubt very much that these mailboxes are "broken". It is a consistent problem with all of the mailboxes I've tried. This is a new installation that switched from Lotus Notes two weeks ago, and is set up by professional people.

I've been informed that there are actually two Exchange Servers involved, set up for load balancing, and the server name specified in the mail profile is a kind of alias that implies access to them both. Can this have anything to do with the difficulty of finding the calendars with MFCMAPI?

May I ask a very general question? Like I've said, I always figure that if Outlook can do something then MFCMAPI (and by reverse-engineering and steal.., I mean borrowing, then ultimately my program) should also be able to do it. But are there any "MAPI trace" tools available so that one can gain insight into exactly what Outlook has said to Exchange, and what Exchange replied?

Thank you.
Coordinator
Mar 26, 2013 at 2:24 PM
RenniePet wrote:
This is a new installation that switched from Lotus Notes two weeks ago
This makes it even more likely that the mailboxes are broken. This is not to besmirch the folks that did the migration. This particular problem is quite common with migrated data.

Outlook has no problems showing these other users' calendars. (I can send you a screen shot...)
A thought - are you sure Outlook is actually showing you the details from these other user's calendars? Outlook has a fallback mechanism for when it can't get the Calendar folder. It takes the information published in the user's Free/Busy and "fakes" a calendar, which for many purposes is good enough. You can tell when you're getting this fake calendar because you can't get any details, like subject, locations, or meeting notes.
Mar 26, 2013 at 3:25 PM
OK, I think we're finally on to something here. (And I'll say once again how much I appreciate all your help and time.)

What Outlook is showing for these other users does include subject and location, but you are right that it is not really information gotten directly from that user's calendar. If I double-click on one of these appointments I get "You do not have permission to view this calendar. Do you want to ask Harry Potter to share his or her Calendar with you?"

I can also see when I right-click on my own calendar and select Properties and look at the Permissions tab, that by default I am granting user "Default" a permission level of "Free/Busy time, subject, location". This is presumably the default setup for all users on this system. And this level of permission does not actually provide any access to the user's calendar datastore, right?

So I have a "solution": tell my customer that he has to change all of the mailboxes to provide "reviewer" calendar permission to the account my program runs under. I had assumed that this was the case, but was wrong. So to some extent this whole thread has been based on a misunderstanding, and I apologize.

But now that I finally understand, to some extent, what is going on, I'm curious as to what this is that Outlook is displaying and how it gets it. This is not the old-fashioned free/busy info that used to be in Exchange's public store, and has been depricated, right? This is some new kind of super-free/busy info? Is it documented somewhere? Can MFCMAPI display it? How can I query Exchange for it? I'd like to offer this in my "calendar connector" program as an alternative to the full-blown calendar-based access that needs reviewer permission granted.
Coordinator
Mar 26, 2013 at 3:32 PM
Mar 27, 2013 at 12:48 PM
So this "new" facility that I was unfamiliar with is six years old.

I think you should delete this thread. Thank you very much for your help.