OSDN Git Service

Enable Clean Up and Show log at GitStatusListCtrl
[tortoisegit/TortoiseGitJp.git] / src / crashrpt / MailMsg.cpp
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //\r
3 //  Module: MailMsg.cpp\r
4 //\r
5 //    Desc: See MailMsg.h\r
6 //\r
7 // Copyright (c) 2003 Michael Carruth\r
8 //\r
9 ///////////////////////////////////////////////////////////////////////////////\r
10 \r
11 #include "stdafx.h"\r
12 #include "MailMsg.h"\r
13 \r
14 CMailMsg::CMailMsg()\r
15 {\r
16    m_lpCmcLogon      = NULL;\r
17    m_lpCmcSend       = NULL;\r
18    m_lpCmcLogoff     = NULL;\r
19    m_lpMapiLogon     = NULL;\r
20    m_lpMapiSendMail  = NULL;\r
21    m_lpMapiLogoff    = NULL;\r
22    m_lpMapiResolveName = NULL;\r
23    m_lpMapiFreeBuffer = NULL;\r
24    m_bReady          = FALSE;\r
25 }\r
26 \r
27 CMailMsg::~CMailMsg()\r
28 {\r
29    if (m_bReady)\r
30       Uninitialize();\r
31 }\r
32 \r
33 CMailMsg& CMailMsg::SetFrom(string sAddress, string sName)\r
34 {\r
35    if (m_bReady || Initialize())\r
36    {\r
37       // only one sender allowed\r
38       if (m_from.size())\r
39          m_from.empty();\r
40 \r
41           m_from.push_back(TStrStrPair(sAddress,sName));\r
42    }\r
43 \r
44    return *this;\r
45 }\r
46 \r
47 CMailMsg& CMailMsg::SetTo(string sAddress, string sName)\r
48 {\r
49    if (m_bReady || Initialize())\r
50    {\r
51       // only one recipient allowed\r
52       if (m_to.size())\r
53          m_to.empty();\r
54 \r
55           m_to.push_back(TStrStrPair(sAddress,sName));\r
56    }\r
57 \r
58    return *this;\r
59 }\r
60 \r
61 CMailMsg& CMailMsg::SetCc(string sAddress, string sName)\r
62 {\r
63    if (m_bReady || Initialize())\r
64    {\r
65       m_cc.push_back(TStrStrPair(sAddress,sName));\r
66    }\r
67 \r
68    return *this;\r
69 }\r
70 \r
71 CMailMsg& CMailMsg::SetBc(string sAddress, string sName)\r
72 {\r
73    if (m_bReady || Initialize())\r
74    {\r
75            m_bcc.push_back(TStrStrPair(sAddress, sName));\r
76    }\r
77 \r
78    return *this;\r
79 }\r
80 \r
81 CMailMsg& CMailMsg::AddAttachment(string sAttachment, string sTitle)\r
82 {\r
83    if (m_bReady || Initialize())\r
84    {\r
85       m_attachments.push_back(TStrStrPair(sAttachment, sTitle));\r
86    }\r
87 \r
88    return *this;\r
89 }\r
90 \r
91 BOOL CMailMsg::Send()\r
92 {\r
93    // try mapi\r
94    int status = MAPISend();\r
95    if (status != 0)\r
96       return status == 1;\r
97    // try cmc\r
98 //   if (CMCSend())\r
99 //      return TRUE;\r
100 \r
101    return FALSE;\r
102 }\r
103 \r
104 /*\r
105 +------------------------------------------------------------------------------\r
106 |\r
107 |       Function:       cResolveName()\r
108 |\r
109 |       Parameters:     [IN]    lpszName = Name of e-mail recipient to resolve.\r
110 |                               [OUT]   ppRecips = Pointer to a pointer to an lpMapiRecipDesc\r
111 |\r
112 |       Purpose:        Resolves an e-mail address and returns a pointer to a \r
113 |                               MapiRecipDesc structure filled with the recipient information\r
114 |                               contained in the address book.\r
115 |\r
116 |       Note:           ppRecips is allocated off the heap using MAPIAllocateBuffer.\r
117 |                               Any user of this method must be sure to release ppRecips when \r
118 |                               done with it using either MAPIFreeBuffer or cFreeBuffer.\r
119 +-------------------------------------------------------------------------------\r
120 */\r
121 int CMailMsg::cResolveName( LHANDLE m_lhSession, const char * lpszName, lpMapiRecipDesc *ppRecip )\r
122 {       \r
123         HRESULT hRes = E_FAIL;\r
124         FLAGS flFlags = 0L;\r
125         ULONG ulReserved = 0L;\r
126         lpMapiRecipDesc pRecips = NULL;\r
127         \r
128         // Always check to make sure there is an active session\r
129         if ( m_lhSession )              \r
130         {\r
131                 hRes = m_lpMapiResolveName (\r
132                                                                      m_lhSession,       // Session handle\r
133                                                                          0L,                    // Parent window.\r
134                                                                          const_cast<LPSTR>(lpszName),           // Name of recipient.  Passed in by argv.\r
135                                                                          flFlags,               // Flags set to 0 for MAPIResolveName.\r
136                                                                          ulReserved,\r
137                                                                          &pRecips\r
138                                                                   );                            \r
139 \r
140                 if ( hRes == SUCCESS_SUCCESS )\r
141                 {  \r
142                         // Copy the recipient descriptor returned from MAPIResolveName to \r
143                         // the out parameter for this function,\r
144                         *ppRecip = pRecips;\r
145                 }  \r
146         }\r
147         return hRes;\r
148 }\r
149 \r
150 \r
151 \r
152 int CMailMsg::MAPISend()\r
153 {\r
154 \r
155    TStrStrVector::iterator p;\r
156    int                  nIndex = 0;\r
157    size_t               nRecipients = 0;\r
158    MapiRecipDesc*       pRecipients = NULL;\r
159    MapiRecipDesc*       pOriginator = NULL;\r
160    MapiRecipDesc*       pFirstRecipient = NULL;\r
161    size_t               nAttachments = 0;\r
162    MapiFileDesc*        pAttachments = NULL;\r
163    ULONG                status = 0;\r
164    MapiMessage          message;\r
165    std::vector<MapiRecipDesc*>  buffersToFree;\r
166    MapiRecipDesc*       pRecip;\r
167    MapiRecipDesc                grecip;\r
168 \r
169    if (m_bReady || Initialize())\r
170    {\r
171           LHANDLE hMapiSession;\r
172           status = m_lpMapiLogon(NULL, NULL, NULL, MAPI_NEW_SESSION | MAPI_LOGON_UI, 0, &hMapiSession);\r
173           if (SUCCESS_SUCCESS != status) {\r
174                   return FALSE;\r
175           }\r
176 \r
177       nRecipients = m_to.size() + m_cc.size() + m_bcc.size() + m_from.size();\r
178       if (nRecipients)\r
179           {\r
180          pRecipients = new MapiRecipDesc[nRecipients];\r
181                  memset(pRecipients, 0, nRecipients * sizeof  MapiRecipDesc);\r
182           }\r
183 \r
184       nAttachments = m_attachments.size();\r
185       if (nAttachments)\r
186          pAttachments = new MapiFileDesc[nAttachments];\r
187 \r
188       if (pRecipients)\r
189       {\r
190          pFirstRecipient = pRecipients;\r
191          if (m_from.size())\r
192          {\r
193             // set from\r
194                          if (cResolveName(hMapiSession, m_from.begin()->first.c_str(), &pOriginator) == SUCCESS_SUCCESS) {\r
195                                 buffersToFree.push_back(pOriginator);\r
196                          }\r
197          }\r
198          if (m_to.size())\r
199          {\r
200                          if (cResolveName(hMapiSession, m_to.begin()->first.c_str(), &pRecip) == SUCCESS_SUCCESS) {\r
201                                 if (pFirstRecipient == NULL)\r
202                                         pFirstRecipient = &pRecipients[nIndex];\r
203                                 pRecip->ulRecipClass = MAPI_TO;\r
204                                 memcpy(&pRecipients[nIndex], pRecip, sizeof pRecipients[nIndex]);\r
205                                 buffersToFree.push_back(pRecip);\r
206                                 nIndex++;\r
207                          }\r
208                          else\r
209                          {\r
210                                  if (pFirstRecipient == NULL)\r
211                                          pFirstRecipient = &pRecipients[nIndex];\r
212                                  grecip.ulRecipClass = MAPI_TO;\r
213                                  grecip.lpEntryID = 0;\r
214                                  grecip.lpszName = 0;\r
215                                  grecip.ulEIDSize = 0;\r
216                                  grecip.ulReserved = 0;\r
217                                  grecip.lpszAddress = (LPTSTR)(LPCTSTR)m_to.begin()->first.c_str();\r
218                                  memcpy(&pRecipients[nIndex], &grecip, sizeof pRecipients[nIndex]);\r
219                                  nIndex++;\r
220                          }\r
221          }              \r
222          if (m_cc.size())\r
223          {\r
224             // set cc's\r
225             for (p = m_cc.begin(); p != m_cc.end(); p++, nIndex++)\r
226             {\r
227                                 if ( cResolveName(hMapiSession, p->first.c_str(), &pRecip) == SUCCESS_SUCCESS) {\r
228                                         if (pFirstRecipient == NULL)\r
229                                                 pFirstRecipient = &pRecipients[nIndex];\r
230                                         pRecip->ulRecipClass = MAPI_CC;\r
231                                         memcpy(&pRecipients[nIndex], pRecip, sizeof pRecipients[nIndex]);\r
232                                         buffersToFree.push_back(pRecip);\r
233                                         nIndex++;\r
234                                 }\r
235             }\r
236          }\r
237    \r
238          if (m_bcc.size())\r
239          {\r
240             // set bcc\r
241             for (p = m_bcc.begin(); p != m_bcc.end(); p++, nIndex++)\r
242             {\r
243                                 if ( cResolveName(hMapiSession, p->first.c_str(), &pRecip) == SUCCESS_SUCCESS) {\r
244                                         if (pFirstRecipient == NULL)\r
245                                                 pFirstRecipient = &pRecipients[nIndex];\r
246                                         pRecip->ulRecipClass = MAPI_BCC;\r
247                                         memcpy(&pRecipients[nIndex], pRecip, sizeof pRecipients[nIndex]);\r
248                                         buffersToFree.push_back(pRecip);\r
249                                         nIndex++;\r
250                                 }\r
251             }\r
252          }\r
253       }\r
254       if (pAttachments)\r
255       {\r
256          // add attachments\r
257          for (p = m_attachments.begin(), nIndex = 0;\r
258               p != m_attachments.end(); p++, nIndex++)\r
259          {\r
260             pAttachments[nIndex].ulReserved        = 0;\r
261             pAttachments[nIndex].flFlags           = 0;\r
262             pAttachments[nIndex].nPosition         = 0;\r
263             pAttachments[nIndex].lpszPathName      = (LPTSTR)p->first.c_str();\r
264             pAttachments[nIndex].lpszFileName      = (LPTSTR)p->second.c_str();\r
265             pAttachments[nIndex].lpFileType        = NULL;\r
266          }\r
267       }\r
268           memset(&message, 0, sizeof message);\r
269       message.ulReserved                        = 0;\r
270           if (!m_sSubject.empty())\r
271               message.lpszSubject                       = (LPTSTR)m_sSubject.c_str();\r
272           else\r
273                   message.lpszSubject = "No Subject";\r
274           if (!m_sMessage.empty())\r
275               message.lpszNoteText                      = (LPTSTR)m_sMessage.c_str();\r
276           else\r
277                   message.lpszNoteText = "No Message Body";\r
278       message.lpszMessageType                   = NULL;\r
279       message.lpszDateReceived                  = NULL;\r
280       message.lpszConversationID                = NULL;\r
281       message.flFlags                           = 0;\r
282       message.lpOriginator                      = pOriginator;\r
283       message.nRecipCount                       = nIndex;\r
284       message.lpRecips                          = pFirstRecipient;\r
285       message.nFileCount                        = nAttachments;\r
286       message.lpFiles                           = pAttachments;\r
287 \r
288       status = m_lpMapiSendMail(hMapiSession, 0, &message, MAPI_DIALOG, 0);\r
289                   \r
290       m_lpMapiLogoff(hMapiSession, NULL, 0, 0);\r
291           std::vector<MapiRecipDesc*>::iterator iter;\r
292           for (iter = buffersToFree.begin(); iter != buffersToFree.end(); iter++) {\r
293                   m_lpMapiFreeBuffer(*iter);\r
294           }\r
295 if (SUCCESS_SUCCESS != status) {\r
296                                 string txt;\r
297                                 TCHAR buf[MAX_PATH];\r
298                                 _tprintf_s(buf, "Message did not get sent due to error code %d.\r\n", status);\r
299                                 txt = buf;\r
300                         switch (status)\r
301                         {  \r
302                         case MAPI_E_AMBIGUOUS_RECIPIENT:\r
303                                 txt += "A recipient matched more than one of the recipient descriptor structures and MAPI_DIALOG was not set. No message was sent.\r\n" ;\r
304                                 break;\r
305                         case MAPI_E_ATTACHMENT_NOT_FOUND:\r
306                                 txt += "The specified attachment was not found. No message was sent.\r\n" ;\r
307                                 break;\r
308                         case MAPI_E_ATTACHMENT_OPEN_FAILURE:\r
309                                 txt += "The specified attachment could not be opened. No message was sent.\r\n" ;\r
310                                 break;\r
311                         case MAPI_E_BAD_RECIPTYPE:\r
312                                 txt += "The type of a recipient was not MAPI_TO, MAPI_CC, or MAPI_BCC. No message was sent.\r\n" ;\r
313                                 break;\r
314                         case MAPI_E_FAILURE:\r
315                                 txt += "One or more unspecified errors occurred. No message was sent.\r\n" ;\r
316                                 break;\r
317                         case MAPI_E_INSUFFICIENT_MEMORY:\r
318                                 txt += "There was insufficient memory to proceed. No message was sent.\r\n" ;\r
319                                 break;\r
320                         case MAPI_E_INVALID_RECIPS:\r
321                                 txt += "One or more recipients were invalid or did not resolve to any address.\r\n" ;\r
322                                 break;\r
323                         case MAPI_E_LOGIN_FAILURE:\r
324                                 txt += "There was no default logon, and the user failed to log on successfully when the logon dialog box was displayed. No message was sent.\r\n" ;\r
325                                 break;\r
326                         case MAPI_E_TEXT_TOO_LARGE:\r
327                                 txt += "The text in the message was too large. No message was sent.\r\n" ;\r
328                                 break;\r
329                         case MAPI_E_TOO_MANY_FILES:\r
330                                 txt += "There were too many file attachments. No message was sent.\r\n" ;\r
331                                 break;\r
332                         case MAPI_E_TOO_MANY_RECIPIENTS:\r
333                                 txt += "There were too many recipients. No message was sent.\r\n" ;\r
334                                 break;\r
335                         case MAPI_E_UNKNOWN_RECIPIENT:\r
336                                 txt += "A recipient did not appear in the address list. No message was sent.\r\n" ;\r
337                                 break;\r
338                         case MAPI_E_USER_ABORT:\r
339                                 txt += "The user canceled one of the dialog boxes. No message was sent.\r\n" ;\r
340                                 break;\r
341                         default:\r
342                                 txt += "Unknown error code.\r\n" ;\r
343                                 break;\r
344                         }\r
345                         ::MessageBox(0, txt.c_str(), "Error", MB_OK);\r
346 }\r
347 \r
348       if (pRecipients)\r
349          delete [] pRecipients;\r
350 \r
351       if (nAttachments)\r
352          delete [] pAttachments;\r
353    }\r
354 \r
355    if (SUCCESS_SUCCESS == status)\r
356            return 1;\r
357    if (MAPI_E_USER_ABORT == status)\r
358            return -1;\r
359    // other failure\r
360    return 0;\r
361 }\r
362 \r
363 BOOL CMailMsg::CMCSend()\r
364 {\r
365    TStrStrVector::iterator p;\r
366    int                  nIndex = 0;\r
367    CMC_recipient*       pRecipients;\r
368    CMC_attachment*      pAttachments;\r
369    CMC_session_id       session;\r
370    CMC_return_code      status = 0;\r
371    CMC_message          message;\r
372    CMC_boolean          bAvailable = FALSE;\r
373    CMC_time             t_now = {0};\r
374 \r
375    if (m_bReady || Initialize())\r
376    {\r
377       pRecipients = new CMC_recipient[m_to.size() + m_cc.size() + m_bcc.size() + m_from.size()];\r
378       pAttachments = new CMC_attachment[m_attachments.size()];\r
379 \r
380       // set cc's\r
381       for (p = m_cc.begin(); p != m_cc.end(); p++, nIndex++)\r
382       {\r
383          pRecipients[nIndex].name                = (LPTSTR)(LPCTSTR)p->second.c_str();\r
384          pRecipients[nIndex].name_type           = CMC_TYPE_INDIVIDUAL;\r
385          pRecipients[nIndex].address             = (LPTSTR)(LPCTSTR)p->first.c_str();\r
386          pRecipients[nIndex].role                = CMC_ROLE_CC;\r
387          pRecipients[nIndex].recip_flags         = 0;\r
388          pRecipients[nIndex].recip_extensions    = NULL;\r
389       }\r
390    \r
391       // set bcc\r
392       for (p = m_bcc.begin(); p != m_bcc.end(); p++, nIndex++)\r
393       {\r
394          pRecipients[nIndex].name                = (LPTSTR)(LPCTSTR)p->second.c_str();\r
395          pRecipients[nIndex].name_type           = CMC_TYPE_INDIVIDUAL;\r
396          pRecipients[nIndex].address             = (LPTSTR)(LPCTSTR)p->first.c_str();\r
397          pRecipients[nIndex].role                = CMC_ROLE_BCC;\r
398          pRecipients[nIndex].recip_flags         = 0;\r
399          pRecipients[nIndex].recip_extensions    = NULL;\r
400       }\r
401    \r
402       // set to\r
403       pRecipients[nIndex].name                   = (LPTSTR)(LPCTSTR)m_to.begin()->second.c_str();\r
404       pRecipients[nIndex].name_type              = CMC_TYPE_INDIVIDUAL;\r
405       pRecipients[nIndex].address                = (LPTSTR)(LPCTSTR)m_to.begin()->first.c_str();\r
406       pRecipients[nIndex].role                   = CMC_ROLE_TO;\r
407       pRecipients[nIndex].recip_flags            = 0;\r
408       pRecipients[nIndex].recip_extensions       = NULL;\r
409    \r
410       // set from\r
411       pRecipients[nIndex+1].name                 = (LPTSTR)(LPCTSTR)m_from.begin()->second.c_str();\r
412       pRecipients[nIndex+1].name_type            = CMC_TYPE_INDIVIDUAL;\r
413       pRecipients[nIndex+1].address              = (LPTSTR)(LPCTSTR)m_from.begin()->first.c_str();\r
414       pRecipients[nIndex+1].role                 = CMC_ROLE_ORIGINATOR;\r
415       pRecipients[nIndex+1].recip_flags          = CMC_RECIP_LAST_ELEMENT;\r
416       pRecipients[nIndex+1].recip_extensions     = NULL;\r
417    \r
418       // add attachments\r
419       for (p = m_attachments.begin(), nIndex = 0;\r
420            p != m_attachments.end(); p++, nIndex++)\r
421       {\r
422          pAttachments[nIndex].attach_title       = (LPTSTR)(LPCTSTR)p->second.c_str();\r
423          pAttachments[nIndex].attach_type        = NULL;\r
424          pAttachments[nIndex].attach_filename    = (LPTSTR)(LPCTSTR)p->first.c_str();\r
425          pAttachments[nIndex].attach_flags       = 0;\r
426          pAttachments[nIndex].attach_extensions  = NULL;\r
427       }\r
428       pAttachments[nIndex-1].attach_flags        = CMC_ATT_LAST_ELEMENT;\r
429 \r
430       message.message_reference                 = NULL;\r
431       message.message_type                      = NULL;\r
432           if (m_sSubject.empty())\r
433                   message.subject = "No Subject";\r
434           else\r
435               message.subject                           = (LPTSTR)(LPCTSTR)m_sSubject.c_str();\r
436       message.time_sent                         = t_now;\r
437           if (m_sMessage.empty())\r
438                   message.text_note = "No Body";\r
439           else\r
440                   message.text_note                         = (LPTSTR)(LPCTSTR)m_sMessage.c_str();\r
441       message.recipients                        = pRecipients;\r
442       message.attachments                       = pAttachments;\r
443       message.message_flags                     = 0;\r
444       message.message_extensions                = NULL;\r
445 \r
446       status = m_lpCmcQueryConfiguration(\r
447                   0, \r
448                   CMC_CONFIG_UI_AVAIL, \r
449                   (void*)&bAvailable, \r
450                   NULL\r
451                   );\r
452 \r
453       if (CMC_SUCCESS == status && bAvailable)\r
454       {\r
455          status = m_lpCmcLogon(\r
456                      NULL,\r
457                      NULL,\r
458                      NULL,\r
459                      NULL,\r
460                      0,\r
461                      CMC_VERSION,\r
462                      CMC_LOGON_UI_ALLOWED |\r
463                      CMC_ERROR_UI_ALLOWED,\r
464                      &session,\r
465                      NULL\r
466                      );\r
467 \r
468          if (CMC_SUCCESS == status)\r
469          {\r
470             status = m_lpCmcSend(session, &message, 0, 0, NULL);\r
471 \r
472             m_lpCmcLogoff(session, NULL, CMC_LOGON_UI_ALLOWED, NULL);\r
473          }\r
474       }\r
475 \r
476       delete [] pRecipients;\r
477       delete [] pAttachments;\r
478    }\r
479 \r
480    return ((CMC_SUCCESS == status) && bAvailable);\r
481 }\r
482 \r
483 BOOL CMailMsg::Initialize()\r
484 {\r
485    m_hMapi = ::LoadLibrary(_T("mapi32.dll"));\r
486    \r
487    if (!m_hMapi)\r
488       return FALSE;\r
489 \r
490    m_lpCmcQueryConfiguration = (LPCMCQUERY)::GetProcAddress(m_hMapi, _T("cmc_query_configuration"));\r
491    m_lpCmcLogon = (LPCMCLOGON)::GetProcAddress(m_hMapi, _T("cmc_logon"));\r
492    m_lpCmcSend = (LPCMCSEND)::GetProcAddress(m_hMapi, _T("cmc_send"));\r
493    m_lpCmcLogoff = (LPCMCLOGOFF)::GetProcAddress(m_hMapi, _T("cmc_logoff"));\r
494    m_lpMapiLogon = (LPMAPILOGON)::GetProcAddress(m_hMapi, _T("MAPILogon"));\r
495    m_lpMapiSendMail = (LPMAPISENDMAIL)::GetProcAddress(m_hMapi, _T("MAPISendMail"));\r
496    m_lpMapiLogoff = (LPMAPILOGOFF)::GetProcAddress(m_hMapi, _T("MAPILogoff"));\r
497    m_lpMapiResolveName = (LPMAPIRESOLVENAME) GetProcAddress(m_hMapi, _T("MAPIResolveName"));\r
498    m_lpMapiFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(m_hMapi, _T("MAPIFreeBuffer"));\r
499 \r
500    m_bReady = (m_lpCmcLogon && m_lpCmcSend && m_lpCmcLogoff) ||\r
501               (m_lpMapiLogon && m_lpMapiSendMail && m_lpMapiLogoff);\r
502 \r
503    return m_bReady;\r
504 }\r
505 \r
506 void CMailMsg::Uninitialize()\r
507 {\r
508    ::FreeLibrary(m_hMapi);\r
509 }