PageRenderTime 61ms CodeModel.GetById 11ms app.highlight 46ms RepoModel.GetById 2ms app.codeStats 0ms

/reporting/crashsender/MailMsg.cpp

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