diff options
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | src/gpg-error.c | 32 | ||||
-rw-r--r-- | src/gpg-error.def.in | 2 | ||||
-rw-r--r-- | src/visibility.c | 6 | ||||
-rw-r--r-- | src/visibility.h | 1 | ||||
-rw-r--r-- | src/w32-add.h | 3 | ||||
-rw-r--r-- | src/w32-reg.c | 54 |
7 files changed, 99 insertions, 8 deletions
@@ -1,6 +1,15 @@ Noteworthy changes in version 1.52 (unreleased) [C38/A38/R_] ----------------------------------------------- + * The KEY_WOW64_xxKEY flags can now be passed to the Regsiry read + functions. + + * New command --getreg for gpg-error on Windows. + + * Interface changes relative to the 1.51 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + _gpgrt_w32_reg_query_string NEW (Windows only). + Release-info: https://dev.gnupg.org/T7385 diff --git a/src/gpg-error.c b/src/gpg-error.c index 4e8bd8b..6d16b36 100644 --- a/src/gpg-error.c +++ b/src/gpg-error.c @@ -521,6 +521,16 @@ my_strusage (int level) case 14: p = "Copyright (C) 2019 g10 Code GmbH"; break; case 19: p = _("Please report bugs to <https://bugs.gnupg.org>.\n"); break; +#ifdef HAVE_W32_SYSTEM + case 31: +#if defined(_WIN64) + p = "(Windows 64 bit)"; +#else + p = "(Windows 32 bit)"; +#endif + break; +#endif + case 1: case 40: p = ("Usage: gpg-error [options] error-numbers"); @@ -548,6 +558,7 @@ main (int argc, char *argv[]) CMD_LIST, CMD_DEFINES, CMD_LOCALE, + CMD_GETREG, OPT_DESC }; static gpgrt_opt_t opts[] = { @@ -559,10 +570,14 @@ main (int argc, char *argv[]) "Print all error codes as #define lines"), #if HAVE_W32_SYSTEM ARGPARSE_c (CMD_LOCALE, "locale", - "Return the locale used for gettext"), + "Print the locale used for gettext"), + ARGPARSE_c (CMD_GETREG, "getreg", + "Print string from the Registry"), #else ARGPARSE_c (CMD_LOCALE, "locale", "@"), + ARGPARSE_c (CMD_GETREG, "getreg", + "@"), #endif ARGPARSE_s_n (OPT_DESC, "desc", "Print with error description"), @@ -574,6 +589,7 @@ main (int argc, char *argv[]) int libversion = 0; int listmode = 0; int localemode = 0; + int getregmode = 0; int desc = 0; const char *s, *s2; const char *source_sym; @@ -594,6 +610,7 @@ main (int argc, char *argv[]) case CMD_LIST: listmode = 1; break; case CMD_DEFINES: listmode = 2; break; case CMD_LOCALE: localemode = 1; break; + case CMD_GETREG: getregmode = 1; break; case OPT_DESC: desc = 1; break; default: pargs.err = ARGPARSE_PRINT_WARNING; break; } @@ -610,6 +627,11 @@ main (int argc, char *argv[]) if (argc > 1) gpgrt_usage (1); } + else if (getregmode) + { + if (argc != 1) + gpgrt_usage (1); + } else if ((argc && listmode) || (!argc && !listmode)) gpgrt_usage (1); @@ -658,6 +680,14 @@ main (int argc, char *argv[]) log_info ("this command is only useful on Windows\n"); #endif } + else if (getregmode) + { +#if HAVE_W32_SYSTEM + printf ("%s\n", gpgrt_w32_reg_get_string (*argv)); +#else + log_info ("this command is only useful on Windows\n"); +#endif + } else if (listmode == 1) { for (i=0; i < GPG_ERR_SOURCE_DIM; i++) diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in index 4344cbc..fad6405 100644 --- a/src/gpg-error.def.in +++ b/src/gpg-error.def.in @@ -256,4 +256,6 @@ EXPORTS gpgrt_spawn_actions_set_inherit_handles @196 gpgrt_spawn_actions_set_env_rev @197 + gpgrt_w32_reg_get_string @198 + ;; end of file with public symbols for Windows. diff --git a/src/visibility.c b/src/visibility.c index b7505b8..836d4d0 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -1380,4 +1380,10 @@ gpgrt_w32_reg_query_string (const char *root, const char *dir, const char *name) return _gpgrt_w32_reg_query_string (root, dir, name); } +char * +gpgrt_w32_reg_get_string (const char *key) +{ + return _gpgrt_w32_reg_get_string (key); +} + #endif /*HAVE_W32_SYSTEM*/ diff --git a/src/visibility.h b/src/visibility.h index 30c6853..079dfb9 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -455,6 +455,7 @@ MARK_VISIBLE (gpgrt_spawn_actions_set_atfork) #define gpgrt_wchar_to_utf8 _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_fname_to_wchar _gpgrt_USE_UNDERSCORED_FUNCTION #define gpgrt_w32_reg_query_string _gpgrt_USE_UNDERSCORED_FUNCTION +#define gpgrt_w32_reg_get_string _gpgrt_USE_UNDERSCORED_FUNCTION #endif /*!_GPGRT_INCL_BY_VISIBILITY_C*/ diff --git a/src/w32-add.h b/src/w32-add.h index d567799..dd6db5d 100644 --- a/src/w32-add.h +++ b/src/w32-add.h @@ -88,3 +88,6 @@ char *gpgrt_wchar_to_utf8 (const wchar_t *wstring); char *gpgrt_w32_reg_query_string (const char *root, const char *dir, const char *name); + +/* Query a string in the registry using a unified key representation. */ +char *gpgrt_w32_reg_get_string (const char *key); diff --git a/src/w32-reg.c b/src/w32-reg.c index b1134a5..5bb8d43 100644 --- a/src/w32-reg.c +++ b/src/w32-reg.c @@ -47,10 +47,30 @@ _gpgrt_w32_reg_query_string (const char *root, const char *dir, const char *name) { HKEY root_key, key_handle; - DWORD n1, nbytes, type; + DWORD n1, nbytes, type, flags; char *result = NULL; + int cross = 0; + /* Check special prefix. */ if (!root) + ; + else if (!strncmp (root, "!64key!", 7)) + { + root += 7; + cross = 64; + } + else if (!strncmp (root, "!32key!", 7)) + { + root += 7; + cross = 32; + } + else if (!strncmp (root, "!cross!", 7)) + { + root += 7; + cross = 1; + } + + if (!root || !*root) root_key = HKEY_CURRENT_USER; else if (!strcmp (root, "HKEY_CLASSES_ROOT") || !strcmp (root, "HKCR")) root_key = HKEY_CLASSES_ROOT; @@ -67,12 +87,26 @@ _gpgrt_w32_reg_query_string (const char *root, const char *dir, else return NULL; - if (RegOpenKeyExA (root_key, dir, 0, KEY_READ, &key_handle)) + flags = KEY_READ; + if (cross == 64) + flags |= KEY_WOW64_64KEY; + else if (cross == 32) + flags |= KEY_WOW64_32KEY; + else if (cross) + { +#if defined(_WIN64) + flags |= KEY_WOW64_32KEY; +#else + flags |= KEY_WOW64_64KEY; +#endif + } + + if (RegOpenKeyExA (root_key, dir, 0, flags, &key_handle)) { - if (root) + if (root && !*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)) + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, flags, &key_handle)) return NULL; /* still no need for a RegClose, so return direct */ } @@ -81,11 +115,11 @@ _gpgrt_w32_reg_query_string (const char *root, const char *dir, nbytes = 1; if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) { - if (root) + if (root && !*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)) + if (RegOpenKeyExA (HKEY_LOCAL_MACHINE, dir, 0, flags, &key_handle)) return NULL; /* Nope. */ if (RegQueryValueExA (key_handle, name, 0, NULL, NULL, &nbytes)) goto leave; @@ -170,8 +204,9 @@ _gpgrt_w32_reg_query_string (const char *root, const char *dir, /* Compact version of gpgrt_w32_reg_query_string. This version * expects a single string as key described here using an example: * - * HKCU\Software\GNU\GnuPG:HomeDir + * <prefix>HKCU\Software\GNU\GnuPG:HomeDir * + * <prefix> := Optional; see below. * HKCU := the class, other supported classes are HKLM, HKCR, HKU, and * HKCC. If no class is given and the string thus starts with * a backslash HKCU with a fallback to HKLM is used. @@ -179,6 +214,11 @@ _gpgrt_w32_reg_query_string (const char *root, const char *dir, * HomeDir := the name of the item. The name is optional to use the default * value. * + * If <prefix> is given it may take these values: + * !64key! := Access a 64 bit key + * !32key! := Access a 32 bit key + * !cross! := On 32-bit use the 64-bit key, on 64-bit use the 32-bit key + * * Note that the first backslash and the first colon act as delimiters. * * Returns a malloced string or NULL if not found. |