diff options
author | Werner Koch <[email protected]> | 2017-11-17 16:25:58 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2017-11-17 16:25:58 +0000 |
commit | b5c4a2721d7b4bd54705c53e6f294ab2ef66a6f7 (patch) | |
tree | c6cb5174ba5144b6ba289c8a0e8d72960a8c7455 /src/w32-reg.c | |
parent | core: New API functions gpgrt_strdup and gpgrt_strconcat. (diff) | |
download | libgpg-error-b5c4a2721d7b4bd54705c53e6f294ab2ef66a6f7.tar.gz libgpg-error-b5c4a2721d7b4bd54705c53e6f294ab2ef66a6f7.zip |
w32: Add new API fucntion gpgrt_w32_reg_query_string.
* src/w32-reg.c: New.
* src/w32-add.h: Add gpgrt_w32_reg_query_string.
* src/visibility.c (gpgrt_w32_reg_query_string): New wrapper.
* src/gpg-error.def.in: Add gpgrt_w32_reg_query_string.
* configure.ac (ac_check_funcs): Add stpcpy.
* src/Makefile.am (arch_sources): Add w32-reg.c
(socklibs): New.
(libgpg_error_la_LIBADD): Add socklibs.
* src/gpgrt-int.h (xfree, xtrymalloc, xtrycalloc)
(xtryrealloc): New internal macros.
(_gpgrt_stpcpy, stpcpy): New replacement fucntion and macro.
* src/logging.c (_gpgrt_logv_internal): Use new registry query
function and add standard registry key.
--
This also fixes the build failure on Widnwos for logging.c.
The code for gpgrt_w32_reg_query_string has been taken from the
function read_w32_registry_string in w32-utils.c in the GPGME package.
Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'src/w32-reg.c')
-rw-r--r-- | src/w32-reg.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/w32-reg.c b/src/w32-reg.c new file mode 100644 index 0000000..8aefa52 --- /dev/null +++ b/src/w32-reg.c @@ -0,0 +1,150 @@ +/* w32-reg.c - Windows registry support + * Copyright (C) 2002, 2005, 2010, 2012, 2017 g10 Code GmbH + * + * This file is part of Libgpg-error. + * + * Libgpg-error is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgpg-error is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef HAVE_W32_SYSTEM +# error This module may only be build for Windows. +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <gpg-error.h> +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "gpgrt-int.h" + + +/* Return a string from the W32 Registry or NULL in case of error. + * Caller must release the return value. A NULL for root is an alias + * for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */ +char * +_gpgrt_w32_reg_query_string (const char *root, const char *dir, + const char *name) +{ + HKEY root_key, key_handle; + DWORD n1, nbytes, type; + char *result = NULL; + + if (!root) + root_key = HKEY_CURRENT_USER; + else if (!strcmp( root, "HKEY_CLASSES_ROOT")) + root_key = HKEY_CLASSES_ROOT; + else if (!strcmp( root, "HKEY_CURRENT_USER")) + root_key = HKEY_CURRENT_USER; + else if (!strcmp( root, "HKEY_LOCAL_MACHINE")) + root_key = HKEY_LOCAL_MACHINE; + else if (!strcmp( root, "HKEY_USERS")) + root_key = HKEY_USERS; + else if (!strcmp( root, "HKEY_PERFORMANCE_DATA")) + root_key = HKEY_PERFORMANCE_DATA; + else if (!strcmp( root, "HKEY_CURRENT_CONFIG")) + root_key = HKEY_CURRENT_CONFIG; + else + return NULL; + + if (RegOpenKeyExA (root_key, dir, 0, KEY_READ, &key_handle)) + { + if (root) + return NULL; /* No need for a RegClose, so return direct. */ + /* It seems to be common practise to fall back to HKLM. */ + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) + return NULL; /* still no need for a RegClose, so return direct */ + } + + nbytes = 1; + if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) + { + if (root) + goto leave; + /* Try to fallback to HKLM also for a missing value. */ + RegCloseKey (key_handle); + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle)) + return NULL; /* Nope. */ + if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) + goto leave; + } + n1 = nbytes + 1; + result = xtrymalloc (n1); + if (!result) + goto leave; + if (RegQueryValueExA (key_handle, name, 0, &type, (LPBYTE) result, &n1)) + { + xfree (result); + result = NULL; + goto leave; + } + result[nbytes] = 0; /* Make sure it is really a string. */ + +#ifndef HAVE_W32CE_SYSTEM /* (Windows CE has no environment.) */ + if (type == REG_EXPAND_SZ && strchr (result, '%')) + { + char *tmp; + + n1 += 1000; + tmp = xtrymalloc (n1 + 1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) + { + xfree (tmp); + n1 = nbytes; + tmp = xtrymalloc (n1 + 1); + if (!tmp) + goto leave; + nbytes = ExpandEnvironmentStrings (result, tmp, n1); + if (nbytes && nbytes > n1) { + xfree (tmp); /* Oops - truncated, better don't expand at all. */ + goto leave; + } + tmp[nbytes] = 0; + xfree (result); + result = tmp; + } + else if (nbytes) /* Okay, reduce the length. */ + { + tmp[nbytes] = 0; + xfree (result); + result = xtrymalloc (strlen (tmp)+1); + if (!result) + result = tmp; + else + { + strcpy (result, tmp); + xfree (tmp); + } + } + else /* Error - don't expand. */ + { + xfree (tmp); + } + } +#endif + + leave: + RegCloseKey (key_handle); + return result; +} |