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

Contents of /trunk/Src/wptRegistry.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26