Last active
February 3, 2023 13:59
-
-
Save markx86/350686b15d01c18a5507cc1532279f0a to your computer and use it in GitHub Desktop.
WINEMAPI Thunderbird patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- wine-8.0/dlls/winemapi/sendmail.c 2023-01-24 16:06:25.000000000 +0100 | |
+++ sendmail.c 2023-02-03 14:47:20.039651438 +0100 | |
@@ -19,6 +19,7 @@ | |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
*/ | |
+#include <windows.h> | |
#include <stdio.h> | |
#include <stdarg.h> | |
@@ -36,37 +37,7 @@ | |
WINE_DEFAULT_DEBUG_CHANNEL(winemapi); | |
-/* Escapes a string for use in mailto: URL */ | |
-static char *escape_string(char *in, char *empty_string) | |
-{ | |
- HRESULT res; | |
- DWORD size; | |
- char *escaped = NULL; | |
- | |
- if (!in) | |
- return empty_string; | |
- | |
- size = 1; | |
- res = UrlEscapeA(in, empty_string, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY); | |
- | |
- if (res == E_POINTER) | |
- { | |
- escaped = HeapAlloc(GetProcessHeap(), 0, size); | |
- | |
- if (!escaped) | |
- return in; | |
- | |
- /* If for some reason UrlEscape fails, just send the original text */ | |
- if (UrlEscapeA(in, escaped, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY) != S_OK) | |
- { | |
- HeapFree(GetProcessHeap(), 0, escaped); | |
- escaped = in; | |
- } | |
- } | |
- | |
- return escaped ? escaped : empty_string; | |
-} | |
- | |
+ | |
/************************************************************************** | |
* MAPISendMail | |
* | |
@@ -90,16 +61,21 @@ | |
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 att_size = 0; | |
- char *to = NULL, *cc = NULL, *bcc = NULL, *subject = NULL, *body = NULL; | |
+ char *to = NULL, *cc = NULL, *bcc = NULL, *subject = NULL, *body = NULL, *attachment = NULL; | |
const char *address; | |
static const char format[] = | |
- "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\""; | |
+ "/c start %s -compose to='%s',subject='%s',cc='%s',bcc='%s',body='%s',attachment='%s'"; | |
static const char smtp[] = "smtp:"; | |
- char *mailto = NULL, *escape = NULL; | |
+ char *mailto = NULL; | |
char empty_string[] = ""; | |
- HRESULT res; | |
+ char path[MAX_PATH]; | |
DWORD size; | |
+ WCHAR *windows_name; | |
+ LPWSTR (*CDECL wine_get_dos_file_name_ptr)(LPCSTR) = NULL; | |
+ | |
+ (void)(empty_string); | |
TRACE("(0x%08Ix 0x%08Ix %p 0x%08lx 0x%08lx)\n", session, uiparam, | |
message, flags, reserved); | |
@@ -107,6 +83,7 @@ | |
if (!message) | |
return MAPI_E_FAILURE; | |
+ TRACE("%d recipients\n", message->nRecipCount); | |
for (i = 0; i < message->nRecipCount; i++) | |
{ | |
if (!message->lpRecips) | |
@@ -154,16 +131,60 @@ | |
if (message->nFileCount) | |
{ | |
- FIXME("Ignoring %lu attachments:\n", message->nFileCount); | |
- for (i = 0; i < message->nFileCount; i++) | |
- FIXME("\t%s (%s)\n", debugstr_a(message->lpFiles[i].lpszPathName), | |
- debugstr_a(message->lpFiles[i].lpszFileName)); | |
+ LPSTR (*CDECL wine_get_unix_file_name_ptr)(LPCWSTR) = NULL; | |
+ wine_get_unix_file_name_ptr = (void*) | |
+ GetProcAddress(GetModuleHandleA("KERNEL32"), | |
+ "wine_get_unix_file_name"); | |
+ if (wine_get_unix_file_name_ptr == NULL) { | |
+ WARN("Cannot get the address of 'wine_get_unix_file_name'\n"); | |
+ } else { | |
+ char** unix_names = HeapAlloc(GetProcessHeap(), 0, message->nFileCount * sizeof(char*)); | |
+ | |
+ if (!unix_names) | |
+ goto exit; | |
+ | |
+ for (i = 0; i < message->nFileCount; i++) { | |
+ unsigned int namesize = lstrlenA(message->lpFiles[i].lpszPathName) + 1; | |
+ LPWSTR wname = HeapAlloc(GetProcessHeap(), 0, 2 * namesize); | |
+ | |
+ TRACE("Translating %s to unix path\n", debugstr_a(message->lpFiles[i].lpszPathName)); | |
+ MultiByteToWideChar(CP_ACP, 0, message->lpFiles[i].lpszPathName, namesize, wname, namesize); | |
+ unix_names[i] = wine_get_unix_file_name_ptr(wname); | |
+ HeapFree(GetProcessHeap(), 0, wname); | |
+ TRACE(" -> %s\n", unix_names[i]); | |
+ | |
+ if (unix_names[i]) { | |
+ // compute overall size, account for trailing ',' or '\0' | |
+ att_size += lstrlenA(unix_names[i]) + 1; | |
+ } | |
+ } | |
+ | |
+ // conversion is done, build list of attachments string | |
+ attachment = HeapAlloc(GetProcessHeap(), 0, att_size); | |
+ | |
+ if (!attachment) | |
+ goto exit; | |
+ | |
+ attachment[0] = '\0'; | |
+ | |
+ // concatenate all file names in one string and free the individual names | |
+ for (i = 0; i < message->nFileCount; i++) { | |
+ if (unix_names[i]) { | |
+ if (attachment[0] != '\0') | |
+ lstrcatA(attachment, ","); | |
+ | |
+ lstrcatA(attachment, unix_names[i]); | |
+ HeapFree(GetProcessHeap(), 0, unix_names[i]); | |
+ } | |
+ } | |
+ TRACE("Attachments: %s\n", attachment); | |
+ } | |
} | |
/* Escape subject and body */ | |
- subject = escape_string(message->lpszSubject, empty_string); | |
- body = escape_string(message->lpszNoteText, empty_string); | |
- | |
+ subject = message->lpszSubject; | |
+ body = message->lpszNoteText; | |
+ | |
TRACE("Subject: %s\n", debugstr_a(subject)); | |
TRACE("Body: %s\n", debugstr_a(body)); | |
@@ -243,34 +264,37 @@ | |
} | |
} | |
ret = MAPI_E_FAILURE; | |
- size = sizeof(format) + to_size + cc_size + bcc_size + subj_size + body_size; | |
- | |
- mailto = HeapAlloc(GetProcessHeap(), 0, size); | |
- | |
- if (!mailto) | |
+ | |
+ wine_get_dos_file_name_ptr = (void*) | |
+ GetProcAddress(GetModuleHandleA("KERNEL32"), | |
+ "wine_get_dos_file_name"); | |
+ if (wine_get_dos_file_name_ptr == NULL) { | |
+ WARN("Cannot get the address of 'wine_get_dos_file_name'\n"); | |
goto exit; | |
+ } | |
- sprintf(mailto, format, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "", body); | |
- | |
- size = 1; | |
- res = UrlEscapeA(mailto, empty_string, &size, URL_ESCAPE_SPACES_ONLY); | |
- | |
- if (res != E_POINTER) | |
+ if ((windows_name = wine_get_dos_file_name_ptr("/usr/bin/thunderbird"))) | |
+ { | |
+ WideCharToMultiByte(CP_UNIXCP, 0, windows_name, -1, path, MAX_PATH, NULL, NULL); | |
+ HeapFree( GetProcessHeap(), 0, windows_name ); | |
+ } | |
+ else | |
+ { | |
+ WARN("Unable to convert '/usr/bin/thunderbird' to DOS path\n"); | |
goto exit; | |
+ } | |
- escape = HeapAlloc(GetProcessHeap(), 0, size); | |
- | |
- if (!escape) | |
- goto exit; | |
+ size = sizeof(format) + lstrlenA(path) + to_size + cc_size + bcc_size + subj_size + body_size + att_size; | |
- res = UrlEscapeA(mailto, escape, &size, URL_ESCAPE_SPACES_ONLY); | |
+ mailto = HeapAlloc(GetProcessHeap(), 0, size); | |
- if (res != S_OK) | |
+ if (!mailto) | |
goto exit; | |
- TRACE("Executing winebrowser.exe with parameters '%s'\n", debugstr_a(escape)); | |
+ sprintf(mailto, format, path, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "", body, attachment ? attachment : ""); | |
+ TRACE("Executing cmd %s\n", mailto); | |
- if ((UINT_PTR) ShellExecuteA(NULL, "open", "winebrowser.exe", escape, NULL, 0) > 32) | |
+ if ((UINT_PTR) ShellExecuteA(NULL, "open", "cmd.exe", mailto, NULL, 0) > 32) | |
ret = SUCCESS_SUCCESS; | |
exit: | |
@@ -278,13 +302,9 @@ | |
HeapFree(GetProcessHeap(), 0, cc); | |
HeapFree(GetProcessHeap(), 0, bcc); | |
HeapFree(GetProcessHeap(), 0, mailto); | |
- HeapFree(GetProcessHeap(), 0, escape); | |
- | |
- if (subject != empty_string) | |
- HeapFree(GetProcessHeap(), 0, subject); | |
- if (body != empty_string) | |
- HeapFree(GetProcessHeap(), 0, body); | |
+ if (attachment != NULL) | |
+ HeapFree(GetProcessHeap(), 0, attachment); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment