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

Contents of /trunk/Src/wptRegistry.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Fri Sep 30 10:10:16 2005 UTC (19 years, 5 months ago) by twoaday
File size: 17452 byte(s)
Almost finished phase 1 of the WinPT GPGME port.
Still need more cleanup, comments and tests.


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26