From: xantares 09 Subject: [PATCH 4/4] reg: Clean up reg_delete Message-Id: Date: Thu, 30 Jul 2015 20:45:32 +0000 From a1047d392615e5f0c9ab308b3a8decd0c2e192a6 Mon Sep 17 00:00:00 2001 From: Jonathan Vollebregt Date: Fri, 5 Sep 2014 20:40:38 +0200 Subject: [PATCH 4/4] reg: Clean up reg_delete To: wine-patches@winehq.org --- programs/reg/reg.c | 128 ++++++++++++++++++++++++----------------------- programs/reg/tests/reg.c | 2 +- 2 files changed, 66 insertions(+), 64 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index 86c2e20..6b32aa6 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -403,111 +403,113 @@ static int reg_add(const WCHAR *key_name, const WCHAR *value_name, const BOOL va 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; + HKEY key = NULL; 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); - if (!sane_path(key_name)) return 1; - subkey = path_open(key_name, FALSE); - if (!subkey) - return 1; - - if (value_name && value_empty) + /* Mutually exclusive options */ + if ((!!value_name + !!value_empty + !!value_all) > 1) { reg_message(STRING_INVALID_CMDLINE); return 1; } - if (value_empty && value_all) - { - reg_message(STRING_INVALID_CMDLINE); + key = path_open(key_name, FALSE); + if (!key) return 1; - } 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_message(STRING_CANNOT_FIND); - 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_message(STRING_CANNOT_FIND); + RegCloseKey(key); + reg_message(STRING_ERROR); return 1; } - reg_message(STRING_SUCCESS); - return 0; } - - 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) + 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) { - /* FIXME: failure */ - RegCloseKey(subkey); + RegCloseKey(key); + reg_message(STRING_ERROR); return 1; } - maxValue++; - szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR)); - 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) + { + i++; + errors++; + continue; + } + + err = RegDeleteValueW(key, enum_v_name); + if (err != ERROR_SUCCESS) { - rc = RegDeleteValueW(subkey, szValue); - if (rc != ERROR_SUCCESS) - break; + i++; + errors++; + continue; } - else break; + + count--; } - if (rc != ERROR_SUCCESS) + + HeapFree(GetProcessHeap(), 0, enum_v_name); + + if (errors) { - /* FIXME delete failed */ + RegCloseKey(key); + reg_message(STRING_ERROR); + 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; + } + + if (RegDeleteTreeW(key, NULL) != ERROR_SUCCESS || RegDeleteKeyW(key, empty_wstr)) + { + RegCloseKey(key); + reg_message(STRING_ERROR); 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/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.5.0
From a1047d392615e5f0c9ab308b3a8decd0c2e192a6 Mon Sep 17 00:00:00 2001
From: Jonathan Vollebregt <jnvsor@gmail.com>
Date: Fri, 5 Sep 2014 20:40:38 +0200
Subject: [PATCH 4/4] reg: Clean up reg_delete
To: wine-patches@winehq.org

---
programs/reg/reg.c       | 128 ++++++++++++++++++++++++-----------------------
programs/reg/tests/reg.c |   2 +-
2 files changed, 66 insertions(+), 64 deletions(-)

diff --git a/programs/reg/reg.c b/programs/reg/reg.c
index 86c2e20..6b32aa6 100644
--- a/programs/reg/reg.c
+++ b/programs/reg/reg.c
@@ -403,111 +403,113 @@ static int reg_add(const WCHAR *key_name, const WCHAR *value_name, const BOOL va
    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;
+    HKEY key = NULL;
    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);
-
    if (!sane_path(key_name))
        return 1;
 
-    subkey = path_open(key_name, FALSE);
-    if (!subkey)
-        return 1;
-
-    if (value_name && value_empty)
+    /* Mutually exclusive options */
+    if ((!!value_name + !!value_empty + !!value_all) > 1)
    {
        reg_message(STRING_INVALID_CMDLINE);
        return 1;
    }
 
-    if (value_empty && value_all)
-    {
-        reg_message(STRING_INVALID_CMDLINE);
+    key = path_open(key_name, FALSE);
+    if (!key)
        return 1;
-    }
 
    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_message(STRING_CANNOT_FIND);
-            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_message(STRING_CANNOT_FIND);
+            RegCloseKey(key);
+            reg_message(STRING_ERROR);
            return 1;
        }
-        reg_message(STRING_SUCCESS);
-        return 0;
    }
-
-    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)
+        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)
        {
-            /* FIXME: failure */
-            RegCloseKey(subkey);
+            RegCloseKey(key);
+            reg_message(STRING_ERROR);
            return 1;
        }
-        maxValue++;
-        szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
 
-        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)
+            {
+                i++;
+                errors++;
+                continue;
+            }
+
+            err = RegDeleteValueW(key, enum_v_name);
+            if (err != ERROR_SUCCESS)
            {
-                rc = RegDeleteValueW(subkey, szValue);
-                if (rc != ERROR_SUCCESS)
-                    break;
+                i++;
+                errors++;
+                continue;
            }
-            else break;
+
+            count--;
        }
-        if (rc != ERROR_SUCCESS)
+
+        HeapFree(GetProcessHeap(), 0, enum_v_name);
+
+        if (errors)
        {
-            /* FIXME  delete failed */
+            RegCloseKey(key);
+            reg_message(STRING_ERROR);
+            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;
+        }
+
+        if (RegDeleteTreeW(key, NULL) != ERROR_SUCCESS || RegDeleteKeyW(key, empty_wstr))
+        {
+            RegCloseKey(key);
+            reg_message(STRING_ERROR);
            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/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.5.0