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

Contents of /trunk/Src/wptRegistry.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 273 - (show annotations)
Fri Dec 8 10:22:17 2006 UTC (18 years, 2 months ago) by twoaday
File size: 17176 byte(s)


1 /* wptRegistry.cpp - Windows Registry access
2 * Copyright (C) 2000-2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (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 GNU
14 * 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 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 /* For the case WinPT will be compiled in mobile mode, we use a wrapper
25 to avoid registry access (read, write) and thus this file will not
26 be used. */
27 #ifndef WINPT_MOBILE
28 #include <windows.h>
29 #include <stdio.h>
30
31 #include "wptErrors.h"
32 #include "wptW32API.h"
33 #include "wptGPG.h"
34 #include "wptRegistry.h"
35 #include "wptKeyserver.h"
36 #include "wptTypes.h"
37 #include "wptNLS.h"
38 #include "wptVersion.h"
39 #include "wptHotkey.h"
40
41 #define rc_ok(rc) ((rc) == ERROR_SUCCESS)
42
43 /* WinPT registry path. */
44 #define WINPT_REG "Software\\WinPT"
45
46 /* GPG registry path. */
47 #define GPG_REG "Software\\GNU\\GnuPG"
48
49 #define GPG_MO_REG "Control Panel\\MingW32\\NLS"
50
51 /* GPG file association context. */
52 struct gpg_filetype_s {
53 const char *descr; /* description. */
54 const char *ext; /* extension. */
55 int nicon; /* number of the image icon. */
56 };
57 typedef struct gpg_filetype_s *gpg_filetype_t;
58
59 /* Global WinPT registry prefereneces. */
60 struct winpt_prefs_s reg_prefs;
61
62
63 /* Return != 0 if GPG4win is installed. */
64 int
65 is_gpg4win_installed (void)
66 {
67 char *p;
68
69 p = get_reg_entry_gpg4win (NULL);
70 if (!p)
71 return 0;
72 if (dir_exist_check (p)) {
73 free_if_alloc (p);
74 return 0;
75 }
76 free_if_alloc (p);
77 return -1;
78 }
79
80
81 /* Return != 0 if GPGee is installed. */
82 static int
83 is_gpgee_installed (void)
84 {
85 HKEY hk;
86 LONG ec;
87
88 ec = RegOpenKeyEx (HKEY_CURRENT_USER, "Software\\GPGee", 0, KEY_READ, &hk);
89 if (ec == ERROR_SUCCESS) {
90 RegCloseKey (hk);
91 return -1;
92 }
93
94 return 0;
95 }
96
97
98 /* Free all members in the registry preference struct. */
99 void
100 free_reg_prefs (void)
101 {
102 free_if_alloc (reg_prefs.backup.path);
103 free_if_alloc (reg_prefs.kserv_conf);
104 free_if_alloc (reg_prefs.homedir);
105 memset (&reg_prefs, 0, sizeof reg_prefs);
106 }
107
108
109
110 /* Install the GPG related into the W32 resgistry, if the entry already
111 exists the function returns immediately. */
112 int
113 regist_inst_gnupg (int create_mokey)
114 {
115 int rc;
116 HKEY reg;
117
118 rc = RegOpenKeyEx (HKEY_CURRENT_USER, GPG_REG, 0, KEY_READ, &reg);
119 if (rc == ERROR_SUCCESS) {
120 RegCloseKey (reg);
121 return 0;
122 }
123 rc = RegCreateKey (HKEY_CURRENT_USER, GPG_REG, &reg);
124 if (rc != ERROR_SUCCESS)
125 return WPTERR_REGISTRY;
126 RegCloseKey (reg);
127
128 if (!create_mokey)
129 return 0;
130
131 rc = RegOpenKeyEx (HKEY_CURRENT_USER, GPG_MO_REG, 0, KEY_READ, &reg);
132 if (rc == ERROR_SUCCESS) {
133 RegCloseKey (reg);
134 return 0;
135 }
136 rc = RegCreateKey (HKEY_CURRENT_USER, GPG_MO_REG, &reg);
137 if (rc != ERROR_SUCCESS)
138 return WPTERR_REGISTRY;
139
140 RegCloseKey (reg);
141 return 0;
142 }
143
144
145 /* Create a new filetype in the W32 registry.
146 We should really care of errors! Otherwise we can damage the registry! */
147 static int
148 create_file_type (const char *exefile, const char *ext,
149 const char *extname, char *iconfile)
150 {
151 HKEY reg = NULL;
152 char deficon[MAX_PATH+1];
153 char defexec[MAX_PATH+1];
154 char p_exefile[MAX_PATH+1];
155 int rc;
156
157 rc = RegCreateKey (HKEY_CLASSES_ROOT, ext, &reg);
158 if( rc_ok( rc ) )
159 rc = RegSetValueEx( reg, NULL, 0, REG_SZ, (BYTE *)extname, strlen( extname ) );
160 if( rc_ok( rc ) )
161 rc = RegCloseKey( reg );
162 if( rc_ok( rc ) )
163 rc = RegCreateKey( HKEY_CLASSES_ROOT, extname, &reg );
164 if( rc_ok( rc ) )
165 rc = RegSetValueEx( reg, NULL, 0, REG_SZ, (BYTE *) extname, strlen( extname ) );
166 if( rc_ok( rc ) )
167 rc = RegCloseKey( reg );
168 if( !rc_ok( rc ) ) {
169 rc = WPTERR_REGISTRY;
170 goto leave;
171 }
172
173 memset( &deficon, 0, sizeof deficon );
174 _snprintf( deficon, sizeof deficon - 1, "%s\\DefaultIcon", extname );
175 memset( &defexec, 0, sizeof defexec );
176 _snprintf( defexec, sizeof defexec - 1, "%s\\shell\\open\\command", extname );
177 memset( &p_exefile, 0, sizeof p_exefile );
178 _snprintf( p_exefile, sizeof p_exefile - 1, "%s %%1", exefile );
179
180 rc = RegCreateKey( HKEY_CLASSES_ROOT, deficon, &reg );
181 if( rc_ok( rc ) )
182 rc = RegSetValueEx(reg, NULL, 0, REG_SZ, (BYTE *)iconfile, strlen( iconfile ) );
183 if( rc_ok( rc ) )
184 rc = RegCloseKey( reg );
185 if( rc_ok( rc ) )
186 rc = RegCreateKey( HKEY_CLASSES_ROOT, defexec, &reg );
187 if( rc_ok( rc ) )
188 rc = RegSetValueEx( reg, NULL, 0, REG_SZ, (BYTE *)p_exefile, strlen( exefile ) );
189 if( rc_ok( rc ) )
190 rc = RegCloseKey( reg );
191 if( !rc_ok( rc ) ) {
192 rc = WPTERR_REGISTRY;
193 goto leave;
194 }
195
196 leave:
197 if (reg)
198 RegCloseKey (reg);
199 return rc;
200 }
201
202
203 /* Register the given WinPT filetype. */
204 static int
205 regist_single_filetype (gpg_filetype_t gfile)
206 {
207 char icon[MAX_PATH+1] = {0};
208 char prog[MAX_PATH+1] = {0};
209
210 if (!GetModuleFileName (glob_hinst, prog, sizeof (prog)-1))
211 return WPTERR_REGISTRY;
212 _snprintf (icon, sizeof (icon) -1, "%s,%d", prog, gfile->nicon);
213 return create_file_type (prog, gfile->ext, gfile->descr, icon);
214 }
215
216 /* Install WinPT into the W32 registry, if the entry already
217 exists the function returns immediately. @with_ext can be
218 used to register some file types (if 1). @created contains
219 1 if the registry key was created.
220 Return value: 0 on success. */
221 int
222 regist_inst_winpt (int with_ext, int *created)
223 {
224 struct gpg_filetype_s gpg_filetypes[] = {
225 {_("GPG Detached Signature"), ".sig", 1},
226 {_("GPG Encrypted Data"), ".gpg", 2},
227 {_("GPG Armored Data"), ".asc", 2},
228 {0}
229 };
230 HKEY reg;
231 char *p = NULL;
232 char modpath[MAX_PATH+1];
233 int rc, i, id, n;
234
235 if (created)
236 *created = 0;
237
238 /* If GPGee is already installed deactivate file extension registering
239 because it is very likely this would overwrite the GPGee settings. */
240 if (is_gpgee_installed ())
241 with_ext = 0;
242
243 rc = RegOpenKeyEx (HKEY_CURRENT_USER, WINPT_REG, 0, KEY_READ, &reg);
244 if (rc == ERROR_SUCCESS) {
245 RegCloseKey (reg);
246 rc = RegOpenKeyEx (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", 0, KEY_READ, &reg);
247 if (rc != ERROR_SUCCESS) {
248 rc = RegCreateKey (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", &reg);
249 if (rc == ERROR_SUCCESS)
250 RegCloseKey (reg);
251 }
252 else
253 RegCloseKey (reg);
254 p = get_reg_entry_keyserver ("Default");
255 if (!p) {
256 char buf[16];
257
258 _snprintf (buf, DIM (buf)-1, "%d", HKP_PORT);
259 set_reg_entry_keyserver ("Default_Port", buf);
260 set_reg_entry_keyserver ("Default", DEF_HKP_KEYSERVER);
261 }
262 free_if_alloc (p);
263 return 0;
264 }
265 rc = RegCreateKey (HKEY_CURRENT_USER, WINPT_REG, &reg);
266 if (rc != ERROR_SUCCESS)
267 return WPTERR_REGISTRY;
268 if (created)
269 *created = 1;
270 RegCloseKey (reg);
271 if (with_ext) {
272 id = msg_box (NULL, _("WinPT can register some GPG file types for you so they can "
273 "be processed with a double click in the explorer.\n"
274 "Do you want to continue?"), _("WinPT"), MB_YESNO|MB_INFO);
275 if (id == IDYES) {
276 for (i = 0; gpg_filetypes[i].ext; i++) {
277 rc = RegOpenKeyEx (HKEY_CLASSES_ROOT, gpg_filetypes[i].ext, 0, KEY_READ, &reg);
278 if (rc == ERROR_SUCCESS) {
279 RegCloseKey (reg);
280 id = log_box (_("WinPT WARNING"), MB_YESNO|MB_INFO,
281 _("It seems there was already a '%s' file type registered by another application.\n"
282 "Do you want to overwrite it?"), gpg_filetypes[i].ext);
283 if (id == IDNO)
284 continue;
285 }
286 regist_single_filetype (&gpg_filetypes[i]);
287 }
288 }
289 }
290 /* Store the install directory for later use. */
291 if ((n=GetModuleFileName (NULL, modpath, MAX_PATH-1)) > 0) {
292 while (n-- > 0) {
293 if (modpath[n] == '\\') {
294 modpath[n] = 0;
295 break;
296 }
297 }
298 set_reg_entry (HKEY_CURRENT_USER, WINPT_REG, "Install Directory", modpath);
299 }
300 return 0;
301 }
302
303
304 /* Expand a string with %foo% entries so that %foo% will
305 be replaced with its actual value. */
306 static char*
307 expand_path (const char *path)
308 {
309 DWORD len;
310 char *p;
311
312 len = ExpandEnvironmentStrings (path, NULL, 0);
313 if (!len)
314 return NULL;
315 len += 1;
316 p = new char[len+1];
317 if (!p)
318 return NULL;
319 len = ExpandEnvironmentStrings (path, p, len);
320 if (!len) {
321 free_if_alloc (p);
322 return NULL;
323 }
324 return p;
325 }
326
327
328 /* Retrieve a registry entry with the directory given in @dir
329 and the key given in @key.
330 Return value is the value or NULL otherwise. */
331 char*
332 get_reg_entry (HKEY root_key, const char *dir, const char *key)
333 {
334 HKEY reg_key = NULL;
335 char *p = NULL, *pp;
336 DWORD type = REG_SZ, nbytes = 0;
337 int rc;
338
339 rc = RegOpenKeyEx (root_key, dir, 0, KEY_QUERY_VALUE, &reg_key);
340 if (rc != ERROR_SUCCESS)
341 goto leave;
342 rc = RegQueryValueEx (reg_key, key, NULL, &type, NULL, &nbytes);
343 if (rc != ERROR_SUCCESS)
344 goto leave;
345 if (!nbytes)
346 goto leave; /* empty */
347 p = new char[nbytes+1];
348 if (!p)
349 BUG (0);
350 rc = RegQueryValueEx (reg_key, key, NULL, &type, (BYTE*)p, &nbytes);
351 if (rc != ERROR_SUCCESS)
352 goto leave;
353 if (type == REG_EXPAND_SZ && strchr (p, '%')) {
354 pp = p;
355 p = expand_path (pp);
356 free_if_alloc (pp);
357 }
358
359 leave:
360 if (reg_key != NULL)
361 RegCloseKey (reg_key);
362 return p;
363 }
364
365
366 /* XXX: use REG_EXPAND_SZ to support multi user environments.
367 keep this type and do not overwrite it with REG_SZ. */
368
369 /* Set a registry entry. */
370 int
371 set_reg_entry (HKEY root_key, const char *dir, const char *key,
372 const char *value)
373 {
374 HKEY reg_key;
375 int rc;
376
377 rc = RegOpenKeyEx (root_key, dir, 0, KEY_WRITE, &reg_key);
378 if (rc != ERROR_SUCCESS)
379 return WPTERR_REGISTRY;
380 rc = RegSetValueEx (reg_key, key, 0, REG_SZ, (BYTE *)value, strlen (value));
381 if (rc != ERROR_SUCCESS)
382 rc = WPTERR_REGISTRY;
383 RegCloseKey (reg_key);
384 return rc;
385 }
386
387
388 int
389 set_reg_key (HKEY root_key, const char *dir, const char *key,
390 const char *value)
391 {
392 HKEY reg_key;
393 int rc;
394
395 rc = RegOpenKeyEx (root_key, dir, 0, KEY_WRITE, &reg_key);
396 if (rc != ERROR_SUCCESS)
397 return WPTERR_REGISTRY;
398
399 rc = RegSetValueEx (reg_key, key, 0, REG_SZ, (BYTE *)value, strlen (value));
400 if (rc != ERROR_SUCCESS) {
401 if (RegCreateKey (root_key, key, &reg_key) != ERROR_SUCCESS) {
402 rc = WPTERR_REGISTRY;
403 goto leave;
404 }
405 rc = RegSetValueEx (reg_key, key, 0, REG_SZ, (BYTE *)value, strlen (value));
406 if (rc != ERROR_SUCCESS)
407 rc = WPTERR_REGISTRY;
408 }
409
410 leave:
411 RegCloseKey (reg_key);
412 return rc;
413 }
414
415
416 int
417 set_reg_entry_gpg (const char *key, const char *value)
418 {
419 return set_reg_entry (HKEY_CURRENT_USER, GPG_REG, key, value);
420 }
421
422
423 int
424 set_reg_entry_mo (const char *value)
425 {
426 return set_reg_entry (HKEY_CURRENT_USER, GPG_MO_REG, "MODir", value);
427 }
428
429
430 char*
431 get_reg_entry_gpg (const char *key)
432 {
433 char *p;
434
435 p = get_reg_entry (HKEY_CURRENT_USER, GPG_REG, key);
436 if (!p || strlen (p) == 0) {
437 free_if_alloc (p);
438 return NULL;
439 }
440 return p;
441 }
442
443
444 /* Return if possible the GPG4Win installation directory concatenated
445 with the string in @path if given. */
446 char*
447 get_reg_entry_gpg4win (const char *path)
448 {
449 const char *fmt;
450 char *p, *pp;
451
452 p = get_reg_entry (HKEY_LOCAL_MACHINE, GPG_REG, "Install Directory");
453 if (!p)
454 return NULL;
455 if (!path)
456 return p;
457 fmt = "%s\\%s";
458 pp = new char[strlen (p) + strlen (path) + strlen (fmt) + 1];
459 if (!pp)
460 BUG (NULL);
461 sprintf (pp, fmt, p, path);
462 free_if_alloc (p);
463 return pp;
464 }
465
466
467 char*
468 get_reg_entry_mo (void)
469 {
470 char *p, *pp;
471 const char *fmt;
472 const char *lang;
473
474 p = get_reg_entry (HKEY_CURRENT_USER, GPG_MO_REG, "MODir");
475 if (p)
476 return p;
477
478 lang = get_gettext_langid ();
479 if (!lang)
480 return NULL;
481 fmt = "share\\locale\\%s\\LC_MESSAGES";
482 pp = new char[strlen (fmt) + strlen (lang) + 4 + 1];
483 if (!pp)
484 BUG (NULL);
485 sprintf (pp, fmt, lang);
486 p = get_reg_entry_gpg4win (pp);
487 free_if_alloc (pp);
488 return p;
489 }
490
491
492 int
493 set_reg_winpt_single (int id, int val)
494 {
495 char buf[64];
496 int rc;
497
498 _snprintf (buf, DIM (buf)-1, "%d", val);
499 rc = set_reg_entry (HKEY_CURRENT_USER, WINPT_REG, cfg[id], buf);
500 return rc;
501 }
502
503
504 int
505 get_reg_winpt_single (int id)
506 {
507 char *buf;
508 int val = 0;
509
510 buf = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG, cfg[id]);
511 if (buf && *buf != ' ')
512 val = 1;
513 else if (!buf)
514 val = -1;
515 free_if_alloc (buf);
516 return val;
517 }
518
519
520 /* Saves the winpt preferences in the registry. */
521 int
522 set_reg_winpt_prefs (winpt_prefs_t opt)
523 {
524 char buf[128];
525 size_t i;
526 int rc = 0;
527
528 for (i=1; i < DIM (cfg); i++) {
529 switch (i) {
530 case CFG_CACHETIME:
531 sprintf (buf, "%d", opt->cache_time);
532 break;
533 case CFG_WORDWRAP:
534 sprintf (buf, "%d", opt->word_wrap);
535 break;
536 case CFG_FILEEXT:
537 sprintf (buf, "%d", opt->default_ext);
538 break;
539 case CFG_NOZIP_MMEDIA:
540 sprintf (buf, "%d", opt->no_zip_mmedia);
541 break;
542 case CFG_VIEWER:
543 sprintf (buf, "%d", opt->use_viewer);
544 break;
545 case CFG_ALWAYSTRUST:
546 sprintf (buf, "%d", opt->always_trust);
547 break;
548 case CFG_AUTOBACKUP:
549 sprintf (buf, "%d", opt->auto_backup);
550 break;
551 case CFG_AUTOBAKMODE:
552 sprintf (buf, "%d", opt->backup.mode);
553 break;
554 case CFG_DISHOTKEYS:
555 sprintf (buf, "%d", opt->no_hotkeys);
556 break;
557 case CFG_EXPERT:
558 sprintf (buf, "%d", opt->expert);
559 break;
560
561 case CFG_FM_PROGRESS:
562 sprintf (buf, "%d", opt->fm.progress);
563 break;
564
565 case CFG_BACKUP_INC_SKR:
566 sprintf (buf, "%d", opt->backup.include_secr);
567 break;
568 }
569 rc = set_reg_entry (HKEY_CURRENT_USER, WINPT_REG, cfg[i], buf);
570 if (rc)
571 goto leave;
572 }
573
574 if (opt->backup.path) {
575 rc = set_reg_entry (HKEY_CURRENT_USER, WINPT_REG, "BackupPath",
576 opt->backup.path);
577 if (rc)
578 goto leave;
579 }
580
581 for (i=0; wpt_hotkeys[i].name; i++) {
582 if (wpt_hotkeys[i].enabled) {
583 buf[0] = wpt_hotkeys[i].key;
584 buf[1] = 0;
585 }
586 else
587 strcpy (buf, " ");
588 rc = set_reg_key (HKEY_CURRENT_USER, WINPT_REG,
589 wpt_hotkeys[i].name, buf);
590 if (rc)
591 break;
592 }
593
594 leave:
595 if (rc) {
596 msg_box (NULL, _("Could not write to Registry."), _("Preferences"), MB_ERR);
597 return rc;
598 }
599 return 0;
600 }
601
602
603 int
604 set_reg_winpt_flag (const char *name, int val)
605 {
606 return set_reg_entry (HKEY_CURRENT_USER, WINPT_REG, name, val? "1" : "0");
607 }
608
609
610 int
611 get_reg_winpt_flag (const char *name)
612 {
613 char *buf;
614 int flag = 0;
615
616 buf = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG, name);
617 if (buf && buf[0] == '1')
618 flag = 1;
619 else if (!buf || buf && buf[0] != '0')
620 flag = -1;
621 free_if_alloc (buf);
622 return flag;
623 }
624
625
626 /* Retrieve the winpt preferences from the registry. */
627 int
628 get_reg_winpt_prefs (winpt_prefs_t opt)
629 {
630 char *val = NULL;
631 size_t i;
632
633 for (i=1; i < DIM (cfg); i++) {
634 val = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG, cfg[i]);
635 if (!val || *val == ' ') {
636 free_if_alloc (val);
637 continue;
638 }
639 switch (i) {
640 case CFG_CACHETIME:
641 opt->cache_time = atoi (val);
642 break;
643 case CFG_WORDWRAP:
644 opt->word_wrap = atoi (val);
645 break;
646 case CFG_FILEEXT:
647 opt->default_ext = atoi (val);
648 break;
649 case CFG_NOZIP_MMEDIA:
650 opt->no_zip_mmedia = atoi (val);
651 break;
652 case CFG_VIEWER:
653 opt->use_viewer = atoi (val);
654 break;
655 case CFG_DISHOTKEYS:
656 opt->no_hotkeys = atoi (val);
657 break;
658 case CFG_ALWAYSTRUST:
659 opt->always_trust = atoi (val);
660 break;
661 case CFG_AUTOBACKUP:
662 opt->auto_backup = atoi (val);
663 break;
664 case CFG_AUTOBAKMODE:
665 opt->backup.mode = atoi (val);
666 break;
667 case CFG_EXPERT:
668 opt->expert = atoi (val);
669 break;
670 case CFG_FM_PROGRESS:
671 opt->fm.progress = atoi (val);
672 break;
673
674 case CFG_BACKUP_INC_SKR:
675 opt->backup.include_secr = atoi (val);
676 break;
677 }
678 free_if_alloc (val);
679 }
680
681 val = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG, "BackupPath");
682 if (val && val[0] != ' ')
683 opt->backup.path = m_strdup (val);
684 free_if_alloc (val);
685
686 for (i=0; wpt_hotkeys[i].name; i++) {
687 wpt_hotkeys[i].enabled = 0;
688 val = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG, wpt_hotkeys[i].name);
689 if (val && val[0] != ' ') {
690 wpt_hotkeys[i].key = *val;
691 wpt_hotkeys[i].enabled = 1;
692 }
693 free_if_alloc (val);
694 }
695 return 0;
696 }
697
698
699 char*
700 get_reg_entry_keyserver (const char *name)
701 {
702 char *p = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", name);
703 if (p && (!strcmp (p, "") || strlen (p) == 0)) {
704 free_if_alloc (p);
705 return NULL;
706 }
707 return p;
708 }
709
710
711 int
712 set_reg_entry_keyserver (const char *name, const char *val)
713 {
714 return set_reg_entry (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", name, val);
715 }
716 #endif

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26