[resend 8/8] reg: Clean up reg_delete

Jonathan Vollebregt jnvsor at gmail.com
Wed Jan 14 11:12:28 CST 2015


---
 programs/reg/reg.c       | 149 +++++++++++++++++++++++------------------------
 programs/reg/tests/reg.c |   2 +-
 2 files changed, 73 insertions(+), 78 deletions(-)

diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index 084a8d5..383d94e 100755
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -414,120 +414,115 @@ 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);
-
-    err = sane_path(key_name);
+    HKEY key = NULL;
+    LONG err = sane_path(key_name);
     if (err != ERROR_SUCCESS)
     {
         reg_print_error(err);
         return 1;
     }
 
-    err = path_open(key_name, &subkey, FALSE);
+    err = path_open(key_name, &key, FALSE);
     if (err != ERROR_SUCCESS)
-    {
-        reg_message(STRING_INVALID_KEY);
-        return 1;
-    }
-
-    if (value_name && value_empty)
-    {
-        reg_message(STRING_INVALID_CMDLINE);
-        return 1;
-    }
+        goto error;
 
-    if (value_empty && value_all)
+    /* 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 (!force)
     {
-        /* FIXME:  Prompt for delete */
+        WINE_FIXME("Prompt for delete\n");
     }
 
-    /* Delete subtree only if no /v* option is given */
-    if (!value_name && !value_empty && !value_all)
+    if (value_empty || value_name)
     {
-        err = RegDeleteTreeW(subkey, NULL);
-        if (err != ERROR_SUCCESS)
-        {
-            reg_print_error(err);
-            return 1;
-        }
+        if (value_name && value_name[0])
+            err = RegDeleteValueW(key, value_name);
+        else
+            err = RegDeleteValueW(key, NULL);
 
-        err = RegDeleteKeyW(subkey, empty_wstr);
         if (err != ERROR_SUCCESS)
-        {
-            reg_print_error(err);
-            return 1;
-        }
-        reg_message(STRING_SUCCESS);
-        return 0;
+            goto error;
     }
-
-    if (value_all)
+    else 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));
+        WCHAR *enum_v_name;
+        DWORD count, max_size, this_size, i = 0, errors = 0;
+
+        err = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
+                &count, &max_size, NULL, NULL, NULL);
+        if (err != ERROR_SUCCESS)
+            goto error;
 
-        while (1)
+        enum_v_name = HeapAlloc(GetProcessHeap(), 0, ++max_size * sizeof(WCHAR));
+
+        while (i < count)
         {
-            count = maxValue;
-            rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL);
-            if (rc == ERROR_SUCCESS)
+            this_size = max_size;
+
+            err = RegEnumValueW(key, i, enum_v_name, &this_size, NULL, NULL, NULL, NULL);
+            if (err != ERROR_SUCCESS)
             {
-                rc = RegDeleteValueW(subkey, szValue);
-                if (rc != ERROR_SUCCESS)
-                    break;
+                i++;
+                errors++;
+                reg_print_error(err);
+                continue;
             }
-            else break;
+
+            err = RegDeleteValueW(key, enum_v_name);
+            if (err != ERROR_SUCCESS)
+            {
+                i++;
+                errors++;
+                reg_print_error(err);
+                continue;
+            }
+
+            count--;
         }
-        if (rc != ERROR_SUCCESS)
+
+        HeapFree(GetProcessHeap(), 0, enum_v_name);
+
+        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)
+        if (key == path_get_rootkey(key_name))
         {
-            RegCloseKey(subkey);
-            reg_message(STRING_CANNOT_FIND);
+            /* "This works well enough on native to make you regret you pressed enter" - stefand */
+            WINE_FIXME("Deleting a root key is not implemented.\n");
+            RegCloseKey(key);
             return 1;
         }
-    }
-    else if (value_empty)
-    {
-        RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0);
+
+        err = RegDeleteTreeW(key, NULL);
+        if (err != ERROR_SUCCESS)
+            goto error;
+        err = RegDeleteKeyW(key, empty_wstr);
+        if (err != ERROR_SUCCESS)
+            goto error;
     }
 
-    RegCloseKey(subkey);
+    RegCloseKey(key);
     reg_message(STRING_SUCCESS);
     return 0;
+
+error:
+    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/tests/reg.c b/programs/reg/tests/reg.c
index a3ecdfb..20ef7af 100644
--- a/programs/reg/tests/reg.c
+++ b/programs/reg/tests/reg.c
@@ -388,7 +388,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.4




More information about the wine-patches mailing list