[PATCH 1/3] reg: Split 'query' functions from reg.c

Hugh McMaster hugh.mcmaster at outlook.com
Wed Mar 17 07:38:04 CDT 2021


Signed-off-by: Hugh McMaster <hugh.mcmaster at outlook.com>
---
 programs/reg/Makefile.in |   1 +
 programs/reg/query.c     | 329 +++++++++++++++++++++++++++++++++++++++
 programs/reg/reg.c       | 315 +------------------------------------
 programs/reg/reg.h       |  16 +-
 4 files changed, 346 insertions(+), 315 deletions(-)
 create mode 100644 programs/reg/query.c

diff --git a/programs/reg/Makefile.in b/programs/reg/Makefile.in
index 248b470eb31..3203126db66 100644
--- a/programs/reg/Makefile.in
+++ b/programs/reg/Makefile.in
@@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mconsole -municode -mno-cygwin
 C_SRCS = \
 	export.c \
 	import.c \
+	query.c \
 	reg.c
 
 RC_SRCS = reg.rc
diff --git a/programs/reg/query.c b/programs/reg/query.c
new file mode 100644
index 00000000000..3d81d120bd2
--- /dev/null
+++ b/programs/reg/query.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2016-2017, 2021 Hugh McMaster
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include <wine/heap.h>
+#include "reg.h"
+
+static const WCHAR *reg_type_to_wchar(DWORD type)
+{
+    int i, array_size = ARRAY_SIZE(type_rels);
+
+    for (i = 0; i < array_size; i++)
+    {
+        if (type == type_rels[i].type)
+            return type_rels[i].name;
+    }
+
+    return NULL;
+}
+
+static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
+{
+    WCHAR *buffer = NULL;
+    int i;
+
+    switch (type)
+    {
+        case REG_SZ:
+        case REG_EXPAND_SZ:
+            buffer = heap_xalloc(size_bytes);
+            lstrcpyW(buffer, (WCHAR *)src);
+            break;
+        case REG_NONE:
+        case REG_BINARY:
+        {
+            WCHAR *ptr;
+            static const WCHAR fmt[] = {'%','0','2','X',0};
+
+            buffer = heap_xalloc((size_bytes * 2 + 1) * sizeof(WCHAR));
+            ptr = buffer;
+            for (i = 0; i < size_bytes; i++)
+                ptr += swprintf(ptr, 3, fmt, src[i]);
+            break;
+        }
+        case REG_DWORD:
+     /* case REG_DWORD_LITTLE_ENDIAN: */
+        case REG_DWORD_BIG_ENDIAN:
+        {
+            const int zero_x_dword = 10;
+            static const WCHAR fmt[] = {'0','x','%','x',0};
+
+            buffer = heap_xalloc((zero_x_dword + 1) * sizeof(WCHAR));
+            swprintf(buffer, zero_x_dword + 1, fmt, *(DWORD *)src);
+            break;
+        }
+        case REG_MULTI_SZ:
+        {
+            const int two_wchars = 2 * sizeof(WCHAR);
+            DWORD tmp_size;
+            const WCHAR *tmp = (const WCHAR *)src;
+            int len, destindex;
+
+            if (size_bytes <= two_wchars)
+            {
+                buffer = heap_xalloc(sizeof(WCHAR));
+                *buffer = 0;
+                return buffer;
+            }
+
+            tmp_size = size_bytes - two_wchars; /* exclude both null terminators */
+            buffer = heap_xalloc(tmp_size * 2 + sizeof(WCHAR));
+            len = tmp_size / sizeof(WCHAR);
+
+            for (i = 0, destindex = 0; i < len; i++, destindex++)
+            {
+                if (tmp[i])
+                    buffer[destindex] = tmp[i];
+                else
+                {
+                    buffer[destindex++] = '\\';
+                    buffer[destindex] = '0';
+                }
+            }
+            buffer[destindex] = 0;
+            break;
+        }
+    }
+    return buffer;
+}
+
+static const WCHAR newlineW[] = {'\n',0};
+
+static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD data_size)
+{
+    static const WCHAR fmt[] = {' ',' ',' ',' ','%','1',0};
+    WCHAR defval[32];
+    WCHAR *reg_data;
+
+    if (value_name && value_name[0])
+        output_string(fmt, value_name);
+    else
+    {
+        LoadStringW(GetModuleHandleW(NULL), STRING_DEFAULT_VALUE, defval, ARRAY_SIZE(defval));
+        output_string(fmt, defval);
+    }
+    output_string(fmt, reg_type_to_wchar(type));
+
+    if (data)
+    {
+        reg_data = reg_data_to_wchar(type, data, data_size);
+        output_string(fmt, reg_data);
+        heap_free(reg_data);
+    }
+    else
+    {
+        LoadStringW(GetModuleHandleW(NULL), STRING_VALUE_NOT_SET, defval, ARRAY_SIZE(defval));
+        output_string(fmt, defval);
+    }
+    output_string(newlineW);
+}
+
+static unsigned int num_values_found = 0;
+
+static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
+{
+    LONG rc;
+    DWORD max_data_bytes = 2048, data_size;
+    DWORD subkey_len;
+    DWORD type, path_len, i;
+    BYTE *data;
+    WCHAR fmt[] = {'%','1','\n',0};
+    WCHAR *subkey_name, *subkey_path;
+    HKEY subkey;
+
+    data = heap_xalloc(max_data_bytes);
+
+    for (;;)
+    {
+        data_size = max_data_bytes;
+        rc = RegQueryValueExW(key, value_name, NULL, &type, data, &data_size);
+        if (rc == ERROR_MORE_DATA)
+        {
+            max_data_bytes = data_size;
+            data = heap_xrealloc(data, max_data_bytes);
+        }
+        else break;
+    }
+
+    if (rc == ERROR_SUCCESS)
+    {
+        output_string(fmt, path);
+        output_value(value_name, type, data, data_size);
+        output_string(newlineW);
+        num_values_found++;
+    }
+
+    heap_free(data);
+
+    if (!recurse)
+    {
+        if (rc == ERROR_FILE_NOT_FOUND)
+        {
+            if (value_name && *value_name)
+            {
+                output_message(STRING_CANNOT_FIND);
+                return 1;
+            }
+            output_string(fmt, path);
+            output_value(NULL, REG_SZ, NULL, 0);
+        }
+        return 0;
+    }
+
+    subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
+
+    path_len = lstrlenW(path);
+
+    i = 0;
+    for (;;)
+    {
+        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);
+            if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
+            {
+                query_value(subkey, value_name, subkey_path, recurse);
+                RegCloseKey(subkey);
+            }
+            heap_free(subkey_path);
+            i++;
+        }
+        else break;
+    }
+
+    heap_free(subkey_name);
+    return 0;
+}
+
+static int query_all(HKEY key, WCHAR *path, BOOL recurse)
+{
+    LONG rc;
+    DWORD max_value_len = 256, value_len;
+    DWORD max_data_bytes = 2048, data_size;
+    DWORD subkey_len;
+    DWORD i, type, path_len;
+    WCHAR fmt[] = {'%','1','\n',0};
+    WCHAR fmt_path[] = {'%','1','\\','%','2','\n',0};
+    WCHAR *value_name, *subkey_name, *subkey_path;
+    BYTE *data;
+    HKEY subkey;
+
+    output_string(fmt, path);
+
+    value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
+    data = heap_xalloc(max_data_bytes);
+
+    i = 0;
+    for (;;)
+    {
+        value_len = max_value_len;
+        data_size = max_data_bytes;
+        rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
+        if (rc == ERROR_SUCCESS)
+        {
+            output_value(value_name, type, data, data_size);
+            i++;
+        }
+        else if (rc == ERROR_MORE_DATA)
+        {
+            if (data_size > max_data_bytes)
+            {
+                max_data_bytes = data_size;
+                data = heap_xrealloc(data, max_data_bytes);
+            }
+            else
+            {
+                max_value_len *= 2;
+                value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
+            }
+        }
+        else break;
+    }
+
+    heap_free(data);
+    heap_free(value_name);
+
+    if (i || recurse)
+        output_string(newlineW);
+
+    subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
+
+    path_len = lstrlenW(path);
+
+    i = 0;
+    for (;;)
+    {
+        subkey_len = MAX_SUBKEY_LEN;
+        rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
+        if (rc == ERROR_SUCCESS)
+        {
+            if (recurse)
+            {
+                subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
+                if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
+                {
+                    query_all(subkey, subkey_path, recurse);
+                    RegCloseKey(subkey);
+                }
+                heap_free(subkey_path);
+            }
+            else output_string(fmt_path, path, subkey_name);
+            i++;
+        }
+        else break;
+    }
+
+    heap_free(subkey_name);
+
+    if (i && !recurse)
+        output_string(newlineW);
+
+    return 0;
+}
+
+int reg_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name,
+              BOOL value_empty, BOOL recurse)
+{
+    HKEY key;
+    int ret;
+
+    if (RegOpenKeyExW(root, path, 0, KEY_READ, &key) != ERROR_SUCCESS)
+    {
+        output_message(STRING_CANNOT_FIND);
+        return 1;
+    }
+
+    output_string(newlineW);
+
+    if (value_name || value_empty)
+    {
+        ret = query_value(key, value_name, key_name, recurse);
+        if (recurse)
+            output_message(STRING_MATCHES_FOUND, num_values_found);
+    }
+    else
+        ret = query_all(key, key_name, recurse);
+
+    RegCloseKey(key);
+
+    return ret;
+}
diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index 997a6703831..8b97c560118 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -61,12 +61,7 @@ static const WCHAR type_dword_le[] = {'R','E','G','_','D','W','O','R','D','_','L
 static const WCHAR type_dword_be[] = {'R','E','G','_','D','W','O','R','D','_','B','I','G','_','E','N','D','I','A','N',0};
 static const WCHAR type_multi_sz[] = {'R','E','G','_','M','U','L','T','I','_','S','Z',0};
 
-static const struct
-{
-    DWORD type;
-    const WCHAR *name;
-}
-type_rels[] =
+const struct reg_type_rels type_rels[] =
 {
     {REG_NONE, type_none},
     {REG_SZ, type_sz},
@@ -78,8 +73,6 @@ type_rels[] =
     {REG_MULTI_SZ, type_multi_sz},
 };
 
-static const WCHAR newlineW[] = {'\n',0};
-
 void *heap_xalloc(size_t size)
 {
     void *buf = heap_alloc(size);
@@ -158,7 +151,7 @@ void WINAPIV output_message(unsigned int id, ...)
     __ms_va_end(va_args);
 }
 
-static void WINAPIV output_string(const WCHAR *fmt, ...)
+void WINAPIV output_string(const WCHAR *fmt, ...)
 {
     __ms_va_list va_args;
 
@@ -517,117 +510,6 @@ static int reg_delete(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name
     return 0;
 }
 
-static WCHAR *reg_data_to_wchar(DWORD type, const BYTE *src, DWORD size_bytes)
-{
-    WCHAR *buffer = NULL;
-    int i;
-
-    switch (type)
-    {
-        case REG_SZ:
-        case REG_EXPAND_SZ:
-            buffer = heap_xalloc(size_bytes);
-            lstrcpyW(buffer, (WCHAR *)src);
-            break;
-        case REG_NONE:
-        case REG_BINARY:
-        {
-            WCHAR *ptr;
-            static const WCHAR fmt[] = {'%','0','2','X',0};
-
-            buffer = heap_xalloc((size_bytes * 2 + 1) * sizeof(WCHAR));
-            ptr = buffer;
-            for (i = 0; i < size_bytes; i++)
-                ptr += swprintf(ptr, 3, fmt, src[i]);
-            break;
-        }
-        case REG_DWORD:
-     /* case REG_DWORD_LITTLE_ENDIAN: */
-        case REG_DWORD_BIG_ENDIAN:
-        {
-            const int zero_x_dword = 10;
-            static const WCHAR fmt[] = {'0','x','%','x',0};
-
-            buffer = heap_xalloc((zero_x_dword + 1) * sizeof(WCHAR));
-            swprintf(buffer, zero_x_dword + 1, fmt, *(DWORD *)src);
-            break;
-        }
-        case REG_MULTI_SZ:
-        {
-            const int two_wchars = 2 * sizeof(WCHAR);
-            DWORD tmp_size;
-            const WCHAR *tmp = (const WCHAR *)src;
-            int len, destindex;
-
-            if (size_bytes <= two_wchars)
-            {
-                buffer = heap_xalloc(sizeof(WCHAR));
-                *buffer = 0;
-                return buffer;
-            }
-
-            tmp_size = size_bytes - two_wchars; /* exclude both null terminators */
-            buffer = heap_xalloc(tmp_size * 2 + sizeof(WCHAR));
-            len = tmp_size / sizeof(WCHAR);
-
-            for (i = 0, destindex = 0; i < len; i++, destindex++)
-            {
-                if (tmp[i])
-                    buffer[destindex] = tmp[i];
-                else
-                {
-                    buffer[destindex++] = '\\';
-                    buffer[destindex] = '0';
-                }
-            }
-            buffer[destindex] = 0;
-            break;
-        }
-    }
-    return buffer;
-}
-
-static const WCHAR *reg_type_to_wchar(DWORD type)
-{
-    int i, array_size = ARRAY_SIZE(type_rels);
-
-    for (i = 0; i < array_size; i++)
-    {
-        if (type == type_rels[i].type)
-            return type_rels[i].name;
-    }
-    return NULL;
-}
-
-static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD data_size)
-{
-    static const WCHAR fmt[] = {' ',' ',' ',' ','%','1',0};
-    WCHAR defval[32];
-    WCHAR *reg_data;
-
-    if (value_name && value_name[0])
-        output_string(fmt, value_name);
-    else
-    {
-        LoadStringW(GetModuleHandleW(NULL), STRING_DEFAULT_VALUE, defval, ARRAY_SIZE(defval));
-        output_string(fmt, defval);
-    }
-    output_string(fmt, reg_type_to_wchar(type));
-
-    if (data)
-    {
-        reg_data = reg_data_to_wchar(type, data, data_size);
-        output_string(fmt, reg_data);
-        heap_free(reg_data);
-    }
-    else
-    {
-        LoadStringW(GetModuleHandleW(NULL), STRING_VALUE_NOT_SET, defval, ARRAY_SIZE(defval));
-        output_string(fmt, defval);
-    }
-    output_string(newlineW);
-}
-
 WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len)
 {
     WCHAR *subkey_path;
@@ -639,199 +521,6 @@ WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD
     return subkey_path;
 }
 
