[Wine-patches] [eterwine] [eterhack] eterbug #6747

Alexander Morozov amorozov на etersoft.ru
Вт Янв 18 18:14:14 MSK 2011


----------- следующая часть -----------
From 4e9939a40b1d63f48e94b612ba09484f0cfce5d1 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Thu, 13 Jan 2011 16:56:24 +0300
Subject: [eterhack 1/4] winemapi: Implement MAPIResolveName (eterbug #6747).

---
 dlls/winemapi/Makefile.in |    2 +-
 dlls/winemapi/main.c      |   28 ++++++++++++++++++++++++++--
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/dlls/winemapi/Makefile.in b/dlls/winemapi/Makefile.in
index 0c1ff6e..0c9c8a6 100644
--- a/dlls/winemapi/Makefile.in
+++ b/dlls/winemapi/Makefile.in
@@ -1,5 +1,5 @@
 MODULE    = winemapi.dll
-IMPORTS   = shlwapi shell32
+IMPORTS   = shlwapi shell32 mapi32
 
 C_SRCS = \
 	main.c \
diff --git a/dlls/winemapi/main.c b/dlls/winemapi/main.c
index a954ab7..0627aa2 100644
--- a/dlls/winemapi/main.c
+++ b/dlls/winemapi/main.c
@@ -26,6 +26,7 @@
 #include "objbase.h"
 #include "mapidefs.h"
 #include "mapi.h"
+#include "mapix.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(winemapi);
@@ -99,8 +100,31 @@ ULONG WINAPI MAPIReadMail(LHANDLE session, ULONG_PTR uiparam, LPSTR msg_id,
 ULONG WINAPI MAPIResolveName(LHANDLE session, ULONG_PTR uiparam, LPSTR name,
     FLAGS flags, ULONG reserved, lpMapiRecipDesc *recip)
 {
-    FIXME("(stub)\n");
-    return MAPI_E_NOT_SUPPORTED;
+    static const char smtp[] = "SMTP:";
+
+    SCODE scode;
+    char *p;
+
+    TRACE("(0x%08lx 0x%08lx %s 0x%08x 0x%08x %p)\n", session, uiparam,
+          debugstr_a(name), flags, reserved, recip);
+
+    if (!name || !strlen(name))
+        return MAPI_E_FAILURE;
+
+    scode = MAPIAllocateBuffer(sizeof(**recip) + sizeof(smtp) + strlen(name),
+                               (LPVOID *)recip);
+    if (scode != S_OK)
+        return MAPI_E_INSUFFICIENT_MEMORY;
+
+    ZeroMemory(*recip, sizeof(**recip));
+    p = (char *)(*recip + 1);
+    strcpy(p, smtp);
+    strcpy(p + sizeof(smtp) - 1, name);
+
+    (*recip)->ulRecipClass = MAPI_TO;
+    (*recip)->lpszName = p + sizeof(smtp) - 1;
+    (*recip)->lpszAddress = p;
+    return SUCCESS_SUCCESS;
 }
 
 ULONG WINAPI MAPISaveMail(LHANDLE session, ULONG_PTR uiparam, lpMapiMessage msg,
-- 
1.7.3.4

----------- следующая часть -----------
From 6c04e5b8229d0f6510c7301bf04036fff0269175 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Fri, 14 Jan 2011 17:58:55 +0300
Subject: [eterhack 2/4] winemapi: Address can contain SMTP: (eterbug #6747).

---
 dlls/winemapi/sendmail.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/dlls/winemapi/sendmail.c b/dlls/winemapi/sendmail.c
index 44c1d00..e4629bb 100644
--- a/dlls/winemapi/sendmail.c
+++ b/dlls/winemapi/sendmail.c
@@ -66,6 +66,7 @@ ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
     const char *address, *subject, *body;
     static const char format[] =
         "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"";
+    static const char smtp[] = "smtp:";
     char *mailto = NULL, *escape = NULL;
     char empty_string[] = "";
     HRESULT res;
@@ -86,6 +87,8 @@ ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
         }
 
         address = message->lpRecips[i].lpszAddress;
+        if (!strncasecmp(address, smtp, sizeof(smtp) - 1))
+            address += sizeof(smtp) - 1;
 
         if (address)
         {
@@ -169,6 +172,8 @@ ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
     for (i = 0; i < message->nRecipCount; i++)
     {
         address = message->lpRecips[i].lpszAddress;
+        if (!strncasecmp(address, smtp, sizeof(smtp) - 1))
+            address += sizeof(smtp) - 1;
 
         if (address)
         {
-- 
1.7.3.4

----------- следующая часть -----------
From c672b0b5822cd5aa0963bdd310a16c2b0f3b7e38 Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Mon, 17 Jan 2011 21:22:27 +0300
Subject: [eterhack 3/4] winebrowser: Add attachment support (eterbug #6747).

---
 programs/winebrowser/main.c |  104 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 102 insertions(+), 2 deletions(-)

diff --git a/programs/winebrowser/main.c b/programs/winebrowser/main.c
index 3d53419..29b4e48 100644
--- a/programs/winebrowser/main.c
+++ b/programs/winebrowser/main.c
@@ -32,7 +32,7 @@
  *  will be fed to a web browser. In the last case the argument is fed
  *  to a mail client. A mailto URL is composed as follows:
  *
- *   mailto:[E-MAIL]?subject=[TOPIC]&cc=[E-MAIL]&bcc=[E-MAIL]&body=[TEXT]
+ *   mailto:[E-MAIL]?subject=[TOPIC]&cc=[E-MAIL]&bcc=[E-MAIL]&body=[TEXT]&attachment=[PATH]
  */
 
 #define WIN32_LEAN_AND_MEAN
@@ -75,6 +75,106 @@ static WCHAR *strdupW( const WCHAR *src )
     return dst;
 }
 
+static WCHAR *strndupW( const WCHAR *src, INT n )
+{
+    WCHAR *dst;
+    int size = (n + 1) * sizeof(WCHAR);
+    if ((dst = HeapAlloc( GetProcessHeap(), 0, size )))
+    {
+        memcpy( dst, src, n * sizeof(WCHAR) );
+        dst[n] = 0;
+    }
+    return dst;
+}
+
+static char *strcat_unixcp( char *dest, const WCHAR *src, INT n, const char *add )
+{
+    char *ret;
+    int len = WideCharToMultiByte( CP_UNIXCP, 0, src, n, NULL, 0, NULL, NULL );
+    int size = len + (dest ? strlen( dest ) : 0) + (add ? strlen( add ) : 0) + 1;
+
+    if (dest)
+        ret = HeapReAlloc( GetProcessHeap(), 0, dest, size );
+    else
+        ret = HeapAlloc( GetProcessHeap(), 0, size );
+    if (ret)
+    {
+        dest = ret + (dest ? strlen( ret ) : 0);
+        WideCharToMultiByte( CP_UNIXCP, 0, src, n, dest, len, NULL, NULL );
+        dest[len] = 0;
+        if (add)
+            strcat( dest, add );
+    }
+    else if (dest)
+        HeapFree( GetProcessHeap(), 0, dest );
+    return ret;
+}
+
+static char *escape_str( char *str )
+{
+    char empty[] = "";
+    char *ret;
+    DWORD size = 1;
+
+    UrlEscapeA( str, empty, &size, URL_ESCAPE_SPACES_ONLY );
+    if ((ret = HeapAlloc( GetProcessHeap(), 0, size )))
+        UrlEscapeA( str, ret, &size, URL_ESCAPE_SPACES_ONLY );
+    HeapFree( GetProcessHeap(), 0, str );
+    return ret;
+}
+
+static char *convert_paths( const WCHAR *args )
+{
+    static const WCHAR attachmentW[] =
+        {'a','t','t','a','c','h','m','e','n','t','=',0};
+
+    const WCHAR *prev = args, *p, *ep;
+    WCHAR *dos_path = NULL;
+    char *buf = NULL, *unix_path = NULL;
+
+    if (!(p = strchrW( args, '?' )))
+        return strdup_unixcp( args );
+
+    for (;;)
+    {
+        ++p;
+        if (strlenW( p ) > strlenW( attachmentW ) &&
+            !memcmp( p, attachmentW, sizeof(attachmentW) - sizeof(WCHAR) ))
+        {
+            p += strlenW( attachmentW );
+            ep = strchrW( p, '&' );
+            /* mailto:name на example.com?attachment=c:\file1&attachment=c:\file2
+             * ^prev                              ^p      ^ep */
+            if (ep)
+            {
+                if (ep == p)
+                    continue;
+                dos_path = strndupW( p, ep - p );
+            }
+            else
+                dos_path = strdupW( p );
+            UrlUnescapeInPlaceW( dos_path, 0 );
+            if (!(unix_path = wine_get_unix_file_name( dos_path )) ||
+                !(unix_path = escape_str( unix_path )) ||
+                !(buf = strcat_unixcp( buf, prev, p - prev, unix_path )))
+                break;
+            HeapFree( GetProcessHeap(), 0, dos_path );
+            HeapFree( GetProcessHeap(), 0, unix_path );
+            if (!ep)
+                return buf;
+            prev = ep;
+            p = ep;
+        }
+        else
+            if (!(p = strchrW( p, '&' )))
+                return strcat_unixcp( buf, prev, -1, NULL );
+    }
+    HeapFree( GetProcessHeap(), 0, buf );
+    HeapFree( GetProcessHeap(), 0, dos_path );
+    HeapFree( GetProcessHeap(), 0, unix_path );
+    return NULL;
+}
+
 /* try to launch a unix app from a comma separated string of app names */
 static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
 {
@@ -82,7 +182,7 @@ static int launch_app( WCHAR *candidates, const WCHAR *argv1 )
     const char *argv_new[3];
 
     if (!(applist = strdup_unixcp( candidates ))) return 1;
-    if (!(cmdline = strdup_unixcp( argv1 )))
+    if (!(cmdline = convert_paths( argv1 )))
     {
         HeapFree( GetProcessHeap(), 0, applist );
         return 1;
-- 
1.7.3.4

----------- следующая часть -----------
From 81eb1b4d227460c0d9d1211c814ac09c067278bc Mon Sep 17 00:00:00 2001
From: Alexander Morozov <amorozov на etersoft.ru>
Date: Tue, 18 Jan 2011 16:38:03 +0300
Subject: [eterhack 4/4] winemapi: Add attachment support (eterbug #6747).

---
 dlls/winemapi/sendmail.c |   43 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/dlls/winemapi/sendmail.c b/dlls/winemapi/sendmail.c
index e4629bb..4a6d122 100644
--- a/dlls/winemapi/sendmail.c
+++ b/dlls/winemapi/sendmail.c
@@ -60,13 +60,15 @@ 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;
+    unsigned int to_size = 0, cc_size = 0, bcc_size = 0, subj_size, body_size,
+        attach_size;
 
-    char *to = NULL, *cc = NULL, *bcc = NULL;
+    char *to = NULL, *cc = NULL, *bcc = NULL, *attach = NULL, *p;
     const char *address, *subject, *body;
     static const char format[] =
-        "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"";
+        "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"%s";
     static const char smtp[] = "smtp:";
+    static const char attachment[] = "&attachment=\"%s\"";
     char *mailto = NULL, *escape = NULL;
     char empty_string[] = "";
     HRESULT res;
@@ -122,9 +124,6 @@ ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
             FIXME("Name resolution and entry identifiers not supported\n");
     }
 
-    if (message->nFileCount)
-        FIXME("Ignoring attachments\n");
-
     subject = message->lpszSubject ? message->lpszSubject : "";
     body = message->lpszNoteText ? message->lpszNoteText : "";
 
@@ -134,6 +133,17 @@ ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
     subj_size = lstrlenA(subject);
     body_size = lstrlenA(body);
 
+    attach_size = message->nFileCount * sizeof(attachment);
+    for (i = 0; i < message->nFileCount; i++)
+    {
+        TRACE("Attachment: %s\n", debugstr_a(message->lpFiles[i].lpszPathName));
+        attach_size += lstrlenA(message->lpFiles[i].lpszPathName);
+        if (message->lpFiles[i].flFlags ||
+            message->lpFiles[i].nPosition != -1L ||
+            message->lpFiles[i].lpszFileName)
+            FIXME("Some features of attachments not supported\n");
+    }
+
     ret = MAPI_E_INSUFFICIENT_MEMORY;
 
     if (to_size)
@@ -206,14 +216,30 @@ 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 + attach_size;
+
+    if (attach_size)
+    {
+        attach = HeapAlloc(GetProcessHeap(), 0, attach_size);
+
+        if (!attach)
+            goto exit;
+
+        attach[0] = 0;
+        p = attach;
+
+        for (i = 0; i < message->nFileCount; i++)
+            p += sprintf(p, attachment, message->lpFiles[i].lpszPathName);
+    }
 
     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, attach ? attach : "");
 
     size = 1;
     res = UrlEscapeA(mailto, empty_string, &size, URL_ESCAPE_SPACES_ONLY);
@@ -240,6 +266,7 @@ exit:
     HeapFree(GetProcessHeap(), 0, to);
     HeapFree(GetProcessHeap(), 0, cc);
     HeapFree(GetProcessHeap(), 0, bcc);
+    HeapFree(GetProcessHeap(), 0, attach);
     HeapFree(GetProcessHeap(), 0, mailto);
     HeapFree(GetProcessHeap(), 0, escape);
 
-- 
1.7.3.4



Подробная информация о списке рассылки Wine-patches