[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