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