[PATCH] Added attachment handling to MAPISendMail function.

Mark Neyhart Mark_Neyhart at legis.state.ak.us
Wed Dec 19 17:13:16 CST 2007


Resolved FIXME regarding attachment handling in MAPISendMail function.
A list of attachments is now built and added to the MAILTO string for
excecution by ShellExecuteA.  The attachment list format is the same
as that specified for a Mozilla command line option.
---
 dlls/mapi32/sendmail.c |   75 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/dlls/mapi32/sendmail.c b/dlls/mapi32/sendmail.c
old mode 100644
new mode 100755
index eb954a5..9286dc6
--- a/dlls/mapi32/sendmail.c
+++ b/dlls/mapi32/sendmail.c
@@ -27,6 +27,7 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
+#include "winternl.h"
 #include "objbase.h"
 #include "mapi.h"
 #include "winreg.h"
@@ -35,9 +36,10 @@
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mapi);
+#define FILELIST_MAX  4000
 
 /**************************************************************************
- *  MAPISendMail	(MAPI32.211)
+ *  MAPISendMail       (MAPI32.211)
  *
  * Send a mail.
  *
@@ -53,7 +55,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(mapi);
  *  Failure: MAPI_E_FAILURE
  *
  * NOTES
- *  This is a temporary hack. 
+ *  This procedure will build a MAILTO string in the form
+ *  mailto:"TOLIST"?subject="SUBJECT"&cc="CCLIST"&bcc="BCCLIST"&body=""&attachment="'ATTACHMENTLIST'"
+ *  and attempt to open it with ShellExecuteA.
  */
 ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
     lpMapiMessage message, FLAGS flags, ULONG reserved )
@@ -61,12 +65,13 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
     ULONG ret = MAPI_E_FAILURE;
     unsigned int i, to_count = 0, cc_count = 0, bcc_count = 0;
     unsigned int to_size = 0, cc_size = 0, bcc_size = 0, subj_size, body_size;
-
     char *to = NULL, *cc = NULL, *bcc = NULL;
-    const char *address, *subject, *body;
+    const char *address, *subject, *body, *filename;
     static const char format[] =
-        "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"";
+        "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"&attachment=\"'%s\"'";
     char *mailto = NULL, *escape = NULL;
+    unsigned int FileListSize = 0;
+    char FileList[FILELIST_MAX] = "\0";
     HRESULT res;
     DWORD size;
 
@@ -111,8 +116,54 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
         else
             FIXME("Name resolution and entry identifiers not supported\n");
     }
-    if (message->nFileCount) FIXME("Ignoring attachments\n");
 
+    ret = SUCCESS_SUCCESS;
+    for (i = 0; i < message->nFileCount; i++)
+    {
+        if (!message->lpFiles)
+        {
+            WARN("No filenames found\n");
+            ret = MAPI_E_FAILURE;
+            break;
+        }
+        filename = message->lpFiles[i].lpszPathName;
+        if (filename)
+        {
+            char TempFile[MAX_PATH + 100] = "\0";
+            unsigned int TempFileSize = 0;
+            unsigned int BufLen;
+            /* We need to make a copy of each attachment file        */
+            /* since the call to the mailing program is asynchronous */
+            /* and the files may be deleted by the calling program.  */
+            /* While we do so, we can use the original file names.   */
+            TRACE("Attachment: %s\n", debugstr_a(filename));
+            lstrcatA(TempFile, "/tmp/");
+            TempFileSize = strlen(TempFile);
+            TRACE("Attachment Original Name: %s\n", debugstr_a(message->lpFiles[i].lpszFileName));
+            BufLen = strlen(message->lpFiles[i].lpszFileName);
+            if (BufLen + TempFileSize > MAX_PATH + 100)
+            {
+                WARN("Attachment file name larger than %d bytes\n",MAX_PATH + 100);
+                return MAPI_E_FAILURE;
+            }
+            lstrcatA(TempFile, message->lpFiles[i].lpszFileName);
+            TempFileSize += BufLen;
+            if (!(CopyFileA(filename, TempFile, FALSE)))
+            {
+                WARN("Failed to make copy of attachment.  Source:%s, Dest:%s\n",
+                    debugstr_a(filename), debugstr_a(TempFile));
+                return MAPI_E_FAILURE;
+            }
+	    if (FileListSize + TempFileSize + 7 > FILELIST_MAX)
+	    {
+	        WARN("Attachment list larger than %d bytes\n",FILELIST_MAX);
+		return MAPI_E_FAILURE;
+	    }
+            lstrcatA(FileList, "file://");
+            lstrcatA(FileList, TempFile);
+            FileListSize += TempFileSize + 7;
+        }
+    }
     subject = message->lpszSubject ? message->lpszSubject : "";
     body = message->lpszNoteText ? message->lpszNoteText : "";
 
@@ -168,16 +219,15 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
         }
     }
     ret = MAPI_E_FAILURE;
-    size = sizeof(format) + to_size + cc_size + bcc_size + subj_size + body_size;
-    
+    size = sizeof(format) + to_size + cc_size + bcc_size + subj_size +
+           body_size + FileListSize;
+
     mailto = HeapAlloc( GetProcessHeap(), 0, size );
     if (!mailto) goto exit;
-
-    sprintf( mailto, format, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "", body );
-
+    sprintf( mailto, format, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "",
+             body, FileList ? FileList : "" );
     size = 0;
     res = UrlEscapeA( mailto, NULL, &size, URL_ESCAPE_SPACES_ONLY );
-    if (res != E_POINTER) goto exit;
 
     escape = HeapAlloc( GetProcessHeap(), 0, size );
     if (!escape) goto exit;
@@ -185,6 +235,7 @@ ULONG WINAPI MAPISendMail( LHANDLE session, ULONG_PTR uiparam,
     res = UrlEscapeA( mailto, escape, &size, URL_ESCAPE_SPACES_ONLY );
     if (res != S_OK) goto exit;
 
+    TRACE( "mailto string:: %s\n", debugstr_a(escape) );
     if ((UINT_PTR)ShellExecuteA( NULL, "open", escape, NULL, NULL, 0 ) > 32)
         ret = SUCCESS_SUCCESS;
 
-- 
1.4.4.3


--------------000206040306020706090703--



More information about the wine-patches mailing list