实施 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
)。对于呼叫者来说,这是一个黑匣子。它仅在提供程序的上下文中才有意义 - 即在您的代码中。
我正在实现简单的 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
)。对于呼叫者来说,这是一个黑匣子。它仅在提供程序的上下文中才有意义 - 即在您的代码中。