mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / winemapi / sendmail.c
blobca1b6c59df155e9a6cc91a51eec6252ddcef9e9d
1 /*
2 * MAPISendMail implementation
4 * Copyright 2005 Hans Leidekker
5 * Copyright 2009 Owen Rudge for CodeWeavers
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdio.h>
23 #include <stdarg.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "mapi.h"
31 #include "winreg.h"
32 #include "shellapi.h"
33 #include "shlwapi.h"
34 #include "winternl.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(winemapi);
39 /* Escapes a string for use in mailto: URL */
40 static char *escape_string(char *in, char *empty_string)
42 HRESULT res;
43 DWORD size;
44 char *escaped = NULL;
46 if (!in)
47 return empty_string;
49 size = 1;
50 res = UrlEscapeA(in, empty_string, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY);
52 if (res == E_POINTER)
54 escaped = HeapAlloc(GetProcessHeap(), 0, size);
56 if (!escaped)
57 return in;
59 /* If for some reason UrlEscape fails, just send the original text */
60 if (UrlEscapeA(in, escaped, &size, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY) != S_OK)
62 HeapFree(GetProcessHeap(), 0, escaped);
63 escaped = in;
67 return escaped ? escaped : empty_string;
70 /**************************************************************************
71 * MAPISendMail
73 * Send a message using a native mail client.
75 * PARAMS
76 * session [I] Handle to a MAPI session.
77 * uiparam [I] Parent window handle.
78 * message [I] Pointer to a MAPIMessage structure.
79 * flags [I] Flags.
80 * reserved [I] Reserved, pass 0.
82 * RETURNS
83 * Success: SUCCESS_SUCCESS
84 * Failure: MAPI_E_FAILURE
87 ULONG WINAPI MAPISendMail(LHANDLE session, ULONG_PTR uiparam,
88 lpMapiMessage message, FLAGS flags, ULONG reserved)
90 ULONG ret = MAPI_E_FAILURE;
91 unsigned int i, to_count = 0, cc_count = 0, bcc_count = 0;
92 unsigned int to_size = 0, cc_size = 0, bcc_size = 0, subj_size, body_size;
94 char *to = NULL, *cc = NULL, *bcc = NULL, *subject = NULL, *body = NULL;
95 const char *address;
96 static const char format[] =
97 "mailto:\"%s\"?subject=\"%s\"&cc=\"%s\"&bcc=\"%s\"&body=\"%s\"";
98 static const char smtp[] = "smtp:";
99 char *mailto = NULL, *escape = NULL;
100 char empty_string[] = "";
101 HRESULT res;
102 DWORD size;
104 TRACE("(0x%08lx 0x%08lx %p 0x%08x 0x%08x)\n", session, uiparam,
105 message, flags, reserved);
107 if (!message)
108 return MAPI_E_FAILURE;
110 for (i = 0; i < message->nRecipCount; i++)
112 if (!message->lpRecips)
114 WARN("No recipients found\n");
115 return MAPI_E_FAILURE;
118 address = message->lpRecips[i].lpszAddress;
120 if (address)
122 if (!_strnicmp(address, smtp, sizeof(smtp) - 1))
123 address += sizeof(smtp) - 1;
125 switch (message->lpRecips[i].ulRecipClass)
127 case MAPI_ORIG:
128 TRACE("From: %s\n", debugstr_a(address));
129 break;
131 case MAPI_TO:
132 TRACE("To: %s\n", debugstr_a(address));
133 to_size += lstrlenA(address) + 1;
134 break;
136 case MAPI_CC:
137 TRACE("Cc: %s\n", debugstr_a(address));
138 cc_size += lstrlenA(address) + 1;
139 break;
141 case MAPI_BCC:
142 TRACE("Bcc: %s\n", debugstr_a(address));
143 bcc_size += lstrlenA(address) + 1;
144 break;
146 default:
147 TRACE("Unknown recipient class: %d\n",
148 message->lpRecips[i].ulRecipClass);
151 else
152 FIXME("Name resolution and entry identifiers not supported\n");
155 if (message->nFileCount)
157 FIXME("Ignoring %u attachments:\n", message->nFileCount);
158 for (i = 0; i < message->nFileCount; i++)
159 FIXME("\t%s (%s)\n", debugstr_a(message->lpFiles[i].lpszPathName),
160 debugstr_a(message->lpFiles[i].lpszFileName));
163 /* Escape subject and body */
164 subject = escape_string(message->lpszSubject, empty_string);
165 body = escape_string(message->lpszNoteText, empty_string);
167 TRACE("Subject: %s\n", debugstr_a(subject));
168 TRACE("Body: %s\n", debugstr_a(body));
170 subj_size = lstrlenA(subject);
171 body_size = lstrlenA(body);
173 ret = MAPI_E_INSUFFICIENT_MEMORY;
175 if (to_size)
177 to = HeapAlloc(GetProcessHeap(), 0, to_size);
179 if (!to)
180 goto exit;
182 to[0] = 0;
185 if (cc_size)
187 cc = HeapAlloc(GetProcessHeap(), 0, cc_size);
189 if (!cc)
190 goto exit;
192 cc[0] = 0;
195 if (bcc_size)
197 bcc = HeapAlloc(GetProcessHeap(), 0, bcc_size);
199 if (!bcc)
200 goto exit;
202 bcc[0] = 0;
205 if (message->lpOriginator)
206 TRACE("From: %s\n", debugstr_a(message->lpOriginator->lpszAddress));
208 for (i = 0; i < message->nRecipCount; i++)
210 address = message->lpRecips[i].lpszAddress;
212 if (address)
214 if (!_strnicmp(address, smtp, sizeof(smtp) - 1))
215 address += sizeof(smtp) - 1;
217 switch (message->lpRecips[i].ulRecipClass)
219 case MAPI_TO:
220 if (to_count)
221 lstrcatA(to, ",");
223 lstrcatA(to, address);
224 to_count++;
225 break;
227 case MAPI_CC:
228 if (cc_count)
229 lstrcatA(cc, ",");
231 lstrcatA(cc, address);
232 cc_count++;
233 break;
235 case MAPI_BCC:
236 if (bcc_count)
237 lstrcatA(bcc, ",");
239 lstrcatA(bcc, address);
240 bcc_count++;
241 break;
245 ret = MAPI_E_FAILURE;
246 size = sizeof(format) + to_size + cc_size + bcc_size + subj_size + body_size;
248 mailto = HeapAlloc(GetProcessHeap(), 0, size);
250 if (!mailto)
251 goto exit;
253 sprintf(mailto, format, to ? to : "", subject, cc ? cc : "", bcc ? bcc : "", body);
255 size = 1;
256 res = UrlEscapeA(mailto, empty_string, &size, URL_ESCAPE_SPACES_ONLY);
258 if (res != E_POINTER)
259 goto exit;
261 escape = HeapAlloc(GetProcessHeap(), 0, size);
263 if (!escape)
264 goto exit;
266 res = UrlEscapeA(mailto, escape, &size, URL_ESCAPE_SPACES_ONLY);
268 if (res != S_OK)
269 goto exit;
271 TRACE("Executing winebrowser.exe with parameters '%s'\n", debugstr_a(escape));
273 if ((UINT_PTR) ShellExecuteA(NULL, "open", "winebrowser.exe", escape, NULL, 0) > 32)
274 ret = SUCCESS_SUCCESS;
276 exit:
277 HeapFree(GetProcessHeap(), 0, to);
278 HeapFree(GetProcessHeap(), 0, cc);
279 HeapFree(GetProcessHeap(), 0, bcc);
280 HeapFree(GetProcessHeap(), 0, mailto);
281 HeapFree(GetProcessHeap(), 0, escape);
283 if (subject != empty_string)
284 HeapFree(GetProcessHeap(), 0, subject);
286 if (body != empty_string)
287 HeapFree(GetProcessHeap(), 0, body);
289 return ret;
292 ULONG WINAPI MAPISendDocuments(ULONG_PTR uiparam, LPSTR delim, LPSTR paths,
293 LPSTR filenames, ULONG reserved)
295 return MAPI_E_NOT_SUPPORTED;