[PATCH 7/7] reg: Clean up reg_delete
Jonathan Vollebregt
jnvsor at gmail.com
Tue Nov 4 14:15:14 CST 2014
---
programs/reg/reg.c | 147 ++++++++++++++++++++++++-----------------------
programs/reg/reg.h | 1 +
programs/reg/reg.rc | 1 +
programs/reg/tests/reg.c | 2 +-
4 files changed, 78 insertions(+), 73 deletions(-)
diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index d92853c..4035649 100755
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -23,9 +23,12 @@
#define ARRAY_SIZE(A) (sizeof(A)/sizeof(*A))
+#define MAX_VALUE_NAME 16384
+
#define ERROR_NO_REMOTE 20000
#define ERROR_INVALID_TYPE 20001
#define ERROR_NAN 20002
+#define ERROR_NO_DELETE_ROOTKEY 20003
WINE_DEFAULT_DEBUG_CHANNEL(reg);
@@ -162,6 +165,8 @@ static int reg_print_error(LONG error_code)
return reg_message(STRING_UNSUPPORTED_TYPE);
case ERROR_NAN:
return reg_message(STRING_NAN);
+ case ERROR_NO_DELETE_ROOTKEY:
+ return reg_message(STRING_NO_DEL_ROOT);
default:
{
static const WCHAR error_string[] = {'%','0','5','d',':',' ','%','s',0};
@@ -448,109 +453,107 @@ error:
return 1;
}
-static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
- BOOL value_all, BOOL force)
+static int reg_delete(const WCHAR *key_name, const WCHAR *value_name, const BOOL value_empty,
+ const BOOL value_all, const BOOL force)
{
- HKEY subkey;
- LONG err;
-
- static const WCHAR stubW[] = {'D','E','L','E','T','E',
- ' ','-',' ','%','s',' ','%','s',' ','%','d',' ','%','d',' ','%','d','\n'
- ,0};
- reg_printfW(stubW, key_name, value_name, value_empty, value_all, force);
+ HKEY key = NULL;
+ LONG err = path_get_key(key_name, &key);
- err = path_get_key(key_name, &subkey);
if (err != ERROR_SUCCESS)
- {
- reg_print_error(err);
- return 1;
- }
+ goto error;
- if (value_name && value_empty)
+ /* Mutually exclusive options */
+ if ((!!value_name + !!value_empty + !!value_all) > 1)
{
- reg_message(STRING_INVALID_CMDLINE);
- return 1;
+ err = ERROR_BAD_COMMAND;
+ goto error;
}
- if (value_empty && value_all)
+ if (!force)
{
- reg_message(STRING_INVALID_CMDLINE);
- return 1;
+ FIXME("Prompt for delete\n");
}
- if (!force)
+ if (value_empty || value_name)
{
- /* FIXME: Prompt for delete */
- }
+ if (value_name && value_name[0])
+ err = RegDeleteValueW(key, value_name);
+ else
+ err = RegDeleteValueW(key, NULL);
- /* Delete subtree only if no /v* option is given */
- if (!value_name && !value_empty && !value_all)
+ if (err != ERROR_SUCCESS)
+ goto error;
+ }
+ else if (value_all)
{
- HKEY root;
- err = path_get_rootkey(key_name, &root);
- err = RegDeleteTreeW(root, strchrW(key_name, '\\') + 1);
+ WCHAR enum_v_name[MAX_VALUE_NAME];
+ DWORD count, max_size, i = 0, errors = 0;
+
+ err = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
+ &count, NULL, NULL, NULL, NULL);
if (err != ERROR_SUCCESS)
+ goto error;
+
+ while (i < count)
{
- reg_print_error(err);
- return 1;
- }
+ max_size = MAX_VALUE_NAME;
- reg_message(STRING_SUCCESS);
- return 0;
- }
+ err = RegEnumValueW(key, i, enum_v_name, &max_size,
+ NULL, NULL, NULL, NULL);
- if (value_all)
- {
- LPWSTR szValue;
- DWORD maxValue;
- DWORD count;
- LONG rc;
-
- rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- &maxValue, NULL, NULL, NULL);
- if (rc != ERROR_SUCCESS)
- {
- /* FIXME: failure */
- RegCloseKey(subkey);
- return 1;
- }
- maxValue++;
- szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
+ if (err != ERROR_SUCCESS)
+ {
+ i++;
+ errors++;
+ reg_print_error(err);
+ continue;
+ }
- while (1)
- {
- count = maxValue;
- rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL);
- if (rc == ERROR_SUCCESS)
+ err = RegDeleteValueW(key, enum_v_name);
+ if (err != ERROR_SUCCESS)
{
- rc = RegDeleteValueW(subkey, szValue);
- if (rc != ERROR_SUCCESS)
- break;
+ i++;
+ errors++;
+ reg_print_error(err);
+ continue;
}
- else break;
+
+ count--;
}
- if (rc != ERROR_SUCCESS)
+
+ if (errors)
{
- /* FIXME delete failed */
+ RegCloseKey(key);
+ return 1;
}
}
- else if (value_name)
+ /* Delete subtree only if no /v* option is given */
+ else
{
- if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS)
+ HKEY root;
+
+ err = path_get_rootkey(key_name, &root);
+ if (key == root)
{
- RegCloseKey(subkey);
- reg_message(STRING_CANNOT_FIND);
- return 1;
+ err = ERROR_NO_DELETE_ROOTKEY;
+ goto error;
}
- }
- else if (value_empty)
- {
- RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0);
+
+ err = RegDeleteTreeW(root, strchrW(key_name, '\\') + 1);
+ if (err != ERROR_SUCCESS)
+ goto error;
}
- RegCloseKey(subkey);
+ RegCloseKey(key);
reg_message(STRING_SUCCESS);
return 0;
+
+error:
+ if (key)
+ RegCloseKey(key);
+
+ reg_print_error(err);
+ return 1;
}
static int reg_query(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
diff --git a/programs/reg/reg.h b/programs/reg/reg.h
index 334e7ad..88356d1 100644
--- a/programs/reg/reg.h
+++ b/programs/reg/reg.h
@@ -34,3 +34,4 @@
#define STRING_INVALID_TYPE 111
#define STRING_UNSUPPORTED_TYPE 112
#define STRING_NAN 113
+#define STRING_NO_DEL_ROOT 114
diff --git a/programs/reg/reg.rc b/programs/reg/reg.rc
index a53013c..4675d35 100644
--- a/programs/reg/reg.rc
+++ b/programs/reg/reg.rc
@@ -39,4 +39,5 @@ STRINGTABLE
STRING_INVALID_TYPE, "Error: Invalid type\n"
STRING_UNSUPPORTED_TYPE, "Error: Unsupported type\n"
STRING_NAN, "Error: This type requires /d to be a positive number\n"
+ STRING_NO_DEL_ROOT, "Error: Cannot delete root key\n"
}
diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c
index 0e9ad74..8a88ecf 100644
--- a/programs/reg/tests/reg.c
+++ b/programs/reg/tests/reg.c
@@ -367,7 +367,7 @@ static void test_delete(void)
run_reg_exe("reg delete HKCU\\" KEY_BASE " /ve /f", &r);
ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
err = RegQueryValueExA(hkey, "", NULL, NULL, NULL, NULL);
- todo_wine ok(err == ERROR_FILE_NOT_FOUND, "got %d\n", err);
+ ok(err == ERROR_FILE_NOT_FOUND, "got %d\n", err);
run_reg_exe("reg delete HKCU\\" KEY_BASE " /va /f", &r);
ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
--
2.1.1
More information about the wine-patches
mailing list