[PATCH 2/2] reg: Add support for querying the registry with the /v and /ve switches

Hugh McMaster hugh.mcmaster at outlook.com
Wed Apr 13 00:38:54 CDT 2016


Recursion is supported.

Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 programs/reg/reg.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 78 insertions(+), 8 deletions(-)

diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index b9ff60a..7753020 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Andrew Riedi
+ * Copyright 2016 Hugh McMaster
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -749,6 +750,80 @@ static int query_all(HKEY key, WCHAR *path, BOOL recurse)
     return 0;
 }
 
+static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
+{
+    LONG rc;
+    DWORD num_subkeys, max_subkey_len, subkey_len;
+    DWORD max_data_bytes, data_size;
+    DWORD type, path_len;
+    BYTE *data;
+    WCHAR fmt[] = {'%','1','\n',0};
+    WCHAR newlineW[] = {'\n',0};
+    WCHAR *subkey_name, *subkey_path;
+    int i;
+    HKEY subkey;
+
+    rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, &num_subkeys, &max_subkey_len,
+                          NULL, NULL, NULL, &max_data_bytes, NULL, NULL);
+    if (rc)
+    {
+        ERR("RegQueryInfoKey failed: %d\n", rc);
+        return 1;
+    }
+
+    data = HeapAlloc(GetProcessHeap(), 0, max_data_bytes);
+    if (!data)
+    {
+        ERR("Failed to allocate memory for data\n");
+        return 1;
+    }
+
+    data_size = max_data_bytes;
+    rc = RegQueryValueExW(key, value_name, NULL, &type, data, &data_size);
+    if (rc == ERROR_SUCCESS)
+    {
+        output_string(fmt, path);
+        output_value(value_name, type, data, data_size);
+        output_string(newlineW);
+    }
+
+    HeapFree(GetProcessHeap(), 0, data);
+
+    if (!recurse)
+    {
+        if (rc == ERROR_FILE_NOT_FOUND)
+            return 1;
+        return 0;
+    }
+
+    max_subkey_len++;
+    subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len * sizeof(WCHAR));
+    if (!subkey_name)
+    {
+        ERR("Failed to allocate memory for subkey_name\n");
+        return 1;
+    }
+
+    path_len = strlenW(path);
+
+    for (i = 0; i < num_subkeys; i++)
+    {
+        subkey_len = max_subkey_len;
+        rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
+        if (rc == ERROR_SUCCESS)
+        {
+            subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
+            RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey);
+            query_value(subkey, value_name, subkey_path, recurse);
+            RegCloseKey(subkey);
+            HeapFree(GetProcessHeap(), 0, subkey_path);
+        }
+    }
+
+    HeapFree(GetProcessHeap(), 0, subkey_name);
+    return 0;
+}
+
 static WCHAR *get_long_path(HKEY root, WCHAR *path)
 {
     DWORD i, len;
@@ -780,8 +855,6 @@ static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL
 {
     WCHAR *p, *path;
     HKEY root, key;
-    static const WCHAR stubW[] = {'S','T','U','B',' ','Q','U','E','R','Y',' ',
-        '-',' ','%','1',' ','%','2',' ','%','3','!','d','!',' ','%','4','!','d','!','\n',0};
     int ret;
 
     if (!sane_path(key_name))
@@ -812,12 +885,9 @@ static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, BOOL
     path = get_long_path(root, p);
 
     if (value_name || value_empty)
-    {
-        output_string(stubW, key_name, value_name, value_empty, recurse);
-        return 1;
-    }
-
-    ret = query_all(key, path, recurse);
+        ret = query_value(key, value_name, path, recurse);
+    else
+        ret = query_all(key, path, recurse);
 
     HeapFree(GetProcessHeap(), 0, path);
     RegCloseKey(key);
-- 
1.9.1




More information about the wine-patches mailing list