Enable building tests for windows
[gpgol.git] / src / main.c
1 /* main.c - DLL entry point
2  * Copyright (C) 2005, 2007, 2008 g10 Code GmbH
3  *
4  * This file is part of GpgOL.
5  *
6  * GpgOL is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1
9  * of the License, or (at your option) any later version.
10  *
11  * GpgOL 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 GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21
22 #include <windows.h>
23 #include <wincrypt.h>
24 #include <ctype.h>
25 #include <winnls.h>
26 #include <unistd.h>
27
28 #include "mymapi.h"
29 #include "mymapitags.h"
30
31 #include "common.h"
32 #include "mymapi.h"
33
34 /* Local function prototypes. */
35 static char *get_locale_dir (void);
36 static void drop_locale_dir (char *locale_dir);
37
38 /* The major version of Outlook we are attached to */
39 int g_ol_version_major;
40
41
42 void
43 i18n_init (void)
44 {
45   char *locale_dir;
46
47 #ifdef ENABLE_NLS
48 # ifdef HAVE_LC_MESSAGES
49   setlocale (LC_TIME, "");
50   setlocale (LC_MESSAGES, "");
51 # else
52   setlocale (LC_ALL, "" );
53 # endif
54 #endif
55
56   locale_dir = get_locale_dir ();
57   if (locale_dir)
58     {
59       bindtextdomain (PACKAGE_GT, locale_dir);
60       drop_locale_dir (locale_dir);
61     }
62   textdomain (PACKAGE_GT);
63 }
64
65 static char *
66 get_gpgme_w32_inst_dir (void)
67 {
68   char *gpg4win_dir = get_gpg4win_dir ();
69   char *tmp;
70   gpgrt_asprintf (&tmp, "%s\\bin\\gpgme-w32spawn.exe", gpg4win_dir);
71   memdbg_alloc (tmp);
72
73   if (!access(tmp, R_OK))
74     {
75       xfree (tmp);
76       gpgrt_asprintf (&tmp, "%s\\bin", gpg4win_dir);
77       memdbg_alloc (tmp);
78       xfree (gpg4win_dir);
79       return tmp;
80     }
81   xfree (tmp);
82   gpgrt_asprintf (&tmp, "%s\\gpgme-w32spawn.exe", gpg4win_dir);
83   memdbg_alloc (tmp);
84
85   if (!access(tmp, R_OK))
86     {
87       xfree (tmp);
88       return gpg4win_dir;
89     }
90   OutputDebugString("Failed to find gpgme-w32spawn.exe!");
91   return NULL;
92 }
93
94 /* Entry point called by DLL loader. */
95 int WINAPI
96 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
97 {
98   (void)reserved;
99
100   if (reason == DLL_PROCESS_ATTACH)
101     {
102       set_global_hinstance (hinst);
103
104       gpg_err_init ();
105
106       /* Set the installation directory for GpgME so that
107          it can find tools like gpgme-w32-spawn correctly. */
108       char *instdir = get_gpgme_w32_inst_dir();
109       gpgme_set_global_flag ("w32-inst-dir", instdir);
110       xfree (instdir);
111
112       /* The next call initializes subsystems of gpgme and should be
113          done as early as possible.  The actual return value (the
114          version string) is not used here.  It may be called at any
115          time later for this. */
116       gpgme_check_version (NULL);
117     }
118   else if (reason == DLL_PROCESS_DETACH)
119     {
120       gpg_err_deinit (0);
121     }
122
123   return TRUE;
124 }
125
126 static char *
127 get_locale_dir (void)
128 {
129   char *instdir;
130   char *p;
131   char *dname;
132
133   instdir = get_gpg4win_dir();
134   if (!instdir)
135     return NULL;
136
137   /* Build the key: "<instdir>/share/locale".  */
138 #define SLDIR "\\share\\locale"
139   dname = xmalloc (strlen (instdir) + strlen (SLDIR) + 1);
140   if (!dname)
141     {
142       xfree (instdir);
143       return NULL;
144     }
145   p = dname;
146   strcpy (p, instdir);
147   p += strlen (instdir);
148   strcpy (p, SLDIR);
149
150   xfree (instdir);
151
152   return dname;
153 }
154
155
156 static void
157 drop_locale_dir (char *locale_dir)
158 {
159   xfree (locale_dir);
160 }
161
162
163 static int
164 get_conf_bool (const char *name, int defaultVal)
165 {
166   char *val = NULL;
167   int ret;
168   load_extension_value (name, &val);
169   ret = val == NULL ? defaultVal : *val != '1' ? 0 : 1;
170   xfree (val);
171   return ret;
172 }
173
174 static int
175 dbg_compat (int oldval)
176 {
177   // We broke the debug levels at some point
178   // This is cmpatibility code with the old
179   // levels.
180
181 #define DBG_MEMORY_OLD     (1<<5) // 32
182 #define DBG_MIME_PARSER_OLD (1<<7) // 128 Unified as DBG_DATA
183 #define DBG_MIME_DATA_OLD   (1<<8) // 256 Unified in read_options
184 #define DBG_OOM_OLD        (1<<9) // 512 Unified as DBG_OOM
185 #define DBG_OOM_EXTRA_OLD  (1<<10)// 1024 Unified in read_options
186   int new_dbg = oldval;
187   if ((oldval & DBG_MEMORY_OLD))
188     {
189       new_dbg |= DBG_MEMORY;
190       new_dbg -= DBG_MEMORY_OLD;
191     }
192   if ((oldval & DBG_OOM_OLD))
193     {
194       new_dbg |= DBG_OOM;
195       new_dbg -= DBG_OOM_OLD;
196     }
197   if ((oldval & DBG_MIME_PARSER_OLD))
198     {
199       new_dbg |= DBG_DATA;
200       new_dbg -= DBG_MIME_PARSER_OLD;
201     }
202   if ((oldval & DBG_MIME_DATA_OLD))
203     {
204       new_dbg |= DBG_DATA;
205       new_dbg -= DBG_MIME_DATA_OLD;
206     }
207   if ((oldval & DBG_OOM_OLD))
208     {
209       new_dbg |= DBG_OOM;
210       new_dbg -= DBG_OOM_OLD;
211     }
212   if ((oldval & DBG_OOM_EXTRA_OLD))
213     {
214       new_dbg |= DBG_OOM;
215       new_dbg -= DBG_OOM_EXTRA_OLD;
216     }
217 #undef DBG_MEMORY_OLD
218 #undef DBG_MIME_PARSER_OLD
219 #undef DBG_MIME_DATA_OLD
220 #undef DBG_OOM_OLD
221 #undef DBG_OOM_EXTRA_OLD
222   return new_dbg;
223 }
224
225 /* Read option settings from the Registry. */
226 void
227 read_options (void)
228 {
229   char *val = NULL;
230
231   /* Set the log file first so that output from this function is
232      logged too.  */
233   load_extension_value ("logFile", &val);
234   set_log_file (val);
235   xfree (val); val = NULL;
236
237   /* Parse the debug flags.  */
238   load_extension_value ("enableDebug", &val);
239   opt.enable_debug = 0;
240   if (val)
241     {
242       char *p, *pend;
243
244       trim_spaces (val);
245       for (p = val; p; p = pend)
246         {
247           pend = strpbrk (p, ", \t\n\r\f");
248           if (pend)
249             {
250               *pend++ = 0;
251               pend += strspn (pend, ", \t\n\r\f");
252             }
253           if (isascii (*p) && isdigit (*p))
254             {
255               opt.enable_debug |= dbg_compat (strtoul (p, NULL, 0));
256
257             }
258           else if (!strcmp (p, "memory"))
259             opt.enable_debug |= DBG_MEMORY;
260           else if (!strcmp (p, "mime-parser"))
261             opt.enable_debug |= DBG_DATA;
262           else if (!strcmp (p, "mime-data"))
263             opt.enable_debug |= DBG_DATA;
264           else if (!strcmp (p, "oom"))
265             opt.enable_debug |= DBG_OOM;
266           else if (!strcmp (p, "oom-extra"))
267             opt.enable_debug |= DBG_OOM;
268           else
269             log_debug ("invalid debug flag `%s' ignored", p);
270         }
271     }
272   else
273     {
274       /* To help the user enable debugging make sure that the registry
275          key exists.  Note that the other registry keys are stored
276          after using the configuration dialog.  */
277       store_extension_value ("enableDebug", "0");
278     }
279   /* Yes we use free here because memtracing did not track the alloc
280      as the option for debuging was not read before. */
281   free (val); val = NULL;
282   if (opt.enable_debug)
283     log_debug ("enabled debug flags:%s%s%s\n",
284                (opt.enable_debug & DBG_MEMORY)? " memory":"",
285                (opt.enable_debug & DBG_DATA)? " data":"",
286                (opt.enable_debug & DBG_OOM)? " oom":""
287                );
288
289   opt.enable_smime = get_conf_bool ("enableSmime", 0);
290   opt.encrypt_default = get_conf_bool ("encryptDefault", 0);
291   opt.sign_default = get_conf_bool ("signDefault", 0);
292   opt.inline_pgp = get_conf_bool ("inlinePGP", 0);
293   opt.reply_crypt = get_conf_bool ("replyCrypt", 1);
294   opt.prefer_smime = get_conf_bool ("preferSmime", 0);
295   opt.autoresolve = get_conf_bool ("autoresolve", 1);
296   opt.autoretrieve = get_conf_bool ("autoretrieve", 0);
297   opt.automation = get_conf_bool ("automation", 1);
298   opt.autosecure = get_conf_bool ("autosecure", 1);
299   opt.autotrust = get_conf_bool ("autotrust", 0);
300   opt.search_smime_servers = get_conf_bool ("searchSmimeServers", 0);
301   opt.smime_html_warn_shown = get_conf_bool ("smimeHtmlWarnShown", 0);
302
303   if (!opt.automation)
304     {
305       // Disabling automation is a shorthand to disable the
306       // others, too.
307       opt.autosecure = 0;
308       opt.autoresolve = 0;
309       opt.autotrust = 0;
310       opt.autoretrieve = 0;
311     }
312
313   /* Hidden options  */
314   opt.sync_enc = get_conf_bool ("syncEnc", 0);
315   opt.sync_dec = get_conf_bool ("syncDec", 0);
316 }
317
318
319 /* Write current options back to the Registry. */
320 int
321 write_options (void)
322 {
323   struct
324   {
325     const char *name;
326     int  mode;
327     int  value;
328     char *s_val;
329   } table[] = {
330     {"smimeHtmlWarnShown",       0, opt.smime_html_warn_shown, NULL},
331     {NULL, 0, 0, NULL}
332   };
333   char buf[32];
334   int rc, i;
335   const char *string;
336
337   for (i=0; table[i].name; i++)
338     {
339       switch (table[i].mode)
340         {
341         case 0:
342           string = table[i].value? "1": "0";
343           log_debug ("storing option `%s' value=`%s'\n",
344                      table[i].name, string);
345           rc = store_extension_value (table[i].name, string);
346           break;
347         case 1:
348           sprintf (buf, "%d", table[i].value);
349           log_debug ("storing option `%s' value=`%s'\n",
350                      table[i].name, buf);
351           rc = store_extension_value (table[i].name, buf);
352           break;
353         case 2:
354           string = table[i].s_val? table[i].s_val : "";
355           log_debug ("storing option `%s' value=`%s'\n",
356                      table[i].name, string);
357           rc = store_extension_value (table[i].name, string);
358           break;
359 /*         case 3: */
360 /*           buf[0] = '0'; */
361 /*           buf[1] = 0; */
362 /*           switch (opt.default_protocol) */
363 /*             { */
364 /*             case PROTOCOL_UNKNOWN: buf[0] = '0'; /\* auto *\/ break; */
365 /*             case PROTOCOL_OPENPGP: buf[0] = '1'; break; */
366 /*             case PROTOCOL_SMIME:   buf[0] = '2'; break; */
367 /*             } */
368 /*           log_debug ("storing option `%s' value=`%s'\n", */
369 /*                      table[i].name, buf); */
370 /*           rc = store_extension_value (table[i].name, buf); */
371 /*           break;   */
372
373         case 4:
374           sprintf (buf, "0x%x", table[i].value);
375           log_debug ("storing option `%s' value=`%s'\n",
376                      table[i].name, buf);
377           rc = store_extension_value (table[i].name, buf);
378           break;
379
380         default:
381           rc = -1;
382           break;
383         }
384       if (rc)
385         log_error ("error storing option `%s': rc = %d\n", table[i].name, rc);
386     }
387
388   return 0;
389 }