Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1412 lines
32 KiB

/*
* o e d o c s . c p p
*
* Purpose:
* sample code for demo of OE object model. Implements a very limited
* subset of funcitonality
*
* History
*
* Copyright (C) Microsoft Corp. 1995, 1996.
*/
#include <pch.hxx>
#include <resource.h>
#include <strconst.h>
#include "demand.h"
#include "dllmain.h"
#include "msoert.h"
#include "msoeobj.h"
#include "oedocs.h"
#include "instance.h"
#include "msgfldr.h"
#include "msgtable.h"
#include "mailutil.h"
#include "oleutil.h"
#include "mshtmdid.h"
#include "shlwapi.h"
static ITypeLib *g_pTypeLib=NULL;
HRESULT CreateOEFolder(IMessageFolder *pFolder, IDispatch **ppdisp);
HRESULT CreateOEMessage(IMimeMessage *pMsg, IMessageFolder *pFolder, OEMSGDATA *pMsgData, IDispatch **ppdisp);
HRESULT FindFolder(BSTR bstr, LONG lIndex, IMessageFolder **ppFolder);
void FreeOEMsgData(POEMSGDATA pMsgData);
HRESULT EnsureTypeLib();
LPWSTR StringFromColIndex(DWORD dw);
DWORD ColIndexFromString(LPWSTR pszW);
/*
* C O E M a i l
*/
COEMail::COEMail(IUnknown *pUnkOuter)
{
m_cRef=1;
m_pFolders = NULL;
CoIncrementInit("COEMail::COEMail", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEMail::~COEMail()
{
ReleaseObj(m_pFolders);
CoDecrementInit("COEMail::COEMail", NULL);
}
HRESULT COEMail::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(IOEMail *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IOEMail))
*lplpObj = (LPVOID)(IOEMail *)this;
else
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
// *** IOEMail **
HRESULT COEMail::get_folders(IOEFolderCollection **p)
{
COEFolderCollection *pNew=NULL;
HRESULT hr=S_OK;
if (!m_pFolders)
{
pNew = new COEFolderCollection(NULL);
if (!pNew)
return E_OUTOFMEMORY;
hr = pNew->Init();
if (FAILED(hr))
goto error;
m_pFolders = (IOEFolderCollection *)pNew;
pNew = NULL; // don't free
}
*p = m_pFolders;
m_pFolders->AddRef();
error:
ReleaseObj(pNew);
return hr;
}
HRESULT COEMail::get_version(BSTR *pbstr)
{
*pbstr = SysAllocString(L"Outlook Express v5.0");
return S_OK;
}
HRESULT COEMail::get_newMsg(IDispatch **ppDisp)
{
COEMessage *pNew=NULL;
HRESULT hr;
IMimeMessage *pMsg=NULL;
pNew = new COEMessage();
if (!pNew)
return E_OUTOFMEMORY;
hr = MimeOleCreateMessage(NULL, &pMsg);
if (FAILED(hr))
goto error;
hr = pNew->Init(pMsg, NULL, NULL);
if (FAILED(hr))
goto error;
hr = pNew->QueryInterface(IID_IDispatch, (LPVOID *)ppDisp);
error:
ReleaseObj(pNew);
ReleaseObj(pMsg);
return hr;
}
HRESULT COEMail::Init()
{
return InitBaseDisp((LPVOID *)(IOEMail *)this, IID_IOEMail, g_pTypeLib);
}
HRESULT EnsureTypeLib()
{
TCHAR szDll[MAX_PATH];
LPWSTR pszW;
// BUG BUG BUG: hack to get typelib loaded quickly. NOT THREAD SAFE
if (!g_pTypeLib)
{
GetModuleFileName(g_hInst, szDll, ARRAYSIZE(szDll));
pszW = PszToUnicode(GetACP(), szDll);
if (pszW)
{
LoadTypeLib(pszW, &g_pTypeLib);
MemFree(pszW);
}
}
if (!g_pTypeLib)
return E_FAIL;
// BUG BUG BUG: hack to get typelib loaded quickly. NOT THREAD SAFE
return S_OK;
}
HRESULT CreateInstance_OEMail(IUnknown *pUnkOuter, IUnknown **ppUnknown)
{
// Locals
COEMail *pMail=NULL;
HRESULT hr=S_OK;
if (NULL != pUnkOuter)
return CLASS_E_NOAGGREGATION;
pMail = new COEMail(NULL);
if (!pMail)
return E_OUTOFMEMORY;
hr = EnsureTypeLib();
if (FAILED(hr))
goto error;
hr = pMail->Init();
if (FAILED(hr))
goto error;
*ppUnknown = (IUnknown *)(IOEMail *)pMail;
pMail->AddRef();
error:
ReleaseObj(pMail);
return hr;
}
/*
* C O E F o l d e r C o l l e c t i o n
*/
COEFolderCollection::COEFolderCollection(IUnknown *pUnkOuter)
{
m_cRef=1;
CoIncrementInit("COEFolderCollection::COEFolderCollection", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEFolderCollection::~COEFolderCollection()
{
CoDecrementInit("COEFolderCollection::COEFolderCollection", NULL);
}
HRESULT COEFolderCollection::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(IOEFolderCollection *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IOEFolderCollection))
*lplpObj = (LPVOID)(IOEFolderCollection *)this;
else
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
HRESULT COEFolderCollection::Init()
{
return InitBaseDisp((LPVOID *)(IOEFolderCollection *)this, IID_IOEFolderCollection, g_pTypeLib);
}
// *** COEFolderCollection **
HRESULT COEFolderCollection::put_length(long v)
{
return E_NOTIMPL;
}
HRESULT COEFolderCollection::get_length(long * p)
{
FOLDERINFO fi;
*p = 0;
Assert(g_pStore);
if (!FAILED(g_pStore->GetFolderInfo(FOLDERID_LOCAL_STORE, &fi)))
*p = fi.cChildren;
return S_OK;
}
HRESULT COEFolderCollection::get__newEnum(IUnknown **p)
{
return E_NOTIMPL;
}
HRESULT COEFolderCollection::item(VARIANT name, VARIANT index, IDispatch** ppdisp)
{
switch(name.vt)
{
case VT_BSTR:
return FindFolderByName(name.bstrVal, ppdisp);
case VT_I4:
return FindFolderByIndex(name.lVal, ppdisp);
}
return E_NOTIMPL;
}
HRESULT COEFolderCollection::FindFolderByName(BSTR bstrName, IDispatch** ppdisp)
{
HRESULT hr=E_FAIL;
IMessageFolder *pFolder;
if (FindFolder(bstrName, NULL, &pFolder)==S_OK)
{
hr = CreateOEFolder(pFolder, ppdisp);
pFolder->Release();
}
return hr;
}
HRESULT COEFolderCollection::FindFolderByIndex(LONG lIndex, IDispatch **ppdisp)
{
HRESULT hr=E_FAIL;
IMessageFolder *pFolder;
*ppdisp=NULL;
if (FindFolder(NULL, lIndex, &pFolder)==S_OK)
{
hr = CreateOEFolder(pFolder, ppdisp);
pFolder->Release();
}
return hr;
}
/*
* C O E F o l d e r
*/
HRESULT CreateOEFolder(IMessageFolder *pFolder, IDispatch **ppdisp)
{
COEFolder *pNew;
HRESULT hr;
pNew = new COEFolder();
if (!pNew)
return E_OUTOFMEMORY;
hr = pNew->Init(pFolder);
if (FAILED(hr))
goto error;
hr = pNew->QueryInterface(IID_IDispatch, (LPVOID *)ppdisp);
error:
ReleaseObj(pNew);
return hr;
}
COEFolder::COEFolder()
{
m_cRef=1;
m_pFolder = NULL;
m_pMessages=NULL;
CoIncrementInit("COEFolder::COEFolder", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEFolder::~COEFolder()
{
ReleaseObj(m_pFolder);
ReleaseObj(m_pMessages);
CoDecrementInit("COEFolder::COEFolder", NULL);
}
HRESULT COEFolder::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(IOEFolder *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IOEFolder))
*lplpObj = (LPVOID)(IOEFolder *)this;
else if (IsEqualIID(riid, IID_OLEDBSimpleProvider))
*lplpObj = (LPVOID)(OLEDBSimpleProvider *)this;
else
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
HRESULT COEFolder::Init(IMessageFolder *pFolder)
{
FOLDERID dwFolder;
ReplaceInterface(m_pFolder, pFolder);
if (FAILED(pFolder->GetFolderId(&dwFolder)) ||
FAILED(g_pStore->GetFolderInfo(dwFolder, &m_fi)))
return E_FAIL;
return InitBaseDisp((LPVOID *)(IOEFolder *)this, IID_IOEFolder, g_pTypeLib);
}
// *** COEFolder**
HRESULT COEFolder::get_messages(IOEMessageCollection **p)
{
COEMessageCollection *pNew=NULL;
HRESULT hr=S_OK;
*p = NULL;
if (!m_pMessages)
{
pNew = new COEMessageCollection(NULL);
if (!pNew)
return E_OUTOFMEMORY;
hr = pNew->Init(m_pFolder);
if (FAILED(hr))
goto error;
m_pMessages = (IOEMessageCollection *)pNew;
pNew = NULL; // don't free
}
*p = m_pMessages;
m_pMessages->AddRef();
error:
ReleaseObj(pNew);
return S_OK;
}
HRESULT COEFolder::get_name(BSTR *pbstr)
{
*pbstr = NULL;
return HrLPSZToBSTR(m_fi.szName, pbstr);
}
HRESULT COEFolder::put_name(BSTR bstr)
{
return E_NOTIMPL;
}
HRESULT COEFolder::get_size(LONG *pl)
{
*pl = 999;//;m_fi.cbUsed;
return S_OK;
}
HRESULT COEFolder::get_unread(LONG *pl)
{
*pl = m_fi.cUnread;
return S_OK;
}
HRESULT COEFolder::get_id(LONG *pl)
{
*pl = (LONG)m_fi.idFolder;
return S_OK;
}
HRESULT COEFolder::get_count(LONG *pl)
{
*pl = m_fi.cMessages;
return S_OK;
}
HRESULT FindFolder(BSTR bstr, LONG lIndex, IMessageFolder **ppFolder)
{
FOLDERID idFolder=0;
HRESULT hr=E_FAIL;
TCHAR szFolder[MAX_PATH];
LONG c=0;
FOLDERINFO fi;
if (bstr)
WideCharToMultiByte(CP_ACP, 0, (WCHAR*)bstr, -1, szFolder, MAX_PATH, NULL, NULL);
if (!FAILED(g_pStore->GetFolderInfo(FOLDERID_LOCAL_STORE, &fi)) &&
!FAILED(g_pStore->GetFolderInfo(fi.idChild, &fi)))
{
do
{
// walk immediate children
if (bstr)
{
if (lstrcmp(fi.szName, szFolder)==0)
{
idFolder = fi.idFolder;
break;
}
}
else
{
if (lIndex == c++)
{
idFolder = fi.idFolder;
break;
}
}
}
while (!FAILED(g_pStore->GetFolderInfo(fi.idSibling, &fi)));
}
if (idFolder)
hr = g_pStore->OpenFolder(idFolder, ppFolder);
return hr;
}
/*
* C O E M e s s a g e C o l l e c t i o n
*/
COEMessageCollection::COEMessageCollection(IUnknown *pUnkOuter)
{
m_cRef=1;
m_pFolder=NULL;
m_pTable=0;
CoIncrementInit("COEMessageCollection::COEMessageCollection", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEMessageCollection::~COEMessageCollection()
{
ReleaseObj(m_pFolder);
ReleaseObj(m_pTable);
CoDecrementInit("COEMessageCollection::COEMessageCollection", NULL);
}
HRESULT COEMessageCollection::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(IOEFolderCollection *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IOEFolderCollection))
*lplpObj = (LPVOID)(IOEFolderCollection *)this;
else
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
HRESULT COEMessageCollection::Init(IMessageFolder *pFolder)
{
FOLDERID idFolder;
CMessageTable *pNew=NULL;
HRESULT hr;
if (!pFolder)
return E_INVALIDARG;
ReplaceInterface(m_pFolder, pFolder);
pFolder->GetFolderId(&idFolder);
pNew = new CMessageTable();
if (pNew == NULL)
return E_OUTOFMEMORY;
hr = pNew->Initialize(idFolder, FALSE);
if (FAILED(hr))
goto error;
hr = pNew->QueryInterface(IID_IMessageTable, (LPVOID *)&m_pTable);
if (FAILED(hr))
goto error;
hr = InitBaseDisp((LPVOID *)(IOEMessageCollection *)this, IID_IOEMessageCollection, g_pTypeLib);
if (FAILED(hr))
goto error;
error:
ReleaseObj(pNew);
return hr;
}
// *** COEMessageCollection **
HRESULT COEMessageCollection::put_length(long v)
{
return E_NOTIMPL;
}
HRESULT COEMessageCollection::get_length(long * pl)
{
*pl = 0;
if (m_pTable)
m_pTable->GetCount(MESSAGE_COUNT_VISIBLE, (ULONG *)pl);
return S_OK;
}
HRESULT COEMessageCollection::get__newEnum(IUnknown **p)
{
return E_NOTIMPL;
}
HRESULT COEMessageCollection::item(VARIANT name, VARIANT index, IDispatch** ppdisp)
{
if (name.vt == VT_I4)
return FindMessageByIndex(name.lVal, ppdisp);
return E_NOTIMPL;
}
HRESULT COEMessageCollection::FindMessageByIndex(LONG l, IDispatch** ppdisp)
{
HRESULT hr = E_FAIL;
MESSAGEINFO msginfo;
POEMSGDATA pMsgData;
if (m_pTable->GetRow(l, &msginfo)==S_OK)
{
if (!MemAlloc((LPVOID *)&pMsgData, sizeof(OEMSGDATA)))
return E_OUTOFMEMORY;
pMsgData->pszSubj = PszDup(msginfo.pszSubject);
pMsgData->pszTo = PszDup(msginfo.pszDisplayTo);
pMsgData->pszCc = PszDup("<not available>");
pMsgData->pszFrom = PszDup(msginfo.pszDisplayFrom);
pMsgData->ftReceived = msginfo.ftReceived;
pMsgData->msgid = msginfo.idMessage;
//m_pFolder->OpenMessage(msginfo.dwMsgId, FALSE, NULL, &pMsg)==S_OK)
// OEMessage frees the data object
hr = CreateOEMessage(NULL, m_pFolder, pMsgData, ppdisp);
if (FAILED(hr))
FreeOEMsgData(pMsgData);
}
return hr;
}
void FreeOEMsgData(POEMSGDATA pMsgData)
{
if (pMsgData)
{
MemFree(pMsgData->pszSubj);
MemFree(pMsgData->pszTo);
MemFree(pMsgData->pszCc);
MemFree(pMsgData->pszFrom);
MemFree(pMsgData);
}
}
/*
* C O E M e s s a g e
*/
HRESULT CreateOEMessage(IMimeMessage *pMsg, IMessageFolder *pFolder, OEMSGDATA *pMsgData, IDispatch **ppdisp)
{
COEMessage *pNew;
HRESULT hr;
pNew = new COEMessage();
if (!pNew)
return E_OUTOFMEMORY;
hr = pNew->Init(pMsg, pFolder, pMsgData);
if (FAILED(hr))
goto error;
hr = pNew->QueryInterface(IID_IDispatch, (LPVOID *)ppdisp);
if (FAILED(hr))
goto error;
error:
ReleaseObj(pNew);
return hr;
}
COEMessage::COEMessage()
{
m_cRef=1;
m_pMsg = NULL;
m_pMsgData = NULL;
m_pFolder = NULL;
CoIncrementInit("COEMessage::COEMessage", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEMessage::~COEMessage()
{
FreeOEMsgData(m_pMsgData);
ReleaseObj(m_pMsg);
ReleaseObj(m_pFolder);
CoDecrementInit("COEMessage::COEMessage", NULL);
}
HRESULT COEMessage::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(IOEMessage *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IOEMessage))
*lplpObj = (LPVOID)(IOEMessage *)this;
else
return E_NOINTERFACE;
AddRef();
return NOERROR;
}
HRESULT COEMessage::Init(IMimeMessage *pMsg, IMessageFolder *pFolder, OEMSGDATA *pMsgData)
{
ReplaceInterface(m_pFolder, pFolder);
ReplaceInterface(m_pMsg, pMsg);
m_pMsgData = pMsgData;
return InitBaseDisp((LPVOID *)(IOEMessage *)this, IID_IOEMessage, g_pTypeLib);
}
// *** COEMessage **
HRESULT COEMessage::get_subject(BSTR *pbstr)
{
LPSTR psz;
if (!m_pMsg)
{
HrLPSZToBSTR(m_pMsgData->pszSubj, pbstr);
return S_OK;
}
if (MimeOleGetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, &psz)==S_OK)
{
HrLPSZToBSTR(psz, pbstr);
MemFree(psz);
return S_OK;
}
return E_FAIL;
}
HRESULT COEMessage::put_subject(BSTR bstr)
{
LPSTR psz;
BindToMessage();
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, psz);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_to(BSTR *pbstr)
{
LPSTR psz;
*pbstr = NULL;
if (!m_pMsg)
{
HrLPSZToBSTR(m_pMsgData->pszTo, pbstr);
return S_OK;
}
if (m_pMsg->GetAddressFormat(IAT_TO, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
{
HrLPSZToBSTR(psz, pbstr);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::put_to(BSTR bstr)
{
LPSTR psz;
BindToMessage();
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, psz);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_cc(BSTR *pbstr)
{
LPSTR psz;
if (!m_pMsg)
{
HrLPSZToBSTR(m_pMsgData->pszCc, pbstr);
return S_OK;
}
*pbstr = NULL;
if (m_pMsg->GetAddressFormat(IAT_CC, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
{
HrLPSZToBSTR(psz, pbstr);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::put_cc(BSTR bstr)
{
LPSTR psz;
BindToMessage();
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_CC), NOFLAGS, psz);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_sender(BSTR *pbstr)
{
LPSTR psz;
*pbstr = NULL;
if (!m_pMsg)
{
HrLPSZToBSTR(m_pMsgData->pszFrom, pbstr);
return S_OK;
}
if (m_pMsg->GetAddressFormat(IAT_FROM, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
{
HrLPSZToBSTR(psz, pbstr);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::put_sender(BSTR bstr)
{
LPSTR psz;
BindToMessage();
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_FROM), NOFLAGS, psz);
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_text(BSTR *pbstr)
{
IStream *pstm;
BindToMessage();
if (m_pMsg->GetTextBody(TXT_PLAIN, IET_DECODED, &pstm, NULL)==S_OK)
{
HrIStreamToBSTR(GetACP(), pstm, pbstr);
pstm->Release();
return S_OK;
}
return E_FAIL;
}
HRESULT COEMessage::put_text(BSTR bstr)
{
IStream *pstm;
LPSTR psz;
BindToMessage();
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
if (MimeOleCreateVirtualStream(&pstm)==S_OK)
{
pstm->Write(psz, lstrlen(psz), NULL);
m_pMsg->SetTextBody(TXT_PLAIN, IET_BINARY, NULL, pstm, NULL);
pstm->Release();
}
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_html(BSTR *pbstr)
{
IStream *pstm;
BindToMessage();
if (m_pMsg->GetTextBody(TXT_HTML, IET_DECODED, &pstm, NULL)==S_OK)
{
HrIStreamToBSTR(GetACP(), pstm, pbstr);
pstm->Release();
return S_OK;
}
return E_FAIL;
}
HRESULT COEMessage::put_html(BSTR bstr)
{
IStream *pstm;
LPSTR psz;
if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
{
if (MimeOleCreateVirtualStream(&pstm)==S_OK)
{
pstm->Write(psz, lstrlen(psz), NULL);
m_pMsg->SetTextBody(TXT_HTML, IET_BINARY, NULL, pstm, NULL);
pstm->Release();
}
MemFree(psz);
}
return S_OK;
}
HRESULT COEMessage::get_url(BSTR *pbstr)
{
IStream *pstm;
BindToMessage();
// BUGBUGBUG: this is a terrible hack also. We can't get a persistent URL moniker to
// the MHTML document (not yet investigated), so for the purpose of this demo-code
// we'll use a tmp file
if (m_pMsg->GetMessageSource(&pstm, 0)==S_OK)
{
WriteStreamToFile(pstm, "c:\\oe_temp$.eml", CREATE_ALWAYS, GENERIC_WRITE);
pstm->Release();
}
*pbstr = SysAllocString(L"c:\\oe_temp$.eml");
return S_OK;
}
HRESULT COEMessage::get_date(BSTR *pbstr)
{
PROPVARIANT pv;
TCHAR rgch[MAX_PATH];
FILETIME *pft=0;
*pbstr = NULL;
if (!m_pMsg)
{
pft = &m_pMsgData->ftReceived;
}
else
{
// Get Receive Time
pv.vt = VT_FILETIME;
if (SUCCEEDED(m_pMsg->GetProp(PIDTOSTR(PID_ATT_RECVTIME), 0, &pv)))
pft = &pv.filetime;
}
if (pft)
{
*rgch=0;
CchFileTimeToDateTimeSz(pft, rgch, sizeof(rgch)/sizeof(TCHAR), DTM_NOSECONDS);
HrLPSZToBSTR(rgch, pbstr);
}
return S_OK;
}
HRESULT COEMessage::send()
{
TCHAR sz[MAX_PATH];
// use default account to send
if (SUCCEEDED(g_pAcctMan->GetDefaultAccountName(ACCT_MAIL, sz, ARRAYSIZE(sz))))
{
PROPVARIANT rUserData;
rUserData.vt = VT_LPSTR;
rUserData.pszVal = sz;
m_pMsg->SetProp(PIDTOSTR(PID_ATT_ACCOUNT), NOFLAGS, &rUserData);
}
HrSendMailToOutBox(g_hwndInit, m_pMsg, TRUE, TRUE);
return S_OK;
}
HRESULT COEMessage::BindToMessage()
{
if (m_pMsg)
return S_OK;
Assert (m_pFolder && m_pMsgData);
return m_pFolder->OpenMessage(m_pMsgData->msgid, NULL, &m_pMsg, NULL);
}
COEMsgTable::COEMsgTable()
{
m_cRef=1;
m_pTable=0;
m_pDSListen=0;
m_fAsc=TRUE;
m_col=COLUMN_RECEIVED;
m_pDataSrcListener=0;
CoIncrementInit("COEMsgTable::COEMsgTable", MSOEAPI_START_SHOWERRORS, NULL, NULL);
}
COEMsgTable::~COEMsgTable()
{
ReleaseObj(m_pTable);
ReleaseObj(m_pDSListen);
ReleaseObj(m_pDataSrcListener);
CoDecrementInit("COEMsgTable::COEMsgTable", NULL);
}
HRESULT COEMsgTable::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
{
if(!lplpObj)
return E_INVALIDARG;
*lplpObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*lplpObj = (LPVOID)(OLEDBSimpleProvider *)this;
else if (IsEqualIID(riid, IID_OLEDBSimpleProvider))
*lplpObj = (LPVOID)(OLEDBSimpleProvider *)this;
else if (IsEqualIID(riid, IID_IDispatch))
*lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
else if (IsEqualIID(riid, IID_IDispatchEx))
*lplpObj = (LPVOID)(IDispatchEx *)this;
else if (IsEqualIID(riid, IID_IOEMsgList))
*lplpObj = (LPVOID)(IOEMsgList *)this;
else
{
DbgPrintInterface(riid, "COEMsgTable::", 1024);
return E_NOINTERFACE;
}
AddRef();
return NOERROR;
}
HRESULT COEMsgTable::Init()
{
FOLDERINFO fi;
HRESULT hr;
g_pStore->GetSpecialFolderInfo(FOLDERID_LOCAL_STORE, FOLDER_INBOX, &fi);
// hr = CoCreateInstance(CLSID_MessageTable, NULL, CLSCTX_INPROC_SERVER,
IID_IMessageTable, (LPVOID *)&m_pTable);
if (FAILED(hr))
goto error;
hr = m_pTable->Initialize(fi.idFolder, FALSE);
if (FAILED(hr))
goto error;
hr = EnsureTypeLib();
if (FAILED(hr))
goto error;
hr = InitBaseDisp((LPVOID *)(IOEMsgList *)this, IID_IOEMsgList, g_pTypeLib);
error:
return hr;
}
HRESULT COEMsgTable::getRowCount(long *pcRows)
{
*pcRows = 0;
if (m_pTable)
m_pTable->GetCount(MESSAGE_COUNT_VISIBLE, (ULONG *)pcRows);
return S_OK;
}
HRESULT COEMsgTable::getColumnCount(long *pcColumns)
{
*pcColumns=COLUMN_MAX;
return S_OK;
}
HRESULT COEMsgTable::getRWStatus(long iRow, long iColumn, OSPRW *prwStatus)
{
*prwStatus = OSPRW_READONLY;
return S_OK;
}
HRESULT COEMsgTable::getVariant(long iRow, long iColumn, OSPFORMAT format, VARIANT __RPC_FAR *pVar)
{
MESSAGEINFO msginfo;
LPSTR pszData = NULL;
TCHAR rgch[MAX_PATH];
pVar->vt = VT_NULL;
if (iRow == 0)
{
// return headings if row==0
pVar->vt = VT_BSTR;
pVar->bstrVal = SysAllocString(StringFromColIndex(iColumn-1));
return S_OK;
}
if (m_pTable->GetRow(iRow-1, &msginfo)==S_OK)
{
switch (iColumn-1)
{
case COLUMN_MSGID:
wnsprintf(rgch,ARRAYSIZE(rgch), "%d", msginfo.idMessage);
pszData = rgch;
break;
case COLUMN_SUBJECT:
pszData = msginfo.pszSubject;
break;
case COLUMN_TO:
pszData = msginfo.pszDisplayTo;
break;
case COLUMN_FROM:
pszData = msginfo.pszDisplayFrom;
break;
case COLUMN_RECEIVED:
pszData = rgch;
*rgch=0;
CchFileTimeToDateTimeSz(&msginfo.ftReceived, rgch, sizeof(rgch)/sizeof(TCHAR), DTM_NOSECONDS);
break;
default:
pVar->vt = VT_NULL;
pVar->lVal = NULL;
return S_OK;
}
}
if (pszData)
{
pVar->vt = VT_BSTR;
HrLPSZToBSTR(pszData, &pVar->bstrVal);
}
else
AssertSz(0, "bad");
return S_OK;
}
HRESULT COEMsgTable::setVariant(long iRow, long iColumn, OSPFORMAT format, VARIANT Var)
{
AssertSz(0, "READONLY Table");
return E_NOTIMPL;
}
HRESULT COEMsgTable::getLocale(BSTR *pbstrLocale)
{
nyi("DATABINDING::getLocale");
return E_NOTIMPL;
}
HRESULT COEMsgTable::deleteRows(long iRow, long cRows, long *pcRowsDeleted)
{
AssertSz(0, "READONLY Table");
return E_NOTIMPL;
}
HRESULT COEMsgTable::insertRows(long iRow, long cRows, long *pcRowsInserted)
{
AssertSz(0, "READONLY Table");
return E_NOTIMPL;
}
HRESULT COEMsgTable::find(long iRowStart, long iColumn, VARIANT val, OSPFIND findFlags, OSPCOMP compType, long *piRowFound)
{
nyi("DATABINDING::find");
return E_NOTIMPL;
}
HRESULT COEMsgTable::addOLEDBSimpleProviderListener(OLEDBSimpleProviderListener *pospIListener)
{
ReplaceInterface(m_pDSListen, pospIListener);
if (pospIListener)
pospIListener->transferComplete(OSPXFER_COMPLETE);
return S_OK;
}
HRESULT COEMsgTable::removeOLEDBSimpleProviderListener(OLEDBSimpleProviderListener *pospIListener)
{
SafeRelease(m_pDSListen);
return S_OK;
}
HRESULT COEMsgTable::isAsync(BOOL *pbAsynch)
{
*pbAsynch = FALSE;
return S_OK;
}
HRESULT COEMsgTable::getEstimatedRows(long *piRows)
{
return getRowCount(piRows);
}
HRESULT COEMsgTable::stopTransfer()
{
return S_OK;
}
HRESULT CreateInstance_OEMsgTable(IUnknown *pUnkOuter, IUnknown **ppUnknown)
{
// Locals
COEMsgTable *pMsgTable=NULL;
HRESULT hr;
if (NULL != pUnkOuter)
return CLASS_E_NOAGGREGATION;
pMsgTable = new COEMsgTable();
if (!pMsgTable)
return E_OUTOFMEMORY;
hr = pMsgTable->Init();
if (FAILED(hr))
goto error;
hr = pMsgTable->QueryInterface(IID_IUnknown, (LPVOID *)ppUnknown);
error:
ReleaseObj(pMsgTable);
return hr;
}
HRESULT COEMsgTable::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
{
return DispGetIDsOfNames(m_pTypeInfo, &bstrName, 1, pid);
}
HRESULT COEMsgTable::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
switch (id)
{
case DISPID_MSDATASRCINTERFACE:
pvarRes->vt = VT_UNKNOWN;
pvarRes->punkVal = (OLEDBSimpleProvider *)this;
AddRef();
return S_OK;
case DISPID_ADVISEDATASRCCHANGEEVENT:
if (pdp->cArgs == 1 && pdp->rgvarg[0].vt == VT_UNKNOWN)
{
ReplaceInterface(m_pDataSrcListener, (DataSourceListener *)pdp->rgvarg[0].punkVal);
return S_OK;
}
else
return E_INVALIDARG;
default:
return DispInvoke(m_pUnkInvoke, m_pTypeInfo, id, wFlags, pdp, pvarRes, pei, NULL);
}
return E_NOTIMPL;
}
HRESULT COEMsgTable::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::DeleteMemberByDispID(DISPID id)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::GetMemberName(DISPID id, BSTR *pbstrName)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::GetNameSpaceParent(IUnknown **ppunk)
{
return E_NOTIMPL;
}
HRESULT COEMsgTable::put_sortColumn(BSTR bstr)
{
FOLDERSORTINFO fsi={0};
m_col = (COLUMN_ID)ColIndexFromString(bstr);
fsi.idSort = m_col;
fsi.dwFlags = m_fAsc ? SORT_ASCENDING : 0;
fsi.fForceSort = FALSE;
if (m_pTable)
m_pTable->SetSortInfo(&fsi);
return S_OK;
}
HRESULT COEMsgTable::get_sortColumn(BSTR *pbstr)
{
*pbstr = SysAllocString(StringFromColIndex(m_col));
return S_OK;
}
HRESULT COEMsgTable::put_sortDirection(VARIANT_BOOL v)
{
FOLDERSORTINFO fsi;
m_fAsc = (v == VARIANT_TRUE);
fsi.idSort = m_col;
fsi.dwFlags = m_fAsc ? SORT_ASCENDING : 0;
fsi.fForceSort = FALSE;
if (m_pTable)
m_pTable->SetSortInfo(&fsi);
return S_OK;
}
HRESULT COEMsgTable::get_sortDirection(VARIANT_BOOL *pv)
{
*pv = m_fAsc ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}
HRESULT COEMsgTable::test()
{
if (m_pDataSrcListener)
m_pDataSrcListener->dataMemberChanged(NULL);
return S_OK;
}
static const WCHAR c_szOESubjW[] = L"oeSubj",
c_szOEToW[] = L"oeTo",
c_szOEFromW[] = L"oeFrom",
c_szOEMsgIdW[] = L"oeMsgId",
c_szOEReceivedW[] = L"oeDate";
DWORD ColIndexFromString(LPWSTR pszW)
{
if (StrCmpIW(c_szOESubjW, pszW)==0)
return COLUMN_SUBJECT;
else
if (StrCmpIW(c_szOEToW, pszW)==0)
return COLUMN_TO;
else
if (StrCmpIW(c_szOEReceivedW, pszW)==0)
return COLUMN_RECEIVED;
else
if (StrCmpIW(c_szOEFromW, pszW)==0)
return COLUMN_FROM;
else
if (StrCmpIW(c_szOEMsgIdW, pszW)==0)
return COLUMN_MSGID;
return (DWORD)-1;
}
LPWSTR StringFromColIndex(DWORD dw)
{
switch (dw)
{
case COLUMN_MSGID:
return (LPWSTR)c_szOEMsgIdW;
case COLUMN_SUBJECT:
return (LPWSTR)c_szOESubjW;
case COLUMN_TO:
return (LPWSTR)c_szOEToW;
case COLUMN_FROM:
return (LPWSTR)c_szOEFromW;
case COLUMN_RECEIVED:
return (LPWSTR)c_szOEReceivedW;
}
return NULL;
}