实施 MAPILogon - return 作为 LPLHANDLE lplhSession 做什么?

Implementing MAPILogon - what to return as LPLHANDLE lplhSession?

我正在实现简单的 MAPI DLL,但我卡在了 MAPILogon 代码处。基本上我不知道 LPLHANDLE lplhSession 参数中的 return 到底是什么。不知何故,在没有任何示例的情况下,我发现我最终需要创建和实现 IMAPISession 所以我尝试了:

my_mapi.h 文件:

#define USES_IID_IMAPISession

#define DLL_EXPORT __declspec(dllexport) WINAPI

#include <initguid.h>
#include <mapiguid.h>
#include <unknwn.h>

typedef struct IMAPISession IMAPISession;
typedef IMAPISession *LPMAPISESSION;

//******************************************************************************
// IMAPISession interface
//******************************************************************************

#undef INTERFACE
#define INTERFACE IMAPISession
DECLARE_INTERFACE_(IMAPISession,IUnknown)
{
    BEGIN_INTERFACE

    /*** IUnknown methods ***/
    STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
    STDMETHOD_(ULONG,Release)(THIS) PURE;

    /*** IMAPISession methods ***/
    STDMETHOD(GetLastError)(THIS_ HRESULT hResult, ULONG ulFlags, LPMAPIERROR *lppMAPIError) PURE;
    STDMETHOD(GetMsgStoresTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) PURE;
    STDMETHOD(OpenMsgStore)(THIS_ ULONG_PTR ulUIParam, ULONG cbId, LPENTRYID lpId, LPCIID lpIFace, ULONG ulFlags, LPMDB *lppMDB) PURE;
    STDMETHOD(OpenAddressBook)(THIS_ ULONG_PTR ulUIParam, LPCIID iid, ULONG ulFlags, LPADRBOOK *lppAdrBook) PURE;
    STDMETHOD(OpenProfileSection)(THIS_ LPMAPIUID lpUID, LPCIID iid, ULONG ulFlags, LPPROFSECT *lppProf) PURE;
    STDMETHOD(GetStatusTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) PURE;
    STDMETHOD(OpenEntry)(THIS_ ULONG cbId, LPENTRYID lpId, LPCIID iid, ULONG ulFlags, ULONG *lpType, LPUNKNOWN *lppUnk) PURE;
    STDMETHOD(CompareEntryIDs)(THIS_ ULONG cbLID, LPENTRYID lpLID, ULONG cbRID, LPENTRYID lpRID, ULONG ulFlags, ULONG *lpRes) PURE;
    STDMETHOD(Advise)(THIS_ ULONG cbId, LPENTRYID lpId, ULONG ulMask, LPMAPIADVISESINK lpSink, ULONG *lpCxn) PURE;
    STDMETHOD(Unadvise)(THIS_ ULONG ulConnection) PURE;
    STDMETHOD(MessageOptions)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, LPSTR lpszAddr, LPMESSAGE lpMsg) PURE;
    STDMETHOD(QueryDefaultMessageOpt)(THIS_ LPSTR lpszAddr, ULONG ulFlags, ULONG *lpcVals, LPSPropValue *lppOpts) PURE;
    STDMETHOD(EnumAdrTypes)(THIS_ ULONG ulFlags, ULONG *lpcTypes, LPSTR **lpppszTypes) PURE;
    STDMETHOD(QueryIdentity)(THIS_ ULONG *lpcbId, LPENTRYID *lppEntryID) PURE;
    STDMETHOD(Logoff)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, ULONG ulReserved) PURE;
    STDMETHOD(SetDefaultStore)(THIS_ ULONG ulFlags, ULONG cbId, LPENTRYID lpId) PURE;
    STDMETHOD(AdminServices)(THIS_ ULONG ulFlags, LPSERVICEADMIN *lppAdmin) PURE;
    STDMETHOD(ShowForm)(THIS_ ULONG_PTR ulUIParam, LPMDB lpStore, LPMAPIFOLDER lpParent, LPCIID iid, ULONG ulToken, LPMESSAGE lpSent, ULONG ulFlags, ULONG ulStatus, ULONG ulMsgFlags, ULONG ulAccess, LPSTR lpszClass) PURE;
    STDMETHOD(PrepareForm)(THIS_ LPCIID lpIFace, LPMESSAGE lpMsg, ULONG *lpToken) PURE;

    END_INTERFACE
};

//------------------------------------------------------------------------------

class TMyMapiSession : public IMAPISession
{
private:    LONG m_cRef;

public:
            TMyMapiSession()
                {
                m_cRef = 1;
                }

            ~TMyMapiSession()
                {
                }

            //------------------------------------------------------------------
            // IUnknown
            //------------------------------------------------------------------

            STDMETHODIMP_(HRESULT) QueryInterface(REFIID riid, void** ppv)
                {
                if (!ppv) return E_POINTER;

                // Find IID
                if      (IID_IUnknown     == riid) *ppv = (IUnknown *)(IMAPISession *)this;
                else if (IID_IMAPISession == riid) *ppv = (IMAPISession *)this;
                else
                    {
                    *ppv = NULL;
                    //return E_NOINTERFACE;
                    return MAPI_E_INTERFACE_NOT_SUPPORTED;
                    }

                // AddRef It
                ((IUnknown *)*ppv)->AddRef();

                return S_OK;
                }

            STDMETHODIMP_(ULONG) AddRef()
                {
                return ::InterlockedIncrement(&m_cRef);
                }

            STDMETHODIMP_(ULONG) Release()
                {
                LONG cRef = ::InterlockedDecrement(&m_cRef);
                if (0 == cRef) delete this;

                return cRef;
                }


