diff options
author | Werner Koch <[email protected]> | 2021-11-17 08:30:48 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2021-11-17 08:30:48 +0000 |
commit | 50539394802fb9478296d52527582697a6693b52 (patch) | |
tree | c611ddd8a044c160d7cc2675aacce5ddfeeda6d9 /common/w32-reg.c | |
parent | sm: Detect circular chains in --list-chain. (diff) | |
download | gnupg-50539394802fb9478296d52527582697a6693b52.tar.gz gnupg-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/w32-reg.c')
-rw-r--r-- | common/w32-reg.c | 200 |
1 files changed, 39 insertions, 161 deletions
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*/ |