mail.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:25k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * mail.cxx
  3.  *
  4.  * Electronic mail class.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: mail.cxx,v $
  30.  * Revision 1.14  1999/02/10 13:20:53  robertj
  31.  * Added ability to have attachments in mail messages.
  32.  *
  33.  * Revision 1.13  1998/11/30 04:48:40  robertj
  34.  * New directory structure
  35.  *
  36.  * Revision 1.12  1998/10/15 05:41:49  robertj
  37.  * New memory leak check code.
  38.  *
  39.  * Revision 1.11  1998/09/24 03:30:48  robertj
  40.  * Added open software license.
  41.  *
  42.  * Revision 1.10  1997/07/14 11:47:19  robertj
  43.  * Added "const" to numerous variables.
  44.  *
  45.  * Revision 1.9  1997/05/16 12:05:05  robertj
  46.  * Added BCC capability to send mail.
  47.  *
  48.  * Revision 1.8  1997/02/05 11:48:08  robertj
  49.  * Fixed compatibility with MSVC debug memory allocation macros.
  50.  *
  51.  * Revision 1.7  1996/11/18 11:30:15  robertj
  52.  * Fixed support for new libraries.
  53.  *
  54.  * Revision 1.6  1996/07/15 10:26:31  robertj
  55.  * MSVC 4.1 Support
  56.  *
  57.  * Revision 1.5  1996/02/15 14:55:01  robertj
  58.  * Win16 compatibility
  59.  *
  60.  * Revision 1.4  1995/08/24 12:41:25  robertj
  61.  * Implementation of mail for GUIs.
  62.  *
  63.  * Revision 1.3  1995/07/02 01:22:50  robertj
  64.  * Changed mail to use CMC then MAPI if available.
  65.  *
  66.  * Revision 1.2  1995/04/01 08:05:04  robertj
  67.  * Added GUI support.
  68.  *
  69.  * Revision 1.1  1995/03/14 12:45:14  robertj
  70.  * Initial revision
  71.  *
  72.  */
  73. #include <ptlib.h>
  74. #include <ptlib/mail.h>
  75. #include <ctype.h>
  76. #if P_HAS_CMC
  77. #include <xcmcext.h>
  78. #include <xcmcmsxt.h>
  79. #endif
  80. #define new PNEW
  81. //////////////////////////////////////////////////////////////////////////////
  82. // PMail
  83. PMail::PMail()
  84. {
  85.   Construct();
  86. }
  87. PMail::PMail(const PString & username, const PString & password)
  88. {
  89.   Construct();
  90.   LogOnCommonInterface(username, password, NULL);
  91. }
  92. PMail::PMail(const PString & username,
  93.              const PString & password,
  94.              const PString & service)
  95. {
  96.   Construct();
  97.   LogOnCommonInterface(username, password, service);
  98. }
  99. PMail::~PMail()
  100. {
  101.   LogOff();
  102. }
  103. void PMail::Construct()
  104. {
  105.   loggedOn = FALSE;
  106.   hUserInterface = NULL;
  107. }
  108. BOOL PMail::LogOn(const PString & username, const PString & password)
  109. {
  110.   return LogOnCommonInterface(username, password, NULL);
  111. }
  112. BOOL PMail::LogOn(const PString & username,
  113.                   const PString & password,
  114.                   const PString & service)
  115. {
  116.   return LogOnCommonInterface(username, password, service);
  117. }
  118. BOOL PMail::LogOnCommonInterface(const char * username,
  119.                                  const char * password,
  120.                                  const char * service)
  121. {
  122.   if (!LogOff())
  123.     return FALSE;
  124. #if P_HAS_CMC
  125.   if (cmc.IsLoaded()) {
  126.     CMC_X_COM_support support[2];
  127.     support[0].item_code = CMC_XS_COM;
  128.     support[0].flags = 0;
  129.     support[1].item_code = CMC_XS_MS;
  130.     support[1].flags = 0;
  131.     CMC_extension extension;
  132.     extension.item_code = CMC_X_COM_SUPPORT_EXT;
  133.     extension.item_data = PARRAYSIZE(support);
  134.     extension.item_reference = support;
  135.     extension.extension_flags = CMC_EXT_LAST_ELEMENT;
  136.     lastError = cmc.logon((CMC_string)service,
  137.                           (CMC_string)username,
  138.                           (CMC_string)password,
  139.                           NULL,
  140.                           (CMC_ui_id)hUserInterface,
  141.                           100,
  142.                           hUserInterface == NULL ? 0 :
  143.                                  (CMC_LOGON_UI_ALLOWED | CMC_ERROR_UI_ALLOWED),
  144.                           &sessionId,
  145.                           &extension);
  146.     loggedOn = lastError == CMC_SUCCESS;
  147.     return loggedOn;
  148.   }
  149. #endif
  150. #if P_HAS_MAPI
  151.   if (mapi.IsLoaded()) {
  152.     PAssert(service == NULL, "Cannot have variable services");
  153.     lastError = mapi.Logon((HWND)hUserInterface, username, password, 0, 0, &sessionId);
  154.     loggedOn = lastError == SUCCESS_SUCCESS;
  155.     return loggedOn;
  156.   }
  157. #endif
  158.   lastError = 1;
  159.   return FALSE;
  160. }
  161. BOOL PMail::LogOff()
  162. {
  163.   if (!loggedOn)
  164.     return TRUE;
  165. #if P_HAS_CMC
  166.   if (cmc.IsLoaded()) {
  167.     lastError = cmc.logoff(sessionId,
  168.                            (CMC_ui_id)hUserInterface,
  169.                            hUserInterface == NULL ? 0
  170.                               : (CMC_LOGOFF_UI_ALLOWED | CMC_ERROR_UI_ALLOWED),
  171.                            NULL);
  172.     switch (lastError) {
  173.       case CMC_SUCCESS :
  174.       case CMC_E_INVALID_SESSION_ID :
  175.       case CMC_E_USER_NOT_LOGGED_ON :
  176.         loggedOn = FALSE;
  177.     }
  178.     return lastError == CMC_SUCCESS;
  179.   }
  180. #endif
  181. #if P_HAS_MAPI
  182.   if (mapi.IsLoaded()) {
  183.     lastError = mapi.Logoff(sessionId, (HWND)hUserInterface, 0, 0);
  184.     if (lastError == SUCCESS_SUCCESS || lastError == MAPI_E_INVALID_SESSION)
  185.       loggedOn = FALSE;
  186.     return lastError == SUCCESS_SUCCESS;
  187.   }
  188. #endif
  189.   lastError = 1;
  190.   return FALSE;
  191. }
  192. BOOL PMail::IsLoggedOn() const
  193. {
  194.   return loggedOn;
  195. }
  196. BOOL PMail::SendNote(const PString & recipient,
  197.                      const PString & subject,
  198.                      const char * body)
  199. {
  200.   PStringList dummy;
  201.   return SendNote(recipient, dummy, dummy, subject, body, dummy);
  202. }
  203. BOOL PMail::SendNote(const PString & recipient,
  204.                      const PString & subject,
  205.                      const char * body,
  206.                      const PStringList & attachments)
  207. {
  208.   PStringList dummy;
  209.   return SendNote(recipient, dummy, dummy, subject, body, attachments);
  210. }
  211. BOOL PMail::SendNote(const PString & recipient,
  212.                      const PStringList & carbonCopies,
  213.                      const PStringList & blindCarbons,
  214.                      const PString & subject,
  215.                      const char * body,
  216.                      const PStringList & attachments)
  217. {
  218. #if P_HAS_CMC
  219.   if (cmc.IsLoaded()) {
  220.     CMC_message message;
  221.     memset(&message, 0, sizeof(message));
  222.     PINDEX size = carbonCopies.GetSize() + blindCarbons.GetSize() + 1;
  223.     message.recipients = new CMC_recipient[size];
  224.     memset(message.recipients, 0, size*sizeof(CMC_recipient));
  225.     message.recipients[0].role = CMC_ROLE_TO;
  226.     message.recipients[0].name = (CMC_string)(const char *)recipient;
  227.     PINDEX count = 0;
  228.     PINDEX i;
  229.     for (i = 0 ; i < carbonCopies.GetSize(); i++) {
  230.       message.recipients[++count].role = CMC_ROLE_CC;
  231.       message.recipients[count].name = (CMC_string)(const char *)carbonCopies[i];
  232.     }
  233.     for (i = 0 ; i < blindCarbons.GetSize(); i++) {
  234.       message.recipients[++count].role = CMC_ROLE_BCC;
  235.       message.recipients[count].name = (CMC_string)(const char *)blindCarbons[i];
  236.     }
  237.     message.recipients[count].recip_flags = CMC_RECIP_LAST_ELEMENT;
  238.     message.subject = (CMC_string)(const char *)subject;
  239.     message.text_note = (CMC_string)body;
  240.     message.message_flags = CMC_MSG_LAST_ELEMENT;
  241.     if (!attachments.IsEmpty()) {
  242.       message.attachments = new CMC_attachment[attachments.GetSize()];
  243.       memset(message.attachments, 0, attachments.GetSize()*sizeof(CMC_attachment));
  244.       for (i = 0 ; i < attachments.GetSize(); i++) {
  245.         message.attachments[i].attach_type = CMC_ATT_OID_BINARY;
  246.         message.attachments[i].attach_filename = (CMC_string)(const char *)attachments[i];
  247.       }
  248.       message.attachments[i-1].attach_flags = CMC_ATT_LAST_ELEMENT;
  249.     }
  250.     lastError = cmc.send(sessionId, &message, 0, (CMC_ui_id)hUserInterface, NULL);
  251.     delete [] message.attachments;
  252.     delete [] message.recipients;
  253.     return lastError == CMC_SUCCESS;
  254.   }
  255. #endif
  256. #if P_HAS_MAPI
  257.   if (mapi.IsLoaded()) {
  258.     MapiMessage message;
  259.     memset(&message, 0, sizeof(message));
  260.     message.nRecipCount = carbonCopies.GetSize() + blindCarbons.GetSize() + 1;
  261.     message.lpRecips = new MapiRecipDesc[message.nRecipCount];
  262.     memset(message.lpRecips, 0, message.nRecipCount*sizeof(MapiRecipDesc));
  263.     message.lpRecips[0].ulRecipClass = MAPI_TO;
  264.     message.lpRecips[0].lpszName = (char *)(const char *)recipient;
  265.     PINDEX count = 0;
  266.     PINDEX i;
  267.     for (i = 0 ; i < carbonCopies.GetSize(); i++) {
  268.       message.lpRecips[++count].ulRecipClass = MAPI_CC;
  269.       message.lpRecips[count].lpszName = (char *)(const char *)carbonCopies[i];
  270.     }
  271.     for (i = 0 ; i < blindCarbons.GetSize(); i++) {
  272.       message.lpRecips[++count].ulRecipClass = MAPI_BCC;
  273.       message.lpRecips[count].lpszName = (char *)(const char *)blindCarbons[i];
  274.     }
  275.     message.lpszSubject = (char *)(const char *)subject;
  276.     message.lpszNoteText = (char *)body;
  277.     if (!attachments.IsEmpty()) {
  278.       message.lpFiles = new MapiFileDesc[attachments.GetSize()];
  279.       memset(message.lpFiles, 0, attachments.GetSize()*sizeof(MapiFileDesc));
  280.       for (i = 0 ; i < attachments.GetSize(); i++) {
  281.         message.lpFiles[i].nPosition = (DWORD)-1;
  282.         message.lpFiles[i].lpszPathName = (CMC_string)(const char *)attachments[i];
  283.       }
  284.     }
  285.     lastError = mapi.SendMail(sessionId, (HWND)hUserInterface, &message, 0, 0);
  286.     delete [] message.lpRecips;
  287.     return lastError == SUCCESS_SUCCESS;
  288.   }
  289. #endif
  290.   lastError = 1;
  291.   return FALSE;
  292. }
  293. PStringArray PMail::GetMessageIDs(BOOL unreadOnly)
  294. {
  295.   PStringArray msgIDs;
  296. #if P_HAS_CMC
  297.   if (cmc.IsLoaded()) {
  298.     CMC_flags flags = CMC_LIST_MSG_REFS_ONLY;
  299.     if (unreadOnly)
  300.       flags |= CMC_LIST_UNREAD_ONLY;
  301.     if (hUserInterface != NULL)
  302.       flags |= CMC_ERROR_UI_ALLOWED;
  303.     CMC_uint32 count = 0;
  304.     CMC_message_summary * messages;
  305.     lastError = cmc.list(sessionId,
  306.                    NULL, flags, NULL, &count, hUserInterface, &messages, NULL);
  307.     if (lastError == CMC_SUCCESS) {
  308.       msgIDs.SetSize((PINDEX)count);
  309.       for (PINDEX m = 0; m < (PINDEX)count; m++) {
  310.         for (CMC_uint32 c = 0; c < messages[m].message_reference->length; c++)
  311.           if (!isprint(messages[m].message_reference->string[c]))
  312.             break;
  313.         if (c >= messages[m].message_reference->length)
  314.           msgIDs[m] = 'L' + PString(messages[m].message_reference->string,
  315.                                     (PINDEX)messages[m].message_reference->length);
  316.         else {
  317.           PCharArray buf((PINDEX)(messages[m].message_reference->length*2 + 6));
  318.           char * ptr = buf.GetPointer();
  319.           *ptr++ = 'H';
  320.           for (c = 0; c < messages[m].message_reference->length; c++) {
  321.             sprintf(ptr, "%02x", messages[m].message_reference->string[c]);
  322.             ptr += 2;
  323.           }
  324.           msgIDs[m] = buf;
  325.         }
  326.       }
  327.       cmc.free_buf(messages);
  328.     }
  329.     return msgIDs;
  330.   }
  331. #endif
  332. #if P_HAS_MAPI
  333.   if (mapi.IsLoaded()) {
  334.     FLAGS flags = unreadOnly ? MAPI_UNREAD_ONLY : 0;
  335.     PINDEX count = 0;
  336.     const char * seed = NULL;
  337.     char msgIdBuffer[64];
  338.     while ((lastError = mapi.FindNext(sessionId, (HWND)hUserInterface,
  339.                       NULL, seed, flags, 0, msgIdBuffer)) == SUCCESS_SUCCESS) {
  340.       if (count >= msgIDs.GetSize())
  341.         msgIDs.SetSize(count+10);
  342.       msgIDs[count] = msgIdBuffer;
  343.       seed = msgIDs[count++];
  344.     }
  345.     msgIDs.SetSize(count);
  346.     return msgIDs;
  347.   }
  348. #endif
  349.   lastError = 1;
  350.   return msgIDs;
  351. }
  352. #if P_HAS_CMC
  353. class CMC_message_reference_ptr
  354. {
  355.   public:
  356.     CMC_message_reference_ptr(const PString & id);
  357.     ~CMC_message_reference_ptr() { free(ref); }
  358.     operator CMC_message_reference *() { return ref; }
  359.   private:
  360.     CMC_message_reference * ref;
  361. };
  362. CMC_message_reference_ptr::CMC_message_reference_ptr(const PString & id)
  363. {
  364.   PINDEX len = id.GetLength();
  365.   if (id[0] == 'H') {
  366.     ref = (CMC_message_reference *)malloc(sizeof(ref)+(len-1)/2);
  367.     ref->length = (len-1)/2;
  368.     for (PINDEX i = 0; i < (PINDEX)ref->length; i++) {
  369.       int val = 0;
  370.       for (PINDEX j = 1; j <= 2; j++) {
  371.         char c = id[i*2+j];
  372.         if (isdigit(c))
  373.           val += c - '0';
  374.         else
  375.           val += toupper(c) - '0' - 7;
  376.       }
  377.       ref->string[i] = (char)val;
  378.     }
  379.   }
  380.   else if (id[0] == 'L') {
  381.     ref = (CMC_message_reference *)malloc(sizeof(ref)+len-1);
  382.     ref->length = len-1;
  383.     memcpy(ref->string, ((const char *)id)+1, len-1);
  384.   }
  385.   else {
  386.     ref = (CMC_message_reference *)malloc(sizeof(ref)+len);
  387.     ref->length = len;
  388.     memcpy(ref->string, (const char *)id, len);
  389.   }
  390. }
  391. #endif
  392. BOOL PMail::GetMessageHeader(const PString & id,
  393.                              Header & hdrInfo)
  394. {
  395. #if P_HAS_CMC
  396.   if (cmc.IsLoaded()) {
  397.     CMC_flags flags =  hUserInterface != NULL ? CMC_ERROR_UI_ALLOWED : 0;
  398.     CMC_uint32 count = 1;
  399.     CMC_message_summary * message;
  400.     CMC_message_reference_ptr seed = id;
  401.     lastError = cmc.list(sessionId,
  402.                     NULL, flags, seed, &count, hUserInterface, &message, NULL);
  403.     if (lastError != CMC_SUCCESS)
  404.       return FALSE;
  405.     hdrInfo.subject = message->subject;
  406.     hdrInfo.received = PTime(0, message->time_sent.minute,
  407.                                 message->time_sent.hour,
  408.                                 message->time_sent.day,
  409.                                 message->time_sent.month,
  410.                                 message->time_sent.year);
  411.     hdrInfo.originatorName = message->originator->name;
  412.     if (message->originator->address != 0)
  413.       hdrInfo.originatorAddress = message->originator->address;
  414.     else
  415.       hdrInfo.originatorAddress = '"' + hdrInfo.originatorName + '"';
  416.     cmc.free_buf(message);
  417.     return TRUE;
  418.   }
  419. #endif
  420. #if P_HAS_MAPI
  421.   if (mapi.IsLoaded()) {
  422.     MapiMessage * message;
  423.     lastError = mapi.ReadMail(sessionId,
  424.                     (HWND)hUserInterface, id, MAPI_ENVELOPE_ONLY, 0, &message);
  425.     if (lastError != SUCCESS_SUCCESS)
  426.       return FALSE;
  427.     PStringStream str = message->lpszDateReceived;
  428.     int min, hr, day, mon, yr;
  429.     char c;
  430.     str >> yr >> c >> mon >> c >> day >> hr >> c >> min;
  431.     hdrInfo.subject = message->lpszSubject;
  432.     hdrInfo.received = PTime(0, min, hr, day, mon, yr);
  433.     hdrInfo.originatorName = message->lpOriginator->lpszName;
  434.     if (message->lpOriginator->lpszAddress != 0)
  435.       hdrInfo.originatorAddress = message->lpOriginator->lpszAddress;
  436.     else
  437.       hdrInfo.originatorAddress = '"' + hdrInfo.originatorName + '"';
  438.     mapi.FreeBuffer(message);
  439.     return TRUE;
  440.   }
  441. #endif
  442.   lastError = 1;
  443.   return FALSE;
  444. }
  445. BOOL PMail::GetMessageBody(const PString & id, PString & body, BOOL markAsRead)
  446. {
  447.   body = PString();
  448. #if P_HAS_CMC
  449.   if (cmc.IsLoaded()) {
  450.     CMC_flags flags = CMC_MSG_AND_ATT_HDRS_ONLY;
  451.     if (!markAsRead)
  452.       flags |= CMC_DO_NOT_MARK_AS_READ;
  453.     if (hUserInterface != NULL)
  454.       flags |= CMC_ERROR_UI_ALLOWED;
  455.     CMC_message_reference_ptr seed = id;
  456.     CMC_message * message;
  457.     lastError = cmc.read(sessionId,seed,flags,&message,hUserInterface,NULL);
  458.     if (lastError != CMC_SUCCESS)
  459.       return FALSE;
  460.     if (message->text_note != NULL)
  461.       body = message->text_note;
  462.     BOOL ok = (message->message_flags&CMC_MSG_TEXT_NOTE_AS_FILE) == 0;
  463.     cmc.free_buf(message);
  464.     return ok;
  465.   }
  466. #endif
  467. #if P_HAS_MAPI
  468.   if (mapi.IsLoaded()) {
  469.     FLAGS flags = MAPI_SUPPRESS_ATTACH;
  470.     if (!markAsRead)
  471.       flags |= MAPI_PEEK;
  472.     MapiMessage * message;
  473.     lastError = mapi.ReadMail(sessionId,
  474.                                  (HWND)hUserInterface, id, flags, 0, &message);
  475.     if (lastError != SUCCESS_SUCCESS)
  476.       return FALSE;
  477.     body = message->lpszNoteText;
  478.     mapi.FreeBuffer(message);
  479.     return TRUE;
  480.   }
  481. #endif
  482.   lastError = 1;
  483.   return FALSE;
  484. }
  485. BOOL PMail::GetMessageAttachments(const PString & id,
  486.                                   PStringArray & filenames,
  487.                                   BOOL includeBody,
  488.                                   BOOL markAsRead)
  489. {
  490.   filenames.SetSize(0);
  491. #if P_HAS_CMC
  492.   if (cmc.IsLoaded()) {
  493.     CMC_flags flags = 0;
  494.     if (!markAsRead)
  495.       flags |= CMC_DO_NOT_MARK_AS_READ;
  496.     if (hUserInterface != NULL)
  497.       flags |= CMC_ERROR_UI_ALLOWED;
  498.     CMC_message_reference_ptr seed = id;
  499.     CMC_message * message;
  500.     lastError = cmc.read(sessionId,seed,flags,&message,hUserInterface,NULL);
  501.     if (lastError != CMC_SUCCESS)
  502.       return FALSE;
  503.     if (message->attachments != NULL) {
  504.       PINDEX total = 1;
  505.       for (CMC_attachment * attachment = message->attachments;
  506.             (attachment->attach_flags&CMC_ATT_LAST_ELEMENT) != 0; attachment++)
  507.         total++;
  508.       filenames.SetSize(total);
  509.       PINDEX attnum = 0;
  510.       attachment = &message->attachments[attnum];
  511.       do {
  512.         if (includeBody ||
  513.                        (message->message_flags&CMC_MSG_TEXT_NOTE_AS_FILE) == 0)
  514.           filenames[attnum++] = attachment->attach_filename;
  515.       } while (((attachment++)->attach_flags&CMC_ATT_LAST_ELEMENT) != 0);
  516.     }
  517.     cmc.free_buf(message);
  518.     return TRUE;
  519.   }
  520. #endif
  521. #if P_HAS_MAPI
  522.   if (mapi.IsLoaded()) {
  523.     FLAGS flags = 0;
  524.     if (includeBody)
  525.       flags |= MAPI_BODY_AS_FILE;
  526.     if (!markAsRead)
  527.       flags |= MAPI_PEEK;
  528.     MapiMessage * message;
  529.     lastError = mapi.ReadMail(sessionId,
  530.                                  (HWND)hUserInterface, id, flags, 0, &message);
  531.     if (lastError != SUCCESS_SUCCESS)
  532.       return FALSE;
  533.     filenames.SetSize(message->nFileCount);
  534.     for (PINDEX i = 0; i < filenames.GetSize(); i++)
  535.       filenames[i] = message->lpFiles[i].lpszPathName;
  536.     mapi.FreeBuffer(message);
  537.     return TRUE;
  538.   }
  539. #endif
  540.   lastError = 1;
  541.   return FALSE;
  542. }
  543. BOOL PMail::MarkMessageRead(const PString & id)
  544. {
  545. #if P_HAS_CMC
  546.   if (cmc.IsLoaded()) {
  547.     CMC_flags flags = CMC_MSG_AND_ATT_HDRS_ONLY;
  548.     if (hUserInterface != NULL)
  549.       flags |= CMC_ERROR_UI_ALLOWED;
  550.     CMC_message_reference_ptr seed = id;
  551.     CMC_message * message;
  552.     lastError = cmc.read(sessionId,seed,flags,&message,hUserInterface,NULL);
  553.     if (lastError != CMC_SUCCESS)
  554.       return FALSE;
  555.     cmc.free_buf(message);
  556.     return TRUE;
  557.   }
  558. #endif
  559. #if P_HAS_MAPI
  560.   if (mapi.IsLoaded()) {
  561.     MapiMessage * message;
  562.     lastError = mapi.ReadMail(sessionId,
  563.                     (HWND)hUserInterface, id, MAPI_ENVELOPE_ONLY, 0, &message);
  564.     if (lastError != SUCCESS_SUCCESS)
  565.       return FALSE;
  566.     mapi.FreeBuffer(message);
  567.     return TRUE;
  568.   }
  569. #endif
  570.   lastError = 1;
  571.   return FALSE;
  572. }
  573. BOOL PMail::DeleteMessage(const PString & id)
  574. {
  575. #if P_HAS_CMC
  576.   if (cmc.IsLoaded()) {
  577.     CMC_flags flags =  hUserInterface != NULL ? CMC_ERROR_UI_ALLOWED : 0;
  578.     CMC_message_reference_ptr seed = id;
  579.     lastError = cmc.act_on(sessionId,
  580.                          seed, CMC_ACT_ON_DELETE, flags, hUserInterface, NULL);
  581.     return lastError == CMC_SUCCESS;
  582.   }
  583. #endif
  584. #if P_HAS_MAPI
  585.   if (mapi.IsLoaded()) {
  586.     lastError = mapi.DeleteMail(sessionId, (HWND)hUserInterface, id, 0, 0);
  587.     return lastError == SUCCESS_SUCCESS;
  588.   }
  589. #endif
  590.   lastError = 1;
  591.   return FALSE;
  592. }
  593. PMail::LookUpResult PMail::LookUp(const PString & name, PString * fullName)
  594. {
  595. #if P_HAS_CMC
  596.   if (cmc.IsLoaded()) {
  597.     CMC_recipient recip_in;
  598.     memset(&recip_in, 0, sizeof(recip_in));
  599.     recip_in.name = (CMC_string)(const char *)name;
  600.     recip_in.recip_flags = CMC_RECIP_LAST_ELEMENT;
  601.     CMC_recipient * recip_out;
  602.     CMC_uint32 count = 1;
  603.     lastError = cmc.look_up(sessionId, &recip_in, CMC_LOOKUP_RESOLVE_IDENTITY,
  604.                           (CMC_ui_id)hUserInterface, &count, &recip_out, NULL);
  605.     switch (lastError) {
  606.       case CMC_SUCCESS :
  607.         if (fullName != NULL)
  608.           *fullName = recip_out->name;
  609.         cmc.free_buf(recip_out);
  610.         return ValidUser;
  611.       case CMC_E_AMBIGUOUS_RECIPIENT :
  612.         return AmbiguousUser;
  613.       case CMC_E_RECIPIENT_NOT_FOUND :
  614.         return UnknownUser;
  615.     }
  616.   
  617.     return LookUpError;
  618.   }
  619. #endif
  620. #if P_HAS_MAPI
  621.   if (mapi.IsLoaded()) {
  622.     MapiRecipDesc * recip;
  623.     lastError = mapi.ResolveName(sessionId,
  624.                       (HWND)hUserInterface, name, MAPI_AB_NOMODIFY, 0, &recip);
  625.     switch (lastError) {
  626.       case SUCCESS_SUCCESS :
  627.         if (fullName != NULL)
  628.           *fullName = recip->lpszName;
  629.         mapi.FreeBuffer(recip);
  630.         return ValidUser;
  631.       case MAPI_E_AMBIGUOUS_RECIPIENT :
  632.         return AmbiguousUser;
  633.       case MAPI_E_UNKNOWN_RECIPIENT :
  634.         return UnknownUser;
  635.     }
  636.   
  637.     return LookUpError;
  638.   }
  639. #endif
  640.   lastError = 1;
  641.   return LookUpError;
  642. }
  643. int PMail::GetErrorCode() const
  644. {
  645.   return (int)lastError;
  646. }
  647. PString PMail::GetErrorText() const
  648. {
  649. #if P_HAS_CMC
  650.   static const char * const cmcErrMsg[] = {
  651.     "CMC_SUCCESS",
  652.     "CMC_E_AMBIGUOUS_RECIPIENT",
  653.     "CMC_E_ATTACHMENT_NOT_FOUND",
  654.     "CMC_E_ATTACHMENT_OPEN_FAILURE",
  655.     "CMC_E_ATTACHMENT_READ_FAILURE",
  656.     "CMC_E_ATTACHMENT_WRITE_FAILURE",
  657.     "CMC_E_COUNTED_STRING_UNSUPPORTED",
  658.     "CMC_E_DISK_FULL",
  659.     "CMC_E_FAILURE",
  660.     "CMC_E_INSUFFICIENT_MEMORY",
  661.     "CMC_E_INVALID_CONFIGURATION",
  662.     "CMC_E_INVALID_ENUM",
  663.     "CMC_E_INVALID_FLAG",
  664.     "CMC_E_INVALID_MEMORY",
  665.     "CMC_E_INVALID_MESSAGE_PARAMETER",
  666.     "CMC_E_INVALID_MESSAGE_REFERENCE",
  667.     "CMC_E_INVALID_PARAMETER",
  668.     "CMC_E_INVALID_SESSION_ID",
  669.     "CMC_E_INVALID_UI_ID",
  670.     "CMC_E_LOGON_FAILURE",
  671.     "CMC_E_MESSAGE_IN_USE",
  672.     "CMC_E_NOT_SUPPORTED",
  673.     "CMC_E_PASSWORD_REQUIRED",
  674.     "CMC_E_RECIPIENT_NOT_FOUND",
  675.     "CMC_E_SERVICE_UNAVAILABLE",
  676.     "CMC_E_TEXT_TOO_LARGE",
  677.     "CMC_E_TOO_MANY_FILES",
  678.     "CMC_E_TOO_MANY_RECIPIENTS",
  679.     "CMC_E_UNABLE_TO_NOT_MARK_AS_READ",
  680.     "CMC_E_UNRECOGNIZED_MESSAGE_TYPE",
  681.     "CMC_E_UNSUPPORTED_ACTION",
  682.     "CMC_E_UNSUPPORTED_CHARACTER_SET",
  683.     "CMC_E_UNSUPPORTED_DATA_EXT",
  684.     "CMC_E_UNSUPPORTED_FLAG",
  685.     "CMC_E_UNSUPPORTED_FUNCTION_EXT",
  686.     "CMC_E_UNSUPPORTED_VERSION",
  687.     "CMC_E_USER_CANCEL",
  688.     "CMC_E_USER_NOT_LOGGED_ON"
  689.   };
  690.   if (cmc.IsLoaded()) {
  691.     if (lastError < PARRAYSIZE(cmcErrMsg))
  692.       return cmcErrMsg[lastError];
  693.     return PString(PString::Printf, "CMC Error=%lu", lastError);
  694.   }
  695. #endif
  696. #if P_HAS_MAPI
  697.   static const char * const mapiErrMsg[] = {
  698.     "SUCCESS_SUCCESS",
  699.     "MAPI_USER_ABORT",
  700.     "MAPI_E_FAILURE",
  701.     "MAPI_E_LOGIN_FAILURE",
  702.     "MAPI_E_DISK_FULL",
  703.     "MAPI_E_INSUFFICIENT_MEMORY",
  704.     "MAPI_E_ACCESS_DENIED",
  705.     "MAPI_E_UNKNOWN",
  706.     "MAPI_E_TOO_MANY_SESSIONS",
  707.     "MAPI_E_TOO_MANY_FILES",
  708.     "MAPI_E_TOO_MANY_RECIPIENTS",
  709.     "MAPI_E_ATTACHMENT_NOT_FOUND",
  710.     "MAPI_E_ATTACHMENT_OPEN_FAILURE",
  711.     "MAPI_E_ATTACHMENT_WRITE_FAILURE",
  712.     "MAPI_E_UNKNOWN_RECIPIENT",
  713.     "MAPI_E_BAD_RECIPTYPE",
  714.     "MAPI_E_NO_MESSAGES",
  715.     "MAPI_E_INVALID_MESSAGE",
  716.     "MAPI_E_TEXT_TOO_LARGE",
  717.     "MAPI_E_INVALID_SESSION",
  718.     "MAPI_E_TYPE_NOT_SUPPORTED",
  719.     "MAPI_E_AMBIGUOUS_RECIPIENT",
  720.     "MAPI_E_MESSAGE_IN_USE",
  721.     "MAPI_E_NETWORK_FAILURE",
  722.     "MAPI_E_INVALID_EDITFIELDS",
  723.     "MAPI_E_INVALID_RECIPS",
  724.     "MAPI_E_NOT_SUPPORTED"
  725.   };
  726.   if (mapi.IsLoaded()) {
  727.     if (lastError < PARRAYSIZE(mapiErrMsg))
  728.       return mapiErrMsg[lastError];
  729.     return PString(PString::Printf, "MAPI Error=%lu", lastError);
  730.   }
  731. #endif
  732.   return "No mail library loaded.";
  733. }
  734. #if P_HAS_CMC
  735. PMail::CMCDLL::CMCDLL()
  736. #ifdef _WIN32
  737.   : PDynaLink("MAPI32.DLL")
  738. #else
  739.   : PDynaLink("CMC.DLL")
  740. #endif
  741. {
  742.   if (!GetFunction("cmc_logon", (Function &)logon) ||
  743.       !GetFunction("cmc_logoff", (Function &)logoff) ||
  744.       !GetFunction("cmc_free", (Function &)free_buf) ||
  745.       !GetFunction("cmc_query_configuration", (Function &)query_configuration) ||
  746.       !GetFunction("cmc_look_up", (Function &)look_up) ||
  747.       !GetFunction("cmc_list", (Function &)list) ||
  748.       !GetFunction("cmc_send", (Function &)send) ||
  749.       !GetFunction("cmc_read", (Function &)read) ||
  750.       !GetFunction("cmc_act_on", (Function &)act_on))
  751.     Close();
  752. }
  753. #endif
  754. #if P_HAS_MAPI
  755. PMail::MAPIDLL::MAPIDLL()
  756. #ifdef _WIN32
  757.   : PDynaLink("MAPI32.DLL")
  758. #else
  759.   : PDynaLink("MAPI.DLL")
  760. #endif
  761. {
  762.   if (!GetFunction("MAPILogon", (Function &)Logon) ||
  763.       !GetFunction("MAPILogoff", (Function &)Logoff) ||
  764.       !GetFunction("MAPISendMail", (Function &)SendMail) ||
  765.       !GetFunction("MAPISendDocuments", (Function &)SendDocuments) ||
  766.       !GetFunction("MAPIFindNext", (Function &)FindNext) ||
  767.       !GetFunction("MAPIReadMail", (Function &)ReadMail) ||
  768.       !GetFunction("MAPISaveMail", (Function &)SaveMail) ||
  769.       !GetFunction("MAPIDeleteMail", (Function &)DeleteMail) ||
  770.       !GetFunction("MAPIFreeBuffer", (Function &)FreeBuffer) ||
  771.       !GetFunction("MAPIAddress", (Function &)Address) ||
  772.       !GetFunction("MAPIDetails", (Function &)Details) ||
  773.       !GetFunction("MAPIResolveName", (Function &)ResolveName))
  774.     Close();
  775. }
  776. #endif
  777. // End Of File ///////////////////////////////////////////////////////////////