aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-12-12 09:24:26 +0000
committerWerner Koch <[email protected]>2024-12-12 09:24:26 +0000
commit652328c786f37e3a3de5c3b143ce9e0d524bfeb4 (patch)
tree49605d237a87a8e8bb9ae3acc5904eac7427d7e4
parentMinor cleanness fix for autogen.sh (diff)
downloadlibgpg-error-652328c786f37e3a3de5c3b143ce9e0d524bfeb4.tar.gz
libgpg-error-652328c786f37e3a3de5c3b143ce9e0d524bfeb4.zip
New Windows API gpgrt_w32_reg_get_string.
* src/w32-reg.c (_gpgrt_w32_reg_query_string): Implement a prefix for root and consider an empty string for root also HKCU. * src/visibility.c (gpgrt_w32_reg_get_string): New. * src/gpg-error.def.in: Add new function. * src/gpg-error.c (my_strusage): Print the Windows version (32 or 64 bit) of the binary. (main): New command --getreg. -- This function is already used internally and we have a similar function in GnuPG. It is much more convenient to work with this function. Also we can now pass the KEY_WOW64_32KEY andKEY_WOW64_64KEY flags to the registry read functions. For example !32key!HKLM\software\gnu\gnupg:ntdskeyserver returns the value using the KEY_WOW64_32KEY flag; likewise for !64key!. If !cross! is used the reversed flag of the binary type is used.
-rw-r--r--NEWS9
-rw-r--r--src/gpg-error.c32
-rw-r--r--src/gpg-error.def.in2
-rw-r--r--src/visibility.c6
-rw-r--r--src/visibility.h1
-rw-r--r--src/w32-add.h3
-rw-r--r--src/w32-reg.c54
7 files changed, 99 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index cfe348c..4bade72 100644
--- a/NEWS
+++ b/NEWS
@@ -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.