Fixed issue #1619: TortoiseGitMerge: Ribbon UI/toolbars can be toggled
[TortoiseGit.git] / src / Utils / MailMsg.cpp
blob14b8cd5acbcf1e9968179b94b587de9dac6f5b24
1 /*************************************************************************************
2 This file is a part of CrashRpt library.
4 Copyright (c) 2003, Michael Carruth
5 All rights reserved.
7 Adjusted by Sven Strickroth <email@cs-ware.de>, 2011
8 * make it work with no attachments
9 * added flag to show mail compose dialog
10 * make it work with 32-64bit inconsistencies (http://msdn.microsoft.com/en-us/library/dd941355.aspx)
11 * auto extract filenames of attachments
12 * added AddCC
14 Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
17 * Redistributions of source code must retain the above copyright notice, this
18 list of conditions and the following disclaimer.
20 * Redistributions in binary form must reproduce the above copyright notice,
21 this list of conditions and the following disclaimer in the documentation
22 and/or other materials provided with the distribution.
24 * Neither the name of the author nor the names of its contributors
25 may be used to endorse or promote products derived from this software without
26 specific prior written permission.
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
30 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
32 SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
34 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ***************************************************************************************/
40 ///////////////////////////////////////////////////////////////////////////////
42 // Module: MailMsg.cpp
44 // Desc: See MailMsg.h
46 // Copyright (c) 2003 Michael Carruth
48 ///////////////////////////////////////////////////////////////////////////////
50 #include "stdafx.h"
51 #include "MailMsg.h"
52 #include "strconv.h"
54 CMailMsg::CMailMsg()
56 m_hMapi = NULL;
57 m_lpMapiSendMail = NULL;
58 m_bReady = FALSE;
59 m_bShowComposeDialog = FALSE;
62 CMailMsg::~CMailMsg()
64 if (m_bReady)
65 MAPIFinalize();
69 void CMailMsg::SetFrom(CString sAddress)
71 strconv_t strconv;
72 LPCSTR lpszAddress = strconv.t2a(sAddress.GetBuffer(0));
73 m_from = lpszAddress;
76 void CMailMsg::SetTo(CString sAddress)
78 strconv_t strconv;
79 LPCSTR lpszAddress = strconv.t2a(sAddress.GetBuffer(0));
80 m_to = lpszAddress;
83 void CMailMsg::SetSubject(CString sSubject)
85 strconv_t strconv;
86 LPCSTR lpszSubject = strconv.t2a(sSubject.GetBuffer(0));
87 m_sSubject = lpszSubject;
90 void CMailMsg::SetMessage(CString sMessage)
92 strconv_t strconv;
93 LPCSTR lpszMessage = strconv.t2a(sMessage.GetBuffer(0));
94 m_sMessage = lpszMessage;
97 void CMailMsg::SetShowComposeDialog(BOOL showComposeDialog)
99 m_bShowComposeDialog = showComposeDialog;
102 void CMailMsg::AddCC(CString sAddress)
104 strconv_t strconv;
105 LPCSTR lpszAddress = strconv.t2a(sAddress.GetBuffer(0));
106 m_cc.push_back(lpszAddress);
109 void CMailMsg::AddAttachment(CString sAttachment, CString sTitle)
111 strconv_t strconv;
112 LPCSTR lpszAttachment = strconv.t2a(sAttachment.GetBuffer(0));
113 if (sTitle.IsEmpty())
115 int position = sAttachment.ReverseFind(_T('\\'));
116 if(position >=0)
118 sTitle = sAttachment.Mid(position+1);
120 else
122 sTitle = sAttachment;
125 LPCSTR lpszTitle = strconv.t2a(sTitle.GetBuffer(0));
126 m_attachments[lpszAttachment] = lpszTitle;
129 BOOL CMailMsg::DetectMailClient(CString& sMailClientName)
131 CRegKey regKey;
132 TCHAR buf[1024] = _T("");
133 ULONG buf_size = 0;
134 LONG lResult;
136 lResult = regKey.Open(HKEY_CURRENT_USER, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
137 if(lResult!=ERROR_SUCCESS)
139 lResult = regKey.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
142 if(lResult==ERROR_SUCCESS)
144 buf_size = 1023;
145 #pragma warning(disable:4996)
146 LONG result = regKey.QueryValue(buf, _T(""), &buf_size);
147 #pragma warning(default:4996)
148 if(result==ERROR_SUCCESS)
150 sMailClientName = buf;
151 return TRUE;
153 regKey.Close();
155 else
157 sMailClientName = "Not Detected";
160 return FALSE;
163 BOOL CMailMsg::MAPIInitialize()
165 // Determine if there is default email program
167 CString sMailClientName;
168 if(!DetectMailClient(sMailClientName))
170 m_sErrorMsg = _T("Error detecting E-mail client");
171 return FALSE;
173 else
175 m_sErrorMsg = _T("Detected E-mail client ") + sMailClientName;
178 // Load MAPI.dll
180 m_hMapi = AtlLoadSystemLibraryUsingFullPath(_T("mapi32.dll"));
181 if (!m_hMapi)
183 m_sErrorMsg = _T("Error loading mapi32.dll");
184 return FALSE;
187 m_lpMapiSendMail = (LPMAPISENDMAIL)::GetProcAddress(m_hMapi, "MAPISendMail");
189 m_bReady = !!m_lpMapiSendMail;
191 if(!m_bReady)
193 m_sErrorMsg = _T("Not found required function entries in mapi32.dll");
196 return m_bReady;
199 void CMailMsg::MAPIFinalize()
201 ::FreeLibrary(m_hMapi);
204 CString CMailMsg::GetEmailClientName()
206 return m_sEmailClientName;
209 BOOL CMailMsg::Send()
211 if(m_lpMapiSendMail==NULL)
212 return FALSE;
214 TStrStrMap::iterator p;
215 int nIndex = 0;
216 MapiRecipDesc* pRecipients = NULL;
217 int nAttachments = 0;
218 MapiFileDesc* pAttachments = NULL;
219 ULONG status = 0;
220 MapiMessage message;
222 if(!m_bReady && !MAPIInitialize())
223 return FALSE;
225 pRecipients = new MapiRecipDesc[2 + m_cc.size()];
226 if(!pRecipients)
228 m_sErrorMsg = _T("Error allocating memory");
229 return FALSE;
232 nAttachments = (int)m_attachments.size();
233 if (nAttachments)
235 pAttachments = new MapiFileDesc[nAttachments];
236 if(!pAttachments)
238 m_sErrorMsg = _T("Error allocating memory");
239 delete[] pRecipients;
240 return FALSE;
244 // set from
245 pRecipients[0].ulReserved = 0;
246 pRecipients[0].ulRecipClass = MAPI_ORIG;
247 pRecipients[0].lpszAddress = (LPSTR)m_from.c_str();
248 pRecipients[0].lpszName = "";
249 pRecipients[0].ulEIDSize = 0;
250 pRecipients[0].lpEntryID = NULL;
252 // set to
253 pRecipients[1].ulReserved = 0;
254 pRecipients[1].ulRecipClass = MAPI_TO;
255 pRecipients[1].lpszAddress = (LPSTR)m_to.c_str();
256 pRecipients[1].lpszName = (LPSTR)m_to.c_str();
257 pRecipients[1].ulEIDSize = 0;
258 pRecipients[1].lpEntryID = NULL;
260 // add cc receipients
261 nIndex = 2;
262 for(int i=0; i < m_cc.size(); i++)
264 pRecipients[nIndex].ulReserved = 0;
265 pRecipients[nIndex].ulRecipClass = MAPI_CC;
266 pRecipients[nIndex].lpszAddress = (LPSTR)m_cc.at(i).c_str();
267 pRecipients[nIndex].lpszName = (LPSTR)m_cc.at(i).c_str();
268 pRecipients[nIndex].ulEIDSize = 0;
269 pRecipients[nIndex].lpEntryID = NULL;
270 nIndex++;
273 nIndex=0;
274 // add attachments
275 for (p = m_attachments.begin(), nIndex = 0;
276 p != m_attachments.end(); p++, nIndex++)
278 pAttachments[nIndex].ulReserved = 0;
279 pAttachments[nIndex].flFlags = 0;
280 pAttachments[nIndex].nPosition = 0xFFFFFFFF;
281 pAttachments[nIndex].lpszPathName = (LPSTR)p->first.c_str();
282 pAttachments[nIndex].lpszFileName = (LPSTR)p->second.c_str();
283 pAttachments[nIndex].lpFileType = NULL;
286 message.ulReserved = 0;
287 message.lpszSubject = (LPSTR)m_sSubject.c_str();
288 message.lpszNoteText = (LPSTR)m_sMessage.c_str();
289 message.lpszMessageType = NULL;
290 message.lpszDateReceived = NULL;
291 message.lpszConversationID = NULL;
292 message.flFlags = 0;
293 message.lpOriginator = pRecipients;
294 message.nRecipCount = (ULONG)(1 + m_cc.size());
295 message.lpRecips = &pRecipients[1];
296 message.nFileCount = nAttachments;
297 message.lpFiles = nAttachments ? pAttachments : NULL;
299 status = m_lpMapiSendMail(NULL, 0, &message, (m_bShowComposeDialog?MAPI_DIALOG:0)|MAPI_LOGON_UI, 0);
301 if(status!=SUCCESS_SUCCESS)
303 m_sErrorMsg.Format(_T("MAPISendMail has failed with code %X."), status);
306 if (pRecipients)
307 delete [] pRecipients;
309 if (nAttachments)
310 delete [] pAttachments;
312 return (SUCCESS_SUCCESS == status);