2003-10-02 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / gpgme / w32-util.c
1 /* w32-util.c - Utility functions for the W32 API
2    Copyright (C) 1999 Free Software Foundation, Inc
3    Copyright (C) 2001 Werner Koch (dd9jn)
4    Copyright (C) 2001, 2002, 2003 g10 Code GmbH
5
6    This file is part of GPGME.
7  
8    GPGME is free software; you can redistribute it and/or modify it
9    under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12  
13    GPGME is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17  
18    You should have received a copy of the GNU General Public License
19    along with GPGME; if not, write to the Free Software Foundation,
20    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #include <sys/time.h>
31 #include <sys/types.h>
32 #include <signal.h>
33 #include <fcntl.h>
34 #include <windows.h>
35 #include <io.h>
36
37 #include "util.h"
38 #include "sema.h"
39
40 DEFINE_STATIC_LOCK (get_path_lock);
41
42 /* Return a string from the Win32 Registry or NULL in case of error.
43   Caller must release the return value.  A NULL for root is an alias
44   for HKEY_CURRENT_USER.  */
45 static char *
46 read_w32_registry_string (const char *root, const char *dir, const char *name)
47 {
48   HKEY root_key, key_handle;
49   DWORD n1, nbytes;
50   char *result = NULL;
51
52   if (!root)
53     root_key = HKEY_CURRENT_USER;
54   else if (!strcmp (root, "HKEY_CLASSES_ROOT"))
55     root_key = HKEY_CLASSES_ROOT;
56   else if (!strcmp (root, "HKEY_CURRENT_USER"))
57     root_key = HKEY_CURRENT_USER;
58   else if (!strcmp (root, "HKEY_LOCAL_MACHINE"))
59     root_key = HKEY_LOCAL_MACHINE;
60   else if (!strcmp (root, "HKEY_USERS"))
61     root_key = HKEY_USERS;
62   else if (!strcmp (root, "HKEY_PERFORMANCE_DATA"))
63     root_key = HKEY_PERFORMANCE_DATA;
64   else if (!strcmp (root, "HKEY_CURRENT_CONFIG"))
65     root_key = HKEY_CURRENT_CONFIG;
66   else
67     return NULL;
68
69   if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle))
70     return NULL;        /* No need for a RegClose, so return directly.  */
71
72   nbytes = 1;
73   if (RegQueryValueEx (key_handle, name, 0, NULL, NULL, &nbytes))
74     goto leave;
75   n1 = nbytes + 1;
76   result = malloc (n1);
77   if (!result)
78     goto leave;
79   if (RegQueryValueEx (key_handle, name, 0, NULL, result, &n1))
80     {
81       free (result);
82       result = NULL;
83       goto leave;
84     }
85   result[nbytes] = 0;   /* Make sure it is really a string.  */
86
87  leave:
88   RegCloseKey (key_handle);
89   return result;
90 }
91
92
93 static const char *
94 find_program_in_registry (const char *name)
95 {
96   char *program = NULL;
97     
98   program = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", name);
99   if (program)
100     {
101       int i;
102
103       DEBUG2 ("found %s in registry: `%s'", name, program);
104       for (i = 0; program[i]; i++)
105         {
106           if (program[i] == '/')
107             program[i] = '\\';
108         }
109     }
110   return program;
111 }
112
113
114 const char *
115 _gpgme_get_gpg_path (void)
116 {
117   static char *gpg_program;
118
119   LOCK (get_path_lock);
120   if (!gpg_program)
121     gpg_program = find_program_in_registry ("gpgProgram");
122 #ifdef GPG_PATH
123   if (!gpg_program)
124     gpg_program = GPG_PATH;
125 #endif
126   UNLOCK (get_path_lock);
127   return gpg_program;
128 }
129
130 const char *
131 _gpgme_get_gpgsm_path (void)
132 {
133   static char *gpgsm_program;
134
135   LOCK (get_path_lock);
136   if (!gpgsm_program)
137     gpgsm_program = find_program_in_registry ("gpgsmProgram");
138 #ifdef GPGSM_PATH
139   if (!gpgsm_program)
140     gpgsm_program = GPGSM_PATH;
141 #endif
142   UNLOCK (get_path_lock);
143   return gpgsm_program;
144 }