Skip to content

Instantly share code, notes, and snippets.

@bosim
Last active August 25, 2016 06:28
Show Gist options
  • Save bosim/371e642ef6d42a90f3454e247e1e658f to your computer and use it in GitHub Desktop.
Save bosim/371e642ef6d42a90f3454e247e1e658f to your computer and use it in GitHub Desktop.
// Example use of kopano MAPI
#include "platform.h"
#include <iostream>
#include <mapi.h>
#include <mapiutil.h>
#include <kopano/Util.h>
#include <kopano/ECLogger.h>
#include "CommonUtil.h"
#include "inetmapi/inetmapi.h"
using namespace std;
IAddrBook *lpAddrBook;
ECLogger* lpLogger;
sending_options sopt;
void fetchMessage(IMAPISession *lpSession, LPMDB lpStore, SBinary &sEntryID) {
HRESULT hr = S_OK;
LPMESSAGE lpMessage = NULL;
LPSTREAM lpStream = NULL;
ULONG ulObjType;
string strMessage;
char *szMessage = NULL;
hr = lpStore->OpenEntry(sEntryID.cb, (LPENTRYID) sEntryID.lpb, &IID_IMessage, MAPI_DEFERRED_ERRORS, &ulObjType, (LPUNKNOWN *) &lpMessage);
if (hr != hrSuccess) {
goto exit;
}
hr = lpMessage->OpenProperty(PR_EC_IMAP_EMAIL, &IID_IStream, 0, 0, (LPUNKNOWN*)&lpStream);
if (hr == hrSuccess) {
hr = Util::HrStreamToString(lpStream, strMessage);
if (hr == hrSuccess) {
strMessage = strMessage.c_str();
}
}
else {
hr = IMToINet(lpSession, lpAddrBook, lpMessage, &szMessage, sopt, lpLogger);
if (hr != hrSuccess) {
lpLogger->Log(EC_LOGLEVEL_ERROR, "Error converting MAPI to MIME: 0x%08x", hr);
goto exit;
}
strMessage = szMessage;
}
std::cout << strMessage << std::endl;
exit:
return;
}
void fetchMessages(IMAPISession *lpSession, LPMDB lpStore, SBinary &sEntryID) {
IMAPIFolder *lpFolder = NULL;
HRESULT hr = S_OK;
ULONG ulObjType;
IMAPITable *lpTable = NULL;
LPSRowSet lpRowSet = NULL;
ULONG ulRows = 0;
enum { EID, SIZE, NUM_COLS };
SizedSPropTagArray(NUM_COLS, spt) = { NUM_COLS, {PR_ENTRYID, PR_MESSAGE_SIZE} };
hr = lpStore->OpenEntry(sEntryID.cb, (LPENTRYID) sEntryID.lpb, &IID_IMAPIFolder, 0, &ulObjType, (LPUNKNOWN *)&lpFolder);
if (hr != hrSuccess) {
cout << "Unable to open inbox" << endl;
goto exit;
}
hr = lpFolder->GetContentsTable(0, &lpTable);
if (hr != hrSuccess) {
cout << "Unable to open contents table" << endl;
goto exit;
}
// Set the columns of the table
hr = lpTable->SetColumns((LPSPropTagArray)&spt, 0);
if (hr != hrSuccess) {
cout << "Unable to setcolumns" << endl;
goto exit;
}
while(TRUE) {
// returns 50 rows from the table, beginning at the current cursor position
hr = lpTable->QueryRows(50, 0, &lpRowSet);
if (hr != hrSuccess)
goto exit;
if (lpRowSet->cRows == 0)
break;
for (int i = 0; i < lpRowSet->cRows; i++)
{
cout << "Text: " << i << lpRowSet->aRow[i].lpProps[EID].Value.bin.cb << endl;
fetchMessage(lpSession, lpStore, lpRowSet->aRow[i].lpProps[EID].Value.bin);
}
ulRows += lpRowSet->cRows;
// Free rows and reset variable
FreeProws(lpRowSet);
lpRowSet = NULL;
}
exit:
return;
}
void recurse(IMAPISession *lpSession, LPMDB lpStore, SBinary &sEntryID) {
IMAPIFolder *lpFolder = NULL;
HRESULT hr = S_OK;
ULONG ulObjType;
IMAPITable *lpTable = NULL;
LPSRowSet lpRowSet = NULL;
enum { EID, NAME, IMAPID, SUBFOLDERS, CONTAINERCLASS, NUM_COLS };
SizedSPropTagArray(NUM_COLS, spt) = { NUM_COLS, {PR_ENTRYID, PR_DISPLAY_NAME_W, PR_EC_IMAP_ID,
PR_SUBFOLDERS, PR_CONTAINER_CLASS_A } };
std::cout << "recurse cb" << sEntryID.cb << " lpb " << (int) *(sEntryID.lpb) << std::endl;
hr = lpSession->OpenEntry(sEntryID.cb, (LPENTRYID) sEntryID.lpb, &IID_IMAPIFolder, 0, &ulObjType, (LPUNKNOWN *) &lpFolder);
if (hr != hrSuccess)
goto exit;
hr = lpFolder->GetHierarchyTable(0, &lpTable);
if (hr != hrSuccess)
goto exit;
hr = lpTable->SetColumns((LPSPropTagArray) &spt, 0);
if (hr != hrSuccess)
goto exit;
hr = lpTable->QueryRows(50, 0, &lpRowSet);
if (hr != hrSuccess)
goto exit;
for (ULONG i = 0; i < lpRowSet->cRows; ++i) {
if (PROP_TYPE(lpRowSet->aRow[i].lpProps[NAME].ulPropTag) == PT_UNICODE) {
char test[20];
wcstombs(test, lpRowSet->aRow[i].lpProps[NAME].Value.lpszW, 20);
std::cout << "Folder: " << test << std::endl;
}
if (PROP_TYPE(lpRowSet->aRow[i].lpProps[SUBFOLDERS].ulPropTag) == PT_BOOLEAN) {
recurse(lpSession, lpStore, lpRowSet->aRow[i].lpProps[EID].Value.bin);
}
}
fetchMessages(lpSession, lpStore, sEntryID);
exit:
if (lpRowSet)
FreeProws(lpRowSet);
if (lpTable)
lpTable->Release();
return;
}
int main(int argc, char *argv[])
{
HRESULT hr = S_OK;
IMAPISession *lpSession = NULL;
ULONG cbEntryID = 0;
LPMDB lpStore = NULL;
LPENTRYID lpEntryID = NULL;
ULONG ulType = 0;
IMAPIFolder *lpInbox = NULL;
ULONG ulRows = 0;
LPSSortOrderSet lpSortCriteria = NULL;
LPSPropValue lpPropVal = NULL;
SBinary sEntryID;
imopt_default_sending_options(&sopt);
sopt.no_recipients_workaround = true; // do not stop processing mail on empty recipient table
sopt.add_received_date = true;
// Initialize mapi system
hr = MAPIInitialize(NULL);
if ( hr != hrSuccess)
goto exit;
lpLogger = new ECLogger_Null();
wchar_t user[20];
wchar_t pass[20];
mbstowcs(user, "XXX", 20);
mbstowcs(pass, "XXX", 20);
hr = HrOpenECSession(lpLogger, &lpSession, "test", "0", user, pass, "http://localhost:10236/");
if (hr != hrSuccess) {
cout << "Cannot open session for user " <<argv[1]<< " with pass " <<argv[2]<< " on server " <<argv[3]<< endl;
goto exit;
}
// Get the default Store of the profile
hr = HrOpenDefaultStore(lpSession, &lpStore);
if (hr != hrSuccess) {
cout << "Unable to open default store" << endl;
goto exit;
}
hr = HrGetOneProp(lpStore, PR_IPM_SUBTREE_ENTRYID, &lpPropVal);
if (hr != hrSuccess) {
goto exit;
}
hr = lpSession->OpenAddressBook(0, NULL, AB_NO_DIALOG, &lpAddrBook);
if (hr != hrSuccess) {
lpLogger->Log(EC_LOGLEVEL_ERROR, "Failed to open addressbook");
goto exit;
}
sEntryID = lpPropVal->Value.bin;
recurse(lpSession, lpStore, sEntryID);
exit:
// Free all allocated memory
if (lpInbox)
lpInbox->Release();
if (lpEntryID)
MAPIFreeBuffer(lpEntryID);
if (lpSortCriteria)
MAPIFreeBuffer(lpSortCriteria);
if ( lpStore)
lpStore->Release();
if (lpSession)
lpSession->Release();
MAPIUninitialize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment