home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / contrib / src / net / smapi.cpp < prev    next >
C/C++ Source or Header  |  2001-09-06  |  15KB  |  439 lines

  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: smapi.cpp,v 1.2 2001/09/06 19:27:52 JS Exp $
  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.  
  34. class wxMapiData
  35. {
  36. public:
  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.  
  63. wxMapiSession::wxMapiSession()
  64. {
  65.     m_data = new wxMapiData;
  66.     
  67.     Initialise();
  68. }
  69.  
  70. wxMapiSession::~wxMapiSession()
  71. {
  72.     //Logoff if logged on
  73.     Logoff();
  74.     
  75.     //Unload the MAPI dll
  76.     Deinitialise();
  77.     
  78.     delete m_data;
  79. }
  80.  
  81. void 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.  
  116. void 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.  
  131. bool 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.  
  205. bool wxMapiSession::LoggedOn() const
  206. {
  207.     return (m_data->m_hSession != 0);
  208. }
  209.  
  210. bool wxMapiSession::MapiInstalled() const
  211. {
  212.     return (m_data->m_hMapi != NULL);
  213. }
  214.  
  215. bool 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.  
  244. bool 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.  
  266. bool 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];
  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.     }
  300.     
  301.     //Setup the "To" recipients
  302.     int nRecipIndex = 0;
  303.     int nToSize = message.m_to.GetCount();
  304.     for (int i=0; i<nToSize; i++)
  305.     {
  306.         MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
  307.         ZeroMemory(&recip, sizeof(MapiRecipDesc));
  308.         recip.ulRecipClass = MAPI_TO;
  309.         wxString& sName = message.m_to[i];
  310.  
  311.         //Try to resolve the name
  312.         lpMapiRecipDesc lpTempRecip;  
  313.         if (Resolve(sName, (void*) &lpTempRecip))
  314.         {
  315.             //Resolve worked, put the resolved name back into the sName
  316.             sName = lpTempRecip->lpszName;
  317.             
  318.             //Don't forget to free up the memory MAPI allocated for us
  319.             m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
  320.         }
  321.         //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
  322.         recip.lpszName = (LPSTR) sName.c_str();
  323.         
  324.         ++nRecipIndex;
  325.     }
  326.     
  327.     //Setup the "CC" recipients
  328.     int nCCSize = message.m_cc.GetCount();
  329.     for (i=0; i<nCCSize; i++)
  330.     {
  331.         MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
  332.         ZeroMemory(&recip, sizeof(MapiRecipDesc));
  333.         recip.ulRecipClass = MAPI_CC;
  334.         wxString& sName = message.m_cc[i];
  335.  
  336.         //Try to resolve the name
  337.         lpMapiRecipDesc lpTempRecip;  
  338.         if (Resolve(sName, (void*) &lpTempRecip))
  339.         {
  340.             //Resolve worked, put the resolved name back into the sName
  341.             sName = lpTempRecip->lpszName;
  342.             
  343.             //Don't forget to free up the memory MAPI allocated for us
  344.             m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
  345.         }
  346.         //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
  347.         recip.lpszName = (LPSTR) sName.c_str();
  348.         
  349.         ++nRecipIndex;
  350.     }
  351.     
  352.     //Setup the "BCC" recipients
  353.     int nBCCSize = message.m_bcc.GetCount();
  354.     for (i=0; i<nBCCSize; i++)
  355.     {
  356.         MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex];
  357.         ZeroMemory(&recip, sizeof(MapiRecipDesc));
  358.         recip.ulRecipClass = MAPI_BCC;
  359.         wxString& sName = message.m_bcc[i];
  360.  
  361.         //Try to resolve the name
  362.         lpMapiRecipDesc lpTempRecip;  
  363.         if (Resolve(sName, (void*) &lpTempRecip))
  364.         {
  365.             //Resolve worked, put the resolved name back into the sName
  366.             sName = lpTempRecip->lpszName;
  367.             
  368.             //Don't forget to free up the memory MAPI allocated for us
  369.             m_data->m_lpfnMAPIFreeBuffer(lpTempRecip);
  370.         }
  371.         //recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
  372.         recip.lpszName = (LPSTR) sName.c_str();
  373.         
  374.         ++nRecipIndex;
  375.     }
  376.     
  377.     //Setup the attachments 
  378.     int nAttachmentSize = message.m_attachments.GetCount();
  379.     int nTitleSize = message.m_attachmentTitles.GetCount();
  380.     if (nTitleSize)
  381.     { 
  382.         wxASSERT(nTitleSize == nAttachmentSize); //If you are going to set the attachment titles then you must set 
  383.         //the attachment title for each attachment
  384.     }
  385.     if (nAttachmentSize)
  386.     {
  387.         mapiMessage.nFileCount = nAttachmentSize;
  388.         mapiMessage.lpFiles = new MapiFileDesc[nAttachmentSize];
  389.         for (i=0; i<nAttachmentSize; i++)
  390.         {
  391.             MapiFileDesc& file = mapiMessage.lpFiles[i];
  392.             ZeroMemory(&file, sizeof(MapiFileDesc));
  393.             file.nPosition = 0xFFFFFFFF;
  394.             wxString& sFilename = message.m_attachments[i];
  395.             //file.lpszPathName = T2A((LPTSTR) (LPCTSTR) sFilename);
  396.  
  397.             file.lpszPathName = (LPSTR) sFilename.c_str();
  398.             //file.lpszFileName = file.lpszPathName;
  399.             file.lpszFileName = NULL;
  400.  
  401.             if (nTitleSize && !message.m_attachmentTitles[i].IsEmpty())
  402.             {
  403.                 wxString& sTitle = message.m_attachmentTitles[i];
  404.                 //file.lpszFileName = T2A((LPTSTR) (LPCTSTR) sTitle);
  405.                 file.lpszFileName = (LPSTR) sTitle.c_str();
  406.             }
  407.         }
  408.     }
  409.     
  410.     //Do the actual send using MAPISendMail
  411.     ULONG nError = m_data->m_lpfnMAPISendMail(m_data->m_hSession, 0, &mapiMessage, MAPI_DIALOG, 0);
  412.     if (nError == SUCCESS_SUCCESS)
  413.     {
  414.         bSuccess = TRUE;
  415.         m_data->m_nLastError = SUCCESS_SUCCESS;
  416.     }
  417.     else
  418.     {
  419.         wxLogDebug(_T("Failed to send mail message, Error:%d\n"), nError);
  420.         m_data->m_nLastError = nError;
  421.     }
  422.     
  423.     //Tidy up the Attachements
  424.     if (nAttachmentSize)
  425.         delete [] mapiMessage.lpFiles;
  426.     
  427.     //Free up the Recipients and Originator memory
  428.     delete [] mapiMessage.lpRecips;
  429.     delete mapiMessage.lpOriginator;
  430.     
  431.     return bSuccess;
  432. }
  433.  
  434. long wxMapiSession::GetLastError() const
  435. {
  436.     return m_data->m_nLastError;
  437. }
  438.  
  439.