]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/net/smapi.cpp
New location for some deprecated files
[wxWidgets.git] / contrib / src / net / smapi.cpp
CommitLineData
decb3a6a
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: smapi.cpp
3// Purpose: Simple MAPI classes
4// Author: PJ Naughter <pjna@naughter.com>
5// Modified by: Julian Smart
6// Created: 2001-08-21
7// RCS-ID: $Id$
8// Copyright: (c) PJ Naughter
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "smapi.h"
14#endif
15
16// For compilers that support precompilation, includes "wx/wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include "wx/wx.h"
25#endif
26
27#include "wx/string.h"
28#include "wx/msw/private.h"
29
30#include <mapi.h>
31
32#include "wx/net/smapi.h"
33
34class wxMapiData
35{
36public:
37 wxMapiData()
38 {
39 m_hSession = 0;
40 m_nLastError = 0;
41 m_hMapi = NULL;
42 m_lpfnMAPILogon = NULL;
43 m_lpfnMAPILogoff = NULL;
44 m_lpfnMAPISendMail = NULL;
45 m_lpfnMAPIResolveName = NULL;
46 m_lpfnMAPIFreeBuffer = NULL;
47 }
48
49 //Data
50 LHANDLE m_hSession; //Mapi Session handle
51 long m_nLastError; //Last Mapi error value
52 HINSTANCE m_hMapi; //Instance handle of the MAPI dll
53 LPMAPILOGON m_lpfnMAPILogon; //MAPILogon function pointer
54 LPMAPILOGOFF m_lpfnMAPILogoff; //MAPILogoff function pointer
55 LPMAPISENDMAIL m_lpfnMAPISendMail; //MAPISendMail function pointer
56 LPMAPIRESOLVENAME m_lpfnMAPIResolveName; //MAPIResolveName function pointer
57 LPMAPIFREEBUFFER m_lpfnMAPIFreeBuffer; //MAPIFreeBuffer function pointer
58};
59
60
61////////////////////////////////// Implementation /////////////////////////////
62
63wxMapiSession::wxMapiSession()
64{
65 m_data = new wxMapiData;
66
67 Initialise();
68}
69
70wxMapiSession::~wxMapiSession()
71{
72 //Logoff if logged on
73 Logoff();
74
75 //Unload the MAPI dll
76 Deinitialise();
77
78 delete m_data;
79}
80
81void wxMapiSession::Initialise()
82{
83 //First make sure the "WIN.INI" entry for MAPI is present aswell
84 //as the MAPI32 dll being present on the system
85 bool bMapiInstalled = (GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0) &&
86 (SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0);
87
88 if (bMapiInstalled)
89 {
90 //Load up the MAPI dll and get the function pointers we are interested in
91 m_data->m_hMapi = ::LoadLibrary(_T("MAPI32.DLL"));
92 if (m_data->m_hMapi)
93 {
94 m_data->m_lpfnMAPILogon = (LPMAPILOGON) GetProcAddress(m_data->m_hMapi, "MAPILogon");
95 m_data->m_lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress(m_data->m_hMapi, "MAPILogoff");
96 m_data->m_lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(m_data->m_hMapi, "MAPISendMail");
97 m_data->m_lpfnMAPIResolveName = (LPMAPIRESOLVENAME) GetProcAddress(m_data->m_hMapi, "MAPIResolveName");
98 m_data->m_lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(m_data->m_hMapi, "MAPIFreeBuffer");
99
100 //If any of the functions are not installed then fail the load
101 if (m_data->m_lpfnMAPILogon == NULL ||
102 m_data->m_lpfnMAPILogoff == NULL ||
103 m_data->m_lpfnMAPISendMail == NULL ||
104 m_data->m_lpfnMAPIResolveName == NULL ||
105 m_data->m_lpfnMAPIFreeBuffer == NULL)
106 {
107 wxLogDebug(_T("Failed to get one of the functions pointer in MAPI32.DLL\n"));
108 Deinitialise();
109 }
110 }
111 }
112 else
113 wxLogDebug(_T("Mapi is not installed on this computer\n"));
114}
115
116void wxMapiSession::Deinitialise()
117{
118 if (m_data->m_hMapi)
119 {
120 //Unload the MAPI dll and reset the function pointers to NULL
121 FreeLibrary(m_data->m_hMapi);
122 m_data->m_hMapi = NULL;
123 m_data->m_lpfnMAPILogon = NULL;
124 m_data->m_lpfnMAPILogoff = NULL;
125 m_data->m_lpfnMAPISendMail = NULL;
126 m_data->m_lpfnMAPIResolveName = NULL;
127 m_data->m_lpfnMAPIFreeBuffer = NULL;
128 }
129}
130
131bool wxMapiSession::Logon(const wxString& sProfileName, const wxString& sPassword, wxWindow* pParentWnd)
132{
133 wxASSERT(MapiInstalled()); //MAPI must be installed
134 wxASSERT(m_data->m_lpfnMAPILogon); //Function pointer must be valid
135
136 //Initialise the function return value
137 bool bSuccess = FALSE;
138
139 //Just in case we are already logged in
140 Logoff();
141
142 //Setup the ascii versions of the profile name and password
143 int nProfileLength = sProfileName.Length();
144 int nPasswordLength = sPassword.Length();
145
146 LPSTR pszProfileName = NULL;
147 LPSTR pszPassword = NULL;
148 if (nProfileLength)
149 {
150// pszProfileName = T2A((LPTSTR) (LPCTSTR) sProfileName);
151// pszPassword = T2A((LPTSTR) (LPCTSTR) sPassword);
152 pszProfileName = (LPSTR) sProfileName.c_str();
153 pszPassword = (LPSTR) sPassword.c_str();
154 }
155
156 //Setup the flags & UIParam parameters used in the MapiLogon call
157 FLAGS flags = 0;
158 ULONG nUIParam = 0;
159 if (nProfileLength == 0)
160 {
161 //No profile name given, then we must interactively request a profile name
162 if (pParentWnd)
163 {
164 nUIParam = (ULONG) (HWND) pParentWnd->GetHWND();
165 flags |= MAPI_LOGON_UI;
166 }
167 else
168 {
169 //No window given, just use the main window of the app as the parent window
170 if (wxTheApp->GetTopWindow())
171 {
172 nUIParam = (ULONG) (HWND) wxTheApp->GetTopWindow()->GetHWND();
173 flags |= MAPI_LOGON_UI;
174 }
175 }
176 }
177
178 //First try to acquire a new MAPI session using the supplied settings using the MAPILogon functio
179 ULONG nError = m_data->m_lpfnMAPILogon(nUIParam, pszProfileName, pszPassword, flags | MAPI_NEW_SESSION, 0, &m_data->m_hSession);
180 if (nError != SUCCESS_SUCCESS && nError != MAPI_E_USER_ABORT)
181 {
182 //Failed to create a create mapi session, try to acquire a shared mapi session
183 wxLogDebug(_T("Failed to logon to MAPI using a new session, trying to acquire a shared one\n"));
184 nError = m_data->m_lpfnMAPILogon(nUIParam, NULL, NULL, 0, 0, &m_data->m_hSession);
185 if (nError == SUCCESS_SUCCESS)
186 {
187 m_data->m_nLastError = SUCCESS_SUCCESS;
188 bSuccess = TRUE;
189 }
190 else
191 {
192 wxLogDebug(_T("Failed to logon to MAPI using a shared session, Error:%d\n"), nError);
193 m_data->m_nLastError = nError;
194 }
195 }
196 else if (nError == SUCCESS_SUCCESS)
197 {
198 m_data->m_nLastError = SUCCESS_SUCCESS;
199 bSuccess = TRUE;
200 }
201
202 return bSuccess;
203}
204
205bool wxMapiSession::LoggedOn() const
206{
207 return (m_data->m_hSession != 0);
208}
209
210bool wxMapiSession::MapiInstalled() const
211{
212 return (m_data->m_hMapi != NULL);
213}
214
215bool wxMapiSession::Logoff()
216{
217 wxASSERT(MapiInstalled()); //MAPI must be installed
218 wxASSERT(m_data->m_lpfnMAPILogoff); //Function pointer must be valid
219
220 //Initialise the function return value
221 bool bSuccess = FALSE;
222
223 if (m_data->m_hSession)
224 {
225 //Call the MAPILogoff function
226 ULONG nError = m_data->m_lpfnMAPILogoff(m_data->m_hSession, 0, 0, 0);
227 if (nError != SUCCESS_SUCCESS)
228 {
229 wxLogDebug(_T("Failed in call to MapiLogoff, Error:%d"), nError);
230 m_data->m_nLastError = nError;
231 bSuccess = TRUE;
232 }
233 else
234 {
235 m_data->m_nLastError = SUCCESS_SUCCESS;
236 bSuccess = TRUE;
237 }
238 m_data->m_hSession = 0;
239 }
240
241 return bSuccess;
242}
243
244bool wxMapiSession::Resolve(const wxString& sName, void* lppRecip1)
245{
246 lpMapiRecipDesc* lppRecip = (lpMapiRecipDesc*) lppRecip1;
247
248 wxASSERT(MapiInstalled()); //MAPI must be installed
249 wxASSERT(m_data->m_lpfnMAPIResolveName); //Function pointer must be valid
250 wxASSERT(LoggedOn()); //Must be logged on to MAPI
251 wxASSERT(m_data->m_hSession); //MAPI session handle must be valid
252
253 //Call the MAPIResolveName function
254// LPSTR lpszAsciiName = T2A((LPTSTR) (LPCTSTR) sName);
255 LPSTR lpszAsciiName = (LPSTR) sName.c_str();
256 ULONG nError = m_data->m_lpfnMAPIResolveName(m_data->m_hSession, 0, lpszAsciiName, 0, 0, lppRecip);
257 if (nError != SUCCESS_SUCCESS)
258 {
259 wxLogDebug(_T("Failed to resolve the name: %s, Error:%d\n"), sName, nError);
260 m_data->m_nLastError = nError;
261 }
262
263 return (nError == SUCCESS_SUCCESS);
264}
265
266bool wxMapiSession::Send(wxMailMessage& message)
267{
268 wxASSERT(MapiInstalled()); //MAPI must be installed
269 wxASSERT(m_data->m_lpfnMAPISendMail); //Function pointer must be valid
270 wxASSERT(m_data->m_lpfnMAPIFreeBuffer); //Function pointer must be valid
271 wxASSERT(LoggedOn()); //Must be logged on to MAPI
272 wxASSERT(m_data->m_hSession); //MAPI session handle must be valid
273
274 //Initialise the function return value
275 bool bSuccess = FALSE;
276
277 //Create the MapiMessage structure to match the message parameter send into us
278 MapiMessage mapiMessage;
279 ZeroMemory(&mapiMessage, sizeof(mapiMessage));
280 mapiMessage.lpszSubject = (LPSTR) message.m_subject.c_str();
281 mapiMessage.lpszNoteText = (LPSTR) message.m_body.c_str();
282// mapiMessage.lpszSubject = T2A((LPTSTR) (LPCTSTR) message.m_subject);
283// mapiMessage.lpszNoteText = T2A((LPTSTR) (LPCTSTR) message.m_body);
284 mapiMessage.nRecipCount = message.m_to.GetCount() + message.m_cc.GetCount() + message.m_bcc.GetCount();
285 wxASSERT(mapiMessage.nRecipCount); //Must have at least 1 recipient!
286
287 //Allocate the recipients array
288 mapiMessage.lpRecips = new MapiRecipDesc[mapiMessage.nRecipCount];
a23c0047
JS
289
290 // If we have a 'From' field, use it
291 if (!message.m_from.IsEmpty())
292 {
293 mapiMessage.lpOriginator = new MapiRecipDesc;
294 ZeroMemory(mapiMessage.lpOriginator, sizeof(MapiRecipDesc));
295
296 mapiMessage.lpOriginator->ulRecipClass = MAPI_ORIG;
297 // TODO Do we have to call Resolve?
298 mapiMessage.lpOriginator->lpszName = (LPSTR) message.m_from.c_str();
299 }
decb3a6a
JS
300
301 //Setup the "To" recipients
302 int nRecipIndex = 0;
303 int nToSize = message.m_to.GetCount();
cceb71da
MB
304 int i;
305 for (i=0; i<nToSize; i++)
decb3a6a
JS
306 {
307 MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
308 ZeroMemory(&recip, sizeof(MapiRecipDesc));
309 recip.ulRecipClass = MAPI_TO;
310 wxString& sName = message.m_to[i];
311
312 //Try to resolve the name
313 lpMapiRecipDesc lpTempRecip;
314 if (Resolve(sName, (void*) &lpTempRecip))
315 {
316 //Resolve worked, put the resolved name back into the sName
317 sName = lpTempRecip->lpszName;
318
319 //Don't forget to free up the memory MAPI allocated for us
320 m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
321 }
322 //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
323 recip.lpszName = (LPSTR) sName.c_str();
324
325 ++nRecipIndex;
326 }
327
328 //Setup the "CC" recipients
329 int nCCSize = message.m_cc.GetCount();
330 for (i=0; i<nCCSize; i++)
331 {
332 MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
333 ZeroMemory(&recip, sizeof(MapiRecipDesc));
334 recip.ulRecipClass = MAPI_CC;
335 wxString& sName = message.m_cc[i];
336
337 //Try to resolve the name
338 lpMapiRecipDesc lpTempRecip;
339 if (Resolve(sName, (void*) &lpTempRecip))
340 {
341 //Resolve worked, put the resolved name back into the sName
342 sName = lpTempRecip->lpszName;
343
344 //Don't forget to free up the memory MAPI allocated for us
345 m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
346 }
347 //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
348 recip.lpszName = (LPSTR) sName.c_str();
349
350 ++nRecipIndex;
351 }
352
353 //Setup the "BCC" recipients
354 int nBCCSize = message.m_bcc.GetCount();
355 for (i=0; i<nBCCSize; i++)
356 {
357 MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
358 ZeroMemory(&recip, sizeof(MapiRecipDesc));
359 recip.ulRecipClass = MAPI_BCC;
360 wxString& sName = message.m_bcc[i];
361
362 //Try to resolve the name
363 lpMapiRecipDesc lpTempRecip;
364 if (Resolve(sName, (void*) &lpTempRecip))
365 {
366 //Resolve worked, put the resolved name back into the sName
367 sName = lpTempRecip->lpszName;
368
369 //Don't forget to free up the memory MAPI allocated for us
370 m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
371 }
372 //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
373 recip.lpszName = (LPSTR) sName.c_str();
374
375 ++nRecipIndex;
376 }
377
378 //Setup the attachments
379 int nAttachmentSize = message.m_attachments.GetCount();
380 int nTitleSize = message.m_attachmentTitles.GetCount();
381 if (nTitleSize)
382 {
383 wxASSERT(nTitleSize == nAttachmentSize); //If you are going to set the attachment titles then you must set
384 //the attachment title for each attachment
385 }
386 if (nAttachmentSize)
387 {
388 mapiMessage.nFileCount = nAttachmentSize;
389 mapiMessage.lpFiles = new MapiFileDesc[nAttachmentSize];
390 for (i=0; i<nAttachmentSize; i++)
391 {
392 MapiFileDesc& file = mapiMessage.lpFiles[i];
393 ZeroMemory(&file, sizeof(MapiFileDesc));
394 file.nPosition = 0xFFFFFFFF;
395 wxString& sFilename = message.m_attachments[i];
396 //file.lpszPathName = T2A((LPTSTR) (LPCTSTR) sFilename);
397
398 file.lpszPathName = (LPSTR) sFilename.c_str();
399 //file.lpszFileName = file.lpszPathName;
400 file.lpszFileName = NULL;
401
402 if (nTitleSize && !message.m_attachmentTitles[i].IsEmpty())
403 {
404 wxString& sTitle = message.m_attachmentTitles[i];
405 //file.lpszFileName = T2A((LPTSTR) (LPCTSTR) sTitle);
406 file.lpszFileName = (LPSTR) sTitle.c_str();
407 }
408 }
409 }
410
411 //Do the actual send using MAPISendMail
412 ULONG nError = m_data->m_lpfnMAPISendMail(m_data->m_hSession, 0, &mapiMessage, MAPI_DIALOG, 0);
413 if (nError == SUCCESS_SUCCESS)
414 {
415 bSuccess = TRUE;
416 m_data->m_nLastError = SUCCESS_SUCCESS;
417 }
418 else
419 {
420 wxLogDebug(_T("Failed to send mail message, Error:%d\n"), nError);
421 m_data->m_nLastError = nError;
422 }
423
424 //Tidy up the Attachements
425 if (nAttachmentSize)
426 delete [] mapiMessage.lpFiles;
427
a23c0047 428 //Free up the Recipients and Originator memory
decb3a6a 429 delete [] mapiMessage.lpRecips;
a23c0047 430 delete mapiMessage.lpOriginator;
decb3a6a
JS
431
432 return bSuccess;
433}
434
435long wxMapiSession::GetLastError() const
436{
437 return m_data->m_nLastError;
438}
439