[PATCH 1 of 2] Implement reading registry entries for other users
Wald Commits
scm-commit at wald.intevation.org
Fri Jun 27 18:54:25 CEST 2014
# HG changeset patch
# User Andre Heinecke <andre.heinecke at intevation.de>
# Date 1403878690 -7200
# Node ID f1795a232418691eed69f3c4a35cdd503b0688bf
# Parent e8bc1215904eb9f8a8e6631d6eb5b4a803a88926
Implement reading registry entries for other users.
diff -r e8bc1215904e -r f1795a232418 cinst/nssstore_win.c
--- a/cinst/nssstore_win.c Fri Jun 27 11:51:53 2014 +0200
+++ b/cinst/nssstore_win.c Fri Jun 27 16:18:10 2014 +0200
@@ -139,6 +139,113 @@
return true;
}
+/**@brief Read (and expand if necessary) a registry string.
+ *
+ * Reads a registry string and calls ExpandEnvironmentString
+ * if necessary on it. Returns a newly allocated string array
+ * with the expanded registry value converted to UTF-8
+ *
+ * Caller has to free return value with free.
+ *
+ * @param [in] root the root key (e.g. HKEY_LOCAL_MACHINE)
+ * @param [in] key the key
+ * @param [in] name the name of the value to read.
+ *
+ * @returns the expanded, null terminated utf-8 string of the value.
+ * or NULL on error.
+ */
+static char*
+read_registry_string (const HKEY root, const wchar_t *key,
+ const wchar_t *name)
+{
+ HKEY key_handle = NULL;
+ DWORD size = 0,
+ type = 0,
+ ex_size = 0,
+ dwRet = 0;
+ LONG ret = 0;
+ char *retval = NULL;
+ wchar_t *buf = NULL,
+ *ex_buf = NULL;
+ if (root == NULL || key == NULL || name == NULL)
+ {
+ ERRORPRINTF ("Invalid call to read_registry_string");
+ return NULL;
+ }
+
+ ret = RegOpenKeyExW (root, key, 0, KEY_READ, &key_handle);
+ if (ret != ERROR_SUCCESS)
+ {
+ ERRORPRINTF ("Failed to open key.");
+ return NULL;
+ }
+
+ /* Get the size */
+ ret = RegQueryValueExW (key_handle, name, 0, NULL, NULL, &size);
+ if (ret != ERROR_MORE_DATA && !(ret == ERROR_SUCCESS && size != 0))
+ {
+ ERRORPRINTF ("Failed to get required registry size.");
+ return retval;
+ }
+
+ /* Size is size in bytes not in characters */
+ buf = xmalloc (size + sizeof(wchar_t));
+
+ /* If the stored value is not zero terminated the returned value also
+ is not zero terminated. That's why we reserve more and ensure it's
+ initialized. */
+ memset (buf, 0, size + sizeof(wchar_t));
+
+ ret = RegQueryValueExW (key_handle, name, 0, &type, (LPBYTE) buf, &size);
+ if (ret != ERROR_SUCCESS)
+ {
+ ERRORPRINTF ("Failed get registry value.");
+ return retval;
+ }
+
+ if (type == REG_SZ || (type == REG_EXPAND_SZ && wcschr (buf, '%') == NULL))
+ {
+ /* Nothing to expand, we are done */
+ retval = wchar_to_utf8 (buf, wcslen (buf));
+ goto done;
+ }
+
+ if (type != REG_EXPAND_SZ)
+ {
+ ERRORPRINTF ("Unhandled registry type %i", type);
+ goto done;
+ }
+
+ /* Expand the registry string */
+ ex_size = ExpandEnvironmentStringsW (buf, NULL, 0);
+
+ if (ex_size == 0)
+ {
+ PRINTLASTERROR ("Failed to determine expanded environment size.");
+ goto done;
+ }
+
+ ex_buf = xmalloc ((ex_size + 1) * sizeof(wchar_t));
+
+ dwRet = ExpandEnvironmentStringsW (buf, ex_buf, ex_size);
+
+ ex_buf[ex_size] = '\0'; /* Make sure it's a string */
+
+ if (dwRet == 0 || dwRet != ex_size)
+ {
+ PRINTLASTERROR ("Failed to expand environment variables.");
+ goto done;
+ }
+
+ retval = wchar_to_utf8 (ex_buf, ex_size);
+
+done:
+ xfree (ex_buf);
+ xfree (buf);
+
+ RegCloseKey (key_handle);
+ return retval;
+}
/**@brief Get the path to all users default registry hive
*
* Enumerates the keys in #PROFILE_LIST and retuns a
@@ -152,7 +259,6 @@
*
* @returns a newly allocated strv of the paths to the registry hives or NULL
*/
-
static char**
locate_other_hives()
{
@@ -198,6 +304,11 @@
key_name, &key_len,
NULL, NULL, NULL, NULL)) == ERROR_SUCCESS)
{
+ char *profile_path = NULL;
+ wchar_t *key_path = NULL;
+ size_t key_path_len = 0,
+ profile_path_len = 0;
+
if (key_len == 257)
{
ERRORPRINTF ("Registry key too long.");
@@ -215,7 +326,30 @@
continue;
}
+ key_path_len = key_len + wcslen(PROFILE_LIST L"\\") + 1;
+ key_path = xmalloc (key_path_len * sizeof (wchar_t));
+
+ wcscpy_s (key_path, key_path_len, PROFILE_LIST L"\\");
+ wcscat_s (key_path, key_path_len, key_name);
+ key_path[key_len - 1] = '\0';
+
DEBUGPRINTF ("Key : %S", key_name);
+ profile_path = read_registry_string (HKEY_LOCAL_MACHINE,
+ key_path, L"ProfileImagePath");
+ xfree (key_path);
+
+ if (profile_path == NULL)
+ {
+ ERRORPRINTF ("Failed to get profile path.");
+ continue;
+ }
+ profile_path_len = strlen (profile_path);
+ str_append_str (&profile_path, &profile_path_len, "\\ntuser.dat", 11);
+
+ strv_append (&retval, profile_path, profile_path_len);
+ DEBUGPRINTF ("Trying to access registry hive: %s", profile_path);
+
+ xfree (profile_path);
}
if (ret != ERROR_NO_MORE_ITEMS)
More information about the Trustbridge-commits
mailing list