            //------------------------------------------------------------------
            // IMAPISession
            //------------------------------------------------------------------

            STDMETHODIMP(GetLastError)(THIS_ HRESULT hResult, ULONG ulFlags, LPMAPIERROR *lppMAPIError) { return E_NOTIMPL; }
            STDMETHODIMP(GetMsgStoresTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) { return E_NOTIMPL; }
            STDMETHODIMP(OpenMsgStore)(THIS_ ULONG_PTR ulUIParam, ULONG cbId, LPENTRYID lpId, LPCIID lpIFace, ULONG ulFlags, LPMDB *lppMDB) { return E_NOTIMPL; }
            STDMETHODIMP(OpenAddressBook)(THIS_ ULONG_PTR ulUIParam, LPCIID iid, ULONG ulFlags, LPADRBOOK *lppAdrBook) { return E_NOTIMPL; }
            STDMETHODIMP(OpenProfileSection)(THIS_ LPMAPIUID lpUID, LPCIID iid, ULONG ulFlags, LPPROFSECT *lppProf) { return E_NOTIMPL; }
            STDMETHODIMP(GetStatusTable)(THIS_ ULONG ulFlags, LPMAPITABLE *lppTable) { return E_NOTIMPL; }
            STDMETHODIMP(OpenEntry)(THIS_ ULONG cbId, LPENTRYID lpId, LPCIID iid, ULONG ulFlags, ULONG *lpType, LPUNKNOWN *lppUnk) { return E_NOTIMPL; }
            STDMETHODIMP(CompareEntryIDs)(THIS_ ULONG cbLID, LPENTRYID lpLID, ULONG cbRID, LPENTRYID lpRID, ULONG ulFlags, ULONG *lpRes) { return E_NOTIMPL; }
            STDMETHODIMP(Advise)(THIS_ ULONG cbId, LPENTRYID lpId, ULONG ulMask, LPMAPIADVISESINK lpSink, ULONG *lpCxn) { return E_NOTIMPL; }
            STDMETHODIMP(Unadvise)(THIS_ ULONG ulConnection) { return E_NOTIMPL; }
            STDMETHODIMP(MessageOptions)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, LPSTR lpszAddr, LPMESSAGE lpMsg) { return E_NOTIMPL; }
            STDMETHODIMP(QueryDefaultMessageOpt)(THIS_ LPSTR lpszAddr, ULONG ulFlags, ULONG *lpcVals, LPSPropValue *lppOpts) { return E_NOTIMPL; }
            STDMETHODIMP(EnumAdrTypes)(THIS_ ULONG ulFlags, ULONG *lpcTypes, LPSTR **lpppszTypes) { return E_NOTIMPL; }
            STDMETHODIMP(QueryIdentity)(THIS_ ULONG *lpcbId, LPENTRYID *lppEntryID) { return E_NOTIMPL; }
            STDMETHODIMP(Logoff)(THIS_ ULONG_PTR ulUIParam, ULONG ulFlags, ULONG ulReserved) { return E_NOTIMPL; }
            STDMETHODIMP(SetDefaultStore)(THIS_ ULONG ulFlags, ULONG cbId, LPENTRYID lpId) { return E_NOTIMPL; }
            STDMETHODIMP(AdminServices)(THIS_ ULONG ulFlags, LPSERVICEADMIN *lppAdmin) { return E_NOTIMPL; }
            STDMETHODIMP(ShowForm)(THIS_ ULONG_PTR ulUIParam, LPMDB lpStore, LPMAPIFOLDER lpParent, LPCIID iid, ULONG ulToken, LPMESSAGE lpSent, ULONG ulFlags, ULONG ulStatus, ULONG ulMsgFlags, ULONG ulAccess, LPSTR lpszClass) { return E_NOTIMPL; }
            STDMETHODIMP(PrepareForm)(THIS_ LPCIID lpIFace, LPMESSAGE lpMsg, ULONG *lpToken) { return E_NOTIMPL; }
};

my_mapi.cpp文件

TMyMapiSession* ms;

extern "C" ULONG DLL_EXPORT MAPILogon(ULONG_PTR ulUIParam, LPSTR lpszProfileName, LPSTR lpszPassword, FLAGS flFlags, ULONG ulReserved, LPLHANDLE lplhSession)
{
// I tried this (see update note below):

ms = new TMyMapiSession();
lplhSession = (LPLHANDLE)ms;
return SUCCESS_SUCCESS;

// Also tried this:
void* ppv;
if (SUCCEEDED(ms->QueryInterface(IID_IMAPISession, &ppv))) {
    lplhSession = (LPLHANDLE)ppv;
    return SUCCESS_SUCCESS;
    }
else {
    return MAPI_E_NOT_SUPPORTED;
    }
}

所以我尝试 return 接口实现和查询接口,return 也...两者都不适用于我正在测试的程序(它适用于邮件客户)。没有任何我能找到的例子,我有点不知道接下来要尝试什么。

有什么例子或帮助我实际上必须 return 给来电者吗?

更新:我还发现我应该将指针地址或任何我需要的东西放入 指向的位置 lplhSession*lplhSession = something; lplhSession = something; 否则 LPLHANDLE 将保持指向 0 使其无效句柄和我正在测试的程序预计会在那里找到非零结果。

为什么要 实现 IMAPISession 接口? IMAPISession是一个Extended MAPI接口,Simple MAPI中没有使用。 lplhSession 是一个不透明的指针大小参数,您可以在其他函数中重复使用它(例如 Mapiaddress)。对于呼叫者来说,这是一个黑匣子。它仅在提供程序的上下文中才有意义 - 即在您的代码中。