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 | |
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]>
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/gpg-error.def.in | 4 | ||||
-rw-r--r-- | src/gpgrt-int.h | 37 | ||||
-rw-r--r-- | src/logging.c | 8 | ||||
-rw-r--r-- | src/visibility.c | 15 | ||||
-rw-r--r-- | src/visibility.h | 5 | ||||
-rw-r--r-- | src/w32-add.h | 5 | ||||
-rw-r--r-- | src/w32-reg.c | 150 |
9 files changed, 225 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac index 53472b3..9f3ea82 100644 --- a/configure.ac +++ b/configure.ac @@ -176,7 +176,7 @@ AC_MSG_WARN([[Without strerror_r, gpg_strerror_r might not be thread-safe]])) ;; esac -AC_CHECK_FUNCS([flockfile vasprintf mmap rand strlwr]) +AC_CHECK_FUNCS([flockfile vasprintf mmap rand strlwr stpcpy setenv]) # diff --git a/src/Makefile.am b/src/Makefile.am index 3210a65..a95b732 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,7 +113,7 @@ CLEANFILES = err-sources.h err-codes.h code-to-errno.h code-from-errno.h \ # if HAVE_W32_SYSTEM arch_sources = w32-gettext.c w32-lock.c w32-lock-obj.h w32-thread.c \ - w32-iconv.c w32-estream.c + w32-iconv.c w32-estream.c w32-reg.c RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ -DLOCALEDIR=\"$(localedir)\" $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) @@ -143,6 +143,7 @@ uninstall-def-file: libgpg_error_la_DEPENDENCIES = $(gpg_error_res) gpg-error.def intllibs = +socklibs = -lws2_32 # # }}} End Windows part @@ -161,6 +162,7 @@ install-def-file: uninstall-def-file: intllibs = @LTLIBINTL@ +socklibs = endif # @@ -197,7 +199,7 @@ nodist_libgpg_error_la_SOURCES = gpg-error.h # without the extra_cppflags because they may include am -idirafter # which is not supported by the RC compiler. libgpg_error_la_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" $(extra_cppflags) -libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(LIBTHREAD) +libgpg_error_la_LIBADD = $(gpg_error_res) $(intllibs) $(socklibs) $(LIBTHREAD) gpg_error_SOURCES = strsource-sym.c strerror-sym.c gpg-error.c gpg_error_CPPFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 7c39502..5c7835f 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -189,4 +189,8 @@ EXPORTS gpgrt_strdup @144 gpgrt_strconcat @145 +#ifdef HAVE_W32_SYSTEM + gpgrt_w32_reg_query_string @148 +#endif + ;; end of file with public symbols for Windows. diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index c226e2b..c0e83b1 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -118,6 +118,13 @@ void _gpgrt_free (void *a); /* The next is only to be used by visibility.c. */ char *_gpgrt_strconcat_core (const char *s1, va_list arg_ptr); +#define xfree(a) _gpgrt_free ((a)) +#define xtrymalloc(a) _gpgrt_malloc ((a)) +#define xtrycalloc(a,b) _gpgrt_calloc ((a),(b)) +#define xtryrealloc(a,b) _gpgrt_realloc ((a),(b)) + + + const char *_gpg_error_check_version (const char *req_version); gpg_err_code_t _gpgrt_lock_init (gpgrt_lock_t *lockhd); @@ -553,4 +560,34 @@ int _gpgrt_logv_internal (int level, int ignore_arg_ptr, int _gpgrt_fd_valid_p (int fd); + +/* + * Platform specific functions (Windows) + */ +#ifdef HAVE_W32_SYSTEM + +char *_gpgrt_w32_reg_query_string (const char *root, + const char *dir, + const char *name); + + +#endif /*HAVE_W32_SYSTEM*/ + +/* + * Missing functions implemented inline. + */ + +#ifndef HAVE_STPCPY +static GPG_ERR_INLINE char * +_gpgrt_stpcpy (char *a, const char *b) +{ + while (*b) + *a++ = *b++; + *a = 0; + return a; +} +#define stpcpy(a,b) _gpgrt_stpcpy ((a), (b)) +#endif /*!HAVE_STPCPY*/ + + #endif /*_GPGRT_GPGRT_INT_H*/ diff --git a/src/logging.c b/src/logging.c index 2e675f5..dbd8066 100644 --- a/src/logging.c +++ b/src/logging.c @@ -787,9 +787,9 @@ _gpgrt_logv_internal (int level, int ignore_arg_ptr, const char *extrastring, tmp = (no_registry ? NULL - : read_w32_registry_string (NULL, GNUPG_REGISTRY_DIR, - "DefaultLogFile")); - log_set_file (tmp && *tmp? tmp : NULL); + : _gpgrt_w32_reg_query_string (NULL, "Software\\\\GNU\\\\GnuPG", + "DefaultLogFile")); + _gpgrt_log_set_sink (tmp && *tmp? tmp : NULL, NULL, -1); _gpgrt_free (tmp); #else /* Make sure a log stream has been set. */ @@ -1119,7 +1119,7 @@ _gpgrt_logv_printhex (const void *buffer, size_t length, cnt = 0; /* (we indicate continuations with a backslash) */ _gpgrt_log_printf (" \\\n"); - _gpgrt_log_debug (""); + _gpgrt_log_debug ("%s", ""); if (fmt && *fmt) _gpgrt_log_printf (" "); } diff --git a/src/visibility.c b/src/visibility.c index 888492a..01ed2ce 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -975,3 +975,18 @@ _gpgrt_log_assert (const char *expr, const char *file, _gpgrt__log_assert (expr, file, line); #endif } + + + + +/* For consistency reasons we use function wrappers also for Windows + * specific function despite that they are technically not needed. */ +#ifdef HAVE_W32_SYSTEM + +char * +gpgrt_w32_reg_query_string (const char *root, const char *dir, const char *name) +{ + return _gpgrt_w32_reg_query_string (root, dir, name); +} + +#endif /*HAVE_W32_SYSTEM*/ diff --git a/src/visibility.h b/src/visibility.h index c4f4fd1..416f266 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -326,6 +326,11 @@ MARK_VISIBLE (_gpgrt_log_assert) #define gpgrt_log_flush _gpgrt_USE_UNDERSCORED_FUNCTION #define _gpgrt_log_assert _gpgrt_USE_UNDERSCORED_FUNCTION + +/* Windows specific functions. */ +#define gpgrt_w32_reg_query_string _gpgrt_USE_UNDERSCORED_FUNCTION + + #endif /*!_GPGRT_INCL_BY_VISIBILITY_C*/ #endif /*_GPGRT_VISIBILITY_H*/ diff --git a/src/w32-add.h b/src/w32-add.h index 5db6500..07e3c7d 100644 --- a/src/w32-add.h +++ b/src/w32-add.h @@ -56,3 +56,8 @@ size_t gpgrt_w32_iconv (gpgrt_w32_iconv_t cd, # define iconv_close(a) gpgrt_w32_iconv_close ((a)) # define iconv(a,b,c,d,e) gpgrt_w32_iconv ((a),(b),(c),(d),(e)) #endif /*GPGRT_ENABLE_W32_ICONV_MACROS*/ + +/* Query a string in the registry. */ +char *gpgrt_w32_reg_query_string (const char *root, + const char *dir, + const char *name); 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; +} |