/reporting/crashsender/MailMsg.cpp

http://crashrpt.googlecode.com/ · C++ · 265 lines · 198 code · 44 blank · 23 comment · 23 complexity · f32aed3698551aecbb06631865ad28b4 MD5 · raw file

  1. /*************************************************************************************
  2. This file is a part of CrashRpt library.
  3. Copyright (c) 2003-2013 The CrashRpt project authors. All Rights Reserved.
  4. Use of this source code is governed by a BSD-style license
  5. that can be found in the License.txt file in the root of the source
  6. tree. All contributing project authors may
  7. be found in the Authors.txt file in the root of the source tree.
  8. ***************************************************************************************/
  9. ///////////////////////////////////////////////////////////////////////////////
  10. //
  11. // Module: MailMsg.cpp
  12. //
  13. // Desc: See MailMsg.h
  14. //
  15. // Copyright (c) 2003 Michael Carruth
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include "stdafx.h"
  19. #include "MailMsg.h"
  20. #include "Utility.h"
  21. #include "strconv.h"
  22. CMailMsg::CMailMsg()
  23. {
  24. m_lpMapiLogon = NULL;
  25. m_lpMapiSendMail = NULL;
  26. m_lpMapiLogoff = NULL;
  27. m_bReady = FALSE;
  28. }
  29. CMailMsg::~CMailMsg()
  30. {
  31. if (m_bReady)
  32. MAPIFinalize();
  33. }
  34. void CMailMsg::SetFrom(CString sAddress)
  35. {
  36. strconv_t strconv;
  37. LPCSTR lpszAddress = strconv.t2a(sAddress.GetBuffer(0));
  38. m_from = lpszAddress;
  39. }
  40. void CMailMsg::AddRecipient(CString sAddress)
  41. {
  42. strconv_t strconv;
  43. LPCSTR lpszAddress = strconv.t2a(sAddress.GetBuffer(0));
  44. m_to.push_back(lpszAddress);
  45. }
  46. void CMailMsg::SetSubject(CString sSubject)
  47. {
  48. strconv_t strconv;
  49. LPCSTR lpszSubject = strconv.t2a(sSubject.GetBuffer(0));
  50. m_sSubject = lpszSubject;
  51. }
  52. void CMailMsg::SetMessage(CString sMessage)
  53. {
  54. strconv_t strconv;
  55. LPCSTR lpszMessage = strconv.t2a(sMessage.GetBuffer(0));
  56. m_sMessage = lpszMessage;
  57. };
  58. void CMailMsg::AddAttachment(CString sAttachment, CString sTitle)
  59. {
  60. strconv_t strconv;
  61. LPCSTR lpszAttachment = strconv.t2a(sAttachment.GetBuffer(0));
  62. LPCSTR lpszTitle = strconv.t2a(sTitle.GetBuffer(0));
  63. m_attachments[lpszAttachment] = lpszTitle;
  64. }
  65. BOOL CMailMsg::DetectMailClient(CString& sMailClientName)
  66. {
  67. CRegKey regKey;
  68. TCHAR buf[1024] = _T("");
  69. ULONG buf_size = 0;
  70. LONG lResult;
  71. lResult = regKey.Open(HKEY_CURRENT_USER, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
  72. if(lResult!=ERROR_SUCCESS)
  73. {
  74. lResult = regKey.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
  75. }
  76. if(lResult==ERROR_SUCCESS)
  77. {
  78. buf_size = 1023;
  79. #pragma warning(disable:4996)
  80. LONG result = regKey.QueryValue(buf, _T(""), &buf_size);
  81. #pragma warning(default:4996)
  82. if(result==ERROR_SUCCESS)
  83. {
  84. sMailClientName = buf;
  85. return TRUE;
  86. }
  87. regKey.Close();
  88. }
  89. else
  90. {
  91. sMailClientName = "Not Detected";
  92. }
  93. return FALSE;
  94. }
  95. BOOL CMailMsg::MAPIInitialize()
  96. {
  97. // Determine if there is default email program
  98. CString sMailClientName;
  99. if(!DetectMailClient(sMailClientName))
  100. {
  101. m_sErrorMsg = _T("Error detecting E-mail client");
  102. return FALSE;
  103. }
  104. else
  105. {
  106. m_sErrorMsg = _T("Detected E-mail client ") + sMailClientName;
  107. }
  108. // Load MAPI.dll
  109. m_hMapi = ::LoadLibrary(_T("mapi32.dll"));
  110. if (!m_hMapi)
  111. {
  112. m_sErrorMsg = _T("Error loading mapi32.dll");
  113. return FALSE;
  114. }
  115. m_lpMapiLogon = (LPMAPILOGON)::GetProcAddress(m_hMapi, "MAPILogon");
  116. m_lpMapiSendMail = (LPMAPISENDMAIL)::GetProcAddress(m_hMapi, "MAPISendMail");
  117. m_lpMapiLogoff = (LPMAPILOGOFF)::GetProcAddress(m_hMapi, "MAPILogoff");
  118. m_bReady = (m_lpMapiLogon && m_lpMapiSendMail && m_lpMapiLogoff);
  119. if(!m_bReady)
  120. {
  121. m_sErrorMsg = _T("Not found required function entries in mapi32.dll");
  122. }
  123. return m_bReady;
  124. }
  125. void CMailMsg::MAPIFinalize()
  126. {
  127. ::FreeLibrary(m_hMapi);
  128. }
  129. CString CMailMsg::GetEmailClientName()
  130. {
  131. return m_sEmailClientName;
  132. }
  133. BOOL CMailMsg::Send()
  134. {
  135. if(m_lpMapiSendMail==NULL)
  136. return FALSE;
  137. TStrStrMap::iterator p;
  138. int nIndex = 0;
  139. MapiRecipDesc* pRecipients = NULL;
  140. int nAttachments = 0;
  141. MapiFileDesc* pAttachments = NULL;
  142. ULONG status = 0;
  143. MapiMessage message;
  144. if(!m_bReady && !MAPIInitialize())
  145. return FALSE;
  146. LHANDLE hMapiSession = 0;
  147. status = m_lpMapiLogon(NULL, NULL, NULL, MAPI_LOGON_UI|MAPI_PASSWORD_UI, NULL, &hMapiSession);
  148. if(status!=SUCCESS_SUCCESS)
  149. {
  150. m_sErrorMsg.Format(_T("MAPILogon has failed with code %X."), status);
  151. return FALSE;
  152. }
  153. pRecipients = new MapiRecipDesc[1+m_to.size()];
  154. if(!pRecipients)
  155. {
  156. m_sErrorMsg = _T("Error allocating memory");
  157. return FALSE;
  158. }
  159. nAttachments = (int)m_attachments.size();
  160. if (nAttachments)
  161. pAttachments = new MapiFileDesc[nAttachments];
  162. if(!pAttachments)
  163. {
  164. m_sErrorMsg = _T("Error allocating memory");
  165. return FALSE;
  166. }
  167. // set from
  168. pRecipients[0].ulReserved = 0;
  169. pRecipients[0].ulRecipClass = MAPI_ORIG;
  170. pRecipients[0].lpszAddress = (LPSTR)m_from.c_str();
  171. pRecipients[0].lpszName = "";
  172. pRecipients[0].ulEIDSize = 0;
  173. pRecipients[0].lpEntryID = NULL;
  174. // set to
  175. size_t i;
  176. for(i=0; i<m_to.size(); i++)
  177. {
  178. pRecipients[i+1].ulReserved = 0;
  179. pRecipients[i+1].ulRecipClass = MAPI_TO;
  180. pRecipients[i+1].lpszAddress = (LPSTR)m_to[i].c_str();
  181. pRecipients[i+1].lpszName = (LPSTR)m_to[i].c_str();
  182. pRecipients[i+1].ulEIDSize = 0;
  183. pRecipients[i+1].lpEntryID = NULL;
  184. }
  185. // add attachments
  186. nIndex=0;
  187. for (p = m_attachments.begin(), nIndex = 0;
  188. p != m_attachments.end(); p++, nIndex++)
  189. {
  190. pAttachments[nIndex].ulReserved = 0;
  191. pAttachments[nIndex].flFlags = 0;
  192. pAttachments[nIndex].nPosition = 0xFFFFFFFF;
  193. pAttachments[nIndex].lpszPathName = (LPSTR)p->first.c_str();
  194. pAttachments[nIndex].lpszFileName = (LPSTR)p->second.c_str();
  195. pAttachments[nIndex].lpFileType = NULL;
  196. }
  197. message.ulReserved = 0;
  198. message.lpszSubject = (LPSTR)m_sSubject.c_str();
  199. message.lpszNoteText = (LPSTR)m_sMessage.c_str();
  200. message.lpszMessageType = NULL;
  201. message.lpszDateReceived = NULL;
  202. message.lpszConversationID = NULL;
  203. message.flFlags = 0;
  204. message.lpOriginator = pRecipients;
  205. message.nRecipCount = (ULONG)m_to.size();
  206. message.lpRecips = &pRecipients[1];
  207. message.nFileCount = nAttachments;
  208. message.lpFiles = nAttachments ? pAttachments : NULL;
  209. status = m_lpMapiSendMail(hMapiSession, 0, &message, 0/*MAPI_DIALOG*/, 0);
  210. if(status!=SUCCESS_SUCCESS)
  211. {
  212. m_sErrorMsg.Format(_T("MAPISendMail has failed with code %X."), status);
  213. }
  214. m_lpMapiLogoff(hMapiSession, NULL, 0, 0);
  215. if (pRecipients)
  216. delete [] pRecipients;
  217. if (nAttachments)
  218. delete [] pAttachments;
  219. return (SUCCESS_SUCCESS == status);
  220. }