Author: akhaldi
Date: Sun Sep 24 11:33:04 2017
New Revision: 75958
URL:
http://svn.reactos.org/svn/reactos?rev=75958&view=rev
Log:
[REG] Sync with Wine Staging 2.16. CORE-13762
39e0e81 reg: Null-terminate incomplete REG_EXPAND_SZ and REG_MULTI_SZ Unicode data.
82fc4c8 reg: Close any open registry keys before starting the key deletion process.
5de883c reg: Use the correct return codes during the import operation.
56e58e4 reg: Delete registry keys via the state machine.
d90f2a5 reg: Delete registry values via the state machine.
db98cc4 reg: Handle unknown registry data types in the state machine.
32d5368 reg: Import hex data via the state machine.
f1874c1 reg: Import REG_DWORD data via the state machine.
038f1c6 reg: Parse data types and import REG_SZ data via the state machine.
0565934 reg: Parse key names and value names in the state machine.
3e87a70 reg: Introduce a partial state machine for importing Windows 3.1 registry data.
aa386af reg: Add initial support for the import operation.
f2fbbec reg: Rename reg.h to resource.h.
c6c95a0 reg: Compile with msvcrt.
8c253c4 reg: Make some variables 'static const'.
337e0f4 reg: Avoid an uninitialized variable warning.
8abec73 reg: Dynamically allocate memory for the value name buffer when deleting all
registry values in a specified key.
e7ea838 reg: Use a helper function to resize a memory buffer.
a1bc33a reg: Use a helper function to free allocated memory.
a6e28cc reg: Use a helper function to allocate memory and die on failure.
90da210 reg: Account for sizeof(WCHAR) when resizing the value name buffer during the
query operation.
fb22f6c reg: Avoid using RegQueryInfoKey() to enumerate subkeys and values in the query
operation.
Added:
trunk/reactos/base/applications/cmdutils/reg/import.c (with props)
trunk/reactos/base/applications/cmdutils/reg/resource.h (with props)
Modified:
trunk/reactos/base/applications/cmdutils/reg/CMakeLists.txt
trunk/reactos/base/applications/cmdutils/reg/lang/bg-BG.rc
trunk/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc
trunk/reactos/base/applications/cmdutils/reg/lang/da-DK.rc
trunk/reactos/base/applications/cmdutils/reg/lang/de-DE.rc
trunk/reactos/base/applications/cmdutils/reg/lang/en-US.rc
trunk/reactos/base/applications/cmdutils/reg/lang/es-ES.rc
trunk/reactos/base/applications/cmdutils/reg/lang/fr-FR.rc
trunk/reactos/base/applications/cmdutils/reg/lang/it-IT.rc
trunk/reactos/base/applications/cmdutils/reg/lang/ja-JP.rc
trunk/reactos/base/applications/cmdutils/reg/lang/ko-KR.rc
trunk/reactos/base/applications/cmdutils/reg/lang/lt-LT.rc
trunk/reactos/base/applications/cmdutils/reg/lang/nl-NL.rc
trunk/reactos/base/applications/cmdutils/reg/lang/no-NO.rc
trunk/reactos/base/applications/cmdutils/reg/lang/pl-PL.rc
trunk/reactos/base/applications/cmdutils/reg/lang/pt-PT.rc
trunk/reactos/base/applications/cmdutils/reg/lang/ro-RO.rc
trunk/reactos/base/applications/cmdutils/reg/lang/ru-RU.rc
trunk/reactos/base/applications/cmdutils/reg/lang/sl-SI.rc
trunk/reactos/base/applications/cmdutils/reg/lang/sq-AL.rc
trunk/reactos/base/applications/cmdutils/reg/lang/sv-SE.rc
trunk/reactos/base/applications/cmdutils/reg/lang/tr-TR.rc
trunk/reactos/base/applications/cmdutils/reg/lang/uk-UA.rc
trunk/reactos/base/applications/cmdutils/reg/lang/zh-CN.rc
trunk/reactos/base/applications/cmdutils/reg/lang/zh-TW.rc
trunk/reactos/base/applications/cmdutils/reg/reg.c
trunk/reactos/base/applications/cmdutils/reg/reg.h
trunk/reactos/media/doc/README.WINE
Modified: trunk/reactos/base/applications/cmdutils/reg/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/CMakeLists.txt [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -2,7 +2,7 @@
remove_definitions(-D_WIN32_WINNT=0x502)
add_definitions(-D_WIN32_WINNT=0x600)
-add_executable(reg reg.c reg.rc)
+add_executable(reg import.c reg.c reg.rc)
set_module_type(reg win32cui UNICODE)
target_link_libraries(reg wine)
add_importlibs(reg advapi32 advapi32_vista user32 msvcrt kernel32 ntdll)
Added: trunk/reactos/base/applications/cmdutils/reg/import.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/import.c (added)
+++ trunk/reactos/base/applications/cmdutils/reg/import.c [iso-8859-1] Sun Sep 24 11:33:04
2017
@@ -0,0 +1,1042 @@
+/*
+ * Copyright 2017 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 <windef.h>
+#include <winbase.h>
+#include <winreg.h>
+#include <stdio.h>
+
+#include <wine/unicode.h>
+#include <wine/debug.h>
+
+#include "reg.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(reg);
+
+static WCHAR *GetWideString(const char *strA)
+{
+ if (strA)
+ {
+ WCHAR *strW;
+ int len = MultiByteToWideChar(CP_ACP, 0, strA, -1, NULL, 0);
+
+ strW = heap_xalloc(len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, strA, -1, strW, len);
+ return strW;
+ }
+ return NULL;
+}
+
+static WCHAR *GetWideStringN(const char *strA, int size, DWORD *len)
+{
+ if (strA)
+ {
+ WCHAR *strW;
+ *len = MultiByteToWideChar(CP_ACP, 0, strA, size, NULL, 0);
+
+ strW = heap_xalloc(*len * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, strA, size, strW, *len);
+ return strW;
+ }
+ *len = 0;
+ return NULL;
+}
+
+static WCHAR *(*get_line)(FILE *);
+
+/* parser definitions */
+enum parser_state
+{
+ HEADER, /* parsing the registry file version header */
+ PARSE_WIN31_LINE, /* parsing a Windows 3.1 registry line */
+ LINE_START, /* at the beginning of a registry line */
+ KEY_NAME, /* parsing a key name */
+ DELETE_KEY, /* deleting a registry key */
+ DEFAULT_VALUE_NAME, /* parsing a default value name */
+ QUOTED_VALUE_NAME, /* parsing a double-quoted value name */
+ DATA_START, /* preparing for data parsing operations */
+ DELETE_VALUE, /* deleting a registry value */
+ DATA_TYPE, /* parsing the registry data type */
+ STRING_DATA, /* parsing REG_SZ data */
+ DWORD_DATA, /* parsing DWORD data */
+ HEX_DATA, /* parsing REG_BINARY, REG_NONE, REG_EXPAND_SZ or REG_MULTI_SZ
data */
+ EOL_BACKSLASH, /* preparing to parse multiple lines of hex data */
+ HEX_MULTILINE, /* parsing multiple lines of hex data */
+ UNKNOWN_DATA, /* parsing an unhandled or invalid data type */
+ SET_VALUE, /* adding a value to the registry */
+ NB_PARSER_STATES
+};
+
+struct parser
+{
+ FILE *file; /* pointer to a registry file */
+ WCHAR two_wchars[2]; /* first two characters from the encoding check
*/
+ BOOL is_unicode; /* parsing Unicode or ASCII data */
+ short int reg_version; /* registry file version */
+ HKEY hkey; /* current registry key */
+ WCHAR *key_name; /* current key name */
+ WCHAR *value_name; /* value name */
+ DWORD parse_type; /* generic data type for parsing */
+ DWORD data_type; /* data type */
+ void *data; /* value data */
+ DWORD data_size; /* size of the data (in bytes) */
+ BOOL backslash; /* TRUE if the current line contains a backslash
*/
+ enum parser_state state; /* current parser state */
+};
+
+typedef WCHAR *(*parser_state_func)(struct parser *parser, WCHAR *pos);
+
+/* parser state machine functions */
+static WCHAR *header_state(struct parser *parser, WCHAR *pos);
+static WCHAR *parse_win31_line_state(struct parser *parser, WCHAR *pos);
+static WCHAR *line_start_state(struct parser *parser, WCHAR *pos);
+static WCHAR *key_name_state(struct parser *parser, WCHAR *pos);
+static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos);
+static WCHAR *default_value_name_state(struct parser *parser, WCHAR *pos);
+static WCHAR *quoted_value_name_state(struct parser *parser, WCHAR *pos);
+static WCHAR *data_start_state(struct parser *parser, WCHAR *pos);
+static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos);
+static WCHAR *data_type_state(struct parser *parser, WCHAR *pos);
+static WCHAR *string_data_state(struct parser *parser, WCHAR *pos);
+static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos);
+static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos);
+static WCHAR *eol_backslash_state(struct parser *parser, WCHAR *pos);
+static WCHAR *hex_multiline_state(struct parser *parser, WCHAR *pos);
+static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos);
+static WCHAR *set_value_state(struct parser *parser, WCHAR *pos);
+
+static const parser_state_func parser_funcs[NB_PARSER_STATES] =
+{
+ header_state, /* HEADER */
+ parse_win31_line_state, /* PARSE_WIN31_LINE */
+ line_start_state, /* LINE_START */
+ key_name_state, /* KEY_NAME */
+ delete_key_state, /* DELETE_KEY */
+ default_value_name_state, /* DEFAULT_VALUE_NAME */
+ quoted_value_name_state, /* QUOTED_VALUE_NAME */
+ data_start_state, /* DATA_START */
+ delete_value_state, /* DELETE_VALUE */
+ data_type_state, /* DATA_TYPE */
+ string_data_state, /* STRING_DATA */
+ dword_data_state, /* DWORD_DATA */
+ hex_data_state, /* HEX_DATA */
+ eol_backslash_state, /* EOL_BACKSLASH */
+ hex_multiline_state, /* HEX_MULTILINE */
+ unknown_data_state, /* UNKNOWN_DATA */
+ set_value_state, /* SET_VALUE */
+};
+
+/* set the new parser state and return the previous one */
+static inline enum parser_state set_state(struct parser *parser, enum parser_state
state)
+{
+ enum parser_state ret = parser->state;
+ parser->state = state;
+ return ret;
+}
+
+/******************************************************************************
+ * Converts a hex representation of a DWORD into a DWORD.
+ */
+static BOOL convert_hex_to_dword(WCHAR *str, DWORD *dw)
+{
+ WCHAR *p, *end;
+ int count = 0;
+
+ while (*str == ' ' || *str == '\t') str++;
+ if (!*str) goto error;
+
+ p = str;
+ while (isxdigitW(*p))
+ {
+ count++;
+ p++;
+ }
+ if (count > 8) goto error;
+
+ end = p;
+ while (*p == ' ' || *p == '\t') p++;
+ if (*p && *p != ';') goto error;
+
+ *end = 0;
+ *dw = strtoulW(str, &end, 16);
+ return TRUE;
+
+error:
+ return FALSE;
+}
+
+/******************************************************************************
+ * Converts comma-separated hex data into a binary string and modifies
+ * the input parameter to skip the concatenating backslash, if found.
+ *
+ * Returns TRUE or FALSE to indicate whether parsing was successful.
+ */
+static BOOL convert_hex_csv_to_hex(struct parser *parser, WCHAR **str)
+{
+ size_t size;
+ BYTE *d;
+ WCHAR *s;
+
+ parser->backslash = FALSE;
+
+ /* The worst case is 1 digit + 1 comma per byte */
+ size = ((lstrlenW(*str) + 1) / 2) + parser->data_size;
+ parser->data = heap_xrealloc(parser->data, size);
+
+ s = *str;
+ d = (BYTE *)parser->data + parser->data_size;
+
+ while (*s)
+ {
+ WCHAR *end;
+ unsigned long wc;
+
+ wc = strtoulW(s, &end, 16);
+ if (wc > 0xff) return FALSE;
+
+ if (s == end && wc == 0)
+ {
+ while (*end == ' ' || *end == '\t') end++;
+ if (*end == '\\')
+ {
+ parser->backslash = TRUE;
+ *str = end + 1;
+ return TRUE;
+ }
+ else if (*end == ';')
+ return TRUE;
+ return FALSE;
+ }
+
+ *d++ = wc;
+ parser->data_size++;
+
+ if (*end && *end != ',')
+ {
+ while (*end == ' ' || *end == '\t') end++;
+ if (*end && *end != ';') return FALSE;
+ return TRUE;
+ }
+
+ if (*end) end++;
+ s = end;
+ }
+
+ return TRUE;
+}
+
+/******************************************************************************
+ * Parses the data type of the registry value being imported and modifies
+ * the input parameter to skip the string representation of the data type.
+ *
+ * Returns TRUE or FALSE to indicate whether a data type was found.
+ */
+static BOOL parse_data_type(struct parser *parser, WCHAR **line)
+{
+ struct data_type { const WCHAR *tag; int len; int type; int parse_type; };
+
+ static const WCHAR quote[] = {'"'};
+ static const WCHAR hex[] = {'h','e','x',':'};
+ static const WCHAR dword[] =
{'d','w','o','r','d',':'};
+ static const WCHAR hexp[] = {'h','e','x','('};
+
+ static const struct data_type data_types[] = {
+ /* tag len type parse type */
+ { quote, 1, REG_SZ, REG_SZ },
+ { hex, 4, REG_BINARY, REG_BINARY },
+ { dword, 6, REG_DWORD, REG_DWORD },
+ { hexp, 4, -1, REG_BINARY }, /* REG_NONE, REG_EXPAND_SZ, REG_MULTI_SZ
*/
+ { NULL, 0, 0, 0 }
+ };
+
+ const struct data_type *ptr;
+
+ for (ptr = data_types; ptr->tag; ptr++)
+ {
+ if (strncmpW(ptr->tag, *line, ptr->len))
+ continue;
+
+ parser->parse_type = ptr->parse_type;
+ parser->data_type = ptr->parse_type;
+ *line += ptr->len;
+
+ if (ptr->type == -1)
+ {
+ WCHAR *end;
+ DWORD val;
+
+ if (!**line || tolowerW((*line)[1]) == 'x')
+ return FALSE;
+
+ /* "hex(xx):" is special */
+ val = wcstoul(*line, &end, 16);
+ if (*end != ')' || *(end + 1) != ':' || (val == ~0u
&& errno == ERANGE))
+ return FALSE;
+
+ parser->data_type = val;
+ *line = end + 2;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/******************************************************************************
+ * Replaces escape sequences with their character equivalents and
+ * null-terminates the string on the first non-escaped double quote.
+ *
+ * Assigns a pointer to the remaining unparsed data in the line.
+ * Returns TRUE or FALSE to indicate whether a closing double quote was found.
+ */
+static BOOL unescape_string(WCHAR *str, WCHAR **unparsed)
+{
+ int str_idx = 0; /* current character under analysis */
+ int val_idx = 0; /* the last character of the unescaped string */
+ int len = lstrlenW(str);
+ BOOL ret;
+
+ for (str_idx = 0; str_idx < len; str_idx++, val_idx++)
+ {
+ if (str[str_idx] == '\\')
+ {
+ str_idx++;
+ switch (str[str_idx])
+ {
+ case 'n':
+ str[val_idx] = '\n';
+ break;
+ case 'r':
+ str[val_idx] = '\r';
+ break;
+ case '0':
+ str[val_idx] = '\0';
+ break;
+ case '\\':
+ case '"':
+ str[val_idx] = str[str_idx];
+ break;
+ default:
+ if (!str[str_idx]) return FALSE;
+ output_message(STRING_ESCAPE_SEQUENCE, str[str_idx]);
+ str[val_idx] = str[str_idx];
+ break;
+ }
+ }
+ else if (str[str_idx] == '"')
+ break;
+ else
+ str[val_idx] = str[str_idx];
+ }
+
+ ret = (str[str_idx] == '"');
+ *unparsed = str + str_idx + 1;
+ str[val_idx] = '\0';
+ return ret;
+}
+
+static HKEY parse_key_name(WCHAR *key_name, WCHAR **key_path)
+{
+ if (!key_name) return 0;
+
+ *key_path = strchrW(key_name, '\\');
+ if (*key_path) (*key_path)++;
+
+ return path_get_rootkey(key_name);
+}
+
+static void close_key(struct parser *parser)
+{
+ if (parser->hkey)
+ {
+ heap_free(parser->key_name);
+ parser->key_name = NULL;
+
+ RegCloseKey(parser->hkey);
+ parser->hkey = NULL;
+ }
+}
+
+static LONG open_key(struct parser *parser, WCHAR *path)
+{
+ HKEY key_class;
+ WCHAR *key_path;
+ LONG res;
+
+ close_key(parser);
+
+ /* Get the registry class */
+ if (!path || !(key_class = parse_key_name(path, &key_path)))
+ return ERROR_INVALID_PARAMETER;
+
+ res = RegCreateKeyExW(key_class, key_path, 0, NULL, REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &parser->hkey, NULL);
+
+ if (res == ERROR_SUCCESS)
+ {
+ parser->key_name = heap_xalloc((lstrlenW(path) + 1) * sizeof(WCHAR));
+ lstrcpyW(parser->key_name, path);
+ }
+ else
+ parser->hkey = NULL;
+
+ return res;
+}
+
+static void free_parser_data(struct parser *parser)
+{
+ if (parser->parse_type == REG_DWORD || parser->parse_type == REG_BINARY)
+ heap_free(parser->data);
+
+ parser->data = NULL;
+ parser->data_size = 0;
+}
+
+static void prepare_hex_string_data(struct parser *parser)
+{
+ if (parser->data_type == REG_EXPAND_SZ || parser->data_type == REG_MULTI_SZ)
+ {
+ if (parser->is_unicode)
+ {
+ WCHAR *data = parser->data;
+ DWORD len = parser->data_size / sizeof(WCHAR);
+
+ if (data[len - 1] != 0)
+ {
+ data[len] = 0;
+ parser->data_size += sizeof(WCHAR);
+ }
+ }
+ else
+ {
+ BYTE *data = parser->data;
+
+ if (data[parser->data_size - 1] != 0)
+ {
+ data[parser->data_size] = 0;
+ parser->data_size++;
+ }
+
+ parser->data = GetWideStringN(parser->data, parser->data_size,
&parser->data_size);
+ parser->data_size *= sizeof(WCHAR);
+ heap_free(data);
+ }
+ }
+}
+
+enum reg_versions {
+ REG_VERSION_31,
+ REG_VERSION_40,
+ REG_VERSION_50,
+ REG_VERSION_FUZZY,
+ REG_VERSION_INVALID
+};
+
+static enum reg_versions parse_file_header(const WCHAR *s)
+{
+ static const WCHAR header_31[] =
{'R','E','G','E','D','I','T',0};
+ static const WCHAR header_40[] =
{'R','E','G','E','D','I','T','4',0};
+ static const WCHAR header_50[] =
{'W','i','n','d','o','w','s','
',
+
'R','e','g','i','s','t','r','y','
','E','d','i','t','o','r','
',
+
'V','e','r','s','i','o','n','
','5','.','0','0',0};
+
+ while (*s == ' ' || *s == '\t') s++;
+
+ if (!strcmpW(s, header_31))
+ return REG_VERSION_31;
+
+ if (!strcmpW(s, header_40))
+ return REG_VERSION_40;
+
+ if (!strcmpW(s, header_50))
+ return REG_VERSION_50;
+
+ /* The Windows version accepts registry file headers beginning with
"REGEDIT" and ending
+ * with other characters, as long as "REGEDIT" appears at the start of the
line. For example,
+ * "REGEDIT 4", "REGEDIT9" and "REGEDIT4FOO" are all
treated as valid file headers.
+ * In all such cases, however, the contents of the registry file are not imported.
+ */
+ if (!strncmpW(s, header_31, 7)) /* "REGEDIT" without NUL */
+ return REG_VERSION_FUZZY;
+
+ return REG_VERSION_INVALID;
+}
+
+/* handler for parser HEADER state */
+static WCHAR *header_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line, *header;
+
+ if (!(line = get_line(parser->file)))
+ return NULL;
+
+ if (!parser->is_unicode)
+ {
+ header = heap_xalloc((lstrlenW(line) + 3) * sizeof(WCHAR));
+ header[0] = parser->two_wchars[0];
+ header[1] = parser->two_wchars[1];
+ lstrcpyW(header + 2, line);
+ parser->reg_version = parse_file_header(header);
+ heap_free(header);
+ }
+ else parser->reg_version = parse_file_header(line);
+
+ switch (parser->reg_version)
+ {
+ case REG_VERSION_31:
+ set_state(parser, PARSE_WIN31_LINE);
+ break;
+ case REG_VERSION_40:
+ case REG_VERSION_50:
+ set_state(parser, LINE_START);
+ break;
+ default:
+ get_line(NULL); /* Reset static variables */
+ return NULL;
+ }
+
+ return line;
+}
+
+/* handler for parser PARSE_WIN31_LINE state */
+static WCHAR *parse_win31_line_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line, *value;
+ static WCHAR hkcr[] =
{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T'};
+ unsigned int key_end = 0;
+
+ if (!(line = get_line(parser->file)))
+ return NULL;
+
+ if (strncmpW(line, hkcr, ARRAY_SIZE(hkcr)))
+ return line;
+
+ /* get key name */
+ while (line[key_end] && !isspaceW(line[key_end])) key_end++;
+
+ value = line + key_end;
+ while (*value == ' ' || *value == '\t') value++;
+
+ if (*value == '=') value++;
+ if (*value == ' ') value++; /* at most one space is skipped */
+
+ line[key_end] = 0;
+
+ if (open_key(parser, line) != ERROR_SUCCESS)
+ {
+ output_message(STRING_OPEN_KEY_FAILED, line);
+ return line;
+ }
+
+ parser->value_name = NULL;
+ parser->data_type = REG_SZ;
+ parser->data = value;
+ parser->data_size = (lstrlenW(value) + 1) * sizeof(WCHAR);
+
+ set_state(parser, SET_VALUE);
+ return value;
+}
+
+/* handler for parser LINE_START state */
+static WCHAR *line_start_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line, *p;
+
+ if (!(line = get_line(parser->file)))
+ return NULL;
+
+ for (p = line; *p; p++)
+ {
+ switch (*p)
+ {
+ case '[':
+ set_state(parser, KEY_NAME);
+ return p + 1;
+ case '@':
+ set_state(parser, DEFAULT_VALUE_NAME);
+ return p;
+ case '"':
+ set_state(parser, QUOTED_VALUE_NAME);
+ return p + 1;
+ case ' ':
+ case '\t':
+ break;
+ default:
+ return p;
+ }
+ }
+
+ return p;
+}
+
+/* handler for parser KEY_NAME state */
+static WCHAR *key_name_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *p = pos, *key_end;
+
+ if (*p == ' ' || *p == '\t' || !(key_end = strrchrW(p,
']')))
+ goto done;
+
+ *key_end = 0;
+
+ if (*p == '-')
+ {
+ set_state(parser, DELETE_KEY);
+ return p + 1;
+ }
+ else if (open_key(parser, p) != ERROR_SUCCESS)
+ output_message(STRING_OPEN_KEY_FAILED, p);
+
+done:
+ set_state(parser, LINE_START);
+ return p;
+}
+
+/* handler for parser DELETE_KEY state */
+static WCHAR *delete_key_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *p = pos;
+
+ close_key(parser);
+
+ if (*p == 'H' || *p == 'h')
+ {
+ HKEY root;
+ WCHAR *path;
+
+ root = parse_key_name(p, &path);
+
+ if (root && path && *path)
+ RegDeleteTreeW(root, path);
+ }
+
+ set_state(parser, LINE_START);
+ return p;
+}
+
+/* handler for parser DEFAULT_VALUE_NAME state */
+static WCHAR *default_value_name_state(struct parser *parser, WCHAR *pos)
+{
+ heap_free(parser->value_name);
+ parser->value_name = NULL;
+
+ set_state(parser, DATA_START);
+ return pos + 1;
+}
+
+/* handler for parser QUOTED_VALUE_NAME state */
+static WCHAR *quoted_value_name_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *val_name = pos, *p;
+
+ if (parser->value_name)
+ {
+ heap_free(parser->value_name);
+ parser->value_name = NULL;
+ }
+
+ if (!unescape_string(val_name, &p))
+ goto invalid;
+
+ /* copy the value name in case we need to parse multiple lines and the buffer is
overwritten */
+ parser->value_name = heap_xalloc((lstrlenW(val_name) + 1) * sizeof(WCHAR));
+ lstrcpyW(parser->value_name, val_name);
+
+ set_state(parser, DATA_START);
+ return p;
+
+invalid:
+ set_state(parser, LINE_START);
+ return val_name;
+}
+
+/* handler for parser DATA_START state */
+static WCHAR *data_start_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *p = pos;
+ unsigned int len;
+
+ while (*p == ' ' || *p == '\t') p++;
+ if (*p != '=') goto invalid;
+ p++;
+ while (*p == ' ' || *p == '\t') p++;
+
+ /* trim trailing whitespace */
+ len = strlenW(p);
+ while (len > 0 && (p[len - 1] == ' ' || p[len - 1] ==
'\t')) len--;
+ p[len] = 0;
+
+ if (*p == '-')
+ set_state(parser, DELETE_VALUE);
+ else
+ set_state(parser, DATA_TYPE);
+ return p;
+
+invalid:
+ set_state(parser, LINE_START);
+ return p;
+}
+
+/* handler for parser DELETE_VALUE state */
+static WCHAR *delete_value_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *p = pos + 1;
+
+ while (*p == ' ' || *p == '\t') p++;
+ if (*p && *p != ';') goto done;
+
+ RegDeleteValueW(parser->hkey, parser->value_name);
+
+done:
+ set_state(parser, LINE_START);
+ return p;
+}
+
+/* handler for parser DATA_TYPE state */
+static WCHAR *data_type_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line = pos;
+
+ if (!parse_data_type(parser, &line))
+ {
+ set_state(parser, LINE_START);
+ return line;
+ }
+
+ switch (parser->parse_type)
+ {
+ case REG_SZ:
+ set_state(parser, STRING_DATA);
+ break;
+ case REG_DWORD:
+ set_state(parser, DWORD_DATA);
+ break;
+ case REG_BINARY: /* all hex data types, including undefined */
+ set_state(parser, HEX_DATA);
+ break;
+ default:
+ set_state(parser, UNKNOWN_DATA);
+ }
+
+ return line;
+}
+
+/* handler for parser STRING_DATA state */
+static WCHAR *string_data_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line;
+
+ parser->data = pos;
+
+ if (!unescape_string(parser->data, &line))
+ goto invalid;
+
+ while (*line == ' ' || *line == '\t') line++;
+ if (*line && *line != ';') goto invalid;
+
+ parser->data_size = (lstrlenW(parser->data) + 1) * sizeof(WCHAR);
+
+ set_state(parser, SET_VALUE);
+ return line;
+
+invalid:
+ free_parser_data(parser);
+ set_state(parser, LINE_START);
+ return line;
+}
+
+/* handler for parser DWORD_DATA state */
+static WCHAR *dword_data_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line = pos;
+
+ parser->data = heap_xalloc(sizeof(DWORD));
+
+ if (!convert_hex_to_dword(line, parser->data))
+ goto invalid;
+
+ parser->data_size = sizeof(DWORD);
+
+ set_state(parser, SET_VALUE);
+ return line;
+
+invalid:
+ free_parser_data(parser);
+ set_state(parser, LINE_START);
+ return line;
+}
+
+/* handler for parser HEX_DATA state */
+static WCHAR *hex_data_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line = pos;
+
+ if (!convert_hex_csv_to_hex(parser, &line))
+ goto invalid;
+
+ if (parser->backslash)
+ {
+ set_state(parser, EOL_BACKSLASH);
+ return line;
+ }
+
+ prepare_hex_string_data(parser);
+
+ set_state(parser, SET_VALUE);
+ return line;
+
+invalid:
+ free_parser_data(parser);
+ set_state(parser, LINE_START);
+ return line;
+}
+
+/* handler for parser EOL_BACKSLASH state */
+static WCHAR *eol_backslash_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *p = pos;
+
+ while (*p == ' ' || *p == '\t') p++;
+ if (*p && *p != ';') goto invalid;
+
+ set_state(parser, HEX_MULTILINE);
+ return pos;
+
+invalid:
+ free_parser_data(parser);
+ set_state(parser, LINE_START);
+ return p;
+}
+
+/* handler for parser HEX_MULTILINE state */
+static WCHAR *hex_multiline_state(struct parser *parser, WCHAR *pos)
+{
+ WCHAR *line;
+
+ if (!(line = get_line(parser->file)))
+ {
+ prepare_hex_string_data(parser);
+ set_state(parser, SET_VALUE);
+ return pos;
+ }
+
+ while (*line == ' ' || *line == '\t') line++;
+ if (!*line || *line == ';') return line;
+
+ if (!isxdigitW(*line)) goto invalid;
+
+ set_state(parser, HEX_DATA);
+ return line;
+
+invalid:
+ free_parser_data(parser);
+ set_state(parser, LINE_START);
+ return line;
+}
+
+/* handler for parser UNKNOWN_DATA state */
+static WCHAR *unknown_data_state(struct parser *parser, WCHAR *pos)
+{
+ FIXME("Unknown registry data type [0x%x]\n", parser->data_type);
+
+ set_state(parser, LINE_START);
+ return pos;
+}
+
+/* handler for parser SET_VALUE state */
+static WCHAR *set_value_state(struct parser *parser, WCHAR *pos)
+{
+ RegSetValueExW(parser->hkey, parser->value_name, 0, parser->data_type,
+ parser->data, parser->data_size);
+
+ free_parser_data(parser);
+
+ if (parser->reg_version == REG_VERSION_31)
+ set_state(parser, PARSE_WIN31_LINE);
+ else
+ set_state(parser, LINE_START);
+
+ return pos;
+}
+
+#define REG_VAL_BUF_SIZE 4096
+
+static WCHAR *get_lineA(FILE *fp)
+{
+ static WCHAR *lineW;
+ static size_t size;
+ static char *buf, *next;
+ char *line;
+
+ heap_free(lineW);
+
+ if (!fp) goto cleanup;
+
+ if (!size)
+ {
+ size = REG_VAL_BUF_SIZE;
+ buf = heap_xalloc(size);
+ *buf = 0;
+ next = buf;
+ }
+ line = next;
+
+ while (next)
+ {
+ char *p = strpbrk(line, "\r\n");
+ if (!p)
+ {
+ size_t len, count;
+ len = strlen(next);
+ memmove(buf, next, len + 1);
+ if (size - len < 3)
+ {
+ size *= 2;
+ buf = heap_xrealloc(buf, size);
+ }
+ if (!(count = fread(buf + len, 1, size - len - 1, fp)))
+ {
+ next = NULL;
+ lineW = GetWideString(buf);
+ return lineW;
+ }
+ buf[len + count] = 0;
+ next = buf;
+ line = buf;
+ continue;
+ }
+ next = p + 1;
+ if (*p == '\r' && *(p + 1) == '\n') next++;
+ *p = 0;
+ lineW = GetWideString(line);
+ return lineW;
+ }
+
+cleanup:
+ lineW = NULL;
+ if (size) heap_free(buf);
+ size = 0;
+ return NULL;
+}
+
+static WCHAR *get_lineW(FILE *fp)
+{
+ static size_t size;
+ static WCHAR *buf, *next;
+ WCHAR *line;
+
+ if (!fp) goto cleanup;
+
+ if (!size)
+ {
+ size = REG_VAL_BUF_SIZE;
+ buf = heap_xalloc(size * sizeof(WCHAR));
+ *buf = 0;
+ next = buf;
+ }
+ line = next;
+
+ while (next)
+ {
+ static const WCHAR line_endings[] = {'\r','\n',0};
+ WCHAR *p = strpbrkW(line, line_endings);
+ if (!p)
+ {
+ size_t len, count;
+ len = strlenW(next);
+ memmove(buf, next, (len + 1) * sizeof(WCHAR));
+ if (size - len < 3)
+ {
+ size *= 2;
+ buf = heap_xrealloc(buf, size * sizeof(WCHAR));
+ }
+ if (!(count = fread(buf + len, sizeof(WCHAR), size - len - 1, fp)))
+ {
+ next = NULL;
+ return buf;
+ }
+ buf[len + count] = 0;
+ next = buf;
+ line = buf;
+ continue;
+ }
+ next = p + 1;
+ if (*p == '\r' && *(p + 1) == '\n') next++;
+ *p = 0;
+ return line;
+ }
+
+cleanup:
+ if (size) heap_free(buf);
+ size = 0;
+ return NULL;
+}
+
+int reg_import(const WCHAR *filename)
+{
+ FILE *fp;
+ static const WCHAR rb_mode[] = {'r','b',0};
+ BYTE s[2];
+ struct parser parser;
+ WCHAR *pos;
+
+ fp = _wfopen(filename, rb_mode);
+ if (!fp)
+ {
+ output_message(STRING_FILE_NOT_FOUND, filename);
+ return 1;
+ }
+
+ if (fread(s, sizeof(WCHAR), 1, fp) != 1)
+ goto error;
+
+ parser.is_unicode = (s[0] == 0xff && s[1] == 0xfe);
+ get_line = parser.is_unicode ? get_lineW : get_lineA;
+
+ parser.file = fp;
+ parser.two_wchars[0] = s[0];
+ parser.two_wchars[1] = s[1];
+ parser.reg_version = -1;
+ parser.hkey = NULL;
+ parser.key_name = NULL;
+ parser.value_name = NULL;
+ parser.parse_type = 0;
+ parser.data_type = 0;
+ parser.data = NULL;
+ parser.data_size = 0;
+ parser.backslash = FALSE;
+ parser.state = HEADER;
+
+ pos = parser.two_wchars;
+
+ /* parser main loop */
+ while (pos)
+ pos = (parser_funcs[parser.state])(&parser, pos);
+
+ if (parser.reg_version == REG_VERSION_INVALID)
+ goto error;
+
+ heap_free(parser.value_name);
+ close_key(&parser);
+
+ fclose(fp);
+ return 0;
+
+error:
+ fclose(fp);
+ return 1;
+}
Propchange: trunk/reactos/base/applications/cmdutils/reg/import.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/bg-BG.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/bg-BG.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/bg-BG.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/cs-CZ.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -38,4 +38,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/da-DK.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/da-DK.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/da-DK.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/de-DE.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/de-DE.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/de-DE.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/en-US.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/en-US.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/es-ES.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/es-ES.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/es-ES.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/fr-FR.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/fr-FR.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/fr-FR.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/it-IT.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/it-IT.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/it-IT.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/ja-JP.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/ja-JP.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/ja-JP.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/ko-KR.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/ko-KR.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/ko-KR.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/lt-LT.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/lt-LT.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/lt-LT.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/nl-NL.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/nl-NL.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/nl-NL.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/no-NO.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/no-NO.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/no-NO.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/pl-PL.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/pl-PL.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/pl-PL.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/pt-PT.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/pt-PT.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/pt-PT.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/ro-RO.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/ro-RO.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/ro-RO.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -39,4 +39,8 @@
STRING_REG_HELP, "TastaÈi «REG /?» pentru mai multe informaÈii.\n"
STRING_FUNC_HELP, "TastaÈi «REG %1 /?» pentru mai multe informaÈii.\n"
STRING_VALUE_NOT_SET, "(valoare nealocatÄ)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/ru-RU.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/ru-RU.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/ru-RU.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "ÐведиÑе ""REG /?"" длÑ
полÑÑÐµÐ½Ð¸Ñ ÑпÑавки по иÑполÑзованиÑ..\n"
STRING_FUNC_HELP, "ÐведиÑе ""REG %1 /?"" длÑ
полÑÑÐµÐ½Ð¸Ñ ÑпÑавки по иÑполÑзованиÑ..\n"
STRING_VALUE_NOT_SET, "(знаÑение не Ñказано)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/sl-SI.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/sl-SI.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/sl-SI.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/sq-AL.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/sq-AL.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/sq-AL.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -37,4 +37,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/sv-SE.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/sv-SE.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/sv-SE.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/tr-TR.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/tr-TR.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/tr-TR.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -35,4 +35,8 @@
STRING_REG_HELP, "Yardım için ""REG /?""
yazınız.\n"
STRING_FUNC_HELP, "Yardım için ""REG %1 /?""
yazınız.\n"
STRING_VALUE_NOT_SET, "(DeÄer belirlenmemiÅ.)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/uk-UA.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/uk-UA.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/uk-UA.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -33,4 +33,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/zh-CN.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/zh-CN.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/zh-CN.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -35,4 +35,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/lang/zh-TW.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/lang/zh-TW.rc [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/lang/zh-TW.rc [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -35,4 +35,8 @@
STRING_REG_HELP, "Type ""REG /?"" for help.\n"
STRING_FUNC_HELP, "Type ""REG %1 /?"" for help.\n"
STRING_VALUE_NOT_SET, "(value not set)"
+ STRING_IMPORT_USAGE, "REG IMPORT file.reg\n"
+ STRING_FILE_NOT_FOUND, "reg: The file '%1' was not found.\n"
+ STRING_OPEN_KEY_FAILED, "reg: Unable to open the registry key
'%1'.\n"
+ STRING_ESCAPE_SEQUENCE, "reg: Unrecognized escape sequence [\\%1!c!]\n"
}
Modified: trunk/reactos/base/applications/cmdutils/reg/reg.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/reg.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/reg.c [iso-8859-1] Sun Sep 24 11:33:04
2017
@@ -25,10 +25,7 @@
#include <shlwapi.h>
#include <wine/unicode.h>
#include <wine/debug.h>
-#include <errno.h>
#include "reg.h"
-
-#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*A))
WINE_DEFAULT_DEBUG_CHANNEL(reg);
@@ -84,6 +81,40 @@
{REG_MULTI_SZ, type_multi_sz},
};
+void *heap_xalloc(size_t size)
+{
+ void *buf = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!buf)
+ {
+ ERR("Out of memory!\n");
+ exit(1);
+ }
+ return buf;
+}
+
+void *heap_xrealloc(void *buf, size_t size)
+{
+ void *new_buf;
+
+ if (buf)
+ new_buf = HeapReAlloc(GetProcessHeap(), 0, buf, size);
+ else
+ new_buf = HeapAlloc(GetProcessHeap(), 0, size);
+
+ if (!new_buf)
+ {
+ ERR("Out of memory!\n");
+ exit(1);
+ }
+
+ return new_buf;
+}
+
+BOOL heap_free(void *buf)
+{
+ return HeapFree(GetProcessHeap(), 0, buf);
+}
+
static void output_writeconsole(const WCHAR *str, DWORD wlen)
{
DWORD count, ret;
@@ -99,12 +130,11 @@
* one in that case.
*/
len = WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, NULL, 0, NULL,
NULL);
- msgA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
- if (!msgA) return;
+ msgA = heap_xalloc(len);
WideCharToMultiByte(GetConsoleOutputCP(), 0, str, wlen, msgA, len, NULL, NULL);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
- HeapFree(GetProcessHeap(), 0, msgA);
+ heap_free(msgA);
}
}
@@ -125,7 +155,7 @@
LocalFree(str);
}
-static void __cdecl output_message(unsigned int id, ...)
+void __cdecl output_message(unsigned int id, ...)
{
WCHAR fmt[1024];
__ms_va_list va_args;
@@ -188,7 +218,7 @@
(input_path[length] == 0 || input_path[length] == '\\'));
}
-static HKEY path_get_rootkey(const WCHAR *path)
+HKEY path_get_rootkey(const WCHAR *path)
{
DWORD i;
@@ -246,7 +276,7 @@
case REG_EXPAND_SZ:
{
*reg_count = (lstrlenW(data) + 1) * sizeof(WCHAR);
- out_data = HeapAlloc(GetProcessHeap(),0,*reg_count);
+ out_data = heap_xalloc(*reg_count);
lstrcpyW((LPWSTR)out_data,data);
break;
}
@@ -256,13 +286,13 @@
{
LPWSTR rest;
unsigned long val;
- val = strtoulW(data, &rest, (tolowerW(data[1]) == 'x') ? 16 :
10);
- if (*rest || data[0] == '-' || (val == ~0u && errno ==
ERANGE) || val > ~0u) {
+ val = wcstoul(data, &rest, (tolowerW(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 = HeapAlloc(GetProcessHeap(),0,*reg_count);
+ out_data = heap_xalloc(*reg_count);
((LPDWORD)out_data)[0] = val;
break;
}
@@ -271,7 +301,7 @@
BYTE hex0, hex1;
int i = 0, destByteIndex = 0, datalen = lstrlenW(data);
*reg_count = ((datalen + datalen % 2) / 2) * sizeof(BYTE);
- out_data = HeapAlloc(GetProcessHeap(), 0, *reg_count);
+ out_data = heap_xalloc(*reg_count);
if(datalen % 2)
{
hex1 = hexchar_to_byte(data[i++]);
@@ -290,7 +320,7 @@
break;
no_hex_data:
/* cleanup, print error */
- HeapFree(GetProcessHeap(), 0, out_data);
+ heap_free(out_data);
output_message(STRING_MISSING_HEXDATA);
out_data = NULL;
break;
@@ -298,7 +328,7 @@
case REG_MULTI_SZ:
{
int i, destindex, len = strlenW(data);
- WCHAR *buffer = HeapAlloc(GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR));
+ WCHAR *buffer = heap_xalloc((len + 2) * sizeof(WCHAR));
for (i = 0, destindex = 0; i < len; i++, destindex++)
{
@@ -314,7 +344,7 @@
if (destindex && !buffer[destindex - 1] &&
(!buffer[destindex] || destindex == 1))
{
- HeapFree(GetProcessHeap(), 0, buffer);
+ heap_free(buffer);
output_message(STRING_INVALID_STRING);
return NULL;
}
@@ -402,7 +432,7 @@
}
RegSetValueExW(key, value_name, 0, reg_type, reg_data, reg_count);
- HeapFree(GetProcessHeap(),0,reg_data);
+ heap_free(reg_data);
}
RegCloseKey(key);
@@ -454,40 +484,35 @@
if (value_all)
{
- LPWSTR szValue;
- DWORD maxValue;
- DWORD count;
+ DWORD max_value_len = 256, value_len;
+ WCHAR *value_name;
LONG rc;
- rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, &maxValue, NULL, NULL, NULL);
- if (rc != ERROR_SUCCESS)
- {
- RegCloseKey(key);
- output_message(STRING_GENERAL_FAILURE);
- return 1;
- }
- maxValue++;
- szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
+ value_name = heap_xalloc(max_value_len * sizeof(WCHAR));
while (1)
{
- count = maxValue;
- rc = RegEnumValueW(key, 0, szValue, &count, NULL, NULL, NULL, NULL);
+ value_len = max_value_len;
+ rc = RegEnumValueW(key, 0, value_name, &value_len, NULL, NULL, NULL,
NULL);
if (rc == ERROR_SUCCESS)
{
- rc = RegDeleteValueW(key, szValue);
+ rc = RegDeleteValueW(key, value_name);
if (rc != ERROR_SUCCESS)
{
- HeapFree(GetProcessHeap(), 0, szValue);
+ heap_free(value_name);
RegCloseKey(key);
output_message(STRING_VALUEALL_FAILED, key_name);
return 1;
}
}
+ else if (rc == ERROR_MORE_DATA)
+ {
+ max_value_len *= 2;
+ value_name = heap_xrealloc(value_name, max_value_len * sizeof(WCHAR));
+ }
else break;
}
- HeapFree(GetProcessHeap(), 0, szValue);
+ heap_free(value_name);
}
else if (value_name || value_empty)
{
@@ -513,16 +538,16 @@
{
case REG_SZ:
case REG_EXPAND_SZ:
- buffer = HeapAlloc(GetProcessHeap(), 0, size_bytes);
+ buffer = heap_xalloc(size_bytes);
strcpyW(buffer, (WCHAR *)src);
break;
case REG_NONE:
case REG_BINARY:
{
WCHAR *ptr;
- WCHAR fmt[] = {'%','0','2','X',0};
-
- buffer = HeapAlloc(GetProcessHeap(), 0, (size_bytes * 2 + 1) *
sizeof(WCHAR));
+ 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 += sprintfW(ptr, fmt, src[i]);
@@ -533,9 +558,9 @@
case REG_DWORD_BIG_ENDIAN:
{
const int zero_x_dword = 10;
- WCHAR fmt[] = {'0','x','%','x',0};
-
- buffer = HeapAlloc(GetProcessHeap(), 0, (zero_x_dword + 1) * sizeof(WCHAR));
+ static const WCHAR fmt[] =
{'0','x','%','x',0};
+
+ buffer = heap_xalloc((zero_x_dword + 1) * sizeof(WCHAR));
sprintfW(buffer, fmt, *(DWORD *)src);
break;
}
@@ -548,13 +573,13 @@
if (size_bytes <= two_wchars)
{
- buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR));
+ buffer = heap_xalloc(sizeof(WCHAR));
*buffer = 0;
return buffer;
}
tmp_size = size_bytes - two_wchars; /* exclude both null terminators */
- buffer = HeapAlloc(GetProcessHeap(), 0, tmp_size * 2 + sizeof(WCHAR));
+ buffer = heap_xalloc(tmp_size * 2 + sizeof(WCHAR));
len = tmp_size / sizeof(WCHAR);
for (i = 0, destindex = 0; i < len; i++, destindex++)
@@ -588,10 +613,10 @@
static void output_value(const WCHAR *value_name, DWORD type, BYTE *data, DWORD
data_size)
{
- WCHAR fmt[] = {' ',' ',' ','
','%','1',0};
+ static const WCHAR fmt[] = {' ',' ',' ','
','%','1',0};
+ static const WCHAR newlineW[] = {'\n',0};
WCHAR defval[32];
WCHAR *reg_data;
- WCHAR newlineW[] = {'\n',0};
if (value_name && value_name[0])
output_string(fmt, value_name);
@@ -606,7 +631,7 @@
{
reg_data = reg_data_to_wchar(type, data, data_size);
output_string(fmt, reg_data);
- HeapFree(GetProcessHeap(), 0, reg_data);
+ heap_free(reg_data);
}
else
{
@@ -619,25 +644,23 @@
static WCHAR *build_subkey_path(WCHAR *path, DWORD path_len, WCHAR *subkey_name, DWORD
subkey_len)
{
WCHAR *subkey_path;
- WCHAR fmt[] = {'%','s','\\','%','s',0};
-
- subkey_path = HeapAlloc(GetProcessHeap(), 0, (path_len + subkey_len + 2) *
sizeof(WCHAR));
- if (!subkey_path)
- {
- ERR("Failed to allocate memory for subkey_path\n");
- return NULL;
- }
+ static const WCHAR fmt[] =
{'%','s','\\','%','s',0};
+
+ subkey_path = heap_xalloc((path_len + subkey_len + 2) * sizeof(WCHAR));
sprintfW(subkey_path, fmt, path, subkey_name);
+
return subkey_path;
}
static unsigned int num_values_found = 0;
+#define MAX_SUBKEY_LEN 257
+
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 max_data_bytes = 2048, data_size;
+ DWORD subkey_len;
DWORD type, path_len, i;
BYTE *data;
WCHAR fmt[] = {'%','1','\n',0};
@@ -645,23 +668,20 @@
WCHAR *subkey_name, *subkey_path;
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);
+ 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);
@@ -670,7 +690,7 @@
num_values_found++;
}
- HeapFree(GetProcessHeap(), 0, data);
+ heap_free(data);
if (!recurse)
{
@@ -687,19 +707,14 @@
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;
- }
+ subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
path_len = strlenW(path);
- for (i = 0; i < num_subkeys; i++)
- {
- subkey_len = max_subkey_len;
+ i = 0;
+ for (;;)
+ {
+ subkey_len = MAX_SUBKEY_LEN;
rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL,
NULL);
if (rc == ERROR_SUCCESS)
{
@@ -709,20 +724,22 @@
query_value(subkey, value_name, subkey_path, recurse);
RegCloseKey(subkey);
}
- HeapFree(GetProcessHeap(), 0, subkey_path);
- }
- }
-
- HeapFree(GetProcessHeap(), 0, subkey_name);
+ 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 num_subkeys, max_subkey_len, subkey_len;
- DWORD num_values, max_value_len, value_len;
- DWORD max_data_bytes, data_size;
+ 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};
@@ -731,60 +748,52 @@
BYTE *data;
HKEY subkey;
- rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, &num_subkeys, &max_subkey_len,
NULL,
- &num_values, &max_value_len, &max_data_bytes, NULL,
NULL);
- if (rc)
- {
- ERR("RegQueryInfoKey failed: %d\n", rc);
- return 1;
- }
-
output_string(fmt, path);
- max_value_len++;
- value_name = HeapAlloc(GetProcessHeap(), 0, max_value_len * sizeof(WCHAR));
- if (!value_name)
- {
- ERR("Failed to allocate memory for value_name\n");
- return 1;
- }
-
- data = HeapAlloc(GetProcessHeap(), 0, max_data_bytes);
- if (!data)
- {
- HeapFree(GetProcessHeap(), 0, value_name);
- ERR("Failed to allocate memory for data\n");
- return 1;
- }
-
- for (i = 0; i < num_values; i++)
+ 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);
- }
-
- HeapFree(GetProcessHeap(), 0, data);
- HeapFree(GetProcessHeap(), 0, value_name);
-
- if (num_values || recurse)
+ 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);
- 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;
- }
+ subkey_name = heap_xalloc(MAX_SUBKEY_LEN * sizeof(WCHAR));
path_len = strlenW(path);
- for (i = 0; i < num_subkeys; i++)
- {
- subkey_len = max_subkey_len;
+ i = 0;
+ for (;;)
+ {
+ subkey_len = MAX_SUBKEY_LEN;
rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL,
NULL);
if (rc == ERROR_SUCCESS)
{
@@ -796,15 +805,17 @@
query_all(subkey, subkey_path, recurse);
RegCloseKey(subkey);
}
- HeapFree(GetProcessHeap(), 0, subkey_path);
+ heap_free(subkey_path);
}
else output_string(fmt_path, path, subkey_name);
- }
- }
-
- HeapFree(GetProcessHeap(), 0, subkey_name);
-
- if (num_subkeys && !recurse)
+ i++;
+ }
+ else break;
+ }
+
+ heap_free(subkey_name);
+
+ if (i && !recurse)
output_string(newlineW);
return 0;
@@ -855,13 +866,13 @@
if (!path)
{
- long_key = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+ long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
strcpyW(long_key, root_rels[i].long_name);
return long_key;
}
len += strlenW(path) + 1; /* add one for the backslash */
- long_key = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
+ long_key = heap_xalloc((len + 1) * sizeof(WCHAR));
sprintfW(long_key, fmt, root_rels[i].long_name, path);
return long_key;
}
@@ -900,32 +911,38 @@
enum operations {
REG_ADD,
REG_DELETE,
+ REG_IMPORT,
REG_QUERY,
REG_INVALID
};
-static const WCHAR addW[] = {'a','d','d',0};
-static const WCHAR deleteW[] =
{'d','e','l','e','t','e',0};
-static const WCHAR queryW[] =
{'q','u','e','r','y',0};
-
static enum operations get_operation(const WCHAR *str, int *op_help)
{
- if (!lstrcmpiW(str, addW))
- {
- *op_help = STRING_ADD_USAGE;
- return REG_ADD;
- }
-
- if (!lstrcmpiW(str, deleteW))
- {
- *op_help = STRING_DELETE_USAGE;
- return REG_DELETE;
- }
-
- if (!lstrcmpiW(str, queryW))
- {
- *op_help = STRING_QUERY_USAGE;
- return REG_QUERY;
+ struct op_info { const WCHAR *op; int id; int help_id; };
+
+ static const WCHAR add[] = {'a','d','d',0};
+ static const WCHAR delete[] =
{'d','e','l','e','t','e',0};
+ static const WCHAR import[] =
{'i','m','p','o','r','t',0};
+ static const WCHAR query[] =
{'q','u','e','r','y',0};
+
+ static const struct op_info op_array[] =
+ {
+ { add, REG_ADD, STRING_ADD_USAGE },
+ { delete, REG_DELETE, STRING_DELETE_USAGE },
+ { import, REG_IMPORT, STRING_IMPORT_USAGE },
+ { query, REG_QUERY, STRING_QUERY_USAGE },
+ { NULL, -1, 0 }
+ };
+
+ const struct op_info *ptr;
+
+ for (ptr = op_array; ptr->op; ptr++)
+ {
+ if (!lstrcmpiW(str, ptr->op))
+ {
+ *op_help = ptr->help_id;
+ return ptr->id;
+ }
}
return REG_INVALID;
@@ -966,7 +983,7 @@
if (argc > 2)
show_op_help = is_help_switch(argvW[2]);
- if (argc == 2 || (show_op_help && argc > 3))
+ if (argc == 2 || ((show_op_help || op == REG_IMPORT) && argc > 3))
{
output_message(STRING_INVALID_SYNTAX);
output_message(STRING_FUNC_HELP, struprW(argvW[1]));
@@ -977,6 +994,9 @@
output_message(op_help);
return 0;
}
+
+ if (op == REG_IMPORT)
+ return reg_import(argvW[2]);
if (!parse_registry_key(argvW[2], &root, &path, &key_name))
return 1;
@@ -1061,7 +1081,7 @@
ret = reg_add(root, path, value_name, value_empty, type, separator, data,
force);
else if (op == REG_DELETE)
ret = reg_delete(root, path, key_name, value_name, value_empty, value_all,
force);
- else if (op == REG_QUERY)
+ else
ret = reg_query(root, path, key_name, value_name, value_empty, recurse);
return ret;
}
Modified: trunk/reactos/base/applications/cmdutils/reg/reg.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/reg.h [iso-8859-1] (original)
+++ trunk/reactos/base/applications/cmdutils/reg/reg.h [iso-8859-1] Sun Sep 24 11:33:04
2017
@@ -1,7 +1,5 @@
/*
- * REG.EXE - Wine-compatible reg program.
- *
- * Copyright 2008 Andrew Riedi
+ * Copyright 2017 Hugh McMaster
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -18,39 +16,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#pragma once
+#ifndef __REG_H__
+#define __REG_H__
-//#include <windef.h>
+#include "resource.h"
-/* Translation IDs. */
-#define STRING_USAGE 101
-#define STRING_ADD_USAGE 102
-#define STRING_DELETE_USAGE 103
-#define STRING_QUERY_USAGE 104
-#define STRING_SUCCESS 105
-#define STRING_INVALID_KEY 106
-#define STRING_INVALID_CMDLINE 107
-#define STRING_NO_REMOTE 108
-#define STRING_CANNOT_FIND 109
-#define STRING_UNSUPPORTED_TYPE 110
-#define STRING_MISSING_INTEGER 111
-#define STRING_MISSING_HEXDATA 112
-#define STRING_UNHANDLED_TYPE 113
-#define STRING_OVERWRITE_VALUE 114
-#define STRING_YESNO 115
-#define STRING_YES 116
-#define STRING_NO 117
-#define STRING_CANCELLED 118
-#define STRING_DEFAULT_VALUE 119
-#define STRING_DELETE_VALUE 120
-#define STRING_DELETE_VALUEALL 121
-#define STRING_DELETE_SUBKEY 122
-#define STRING_INVALID_STRING 123
-#define STRING_VALUEALL_FAILED 124
-#define STRING_GENERAL_FAILURE 125
-#define STRING_MATCHES_FOUND 126
-#define STRING_INVALID_SYNTAX 127
-#define STRING_INVALID_OPTION 128
-#define STRING_REG_HELP 129
-#define STRING_FUNC_HELP 130
-#define STRING_VALUE_NOT_SET 131
+#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*A))
+
+/* reg.c */
+void *heap_xalloc(size_t size);
+void *heap_xrealloc(void *buf, size_t size);
+BOOL heap_free(void *buf);
+void __cdecl output_message(unsigned int id, ...);
+HKEY path_get_rootkey(const WCHAR *path);
+
+/* import.c */
+int reg_import(const WCHAR *filename);
+
+#endif /* __REG_H__ */
Added: trunk/reactos/base/applications/cmdutils/reg/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/cmdutils…
==============================================================================
--- trunk/reactos/base/applications/cmdutils/reg/resource.h (added)
+++ trunk/reactos/base/applications/cmdutils/reg/resource.h [iso-8859-1] Sun Sep 24
11:33:04 2017
@@ -0,0 +1,60 @@
+/*
+ * REG.EXE - Wine-compatible reg program.
+ *
+ * Copyright 2008 Andrew Riedi
+ *
+ * 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
+ */
+
+#pragma once
+
+//#include <windef.h>
+
+/* Translation IDs. */
+#define STRING_USAGE 101
+#define STRING_ADD_USAGE 102
+#define STRING_DELETE_USAGE 103
+#define STRING_QUERY_USAGE 104
+#define STRING_SUCCESS 105
+#define STRING_INVALID_KEY 106
+#define STRING_INVALID_CMDLINE 107
+#define STRING_NO_REMOTE 108
+#define STRING_CANNOT_FIND 109
+#define STRING_UNSUPPORTED_TYPE 110
+#define STRING_MISSING_INTEGER 111
+#define STRING_MISSING_HEXDATA 112
+#define STRING_UNHANDLED_TYPE 113
+#define STRING_OVERWRITE_VALUE 114
+#define STRING_YESNO 115
+#define STRING_YES 116
+#define STRING_NO 117
+#define STRING_CANCELLED 118
+#define STRING_DEFAULT_VALUE 119
+#define STRING_DELETE_VALUE 120
+#define STRING_DELETE_VALUEALL 121
+#define STRING_DELETE_SUBKEY 122
+#define STRING_INVALID_STRING 123
+#define STRING_VALUEALL_FAILED 124
+#define STRING_GENERAL_FAILURE 125
+#define STRING_MATCHES_FOUND 126
+#define STRING_INVALID_SYNTAX 127
+#define STRING_INVALID_OPTION 128
+#define STRING_REG_HELP 129
+#define STRING_FUNC_HELP 130
+#define STRING_VALUE_NOT_SET 131
+#define STRING_IMPORT_USAGE 132
+#define STRING_FILE_NOT_FOUND 133
+#define STRING_OPEN_KEY_FAILED 134
+#define STRING_ESCAPE_SEQUENCE 135
Propchange: trunk/reactos/base/applications/cmdutils/reg/resource.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/media/doc/README.WINE
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=…
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Sun Sep 24 11:33:04 2017
@@ -227,7 +227,7 @@
ReactOS shares the following programs with Winehq.
reactos/base/applications/cmdutils/cscript # Synced to WineStaging-2.9
-reactos/base/applications/cmdutils/reg # Synced to WineStaging-2.9
+reactos/base/applications/cmdutils/reg # Synced to WineStaging-2.16
reactos/base/applications/cmdutils/schtasks # Synced to WineStaging-2.9
reactos/base/applications/cmdutils/taskkill # Synced to WineStaging-2.9
reactos/base/applications/cmdutils/wmic # Synced to WineStaging-2.9