1 /* w32-reg.c - MS-Windows Registry access
2 * Copyright (C) 1999, 2002, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify it
7 * under the terms of either
9 * - the GNU Lesser General Public License as published by the Free
10 * Software Foundation; either version 3 of the License, or (at
11 * your option) any later version.
15 * - the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at
17 * your option) any later version.
19 * or both in parallel, as here.
21 * GnuPG is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
26 * You should have received a copies of the GNU General Public License
27 * and the GNU Lesser General Public License along with this program;
28 * if not, see <https://www.gnu.org/licenses/>.
32 #ifdef HAVE_W32_SYSTEM
33 /* This module is only used in this environment */
39 #ifdef HAVE_WINSOCK2_H
40 # include <winsock2.h>
45 #include "common-defs.h"
51 get_root_key(const char *root)
56 root_key = HKEY_CURRENT_USER;
57 else if (!strcmp( root, "HKEY_CLASSES_ROOT" ) )
58 root_key = HKEY_CLASSES_ROOT;
59 else if (!strcmp( root, "HKEY_CURRENT_USER" ) )
60 root_key = HKEY_CURRENT_USER;
61 else if (!strcmp( root, "HKEY_LOCAL_MACHINE" ) )
62 root_key = HKEY_LOCAL_MACHINE;
63 else if (!strcmp( root, "HKEY_USERS" ) )
64 root_key = HKEY_USERS;
65 else if (!strcmp( root, "HKEY_PERFORMANCE_DATA" ) )
66 root_key = HKEY_PERFORMANCE_DATA;
67 else if (!strcmp( root, "HKEY_CURRENT_CONFIG" ) )
68 root_key = HKEY_CURRENT_CONFIG;
76 /* Return a string from the Win32 Registry or NULL in case of error.
77 Caller must release the return value. A NULL for root is an alias
78 for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */
80 read_w32_registry_string (const char *root, const char *dir, const char *name)
82 #ifdef HAVE_W32CE_SYSTEM
83 HKEY root_key, key_handle;
84 DWORD n1, nbytes, type;
86 wchar_t *wdir, *wname;
88 if ( !(root_key = get_root_key(root) ) )
91 wdir = utf8_to_wchar (dir);
95 if (RegOpenKeyEx (root_key, wdir, 0, KEY_READ, &key_handle) )
100 return NULL; /* No need for a RegClose, so return immediately. */
102 /* It seems to be common practise to fall back to HKLM. */
103 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, wdir, 0, KEY_READ, &key_handle) )
106 return NULL; /* Still no need for a RegClose. */
113 wname = utf8_to_wchar (name);
121 if (RegQueryValueEx (key_handle, wname, 0, NULL, NULL, &nbytes))
123 result = xtrymalloc ((n1=nbytes+2));
126 if (RegQueryValueEx (key_handle, wname, 0, &type, result, &n1))
132 result[nbytes] = 0; /* Make sure it is a string. */
133 result[nbytes+1] = 0;
134 if (type == REG_SZ || type == REG_EXPAND_SZ)
136 wchar_t *tmp = (void*)result;
137 result = wchar_to_utf8 (tmp);
143 RegCloseKey (key_handle);
145 #else /*!HAVE_W32CE_SYSTEM*/
146 HKEY root_key, key_handle;
147 DWORD n1, nbytes, type;
150 if ( !(root_key = get_root_key(root) ) )
153 if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle) )
156 return NULL; /* No need for a RegClose, so return immediately. */
157 /* It seems to be common practise to fall back to HKLM. */
158 if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
159 return NULL; /* Still no need for a RegClose. */
163 if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) )
165 result = xtrymalloc ((n1=nbytes+1));
168 if (RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ))
174 result[nbytes] = 0; /* Make sure it is a string. */
175 if (type == REG_EXPAND_SZ && strchr (result, '%'))
180 tmp = xtrymalloc (n1+1);
183 nbytes = ExpandEnvironmentStrings (result, tmp, n1);
184 if (nbytes && nbytes > n1)
188 tmp = xtrymalloc (n1 + 1);
191 nbytes = ExpandEnvironmentStrings (result, tmp, n1);
192 if (nbytes && nbytes > n1)
194 /* Oops - truncated, better don't expand at all. */
204 /* Okay, reduce the length. */
207 result = xtrymalloc (strlen (tmp)+1);
212 strcpy (result, tmp);
218 /* Error - don't expand. */
224 RegCloseKey (key_handle);
226 #endif /*!HAVE_W32CE_SYSTEM*/
230 #endif /*HAVE_W32_SYSTEM*/