MAPI – Enumerating emails in C++


   The Microsoft Exchange server and outlook have become indispensable in an office environment. More applications are written using MAPI to handle e-mails for several purposes. This article explains how to use MAPI to enumerate the e-mails in one’s inbox.

   The first step in any MAPI environment is to initialize MAPI by calling The Microsoft Exchange server and outlook have become indispensable in an office environment. More applications are written using MAPI to handle e-mails for several purposes. This article explains how to use MAPI to enumerate the e-mails in one’s inbox.

   The first step in any MAPI environment is to initialize MAPI by calling MapiInitialize() function. Then the use of MAPILogonEx with the right Exchange mail profile gets access to all the messages/ data inside one’s profile.

   After one has logged in, then the same session can be used to access the inbox, sent items, deleted items etc., data from the mail box. The following program is a sample for enumerating all the e-mails from one’s inbox.

   This program assumes that the user already has a profile created and has enough rights to access it through a program i.e., Reading e-mails, Writing e-mails etc., If there is any problems in the Exchange Development kit installation refer to Installation, Configuration and Recompiling the MAPI Exchange Development Kit to rectify the linker problems.


      #include <afxwin.h>
#include <edk.h>

LPMAPISESSION pSession = NULL;

int main()
{

HRESULT hr = S_OK;
//Initialize MAPI libraries. First step on MAPI Programming
hr = MAPIInitialize (NULL);

// logon to MAPI for enumerating emails from inbox. This can also be used to open the public folders, if one has access.
hr = MAPILogonEx (NULL, "ProfileName", NULL, MAPI_EXTENDED| MAPI_NEW_SESSION|
MAPI_LOGON_UI| MAPI_EXPLICIT_PROFILE,&pSession);
if (FAILED (hr))
return E_FAIL;

// Find default message store using HRMAPI function
ULONG cbDefStoreEntryid = 0;
LPENTRYID pDefStoreEntryid = NULL;
hr = HrMAPIFindDefaultMsgStore(pSession, &cbDefStoreEntryid, &pDefStoreEntryid);
if (FAILED (hr))
return E_FAIL;

// open the MAPI Public Folder tree
LPMDB pDefaultMsgStore = NULL;
hr = pSession->OpenMsgStore(0, cbDefStoreEntryid, pDefStoreEntryid, NULL,
MDB_WRITE | MAPI_DEFERRED_ERRORS, &pDefaultMsgStore );
if (FAILED (hr))
return E_FAIL;

DWORD cbeid = 0;
LPENTRYID lpeid = NULL;
LPMAPIFOLDER pFolder = NULL;
ULONG ulObjType = 0;

//Path to the inbox
CString l_strFullPath = "@PR_IPM_SUBTREE_ENTRYID\Inbox";

//Used to filter the columns for enumerating emails using MAPI
SizedSPropTagArray ( 2, rgPropTag ) =
{
2,
{
PR_ENTRYID, // its unique across directory
PR_SUBJECT
}
};

// Open the Inbox folder
hr = HrMAPIOpenFolderEx(pDefaultMsgStore,  '\', (LPCTSTR)l_strFullPath, &pFolder);
if (FAILED (hr))
return E_FAIL;

LPMAPITABLE lpMapiTbl = NULL;
        //Enumerate emails using MAPI in C++

        hr = pFolder->GetContentsTable(0, &lpMapiTbl);
if (FAILED (hr))
return E_FAIL;

// Get count rows
ULONG ulRows = 0;
hr = lpMapiTbl->GetRowCount(0, &ulRows);
if (FAILED (hr))
return E_FAIL;

hr = lpMapiTbl->SetColumns((LPSPropTagArray)&rgPropTag, 0 );

if (FAILED (hr)) return E_FAIL;

// Get all rows
SRowSet * pRows = NULL;
hr = HrQueryAllRows(lpMapiTbl,NULL, NULL, NULL, ulRows,&pRows);
if (FAILED (hr)) return E_FAIL;

printf("Total Number of messages : %dn",pRows->cRows);
       //Uncomment this loop if you want to display the subject of all emails
/* for(int i=0;i<pRows->cRows;i++)
{
if(PR_SUBJECT == pRows -> aRow[i].lpProps[1].ulPropTag)
{
printf("%sn",pRows -> aRow[i].lpProps[1].Value.lpszA);
}

}
*/
       //Release all the resources used
if (lpMapiTbl)
lpMapiTbl->Release();
if (pRows)
FreeProws(pRows);

if(pFolder)
pFolder->Release();

if(pDefaultMsgStore)
pDefaultMsgStore->Release();

MAPIFreeBuffer (lpeid);

pFolder = NULL;
//Free all MAPI libraries
MAPIUninitialize();

}

   The above sample code can retrieve the whole environment block and display it in the console.

C++ MAPI Enumerate emails – Libraries Required:

Link the MFC used in Shared Dll option in the MFC properties. Add these libraries in the project settings–> Link –> Object/library modules.
mapi32.lib Edkguid.lib Edkutils.lib Edkmapi.lib Addrlkup.lib Edkdebug.lib Version.lib Mblogon.lib.