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.

502 lines
11 KiB

  1. /*
  2. * m e s s a g e . c p p
  3. *
  4. * Purpose:
  5. * Implements the OE-MOM 'Message' object and 'MessageCollection'
  6. *
  7. * History
  8. *
  9. * Copyright (C) Microsoft Corp. 1995, 1996.
  10. */
  11. #include <pch.hxx>
  12. #include "msoeobj.h"
  13. #include "message.h"
  14. #include "instance.h"
  15. void FreeOEMsgData(POEMSGDATA pMsgData);
  16. COEMessageCollection::COEMessageCollection(IUnknown *pUnkOuter) : CBaseDisp()
  17. {
  18. m_pTable=NULL;
  19. m_idFolder = FOLDERID_INVALID;
  20. CoIncrementInit("COEMessageCollection::COEMessageCollection", MSOEAPI_START_SHOWERRORS, NULL, NULL);
  21. }
  22. COEMessageCollection::~COEMessageCollection()
  23. {
  24. ReleaseObj(m_pTable);
  25. CoDecrementInit("COEMessageCollection::COEMessageCollection", NULL);
  26. }
  27. HRESULT COEMessageCollection::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
  28. {
  29. if(!lplpObj)
  30. return E_INVALIDARG;
  31. *lplpObj = NULL;
  32. if (IsEqualIID(riid, IID_IUnknown))
  33. *lplpObj = (LPVOID)(IOEFolderCollection *)this;
  34. else if (IsEqualIID(riid, IID_IDispatch))
  35. *lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
  36. else if (IsEqualIID(riid, IID_IOEMessageCollection))
  37. *lplpObj = (LPVOID)(IOEMessageCollection *)this;
  38. else
  39. return E_NOINTERFACE;
  40. AddRef();
  41. return NOERROR;
  42. }
  43. HRESULT COEMessageCollection::Init(FOLDERID idFolder)
  44. {
  45. HRESULT hr;
  46. m_idFolder = idFolder;
  47. // Create a Message Table
  48. // hr = CoCreateInstance(CLSID_MessageTable, NULL, CLSCTX_INPROC_SERVER, IID_IMessageTable, (LPVOID *)&m_pTable);
  49. if (FAILED(hr))
  50. goto exit;
  51. // Tell the table which folder to look at
  52. hr = m_pTable->Initialize(idFolder, NULL, FALSE, NULL);
  53. if (FAILED(hr))
  54. goto exit;
  55. hr = CBaseDisp::EnsureTypeLibrary((LPVOID *)(IOEMessageCollection *)this, IID_IOEMessageCollection);
  56. if (FAILED(hr))
  57. goto exit;
  58. exit:
  59. return hr;
  60. }
  61. // *** COEMessageCollection **
  62. HRESULT COEMessageCollection::put_length(long v)
  63. {
  64. return E_NOTIMPL;
  65. }
  66. HRESULT COEMessageCollection::get_length(long * pl)
  67. {
  68. *pl = 0;
  69. if (m_pTable)
  70. m_pTable->GetCount(MESSAGE_COUNT_VISIBLE, (ULONG *)pl);
  71. return S_OK;
  72. }
  73. HRESULT COEMessageCollection::get__newEnum(IUnknown **p)
  74. {
  75. return E_NOTIMPL;
  76. }
  77. HRESULT COEMessageCollection::item(VARIANT name, VARIANT index, IDispatch** ppdisp)
  78. {
  79. if (name.vt == VT_I4)
  80. return _FindMessageByIndex(name.lVal, ppdisp);
  81. return E_NOTIMPL;
  82. }
  83. HRESULT COEMessageCollection::_FindMessageByIndex(LONG l, IDispatch** ppdisp)
  84. {
  85. HRESULT hr = E_FAIL;
  86. LPMESSAGEINFO pmsginfo;
  87. POEMSGDATA pMsgData;
  88. if (m_pTable->GetRow(l, &pmsginfo)==S_OK)
  89. {
  90. if (!MemAlloc((LPVOID *)&pMsgData, sizeof(OEMSGDATA)))
  91. return E_OUTOFMEMORY;
  92. pMsgData->pszSubj = PszDup(pmsginfo->pszSubject);
  93. pMsgData->pszTo = PszDup(pmsginfo->pszDisplayTo);
  94. pMsgData->pszCc = PszDup("<not available>");
  95. pMsgData->pszFrom = PszDup(pmsginfo->pszDisplayFrom);
  96. pMsgData->ftReceived = pmsginfo->ftReceived;
  97. pMsgData->msgid = pmsginfo->idMessage;
  98. //m_pFolder->OpenMessage(msginfo.dwMsgId, FALSE, NULL, &pMsg)==S_OK)
  99. // OEMessage frees the data object
  100. hr = CreateOEMessage(NULL, m_idFolder, pMsgData, ppdisp);
  101. if (FAILED(hr))
  102. FreeOEMsgData(pMsgData);
  103. }
  104. return hr;
  105. }
  106. void FreeOEMsgData(POEMSGDATA pMsgData)
  107. {
  108. if (pMsgData)
  109. {
  110. MemFree(pMsgData->pszSubj);
  111. MemFree(pMsgData->pszTo);
  112. MemFree(pMsgData->pszCc);
  113. MemFree(pMsgData->pszFrom);
  114. MemFree(pMsgData);
  115. }
  116. }
  117. /*
  118. * C O E M e s s a g e
  119. */
  120. HRESULT CreateOEMessage(IMimeMessage *pMsg, FOLDERID idFolder, OEMSGDATA *pMsgData, IDispatch **ppdisp)
  121. {
  122. COEMessage *pNew;
  123. HRESULT hr;
  124. pNew = new COEMessage();
  125. if (!pNew)
  126. return E_OUTOFMEMORY;
  127. hr = pNew->Init(pMsg, idFolder, pMsgData);
  128. if (FAILED(hr))
  129. goto error;
  130. hr = pNew->QueryInterface(IID_IDispatch, (LPVOID *)ppdisp);
  131. if (FAILED(hr))
  132. goto error;
  133. error:
  134. ReleaseObj(pNew);
  135. return hr;
  136. }
  137. COEMessage::COEMessage()
  138. {
  139. m_cRef=1;
  140. m_pMsg = NULL;
  141. m_pMsgData = NULL;
  142. CoIncrementInit("COEMessage::COEMessage", MSOEAPI_START_SHOWERRORS, NULL, NULL);
  143. }
  144. COEMessage::~COEMessage()
  145. {
  146. FreeOEMsgData(m_pMsgData);
  147. ReleaseObj(m_pMsg);
  148. CoDecrementInit("COEMessage::COEMessage", NULL);
  149. }
  150. HRESULT COEMessage::PrivateQueryInterface(REFIID riid, LPVOID *lplpObj)
  151. {
  152. if(!lplpObj)
  153. return E_INVALIDARG;
  154. *lplpObj = NULL;
  155. if (IsEqualIID(riid, IID_IUnknown))
  156. *lplpObj = (LPVOID)(IOEMessage *)this;
  157. else if (IsEqualIID(riid, IID_IDispatch))
  158. *lplpObj = (LPVOID)(IDispatch *)(CBaseDisp *)this;
  159. else if (IsEqualIID(riid, IID_IOEMessage))
  160. *lplpObj = (LPVOID)(IOEMessage *)this;
  161. else
  162. return E_NOINTERFACE;
  163. AddRef();
  164. return NOERROR;
  165. }
  166. HRESULT COEMessage::Init(IMimeMessage *pMsg, FOLDERID idFolder, OEMSGDATA *pMsgData)
  167. {
  168. m_idFolder = idFolder;
  169. ReplaceInterface(m_pMsg, pMsg);
  170. m_pMsgData = pMsgData;
  171. return CBaseDisp::EnsureTypeLibrary((LPVOID *)(IOEMessage *)this, IID_IOEMessage);
  172. }
  173. // *** COEMessage **
  174. HRESULT COEMessage::get_subject(BSTR *pbstr)
  175. {
  176. LPSTR psz;
  177. if (!m_pMsg)
  178. {
  179. HrLPSZToBSTR(m_pMsgData->pszSubj, pbstr);
  180. return S_OK;
  181. }
  182. if (MimeOleGetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, &psz)==S_OK)
  183. {
  184. HrLPSZToBSTR(psz, pbstr);
  185. MemFree(psz);
  186. return S_OK;
  187. }
  188. return E_FAIL;
  189. }
  190. HRESULT COEMessage::put_subject(BSTR bstr)
  191. {
  192. LPSTR psz;
  193. BindToMessage();
  194. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  195. {
  196. MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_SUBJECT), NOFLAGS, psz);
  197. MemFree(psz);
  198. }
  199. return S_OK;
  200. }
  201. HRESULT COEMessage::get_to(BSTR *pbstr)
  202. {
  203. LPSTR psz;
  204. *pbstr = NULL;
  205. if (!m_pMsg)
  206. {
  207. HrLPSZToBSTR(m_pMsgData->pszTo, pbstr);
  208. return S_OK;
  209. }
  210. if (m_pMsg->GetAddressFormat(IAT_TO, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
  211. {
  212. HrLPSZToBSTR(psz, pbstr);
  213. MemFree(psz);
  214. }
  215. return S_OK;
  216. }
  217. HRESULT COEMessage::put_to(BSTR bstr)
  218. {
  219. LPSTR psz;
  220. BindToMessage();
  221. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  222. {
  223. MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_TO), NOFLAGS, psz);
  224. MemFree(psz);
  225. }
  226. return S_OK;
  227. }
  228. HRESULT COEMessage::get_cc(BSTR *pbstr)
  229. {
  230. LPSTR psz;
  231. if (!m_pMsg)
  232. {
  233. HrLPSZToBSTR(m_pMsgData->pszCc, pbstr);
  234. return S_OK;
  235. }
  236. *pbstr = NULL;
  237. if (m_pMsg->GetAddressFormat(IAT_CC, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
  238. {
  239. HrLPSZToBSTR(psz, pbstr);
  240. MemFree(psz);
  241. }
  242. return S_OK;
  243. }
  244. HRESULT COEMessage::put_cc(BSTR bstr)
  245. {
  246. LPSTR psz;
  247. BindToMessage();
  248. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  249. {
  250. MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_CC), NOFLAGS, psz);
  251. MemFree(psz);
  252. }
  253. return S_OK;
  254. }
  255. HRESULT COEMessage::get_sender(BSTR *pbstr)
  256. {
  257. LPSTR psz;
  258. *pbstr = NULL;
  259. if (!m_pMsg)
  260. {
  261. HrLPSZToBSTR(m_pMsgData->pszFrom, pbstr);
  262. return S_OK;
  263. }
  264. if (m_pMsg->GetAddressFormat(IAT_FROM, AFT_DISPLAY_FRIENDLY, &psz)==S_OK)
  265. {
  266. HrLPSZToBSTR(psz, pbstr);
  267. MemFree(psz);
  268. }
  269. return S_OK;
  270. }
  271. HRESULT COEMessage::put_sender(BSTR bstr)
  272. {
  273. LPSTR psz;
  274. BindToMessage();
  275. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  276. {
  277. MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_FROM), NOFLAGS, psz);
  278. MemFree(psz);
  279. }
  280. return S_OK;
  281. }
  282. HRESULT COEMessage::get_text(BSTR *pbstr)
  283. {
  284. IStream *pstm;
  285. BindToMessage();
  286. if (m_pMsg->GetTextBody(TXT_PLAIN, IET_DECODED, &pstm, NULL)==S_OK)
  287. {
  288. HrIStreamToBSTR(GetACP(), pstm, pbstr);
  289. pstm->Release();
  290. return S_OK;
  291. }
  292. return E_FAIL;
  293. }
  294. HRESULT COEMessage::put_text(BSTR bstr)
  295. {
  296. IStream *pstm;
  297. LPSTR psz;
  298. BindToMessage();
  299. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  300. {
  301. if (MimeOleCreateVirtualStream(&pstm)==S_OK)
  302. {
  303. pstm->Write(psz, lstrlen(psz), NULL);
  304. m_pMsg->SetTextBody(TXT_PLAIN, IET_BINARY, NULL, pstm, NULL);
  305. pstm->Release();
  306. }
  307. MemFree(psz);
  308. }
  309. return S_OK;
  310. }
  311. HRESULT COEMessage::get_html(BSTR *pbstr)
  312. {
  313. IStream *pstm;
  314. BindToMessage();
  315. if (m_pMsg->GetTextBody(TXT_HTML, IET_DECODED, &pstm, NULL)==S_OK)
  316. {
  317. HrIStreamToBSTR(GetACP(), pstm, pbstr);
  318. pstm->Release();
  319. return S_OK;
  320. }
  321. return E_FAIL;
  322. }
  323. HRESULT COEMessage::put_html(BSTR bstr)
  324. {
  325. IStream *pstm;
  326. LPSTR psz;
  327. if (HrBSTRToLPSZ(CP_ACP, bstr, &psz)==S_OK)
  328. {
  329. if (MimeOleCreateVirtualStream(&pstm)==S_OK)
  330. {
  331. pstm->Write(psz, lstrlen(psz), NULL);
  332. m_pMsg->SetTextBody(TXT_HTML, IET_BINARY, NULL, pstm, NULL);
  333. pstm->Release();
  334. }
  335. MemFree(psz);
  336. }
  337. return S_OK;
  338. }
  339. HRESULT COEMessage::get_url(BSTR *pbstr)
  340. {
  341. IStream *pstm;
  342. BindToMessage();
  343. // BUGBUGBUG: this is a terrible hack also. We can't get a persistent URL moniker to
  344. // the MHTML document (not yet investigated), so for the purpose of this demo-code
  345. // we'll use a tmp file
  346. if (m_pMsg->GetMessageSource(&pstm, 0)==S_OK)
  347. {
  348. WriteStreamToFile(pstm, "c:\\oe_temp$.eml", CREATE_ALWAYS, GENERIC_WRITE);
  349. pstm->Release();
  350. }
  351. *pbstr = SysAllocString(L"c:\\oe_temp$.eml");
  352. return S_OK;
  353. }
  354. HRESULT COEMessage::get_date(BSTR *pbstr)
  355. {
  356. PROPVARIANT pv;
  357. TCHAR rgch[MAX_PATH];
  358. FILETIME *pft=0;
  359. *pbstr = NULL;
  360. if (!m_pMsg)
  361. {
  362. pft = &m_pMsgData->ftReceived;
  363. }
  364. else
  365. {
  366. // Get Receive Time
  367. pv.vt = VT_FILETIME;
  368. if (SUCCEEDED(m_pMsg->GetProp(PIDTOSTR(PID_ATT_RECVTIME), 0, &pv)))
  369. pft = &pv.filetime;
  370. }
  371. if (pft)
  372. {
  373. *rgch=0;
  374. CchFileTimeToDateTimeSz(pft, rgch, sizeof(rgch)/sizeof(TCHAR), DTM_NOSECONDS);
  375. HrLPSZToBSTR(rgch, pbstr);
  376. }
  377. return S_OK;
  378. }
  379. HRESULT COEMessage::send()
  380. {
  381. /*
  382. TCHAR sz[MAX_PATH];
  383. // use default account to send
  384. if (SUCCEEDED(g_pAcctMan->GetDefaultAccountId(ACCT_MAIL, sz, ARRAYSIZE(sz))))
  385. {
  386. PROPVARIANT rUserData;
  387. rUserData.vt = VT_LPSTR;
  388. rUserData.pszVal = sz;
  389. m_pMsg->SetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &rUserData);
  390. }
  391. HrSendMailToOutBox(g_hwndInit, m_pMsg, TRUE, TRUE);
  392. */
  393. return E_FAIL;
  394. }
  395. HRESULT COEMessage::BindToMessage()
  396. {
  397. if (m_pMsg)
  398. return S_OK;
  399. //Assert (m_pFolder && m_pMsgData);
  400. //return m_pFolder->OpenMessage(m_pMsgData->msgid, NULL, &m_pMsg, NULL);
  401. return E_FAIL;
  402. }