c++mimemapi

c++ mapi IConverterSession MIMEToMAPI() is not working


Hi I am trying to use MAPI to convert the contents of an EML file to IMESSAGE data. I implemented the IConverterSession as follows, I didn't get any FAILED(hr) errors anywhere, but when I check the outlook store, a new pMessage has been created but the contents are empty. Outlook is installed 2016 version (not C2R)

#define USES_IID_IMAPIFolder

#include <initguid.h>
#include <mapiutil.h>
#include <mimeole.h>

interface IConverterSession : public IUnknown {
public:
    virtual HRESULT STDMETHODCALLTYPE MIMEToMAPI(LPSTREAM pstm, LPMESSAGE pmsg, LPCSTR pszSrcSrv, ULONG ulFlags)=0;
};


DEFINE_GUID(CLSID_IConverterSession, 0x4e3a7680, 0xb77a, 0x11d0, 0x9d, 0xa5, 0x0, 0xc0, 0x4f, 0xd6, 0x56, 0x85);
DEFINE_GUID(IID_IConverterSession, 0x4b401570, 0xb77b, 0x11d0, 0x9d, 0xa5, 0x0, 0xc0, 0x4f, 0xd6, 0x56, 0x85);

// ...

hr =  pInboxFolder->CreateMessage(nullptr, 0, &pMessage); // pInboxFolder is valid

IConverterSession *pIConverter = nullptr;
HRESULT hr = CoCreateInstance(
    CLSID_IConverterSession, nullptr, CLSCTX_INPROC_SERVER,
    IID_IConverterSession, reinterpret_cast<LPVOID*>(&pIConverter)
);

if (FAILED(hr) || !pIConverter) {
    std::cout << "CoCreateInstance failed: 0x" << std::hex << hr << "\n";
    return hr;
}

LPSTREAM pStream = nullptr;
hr = OpenStreamOnFile(
        MAPIAllocateBuffer, MAPIFreeBuffer, STGM_READ,
        (LPTSTR)emlPath.c_str(), nullptr, &pStream
);

if (FAILED(hr) || !pStream) {
        std::cout << "OpenStreamOnFile failed: 0x" << std::hex << hr << "\n";
        return hr;
}

hr = pIConverter->MIMEToMAPI(pStream, pMessage, nullptr, CCSF_SMTP | CCSF_INCLUDE_BCC);

if (FAILED(hr) || !pMessage) {
    std::cout << "MIMEToMAPI failed: 0x" << std::hex << hr << "\n";
    return hr;
}

hr = pMessage->SaveChanges(0);

The istream data is fine(read ok, seek{0} ok), the eml file is fine, when I put the same file into my python code(pywin32) it works fine, and the CLSID_IConverterSession value is registered just fine in the registry editor. Why isn't MIMEToMAPI() working? If it's an encoding issue, I'd expect some weird value to go in there, but there really isn't any data there. Just empty message items. The result is the same whether set hCharset or not.


Solution

  • The problem was in the declaration of IConverterSession.

    I should have declared all the methods as per the original interface so that the v-table doesn't get twisted and call the methods correctly.

    interface IConverterSession : public IUnknown {
    public:
        virtual HRESULT STDMETHODCALLTYPE SetAdrBook(LPADRBOOK pab);
        virtual HRESULT STDMETHODCALLTYPE SetEncoding(ENCODINGTYPE et);
    
        virtual HRESULT PlaceHolder1();
    
        virtual HRESULT STDMETHODCALLTYPE MIMEToMAPI(LPSTREAM pstm, LPMESSAGE pmsg, LPCSTR pszSrcSrv, ULONG ulFlags);
        virtual HRESULT STDMETHODCALLTYPE MAPIToMIMEStm(LPMESSAGE pmsg, LPSTREAM pstm, ULONG ulFlags);
    
        virtual HRESULT PlaceHolder2();
        virtual HRESULT PlaceHolder3();
        virtual HRESULT PlaceHolder4();
    
        virtual HRESULT STDMETHODCALLTYPE SetTextWrapping(bool fWrapText, ULONG ulWrapWidth);
        virtual HRESULT STDMETHODCALLTYPE SetSaveFormat(MIMESAVETYPE mstSaveFormat);
    
        virtual HRESULT PlaceHolder5();
    
        virtual HRESULT STDMETHODCALLTYPE SetCharset(bool fApply, HCHARSET hcharset, CSETAPPLYTYPE csetapplytype);
    };