/[winpt]/trunk/Src/wptMAPI.cpp
ViewVC logotype

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File size: 11121 byte(s)
WinPT initial checkin.


1 twoaday 2 /* wptMAPI.cpp
2     * Copyright (C) 2003, 2004 Timo Schulz
3     *
4     * This file is part of WinPT.
5     *
6     * WinPT is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * WinPT is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with WinPT; if not, write to the Free Software Foundation,
18     * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19     */
20    
21     #include <windows.h>
22     #include <stdio.h>
23     #include <mapi.h>
24    
25     extern HINSTANCE glob_hinst;
26    
27     #include "../resource.h"
28     #include "wptTypes.h"
29     #include "wptErrors.h"
30     #include "wptW32API.h"
31     #include "wptGPG.h"
32    
33    
34     static LPMAPILOGON mapi_logon = NULL;
35     static LPMAPILOGOFF mapi_logoff = NULL;
36     static LPMAPISENDDOCUMENTS mapi_send_documents = NULL;
37     static LPMAPISENDMAIL mapi_send_mail = NULL;
38     static HINSTANCE hlib = NULL;
39     static int init = 0;
40    
41     #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)
42    
43    
44    
45     int
46     mapi_init (void)
47     {
48     if (init)
49     return 0;
50    
51     hlib = LoadLibrary ("MAPI32.DLL");
52     if (!hlib)
53     return -1;
54    
55     mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");
56     mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");
57     mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");
58     mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");
59     if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)
60     return -1;
61     init = 1;
62    
63     return 0;
64     } /* mapi_init */
65    
66    
67     void
68     mapi_deinit (void)
69     {
70     if (hlib) {
71     FreeLibrary (hlib);
72     hlib = NULL;
73     init = 0;
74     }
75     } /* mapi_deinit */
76    
77    
78     int
79     mapi_send_ascfile (char * ascfile)
80     {
81     LHANDLE hd;
82     int rc;
83    
84     if (!init)
85     return 0;
86    
87     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
88     if (rc != SUCCESS_SUCCESS) {
89     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
90     goto fail;
91     }
92     rc = mapi_send_documents (0, ";", ascfile, NULL, 0);
93     if (rc == MAPI_E_USER_ABORT)
94     rc = SUCCESS_SUCCESS;
95     if (rc != SUCCESS_SUCCESS)
96     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
97    
98     fail:
99     mapi_logoff (hd, 0, 0, 0);
100     return rc;
101     }
102    
103    
104     int
105     mapi_send_pubkey (const char * keyid, char * keyfile)
106     {
107     LHANDLE hd;
108     const char * fmt;
109     char * keyinf = NULL;
110     int rc;
111    
112     if (!init)
113     return 0;
114    
115     fmt = _("GPG Public Key of %s");
116     keyinf = new char[strlen (fmt) + strlen (keyid) + 2];
117     if (!keyinf)
118     BUG (0);
119     sprintf (keyinf, fmt, keyid);
120     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
121     if (rc != SUCCESS_SUCCESS) {
122     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
123     goto fail;
124     }
125     rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);
126     if (rc == MAPI_E_USER_ABORT)
127     rc = SUCCESS_SUCCESS;
128     if (rc != SUCCESS_SUCCESS)
129     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
130    
131     fail:
132     mapi_logoff (hd, 0, 0, 0);
133     free_if_alloc (keyinf);
134     return rc;
135     } /* mapi_send_pubkey */
136    
137    
138     static void
139     free_mapi_msg (MapiMessage * msg)
140     {
141     if (!msg)
142     return;
143     safe_free (msg->lpszSubject);
144     safe_free (msg->lpszNoteText);
145     safe_free (msg);
146     } /* free_mapi_msg */
147    
148    
149     static void
150     free_recip_tab (MapiRecipDesc * recip, size_t n)
151     {
152     size_t i;
153    
154     if (!recip)
155     return;
156     if (!n)
157     return;
158     for (i=0; i < n; i++)
159     safe_free (recip[i].lpszName);
160     safe_free (recip);
161     } /* free_recip_tab */
162    
163    
164     static void
165     free_files_tab (MapiFileDesc * files, size_t n)
166     {
167     size_t i;
168    
169     if (!files)
170     return;
171     if (!n)
172     return;
173     for (i=0; i < n; i++) {
174     safe_free (files[i].lpszFileName);
175     safe_free (files[i].lpszPathName);
176     }
177     safe_free (files);
178     } /* free_files_tab */
179    
180    
181    
182     static gpgme_recipients_t
183     conv_recipients (gpgme_recipients_t rset)
184     {
185     gpgme_recipients_t r;
186     gpgme_error_t rc;
187     void * ctx=NULL;
188     const char * s;
189    
190     /* we need to convert the recipients to email addresses so
191     GPG can handle them. */
192     rc = gpgme_recipients_new (&r);
193     if (rc)
194     return NULL;
195     gpgme_recipients_enum_open (rset, &ctx);
196    
197     while ((s=gpgme_recipients_enum_read (rset, &ctx))) {
198     char * p, * q, * buf;
199     if (!(p = strchr (s, '<')) || !(q = strchr (s, '>')))
200     continue;
201     buf = (char * )calloc (1, (q-s)-(p-s)+2);
202     strncpy (buf, s+(p-s)+1, (q-s)-(p-s)-1);
203     gpgme_recipients_add_name (r, buf);
204     safe_free (buf);
205     }
206     return r;
207     } /* conv_recipients */
208    
209    
210     static char *
211     secure_attachment (gpgme_recipients_t rset, const char * fname)
212     {
213     char tmpdir[512+32], * p;
214     gpgme_recipients_t addrs;
215     gpgme_ctx_t ctx;
216     gpgme_error_t rc;
217    
218     if (strlen (fname) > 200)
219     BUG (0);
220     GetTempPath (sizeof tmpdir-200, tmpdir);
221     p = strrchr (fname, '\\');
222     if (!p)
223     strcat (tmpdir, fname);
224     else
225     strcat (tmpdir, fname+(p-fname)+1);
226     strcat (tmpdir, ".asc");
227    
228     rc = gpgme_new (&ctx);
229     if (rc)
230     return NULL;
231     gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
232     gpgme_control (ctx, GPGME_CTRL_FORCETRUST, 1);
233     addrs = conv_recipients (rset);
234     if (!addrs) {
235     msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);
236     gpgme_release (NULL);
237     return NULL;
238     }
239     rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);
240     if (rc)
241     log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);
242     gpgme_recipients_release (addrs);
243     gpgme_release (ctx);
244     return strdup (tmpdir);
245     } /* secure_attachment */
246    
247    
248     static char *
249     secure_message (gpgme_recipients_t rset, const char * data)
250     {
251     gpgme_recipients_t addrs;
252     gpgme_error_t rc;
253     gpgme_data_t in, out;
254     gpgme_ctx_t ctx;
255     char * p;
256     size_t n=0;
257    
258     rc = gpgme_new (&ctx);
259     if (rc)
260     return NULL;
261     gpgme_control (ctx, GPGME_CTRL_ARMOR, 1);
262     gpgme_control (ctx, GPGME_CTRL_FORCETRUST, 1);
263    
264     addrs = conv_recipients (rset);
265     rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);
266     if (rc) {
267     gpgme_release (ctx);
268     return NULL;
269     }
270     gpgme_data_new (&out);
271    
272     rc = gpgme_op_encrypt (ctx, addrs, in, out);
273     if (rc)
274     log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");
275    
276     p = gpgme_data_release_and_return_string (out);
277    
278     gpgme_data_release (in);
279     gpgme_release (ctx);
280     gpgme_recipients_release (addrs);
281    
282     return p;
283     } /* secure_message */
284    
285    
286     int
287     mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,
288     const char * subject, const char ** files, size_t nfiles)
289     {
290     LHANDLE hd;
291     MapiMessage * msg;
292     MapiRecipDesc * recip;
293     MapiFileDesc * attch;
294     char * p;
295     const char * s;
296     void * ctx=NULL;
297     size_t n, i=0;
298     int rc;
299    
300     if (!init)
301     return 0;
302    
303     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
304     if (rc != SUCCESS_SUCCESS) {
305     MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
306     return rc;
307     }
308    
309     msg = (MapiMessage *)calloc (1, sizeof * msg);
310     p = msg->lpszSubject = strdup (subject);
311     if (!p)
312     BUG (0);
313     p = msg->lpszNoteText = secure_message (rset, msgtxt);
314     if (!p)
315     BUG (0);
316     n = msg->nRecipCount = gpgme_recipients_count (rset);
317     recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);
318    
319     gpgme_recipients_enum_open (rset, &ctx);
320     while ((s = gpgme_recipients_enum_read (rset, &ctx))) {
321     if (!i)
322     recip[i].ulRecipClass = MAPI_TO;
323     else
324     recip[i].ulRecipClass = MAPI_CC;
325     p = recip[i].lpszName = strdup (s);
326     if (!p)
327     BUG (0);
328     i++;
329     }
330     msg->lpRecips = recip;
331    
332     if (nfiles) {
333     msg->nFileCount = nfiles;
334     attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);
335     for (i=0; i < nfiles; i++) {
336     char * p = secure_attachment (rset, *files);
337     if (!p)
338     continue;
339     attch[i].lpszFileName = strdup (*files);
340     attch[i].lpszPathName = strdup (p);
341     files++;
342     safe_free (p);
343     }
344     msg->lpFiles = attch;
345     }
346    
347     rc = mapi_send_mail (hd, 0, msg, 0, 0);
348     if (rc == MAPI_E_USER_ABORT)
349     rc = SUCCESS_SUCCESS;
350     if (rc != SUCCESS_SUCCESS)
351     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
352    
353     free_recip_tab (recip, n);
354     free_files_tab (attch, nfiles);
355     free_mapi_msg (msg);
356     mapi_logoff (hd, 0, 0, 0);
357    
358     return 0;
359     } /* mapi_send_message */
360    
361    
362     static int
363     add_recipient (gpgme_recipients_t * r_rset, const char * addr)
364     {
365     gpgme_keycache_t pub = keycache_get_ctx (1);
366     gpgme_key_t key;
367     gpgme_error_t rc;
368     const char * s;
369    
370     if (!*r_rset)
371     gpgme_recipients_new (&(*r_rset));
372     rc = gpgme_keycache_find_key (pub, addr, 0, &key);
373     if (rc) {
374     log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);
375     return -1;
376     }
377     s = gpgme_key_get_string_attr (key, GPGME_ATTR_USERID, NULL, 0);
378     if (s)
379     gpgme_recipients_add_name (*r_rset, s);
380     return 0;
381     } /* add_recipient */
382    
383    
384     static int
385     add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)
386     {
387     char buf[1024], * p;
388     int n=0;
389    
390     n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);
391     if (!n)
392     return -1;
393     p = strtok (buf, ";,");
394     while (p != NULL) {
395     add_recipient (&*r_rset, p);
396     p = strtok (NULL, ";,");
397     }
398     return 0;
399     } /* add_all_recipients */
400    
401    
402     BOOL CALLBACK
403     winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
404     {
405     static gpgme_recipients_t rset=NULL;
406     char subject[128];
407     char * msgbuf;
408     int n;
409    
410     switch (msg) {
411     case WM_INITDIALOG:
412     center_window (dlg);
413     SetForegroundWindow (dlg);
414     break;
415    
416     case WM_COMMAND:
417     switch (LOWORD (wparam)) {
418     case IDOK:
419     add_all_recipients (dlg, IDC_PMAIL_TO, &rset);
420     add_all_recipients (dlg, IDC_PMAIL_CC, &rset);
421     if (!gpgme_recipients_count (rset)) {
422     msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);
423     return FALSE;
424     }
425     n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);
426     if (!n)
427     strcpy (subject, "");
428     n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);
429     if (!n) {
430     msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);
431     return FALSE;
432     }
433     msgbuf = (char * )calloc (1, n+2);
434     GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);
435     mapi_send_message (rset, msgbuf, subject, NULL, 0);
436     safe_free (msgbuf);
437     EndDialog (dlg, TRUE);
438     break;
439    
440     case IDCANCEL:
441     EndDialog (dlg, FALSE);
442     break;
443     }
444     break;
445     }
446    
447     return FALSE;
448     } /* winpt_mail_proc */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26