MAPI on Windows Mobile: Backup and Restore Mails

  • Backup\Restore: is there a standard way?
  • How to programmatically mark messages so that they are downloaded at next sync
  • About linked attachments

Yet another post about MAPI on Windows Mobile, it seems it became an common topic (not well covered over the web probably)… I recently worked with one of my colleagues in Redmond (thanks Alex! smile_regular) about the following topic: how to use MAPI, if possible, to backup and restore e-mails sync-ed with a backend Exchange server (so by using ActiveSync MAPI Store).

After some investigation about the possible combination of properties, we understood that if the message is partially downloaded (only the header, or partially downloaded, or without downloading attachments) the is no standard way on how to retrieve the rest of information, such as a link or so to click for downloading, after restoring the messages from a backup file – simply because the server at that point will consider the message as different from the initial one.

At the beginning we imagined the problem was only with message body… and you can programmatically state if a message hasn't fully downloaded by looking at its properties MSGSTATUS_HEADERONLY, MSGSTATUS_PARTIAL_DOWNLOAD or MSGSTATUS_PARTIAL. So… how to programmatically mark messages so that they are downloaded at next sync? To mark a message for download, you should close the messaging application (tmail.exe), add the property MSGSTATUS_REMOTE_DOWNLOAD to the message and then restart the messaging application (tmail.exe). Note that if you don't want the download to start immediately, then you should also modify the message's PR_CE_SUPPRESS_FETCH property in the same call to IItem::SetProps, accordingly to documentation. I’m talking about something like:

 SPropValue rgProps[2];

rgProps[0].ulPropTag = PR_MSG_STATUS;
rgProps[0].Value.ul  = ulMsgStatus | MSGSTATUS_REMOTE_DOWNLOAD | MSGSTATUS_REMOTE_DOWNLOAD_ATTACH;
rgProps[1].ulPropTag = PR_CE_SUPPRESS_FETCH;
rgProps[1].Value.ul  = 1;

hr = pMsg->SetProps(2, &rgProps, NULL);
CHR(hr);

Note: MSGSTATUS_REMOTE_DOWNLOAD is not mentioned under the "Windows Mobile Defined MAPI Properties" documentation, but you can see it defined in the related SDK's header file ("C:\Program Files (x86)\Windows Mobile 6 SDK\PocketPC\Include\Armv4i\cemapi.h"), so you can use it – in other words, the documentation is not complete on that page.

Note that this may not be a complete solution, accordingly to Jay Ongg's answer to a comment on a Windows Mobile Dev Team's blog post (here):

"[...] Regarding MSGSTATUS_PARTIAL, downloading a whole message is actually more complicated than just setting a flag. Depending on the transport, you have to think about downloading attachments, which is done different for HTML mail vs normal attachments, I believe. With that said, this might work... try setting the MSGSTATUS_REMOTE_DOWNLOAD flag to start out, and MSGSTATUS_REMOTE_DOWNLOAD_ATTACH as well. "

Indeed, as reported by Jay, the approach above resolved the problem for message bodies, but not for attachments! smile_sad So… to recap: imagine you wish to copy a MAPI message that has a non-downloaded attachment into an unspecified backup storage; later, you copy the message from the backup store into the messaging store. What we expected was that the attachment to still be part of the message, but we found that the message's link to download the attachment is missing. Is there any supported way so that the attachment remains in the message after performing the backup and then retrieving the message? The answer is simply “no”. Trying to copy (backup) the email message with a non-downloaded attachment will not work. The link to the attachment will be lost, the attachment won’t be retrievable. The email and the non-downloaded attachment are associated with each other in Exchange, however the attachment is not actually a part of the message, so copying the message will not make a copy of the attachment. So the solution is to force the attachment to be downloaded before backing up the message (if user wants to maintain the attachment). Obviously saving the message and attachment on the device might not be a workable solution due to the storage space required… but, as usual, that depends on scenarios.

 

Cheers!

~raffaele & Alex