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

Annotation of /trunk/Src/wptMAPI.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File size: 11240 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

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     #include <windows.h>
21     #include <stdio.h>
22     #include <mapi.h>
23    
24     extern HINSTANCE glob_hinst;
25    
26     #include "../resource.h"
27     #include "wptTypes.h"
28     #include "wptErrors.h"
29     #include "wptW32API.h"
30     #include "wptGPG.h"
31    
32    
33     static LPMAPILOGON mapi_logon = NULL;
34     static LPMAPILOGOFF mapi_logoff = NULL;
35     static LPMAPISENDDOCUMENTS mapi_send_documents = NULL;
36     static LPMAPISENDMAIL mapi_send_mail = NULL;
37     static HINSTANCE hlib = NULL;
38     static int init = 0;
39    
40     #define load_one_fnc(cast, hlib, name) (cast)GetProcAddress ((hlib), name)
41    
42    
43     int
44     mapi_init (void)
45     {
46     if (init)
47     return 0;
48    
49     hlib = LoadLibrary ("MAPI32.DLL");
50     if (!hlib)
51     return -1;
52    
53     mapi_logon = load_one_fnc (LPMAPILOGON, hlib, "MAPILogon");
54     mapi_logoff = load_one_fnc (LPMAPILOGOFF, hlib, "MAPILogoff");
55     mapi_send_documents = load_one_fnc (LPMAPISENDDOCUMENTS, hlib, "MAPISendDocuments");
56     mapi_send_mail = load_one_fnc (LPMAPISENDMAIL, hlib, "MAPISendMail");
57     if (!mapi_logon || !mapi_logoff || !mapi_send_documents || !mapi_send_mail)
58     return -1;
59     init = 1;
60    
61     return 0;
62     } /* mapi_init */
63    
64    
65     void
66     mapi_deinit (void)
67     {
68     if (hlib) {
69     FreeLibrary (hlib);
70     hlib = NULL;
71     init = 0;
72     }
73     } /* mapi_deinit */
74    
75 twoaday 24 #if 0 /* low:priority XXX port the code */
76 twoaday 2 int
77 twoaday 23 mapi_send_ascfile (char *ascfile)
78 twoaday 2 {
79     LHANDLE hd;
80     int rc;
81    
82     if (!init)
83     return 0;
84    
85     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
86     if (rc != SUCCESS_SUCCESS) {
87     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
88     goto fail;
89     }
90     rc = mapi_send_documents (0, ";", ascfile, NULL, 0);
91     if (rc == MAPI_E_USER_ABORT)
92     rc = SUCCESS_SUCCESS;
93     if (rc != SUCCESS_SUCCESS)
94     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
95    
96     fail:
97     mapi_logoff (hd, 0, 0, 0);
98     return rc;
99     }
100    
101    
102     int
103 twoaday 23 mapi_send_pubkey (const char *keyid, char *keyfile)
104 twoaday 2 {
105     LHANDLE hd;
106     const char * fmt;
107     char * keyinf = NULL;
108     int rc;
109    
110     if (!init)
111     return 0;
112    
113     fmt = _("GPG Public Key of %s");
114     keyinf = new char[strlen (fmt) + strlen (keyid) + 2];
115     if (!keyinf)
116     BUG (0);
117     sprintf (keyinf, fmt, keyid);
118     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
119     if (rc != SUCCESS_SUCCESS) {
120     MessageBox (NULL, _("MAPI Login failed."), "MAPI", MB_ICONWARNING|MB_OK);
121     goto fail;
122     }
123     rc = mapi_send_documents (0, ";", keyfile, keyinf, 0);
124     if (rc == MAPI_E_USER_ABORT)
125     rc = SUCCESS_SUCCESS;
126     if (rc != SUCCESS_SUCCESS)
127     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ICONERROR|MB_OK);
128    
129     fail:
130     mapi_logoff (hd, 0, 0, 0);
131     free_if_alloc (keyinf);
132     return rc;
133     } /* mapi_send_pubkey */
134    
135    
136     static void
137     free_mapi_msg (MapiMessage * msg)
138     {
139     if (!msg)
140     return;
141     safe_free (msg->lpszSubject);
142     safe_free (msg->lpszNoteText);
143     safe_free (msg);
144     } /* free_mapi_msg */
145    
146    
147     static void
148 twoaday 23 free_recip_tab (MapiRecipDesc *recip, size_t n)
149 twoaday 2 {
150     size_t i;
151    
152     if (!recip)
153     return;
154     if (!n)
155     return;
156     for (i=0; i < n; i++)
157     safe_free (recip[i].lpszName);
158     safe_free (recip);
159     } /* free_recip_tab */
160    
161    
162     static void
163     free_files_tab (MapiFileDesc * files, size_t n)
164     {
165     size_t i;
166    
167     if (!files)
168     return;
169     if (!n)
170     return;
171     for (i=0; i < n; i++) {
172     safe_free (files[i].lpszFileName);
173     safe_free (files[i].lpszPathName);
174     }
175     safe_free (files);
176     } /* free_files_tab */
177    
178    
179    
180     static gpgme_recipients_t
181     conv_recipients (gpgme_recipients_t rset)
182     {
183     gpgme_recipients_t r;
184     gpgme_error_t rc;
185     void * ctx=NULL;
186     const char * s;
187    
188     /* we need to convert the recipients to email addresses so
189     GPG can handle them. */
190     rc = gpgme_recipients_new (&r);
191     if (rc)
192     return NULL;
193     gpgme_recipients_enum_open (rset, &ctx);
194    
195     while ((s=gpgme_recipients_enum_read (rset, &ctx))) {
196     char * p, * q, * buf;
197     if (!(p = strchr (s, '<')) || !(q = strchr (s, '>')))
198     continue;
199     buf = (char * )calloc (1, (q-s)-(p-s)+2);
200 twoaday 22 if (!buf)
201     BUG (0);
202 twoaday 2 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 twoaday 23 secure_attachment (gpgme_recipients_t rset, const char *fname)
212 twoaday 2 {
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 twoaday 23 gpgme_set_armor (ctx, 1);
232 twoaday 2 addrs = conv_recipients (rset);
233     if (!addrs) {
234     msg_box (NULL, _("No valid mail addresses found."), _("Secure Attachment"), MB_ERR);
235     gpgme_release (NULL);
236     return NULL;
237     }
238     rc = gpgme_op_file_encrypt (ctx, addrs, fname, tmpdir);
239     if (rc)
240     log_box (_("Secure Attachment"), MB_ERR, _("Could not encrypt '%s'"), fname);
241     gpgme_recipients_release (addrs);
242     gpgme_release (ctx);
243     return strdup (tmpdir);
244     } /* secure_attachment */
245    
246    
247 twoaday 25 static gpgme_error_t
248     secure_message (gpgme_recipients_t rset, const char *data,
249     char *enc_msg, size_t *r_enclen)
250 twoaday 2 {
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 twoaday 23 gpgme_set_armor (ctx, 1);
262 twoaday 2
263     addrs = conv_recipients (rset);
264     rc = gpgme_data_new_from_mem (&in, data, strlen (data), 1);
265     if (rc) {
266     gpgme_release (ctx);
267 twoaday 25 return rc;
268 twoaday 2 }
269     gpgme_data_new (&out);
270 twoaday 23 rc = gpgme_op_encrypt (ctx, addrs, GPGME_ENCRYPT_ALWAYS_TRUST, in, out);
271 twoaday 2 if (rc)
272     log_box (_("Secure Message"), MB_ERR, "Could not encrypt the data");
273    
274 twoaday 25 *r_enc_msg = gpgme_data_release_and_get_mem (&n);
275     *r_enclen = n;
276 twoaday 2
277     gpgme_data_release (in);
278     gpgme_release (ctx);
279     gpgme_recipients_release (addrs);
280    
281 twoaday 25 return rc;
282 twoaday 2 } /* secure_message */
283    
284    
285     int
286     mapi_send_message (gpgme_recipients_t rset, const char * msgtxt,
287 twoaday 23 const char * subject, const char **files, size_t nfiles)
288 twoaday 2 {
289     LHANDLE hd;
290     MapiMessage * msg;
291     MapiRecipDesc * recip;
292     MapiFileDesc * attch;
293     char * p;
294     const char * s;
295     void * ctx=NULL;
296 twoaday 25 size_t n, i=0, encmsg_len=0;
297 twoaday 2 int rc;
298    
299     if (!init)
300     return 0;
301    
302     rc = mapi_logon (0, NULL, NULL, MAPI_LOGON_UI, 0, &hd);
303     if (rc != SUCCESS_SUCCESS) {
304     MessageBox (NULL, "MAPI Login failed.", "MAPI", MB_ICONWARNING|MB_OK);
305     return rc;
306     }
307    
308     msg = (MapiMessage *)calloc (1, sizeof * msg);
309 twoaday 22 if (!msg)
310     BUG (0);
311 twoaday 2 p = msg->lpszSubject = strdup (subject);
312     if (!p)
313     BUG (0);
314 twoaday 25 p = msg->lpszNoteText = secure_message (rset, msgtxt, &p, &encmsg_len);
315 twoaday 2 if (!p)
316     BUG (0);
317     n = msg->nRecipCount = gpgme_recipients_count (rset);
318     recip = (MapiRecipDesc *)calloc (n+1, sizeof * recip);
319 twoaday 22 if (!recip)
320     BUG (0);
321 twoaday 2
322     gpgme_recipients_enum_open (rset, &ctx);
323     while ((s = gpgme_recipients_enum_read (rset, &ctx))) {
324     if (!i)
325     recip[i].ulRecipClass = MAPI_TO;
326     else
327     recip[i].ulRecipClass = MAPI_CC;
328     p = recip[i].lpszName = strdup (s);
329     if (!p)
330     BUG (0);
331     i++;
332     }
333     msg->lpRecips = recip;
334    
335     if (nfiles) {
336     msg->nFileCount = nfiles;
337     attch = (MapiFileDesc *)calloc (nfiles+1, sizeof * attch);
338 twoaday 22 if (!attch)
339     BUG (0);
340 twoaday 2 for (i=0; i < nfiles; i++) {
341     char * p = secure_attachment (rset, *files);
342     if (!p)
343     continue;
344     attch[i].lpszFileName = strdup (*files);
345     attch[i].lpszPathName = strdup (p);
346     files++;
347     safe_free (p);
348     }
349     msg->lpFiles = attch;
350     }
351    
352     rc = mapi_send_mail (hd, 0, msg, 0, 0);
353     if (rc == MAPI_E_USER_ABORT)
354     rc = SUCCESS_SUCCESS;
355     if (rc != SUCCESS_SUCCESS)
356     MessageBox (NULL, _("Could not sent mail."), "MAPI", MB_ERR);
357    
358     free_recip_tab (recip, n);
359     free_files_tab (attch, nfiles);
360     free_mapi_msg (msg);
361     mapi_logoff (hd, 0, 0, 0);
362    
363     return 0;
364     } /* mapi_send_message */
365    
366    
367     static int
368     add_recipient (gpgme_recipients_t * r_rset, const char * addr)
369     {
370 twoaday 25 gpg_keycache_t pub = keycache_get_ctx (1);
371 twoaday 2 gpgme_key_t key;
372     gpgme_error_t rc;
373     const char * s;
374    
375     if (!*r_rset)
376     gpgme_recipients_new (&(*r_rset));
377     rc = gpgme_keycache_find_key (pub, addr, 0, &key);
378     if (rc) {
379     log_box (_("Add Recipient"), MB_ERR, _("Could not find key for '%s'"), addr);
380     return -1;
381     }
382 twoaday 23 s = key->uids->uid;
383 twoaday 2 if (s)
384     gpgme_recipients_add_name (*r_rset, s);
385     return 0;
386     } /* add_recipient */
387    
388    
389     static int
390     add_all_recipients (HWND dlg, int itemid, gpgme_recipients_t * r_rset)
391     {
392     char buf[1024], * p;
393     int n=0;
394    
395     n = GetDlgItemText (dlg, itemid, buf, sizeof buf-10);
396     if (!n)
397     return -1;
398     p = strtok (buf, ";,");
399     while (p != NULL) {
400     add_recipient (&*r_rset, p);
401     p = strtok (NULL, ";,");
402     }
403     return 0;
404     } /* add_all_recipients */
405    
406    
407     BOOL CALLBACK
408     winpt_mail_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
409     {
410     static gpgme_recipients_t rset=NULL;
411     char subject[128];
412     char * msgbuf;
413     int n;
414    
415     switch (msg) {
416     case WM_INITDIALOG:
417 twoaday 23 center_window (dlg, NULL);
418 twoaday 2 SetForegroundWindow (dlg);
419     break;
420    
421     case WM_COMMAND:
422     switch (LOWORD (wparam)) {
423     case IDOK:
424     add_all_recipients (dlg, IDC_PMAIL_TO, &rset);
425     add_all_recipients (dlg, IDC_PMAIL_CC, &rset);
426     if (!gpgme_recipients_count (rset)) {
427     msg_box (dlg, _("Please enter a recipient."), _("Mail"), MB_ERR);
428     return FALSE;
429     }
430     n=GetDlgItemText (dlg, IDC_PMAIL_SUBJECT, subject, sizeof subject-1);
431     if (!n)
432     strcpy (subject, "");
433     n = SendDlgItemMessage (dlg, IDC_PMAIL_MSG, WM_GETTEXTLENGTH, 0, 0);
434     if (!n) {
435     msg_box (dlg, _("Please enter a message."), _("Mail"), MB_ERR);
436     return FALSE;
437     }
438     msgbuf = (char * )calloc (1, n+2);
439 twoaday 22 if (!msgbuf)
440     BUG (0);
441 twoaday 2 GetDlgItemText (dlg, IDC_PMAIL_MSG, msgbuf, n+1);
442     mapi_send_message (rset, msgbuf, subject, NULL, 0);
443     safe_free (msgbuf);
444     EndDialog (dlg, TRUE);
445     break;
446    
447     case IDCANCEL:
448     EndDialog (dlg, FALSE);
449     break;
450     }
451     break;
452     }
453    
454     return FALSE;
455     } /* winpt_mail_proc */
456 twoaday 23 #endif

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26