diff options
author | Werner Koch <wk@gnupg.org> | 2021-11-17 09:30:48 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2021-11-17 09:30:48 +0100 |
commit | 50539394802fb9478296d52527582697a6693b52 (patch) | |
tree | c611ddd8a044c160d7cc2675aacce5ddfeeda6d9 /common | |
parent | sm: Detect circular chains in --list-chain. (diff) | |
download | gnupg2-50539394802fb9478296d52527582697a6693b52.tar.xz gnupg2-50539394802fb9478296d52527582697a6693b52.zip |
common,w32: New function read_w32_reg_string.
* common/w32-reg.c (get_root_key): Remove.
(read_w32_registry_string): Turn into a wrapper for the gpgrt
function.
(read_w32_reg_string): New.
Diffstat (limited to 'common')
-rw-r--r-- | common/t-w32-reg.c | 43 | ||||
-rw-r--r-- | common/w32-reg.c | 200 | ||||
-rw-r--r-- | common/w32help.h | 1 |
3 files changed, 65 insertions, 179 deletions
diff --git a/common/t-w32-reg.c b/common/t-w32-reg.c index 01816db54..9665003ea 100644 --- a/common/t-w32-reg.c +++ b/common/t-w32-reg.c @@ -44,25 +44,28 @@ static void test_read_registry (void) { - char *string; + char *string1, *string2; -#ifdef HAVE_W32CE_SYSTEM - string = read_w32_registry_string ("HKEY_CLASSES_ROOT", - "BOOTSTRAP\\CLSID", NULL); - if (!string) - fail (0); - fprintf (stderr, "Bootstrap clsid: %s\n", string); - xfree (string); -#endif - - string = read_w32_registry_string + string1 = read_w32_registry_string ("HKEY_CURRENT_USER", "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "User Agent"); - if (!string) + if (!string1) fail (0); - fprintf (stderr, "User agent: %s\n", string); - xfree (string); + fprintf (stderr, "User agent: %s\n", string1); + + string2 = read_w32_reg_string + ("HKCU\\Software\\Microsoft\\Windows\\CurrentVersion" + "\\Internet Settings:User Agent"); + if (!string2) + fail (1); + fprintf (stderr, "User agent: %s\n", string2); + if (strcmp (string1, string2)) + fail (2); + + + xfree (string1); + xfree (string2); } @@ -71,10 +74,14 @@ test_read_registry (void) int main (int argc, char **argv) { - (void)argc; - (void)argv; - - test_read_registry (); + if (argc > 1) + { + char *string = read_w32_reg_string (argv[1]); + printf ("%s -> %s\n", argv[1], string? string : "(null)"); + xfree (string); + } + else + test_read_registry (); return 0; } diff --git a/common/w32-reg.c b/common/w32-reg.c index d8d94b90e..94049a283 100644 --- a/common/w32-reg.c +++ b/common/w32-reg.c @@ -47,184 +47,62 @@ #include "w32help.h" -static HKEY -get_root_key(const char *root) -{ - HKEY root_key; - - 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; - - return root_key; -} - - /* Return a string from the Win32 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 * read_w32_registry_string (const char *root, const char *dir, const char *name) { -#ifdef HAVE_W32CE_SYSTEM - HKEY root_key, key_handle; - DWORD n1, nbytes, type; - char *result = NULL; - wchar_t *wdir, *wname; - - if ( !(root_key = get_root_key(root) ) ) - return NULL; - - wdir = utf8_to_wchar (dir); - if (!wdir) - return NULL; - - if (RegOpenKeyEx (root_key, wdir, 0, KEY_READ, &key_handle) ) - { - if (root) - { - xfree (wdir); - return NULL; /* No need for a RegClose, so return immediately. */ - } - /* It seems to be common practise to fall back to HKLM. */ - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, wdir, 0, KEY_READ, &key_handle) ) - { - xfree (wdir); - return NULL; /* Still no need for a RegClose. */ - } - } - xfree (wdir); + return gpgrt_w32_reg_query_string (root, dir, name); +} - if (name) - { - wname = utf8_to_wchar (name); - if (!wname) - goto leave; - } - else - wname = NULL; - nbytes = 2; - if (RegQueryValueEx (key_handle, wname, 0, NULL, NULL, &nbytes)) - goto leave; - result = xtrymalloc ((n1=nbytes+2)); - if (!result) - goto leave; - if (RegQueryValueEx (key_handle, wname, 0, &type, result, &n1)) - { - xfree (result); - result = NULL; - goto leave; - } - result[nbytes] = 0; /* Make sure it is a string. */ - result[nbytes+1] = 0; - if (type == REG_SZ || type == REG_EXPAND_SZ) - { - wchar_t *tmp = (void*)result; - result = wchar_to_utf8 (tmp); - xfree (tmp); - } - - leave: - xfree (wname); - RegCloseKey (key_handle); - return result; -#else /*!HAVE_W32CE_SYSTEM*/ - HKEY root_key, key_handle; - DWORD n1, nbytes, type; - char *result = NULL; +/* Compact version of read_w32_registry_string. This version expects + * a single string as key described here using an example: + * + * HKCU\Software\GNU\GnuPG:HomeDir + * + * 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. + * Software\GNU\GnuPG := The actual key. + * HomeDir := the name of the item. The name is optional to use the default + * value. + * + * Note that the first backslash and the first colon act as delimiters. + * + * Returns a malloced string or NULL if not found. + */ +char * +read_w32_reg_string (const char *key_arg) +{ + char *key; + char *p1, *p2; + char *result; - if ( !(root_key = get_root_key(root) ) ) + if (!key_arg) return NULL; - - if (RegOpenKeyEx (root_key, dir, 0, KEY_READ, &key_handle) ) + key = xtrystrdup (key_arg); + if (!key) { - if (root) - return NULL; /* No need for a RegClose, so return immediately. */ - /* It seems to be common practise to fall back to HKLM. */ - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) ) - return NULL; /* Still no need for a RegClose. */ + log_info ("warning: malloc failed while reading registry key\n"); + return NULL; } - nbytes = 1; - if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) - goto leave; - result = xtrymalloc ((n1=nbytes+1)); - if (!result) - goto leave; - if (RegQueryValueEx( key_handle, name, 0, &type, result, &n1 )) + p1 = strchr (key, '\\'); + if (!p1) { - xfree (result); - result = NULL; - goto leave; - } - result[nbytes] = 0; /* Make sure it is a string. */ - 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) - { - /* Oops - truncated, better don't expand at all. */ - xfree (tmp); - 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); - } + xfree (key); + return NULL; } + *p1++ = 0; + p2 = strchr (p1, ':'); + if (p2) + *p2++ = 0; - leave: - RegCloseKey (key_handle); + result = gpgrt_w32_reg_query_string (*key? key : NULL, p1, p2); + xfree (key); return result; -#endif /*!HAVE_W32CE_SYSTEM*/ } - #endif /*HAVE_W32_SYSTEM*/ diff --git a/common/w32help.h b/common/w32help.h index edb51b8b7..a79081f8e 100644 --- a/common/w32help.h +++ b/common/w32help.h @@ -44,6 +44,7 @@ char **w32_parse_commandline (char *cmdline, int globing, int *r_argv, /*-- w32-reg.c --*/ char *read_w32_registry_string (const char *root, const char *dir, const char *name ); +char *read_w32_reg_string (const char *key); /* Other stuff. */ #ifdef HAVE_W32CE_SYSTEM |