-static unsigned int num_values_found = 0;
-
-static int query_value(HKEY key, WCHAR *value_name, WCHAR *path, BOOL recurse)
-{
-    LONG rc;
-    DWORD max_data_bytes = 2048, data_size;
-    DWORD subkey_len;
-    DWORD type, path_len, i;
-    BYTE *data;
-    WCHAR fmt[] = {'%','1','\n',0};
-    WCHAR *subkey_name, *subkey_path;
-    HKEY subkey;
-
-    data = heap_xalloc(max_data_bytes);
-
-    for (;;)
-    {
-        data_size = max_data_bytes;
-        rc = RegQueryValueExW(key, value_name, NULL, &type, data, &data_size);
-        if (rc == ERROR_MORE_DATA)
-        {
-            max_data_bytes = data_size;
-            data = heap_xrealloc(data, max_data_bytes);
-        }
-        else break;
-    }
-
-    if (rc == ERROR_SUCCESS)
-    {
-        output_string(fmt, path);
-        output_value(value_name, type, data, data_size);
-        output_string(newlineW);
-        num_values_found++;
-    }
-
-    heap_free(data);
-
-    if (!recurse)
-    {
-        if (rc == ERROR_FILE_NOT_FOUND)
-        {
-            if (value_name && *value_name)
-            {
-                output_message(STRING_CANNOT_FIND);
-                return 1;
-            }
-            output_string(fmt, path);
-            output_value(NULL, REG_SZ, NULL, 0);
-        }
-        return 0;
-    }
-
-    subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
-
-    path_len = lstrlenW(path);
-
-    i = 0;
-    for (;;)
-    {
-        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);
-            if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
-            {
-                query_value(subkey, value_name, subkey_path, recurse);
-                RegCloseKey(subkey);
-            }
-            heap_free(subkey_path);
-            i++;
-        }
-        else break;
-    }
-
-    heap_free(subkey_name);
-    return 0;
-}
-
-static int query_all(HKEY key, WCHAR *path, BOOL recurse)
-{
-    LONG rc;
-    DWORD max_value_len = 256, value_len;
-    DWORD max_data_bytes = 2048, data_size;
-    DWORD subkey_len;
-    DWORD i, type, path_len;
-    WCHAR fmt[] = {'%','1','\n',0};
-    WCHAR fmt_path[] = {'%','1','\\','%','2','\n',0};
-    WCHAR *value_name, *subkey_name, *subkey_path;
-    BYTE *data;
-    HKEY subkey;
-
-    output_string(fmt, path);
-
-    value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
-    data = heap_xalloc(max_data_bytes);
-
-    i = 0;
-    for (;;)
-    {
-        value_len = max_value_len;
-        data_size = max_data_bytes;
-        rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, &data_size);
-        if (rc == ERROR_SUCCESS)
-        {
-            output_value(value_name, type, data, data_size);
-            i++;
-        }
-        else if (rc == ERROR_MORE_DATA)
-        {
-            if (data_size > max_data_bytes)
-            {
-                max_data_bytes = data_size;
-                data = heap_xrealloc(data, max_data_bytes);
-            }
-            else
-            {
-                max_value_len *= 2;
-                value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
-            }
-        }
-        else break;
-    }
-
-    heap_free(data);
-    heap_free(value_name);
-
-    if (i || recurse)
-        output_string(newlineW);
-
-    subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
-
-    path_len = lstrlenW(path);
-
-    i = 0;
-    for (;;)
-    {
-        subkey_len = MAX_SUBKEY_LEN;
-        rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
-        if (rc == ERROR_SUCCESS)
-        {
-            if (recurse)
-            {
-                subkey_path = build_subkey_path(path, path_len, subkey_name, subkey_len);
-                if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
-                {
-                    query_all(subkey, subkey_path, recurse);
-                    RegCloseKey(subkey);
-                }
-                heap_free(subkey_path);
-            }
-            else output_string(fmt_path, path, subkey_name);
-            i++;
-        }
-        else break;
-    }
-
-    heap_free(subkey_name);
-
-    if (i && !recurse)
-        output_string(newlineW);
-
-    return 0;
-}
-
-static int reg_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name,
-                     BOOL value_empty, BOOL recurse)
-{
-    HKEY key;
-    int ret;
-
-    if (RegOpenKeyExW(root, path, 0, KEY_READ, &key) != ERROR_SUCCESS)
-    {
-        output_message(STRING_CANNOT_FIND);
-        return 1;
-    }
-
-    output_string(newlineW);
-
-    if (value_name || value_empty)
-    {
-        ret = query_value(key, value_name, key_name, recurse);
-        if (recurse)
-            output_message(STRING_MATCHES_FOUND, num_values_found);
-    }
-    else
-        ret = query_all(key, key_name, recurse);
-
-    RegCloseKey(key);
-
-    return ret;
-}
-
 static WCHAR *get_long_key(HKEY root, WCHAR *path)
 {
     DWORD i, array_size = ARRAY_SIZE(root_rels), len;
diff --git a/programs/reg/reg.h b/programs/reg/reg.h
index a27399d06a4..471ed9c4d55 100644
--- a/programs/reg/reg.h
+++ b/programs/reg/reg.h
@@ -24,19 +24,31 @@
 #define MAX_SUBKEY_LEN   257
 
 /* reg.c */
+struct reg_type_rels {
+    DWORD type;
+    const WCHAR *name;
+};
+
+extern const struct reg_type_rels type_rels[8];
+
 void *heap_xalloc(size_t size);
 void *heap_xrealloc(void *buf, size_t size);
 void output_writeconsole(const WCHAR *str, DWORD wlen);
 void WINAPIV output_message(unsigned int id, ...);
+void WINAPIV output_string(const WCHAR *fmt, ...);
 BOOL ask_confirm(unsigned int msgid, WCHAR *reg_info);
 HKEY path_get_rootkey(const WCHAR *path);
 WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD subkey_len);
 BOOL parse_registry_key(const WCHAR *key, HKEY *root, WCHAR **path, WCHAR **long_key);
 
+/* export.c */
+int reg_export(int argc, WCHAR *argv[]);
+
 /* import.c */
 int reg_import(const WCHAR *filename);
 
-/* export.c */
-int reg_export(int argc, WCHAR *argv[]);
+/* query.c */
+int reg_query(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name,
+              BOOL value_empty, BOOL recurse);
 
 #endif /* __REG_H__ */
-- 
2.31.0




More information about the wine-devel mailing list