https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bcb87edb6ac6482ac6f9c…
commit bcb87edb6ac6482ac6f9c3cbd96e4b0603699023
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sun Jan 16 20:25:08 2022 +0100
Commit: Thomas Csovcsity <thc.fr13nd(a)gmail.com>
CommitDate: Sun Jun 19 13:06:29 2022 +0200
[WINESYNC] reg: Split 'add' functions from reg.c.
Signed-off-by: Hugh McMaster <hugh.mcmaster(a)outlook.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id 7e7d92d5e97f89a409db0dd091419b4f1bfe7ed4 by Hugh McMaster
<hugh.mcmaster(a)outlook.com>
---
base/applications/cmdutils/reg/add.c | 213 +++++++++++++++++++++++++++++++++++
base/applications/cmdutils/reg/reg.c | 192 -------------------------------
base/applications/cmdutils/reg/reg.h | 4 +
sdk/tools/winesync/reg.cfg | 2 +-
4 files changed, 218 insertions(+), 193 deletions(-)
diff --git a/base/applications/cmdutils/reg/add.c b/base/applications/cmdutils/reg/add.c
new file mode 100644
index 00000000000..2d8521f9234
--- /dev/null
+++ b/base/applications/cmdutils/reg/add.c
@@ -0,0 +1,213 @@
+/*
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <windows.h>
+#include <wine/heap.h>
+#include "reg.h"
+
+static DWORD wchar_get_type(const WCHAR *type_name)
+{
+ DWORD i;
+
+ if (!type_name)
+ return REG_SZ;
+
+ for (i = 0; i < ARRAY_SIZE(type_rels); i++)
+ {
+ if (!wcsicmp(type_rels[i].name, type_name))
+ return type_rels[i].type;
+ }
+
+ return ~0u;
+}
+
+/* hexchar_to_byte from programs/regedit/hexedit.c */
+static inline BYTE hexchar_to_byte(WCHAR ch)
+{
+ if (ch >= '0' && ch <= '9')
+ return ch - '0';
+ else if (ch >= 'a' && ch <= 'f')
+ return ch - 'a' + 10;
+ else if (ch >= 'A' && ch <= 'F')
+ return ch - 'A' + 10;
+ else
+ return -1;
+}
+
+static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DWORD
*reg_count)
+{
+ static const WCHAR empty;
+ LPBYTE out_data = NULL;
+ *reg_count = 0;
+
+ if (!data) data = ∅
+
+ switch (reg_type)
+ {
+ case REG_NONE:
+ case REG_SZ:
+ case REG_EXPAND_SZ:
+ {
+ *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
+ out_data = heap_xalloc(*reg_count);
+ lstrcpyW((LPWSTR)out_data,data);
+ break;
+ }
+ case REG_DWORD:
+ /* case REG_DWORD_LITTLE_ENDIAN: */
+ case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */
+ {
+ LPWSTR rest;
+ unsigned long val;
+ val = wcstoul(data, &rest, (towlower(data[1]) == 'x') ? 16 :
10);
+ if (*rest || data[0] == '-' || (val == ~0u && errno ==
ERANGE)) {
+ output_message(STRING_MISSING_INTEGER);
+ break;
+ }
+ *reg_count = sizeof(DWORD);
+ out_data = heap_xalloc(*reg_count);
+ ((LPDWORD)out_data)[0] = val;
+ break;
+ }
+ case REG_BINARY:
+ {
+ BYTE hex0, hex1;
+ int i = 0, destByteIndex = 0, datalen = lstrlenW(data);
+ *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE);
+ out_data = heap_xalloc(*reg_count);
+ if(datalen % 2)
+ {
+ hex1 = hexchar_to_byte(data[i++]);
+ if(hex1 == 0xFF)
+ goto no_hex_data;
+ out_data[destByteIndex++] = hex1;
+ }
+ for(;i + 1 < datalen;i += 2)
+ {
+ hex0 = hexchar_to_byte(data[i]);
+ hex1 = hexchar_to_byte(data[i + 1]);
+ if(hex0 == 0xFF || hex1 == 0xFF)
+ goto no_hex_data;
+ out_data[destByteIndex++] = (hex0 << 4) | hex1;
+ }
+ break;
+ no_hex_data:
+ /* cleanup, print error */
+ heap_free(out_data);
+ output_message(STRING_MISSING_HEXDATA);
+ out_data = NULL;
+ break;
+ }
+ case REG_MULTI_SZ:
+ {
+ int i, destindex, len = lstrlenW(data);
+ WCHAR *buffer = heap_xalloc((len + 2) * sizeof(WCHAR));
+
+ for (i = 0, destindex = 0; i < len; i++, destindex++)
+ {
+ if (!separator && data[i] == '\\' && data[i + 1]
== '0')
+ {
+ buffer[destindex] = 0;
+ i++;
+ }
+ else if (data[i] == separator)
+ buffer[destindex] = 0;
+ else
+ buffer[destindex] = data[i];
+
+ if (destindex && !buffer[destindex - 1] &&
(!buffer[destindex] || destindex == 1))
+ {
+ heap_free(buffer);
+ output_message(STRING_INVALID_STRING);
+ return NULL;
+ }
+ }
+ buffer[destindex] = 0;
+ if (destindex && buffer[destindex - 1])
+ buffer[++destindex] = 0;
+ *reg_count = (destindex + 1) * sizeof(WCHAR);
+ return (BYTE *)buffer;
+ }
+ default:
+ output_message(STRING_UNHANDLED_TYPE, reg_type, data);
+ }
+
+ return out_data;
+}
+
+int reg_add(HKEY root, WCHAR *path, WCHAR *value_name, BOOL value_empty,
+ WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
+{
+ HKEY key;
+
+ if (RegCreateKeyW(root, path, &key) != ERROR_SUCCESS)
+ {
+ output_message(STRING_INVALID_KEY);
+ return 1;
+ }
+
+ if (value_name || value_empty || data)
+ {
+ DWORD reg_type;
+ DWORD reg_count = 0;
+ BYTE* reg_data = NULL;
+
+ if (!force)
+ {
+ if (RegQueryValueExW(key, value_name, NULL, NULL, NULL, NULL) ==
ERROR_SUCCESS)
+ {
+ if (!ask_confirm(STRING_OVERWRITE_VALUE, value_name))
+ {
+ RegCloseKey(key);
+ output_message(STRING_CANCELLED);
+ return 0;
+ }
+ }
+ }
+
+ reg_type = wchar_get_type(type);
+ if (reg_type == ~0u)
+ {
+ RegCloseKey(key);
+ output_message(STRING_UNSUPPORTED_TYPE, type);
+ return 1;
+ }
+ if ((reg_type == REG_DWORD || reg_type == REG_DWORD_BIG_ENDIAN) &&
!data)
+ {
+ RegCloseKey(key);
+ output_message(STRING_INVALID_CMDLINE);
+ return 1;
+ }
+
+ if (!(reg_data = get_regdata(data, reg_type, separator, ®_count)))
+ {
+ RegCloseKey(key);
+ return 1;
+ }
+
+ RegSetValueExW(key, value_name, 0, reg_type, reg_data, reg_count);
+ heap_free(reg_data);
+ }
+
+ RegCloseKey(key);
+ output_message(STRING_SUCCESS);
+
+ return 0;
+}
diff --git a/base/applications/cmdutils/reg/reg.c b/base/applications/cmdutils/reg/reg.c
index 81b2f1b295e..8be4a6e5b40 100644
--- a/base/applications/cmdutils/reg/reg.c
+++ b/base/applications/cmdutils/reg/reg.c
@@ -17,8 +17,6 @@
*/
#include <windows.h>
-#include <errno.h>
-#include <stdio.h>
#include <stdlib.h>
#include <wine/debug.h>
#include <wine/heap.h>
@@ -213,136 +211,6 @@ HKEY path_get_rootkey(const WCHAR *path)
return NULL;
}
-static DWORD wchar_get_type(const WCHAR *type_name)
-{
- DWORD i;
-
- if (!type_name)
- return REG_SZ;
-
- for (i = 0; i < ARRAY_SIZE(type_rels); i++)
- {
- if (!wcsicmp(type_rels[i].name, type_name))
- return type_rels[i].type;
- }
-
- return ~0u;
-}
-
-/* hexchar_to_byte from programs/regedit/hexedit.c */
-static inline BYTE hexchar_to_byte(WCHAR ch)
-{
- if (ch >= '0' && ch <= '9')
- return ch - '0';
- else if (ch >= 'a' && ch <= 'f')
- return ch - 'a' + 10;
- else if (ch >= 'A' && ch <= 'F')
- return ch - 'A' + 10;
- else
- return -1;
-}
-
-static LPBYTE get_regdata(const WCHAR *data, DWORD reg_type, WCHAR separator, DWORD
*reg_count)
-{
- static const WCHAR empty;
- LPBYTE out_data = NULL;
- *reg_count = 0;
-
- if (!data) data = ∅
-
- switch (reg_type)
- {
- case REG_NONE:
- case REG_SZ:
- case REG_EXPAND_SZ:
- {
- *reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
- out_data = heap_xalloc(*reg_count);
- lstrcpyW((LPWSTR)out_data,data);
- break;
- }
- case REG_DWORD:
- /* case REG_DWORD_LITTLE_ENDIAN: */
- case REG_DWORD_BIG_ENDIAN: /* Yes, this is correct! */
- {
- LPWSTR rest;
- unsigned long val;
- val = wcstoul(data, &rest, (towlower(data[1]) == 'x') ? 16 :
10);
- if (*rest || data[0] == '-' || (val == ~0u && errno ==
ERANGE)) {
- output_message(STRING_MISSING_INTEGER);
- break;
- }
- *reg_count = sizeof(DWORD);
- out_data = heap_xalloc(*reg_count);
- ((LPDWORD)out_data)[0] = val;
- break;
- }
- case REG_BINARY:
- {
- BYTE hex0, hex1;
- int i = 0, destByteIndex = 0, datalen = lstrlenW(data);
- *reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE);
- out_data = heap_xalloc(*reg_count);
- if(datalen % 2)
- {
- hex1 = hexchar_to_byte(data[i++]);
- if(hex1 == 0xFF)
- goto no_hex_data;
- out_data[destByteIndex++] = hex1;
- }
- for(;i + 1 < datalen;i += 2)
- {
- hex0 = hexchar_to_byte(data[i]);
- hex1 = hexchar_to_byte(data[i + 1]);
- if(hex0 == 0xFF || hex1 == 0xFF)
- goto no_hex_data;
- out_data[destByteIndex++] = (hex0 << 4) | hex1;
- }
- break;
- no_hex_data:
- /* cleanup, print error */
- heap_free(out_data);
- output_message(STRING_MISSING_HEXDATA);
- out_data = NULL;
- break;
- }
- case REG_MULTI_SZ:
- {
- int i, destindex, len = lstrlenW(data);
- WCHAR *buffer = heap_xalloc((len + 2) * sizeof(WCHAR));
-
- for (i = 0, destindex = 0; i < len; i++, destindex++)
- {
- if (!separator && data[i] == '\\' && data[i + 1]
== '0')
- {
- buffer[destindex] = 0;
- i++;
- }
- else if (data[i] == separator)
- buffer[destindex] = 0;
- else
- buffer[destindex] = data[i];
-
- if (destindex && !buffer[destindex - 1] &&
(!buffer[destindex] || destindex == 1))
- {
- heap_free(buffer);
- output_message(STRING_INVALID_STRING);
- return NULL;
- }
- }
- buffer[destindex] = 0;
- if (destindex && buffer[destindex - 1])
- buffer[++destindex] = 0;
- *reg_count = (destindex + 1) * sizeof(WCHAR);
- return (BYTE *)buffer;
- }
- default:
- output_message(STRING_UNHANDLED_TYPE, reg_type, data);
- }
-
- return out_data;
-}
-
static BOOL sane_path(const WCHAR *key)
{
unsigned int i = lstrlenW(key);
@@ -362,66 +230,6 @@ static BOOL sane_path(const WCHAR *key)
return TRUE;
}
-static int reg_add(HKEY root, WCHAR *path, WCHAR *value_name, BOOL value_empty,
- WCHAR *type, WCHAR separator, WCHAR *data, BOOL force)
-{
- HKEY key;
-
- if (RegCreateKeyW(root, path, &key) != ERROR_SUCCESS)
- {
- output_message(STRING_INVALID_KEY);
- return 1;
- }
-
- if (value_name || value_empty || data)
- {
- DWORD reg_type;
- DWORD reg_count = 0;
- BYTE* reg_data = NULL;
-
- if (!force)
- {
- if (RegQueryValueExW(key, value_name, NULL, NULL, NULL, NULL) ==
ERROR_SUCCESS)
- {
- if (!ask_confirm(STRING_OVERWRITE_VALUE, value_name))
- {
- RegCloseKey(key);
- output_message(STRING_CANCELLED);
- return 0;
- }
- }
- }
-
- reg_type = wchar_get_type(type);
- if (reg_type == ~0u)
- {
- RegCloseKey(key);
- output_message(STRING_UNSUPPORTED_TYPE, type);
- return 1;
- }
- if ((reg_type == REG_DWORD || reg_type == REG_DWORD_BIG_ENDIAN) &&
!data)
- {
- RegCloseKey(key);
- output_message(STRING_INVALID_CMDLINE);
- return 1;
- }
-
- if (!(reg_data = get_regdata(data, reg_type, separator, ®_count)))
- {
- RegCloseKey(key);
- return 1;
- }
-
- RegSetValueExW(key, value_name, 0, reg_type, reg_data, reg_count);
- heap_free(reg_data);
- }
-
- RegCloseKey(key);
- output_message(STRING_SUCCESS);
-
- return 0;
-}
-
WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD
subkey_len)
{
WCHAR *subkey_path;
diff --git a/base/applications/cmdutils/reg/reg.h b/base/applications/cmdutils/reg/reg.h
index c8baaa0f9a9..b14470b2cbf 100644
--- a/base/applications/cmdutils/reg/reg.h
+++ b/base/applications/cmdutils/reg/reg.h
@@ -41,6 +41,10 @@ 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);
+/* add.c */
+int reg_add(HKEY root, WCHAR *path, WCHAR *value_name, BOOL value_empty,
+ WCHAR *type, WCHAR separator, WCHAR *data, BOOL force);
+
/* delete.c */
int reg_delete(HKEY root, WCHAR *path, WCHAR *key_name, WCHAR *value_name,
BOOL value_empty, BOOL value_all, BOOL force);
diff --git a/sdk/tools/winesync/reg.cfg b/sdk/tools/winesync/reg.cfg
index bf7d17e38a6..49526f7bef5 100644
--- a/sdk/tools/winesync/reg.cfg
+++ b/sdk/tools/winesync/reg.cfg
@@ -4,4 +4,4 @@ directories:
files:
programs/reg/resource.h: base/applications/cmdutils/reg/resource.h
tags:
- wine: 81a3eecc3c2e7ddced2f25cabc6de47101fd4fb1
+ wine: 7e7d92d5e97f89a409db0dd091419b4f1bfe7ed4