From: Jonathan Vollebregt Subject: [PATCH 6/6] reg: Clean up reg_delete Message-Id: <1414411809-1943-6-git-send-email-jnvsor@gmail.com> Date: Mon, 27 Oct 2014 13:10:09 +0100 --- programs/reg/reg.c | 108 +++++++++++++++++++++++------------------------ programs/reg/reg.h | 1 + programs/reg/reg.rc | 1 + programs/reg/tests/reg.c | 2 +- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index 6d2ed8b..36335e5 100755 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -21,6 +21,7 @@ #include "reg.h" #define ARRAY_COUNT(A) (sizeof(A)/sizeof(*A)) +#define MAX_VALUE_NAME 16384 typedef struct { HKEY key; @@ -447,26 +448,16 @@ static int reg_add( const WCHAR *key_name, const WCHAR *value_name, const BO return 0; } -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 = path_get_key(key_name); + HKEY key = path_get_key(key_name); - 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); - - if (!subkey) - return 1; - - if (value_name && value_empty) - { - reg_message(STRING_INVALID_CMDLINE); + if (!key) return 1; - } - if (value_empty && value_all) + /* Mutually exclusive options */ + if ((!!value_name + !!value_empty + !!value_all) > 1) { reg_message(STRING_INVALID_CMDLINE); return 1; @@ -477,70 +468,77 @@ static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, /* FIXME: Prompt for delete */ } - /* Delete subtree only if no /v* option is given */ - if (!value_name && !value_empty && !value_all) + if (value_empty || (value_name && !value_name[0])) { - HKEY root = path_get_rootkey(key_name); - - if (RegDeleteTreeW(root, strchrW(key_name,'\\')+1) != ERROR_SUCCESS) + RegDeleteValueW(key, NULL); + } + else if (value_name) + { + if (RegDeleteValueW(key, value_name) != ERROR_SUCCESS) { + RegCloseKey(key); reg_message(STRING_CANNOT_FIND); return 1; } - reg_message(STRING_SUCCESS); - return 0; } - - if (value_all) + else if (value_all) { - LPWSTR szValue; - DWORD maxValue; - DWORD count; - LONG rc; + WCHAR enum_v_name[MAX_VALUE_NAME]; + DWORD rc, count, max_size, i = 0; - rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - &maxValue, NULL, NULL, NULL); + rc = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL, + &count, NULL, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { - /* FIXME: failure */ - RegCloseKey(subkey); + RegCloseKey(key); + reg_message(STRING_CANNOT_FIND); return 1; } - maxValue++; - szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR)); - while (1) + while (i < count) { - count = maxValue; - rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL); - if (rc == ERROR_SUCCESS) + max_size = MAX_VALUE_NAME; + + rc = RegEnumValueW(key, i, enum_v_name, &max_size, + NULL, NULL, NULL, NULL); + + if (rc != ERROR_SUCCESS) { - rc = RegDeleteValueW(subkey, szValue); - if (rc != ERROR_SUCCESS) - break; + i++; + continue; } - else break; - } - if (rc != ERROR_SUCCESS) - { - /* FIXME delete failed */ + else if (RegDeleteValueW(key, enum_v_name) != ERROR_SUCCESS) + { + i++; + continue; + } + + count--; } + + RegDeleteValueW(key, NULL); } - else if (value_name) + /* Delete subtree only if no /v* option is given */ + else { - if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS) + HKEY root = path_get_rootkey(key_name); + + if (key == root) + { + RegCloseKey(key); + reg_message(STRING_NO_DEL_ROOT); + return 1; + } + + if (RegDeleteTreeW(root, strchrW(key_name, '\\') + 1) != ERROR_SUCCESS) { - RegCloseKey(subkey); + RegCloseKey(key); reg_message(STRING_CANNOT_FIND); return 1; } } - else if (value_empty) - { - RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0); - } - RegCloseKey(subkey); + RegCloseKey(key); reg_message(STRING_SUCCESS); return 0; } diff --git a/programs/reg/reg.h b/programs/reg/reg.h index 45c4782..9ccbd99 100644 --- a/programs/reg/reg.h +++ b/programs/reg/reg.h @@ -33,3 +33,4 @@ #define STRING_ERROR 110 #define STRING_UNHANDLED_TYPE 111 #define STRING_NAN 112 +#define STRING_NO_DEL_ROOT 113 diff --git a/programs/reg/reg.rc b/programs/reg/reg.rc index 8eba7c9..9a30b2e 100644 --- a/programs/reg/reg.rc +++ b/programs/reg/reg.rc @@ -38,4 +38,5 @@ STRINGTABLE STRING_ERROR, "Error: An internal error occurred\n" STRING_UNHANDLED_TYPE, "Error: Unhandled Type" 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 5836af2..56745d3 100644 --- a/programs/reg/tests/reg.c +++ b/programs/reg/tests/reg.c @@ -356,7 +356,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