<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:Calibri
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>---
<br><div><div dir="ltr"><div><span style="font-family:monospace;"> programs/reg/reg.c       | 128 ++++++++++++++++++++++++-----------------------
<br> programs/reg/tests/reg.c |   2 +-
<br> 2 files changed, 66 insertions(+), 64 deletions(-)
<br>
<br>diff --git a/programs/reg/reg.c b/programs/reg/reg.c
<br>index 86c2e20..6b32aa6 100644
<br>--- a/programs/reg/reg.c
<br>+++ b/programs/reg/reg.c
<br>@@ -403,111 +403,113 @@ static int reg_add(const WCHAR *key_name, const WCHAR *value_name, const BOOL va
<br>     return 0;
<br> }
<br>  <br>-static int reg_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty,
<br>-    BOOL value_all, BOOL force)
<br>+static int reg_delete(const WCHAR *key_name, const WCHAR *value_name, const BOOL value_empty,
<br>+    const BOOL value_all, const BOOL force)
<br> {
<br>-    HKEY subkey;
<br>+    HKEY key = NULL;
<br>     LONG err;
<br>  <br>-    static const WCHAR stubW[] = {'D','E','L','E','T','E',
<br>-        ' ','-',' ','%','s',' ','%','s',' ','%','d',' ','%','d',' ','%','d','\n'
<br>-        ,0};
<br>-    reg_printfW(stubW, key_name, value_name, value_empty, value_all, force);
<br>-
<br>     if (!sane_path(key_name))
<br>         return 1;
<br>  <br>-    subkey = path_open(key_name, FALSE);
<br>-    if (!subkey)
<br>-        return 1;
<br>-
<br>-    if (value_name && value_empty)
<br>+    /* Mutually exclusive options */
<br>+    if ((!!value_name + !!value_empty + !!value_all) > 1)
<br>     {
<br>         reg_message(STRING_INVALID_CMDLINE);
<br>         return 1;
<br>     }
<br>  <br>-    if (value_empty && value_all)
<br>-    {
<br>-        reg_message(STRING_INVALID_CMDLINE);
<br>+    key = path_open(key_name, FALSE);
<br>+    if (!key)
<br>         return 1;
<br>-    }
<br>  <br>     if (!force)
<br>     {
<br>-        /* FIXME:  Prompt for delete */
<br>+        WINE_FIXME("Prompt for delete\n");
<br>     }
<br>  <br>-    /* Delete subtree only if no /v* option is given */
<br>-    if (!value_name && !value_empty && !value_all)
<br>+    if (value_empty || value_name)
<br>     {
<br>-        err = RegDeleteTreeW(subkey, NULL);
<br>-        if (err != ERROR_SUCCESS)
<br>-        {
<br>-            reg_message(STRING_CANNOT_FIND);
<br>-            return 1;
<br>-        }
<br>+        if (value_name && value_name[0])
<br>+            err = RegDeleteValueW(key, value_name);
<br>+        else
<br>+            err = RegDeleteValueW(key, NULL);
<br>  <br>-        err = RegDeleteKeyW(subkey, empty_wstr);
<br>         if (err != ERROR_SUCCESS)
<br>         {
<br>-            reg_message(STRING_CANNOT_FIND);
<br>+            RegCloseKey(key);
<br>+            reg_message(STRING_ERROR);
<br>             return 1;
<br>         }
<br>-        reg_message(STRING_SUCCESS);
<br>-        return 0;
<br>     }
<br>-
<br>-    if (value_all)
<br>+    else if (value_all)
<br>     {
<br>-        LPWSTR szValue;
<br>-        DWORD maxValue;
<br>-        DWORD count;
<br>-        LONG rc;
<br>-
<br>-        rc = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
<br>-            &maxValue, NULL, NULL, NULL);
<br>-        if (rc != ERROR_SUCCESS)
<br>+        WCHAR *enum_v_name;
<br>+        DWORD count, max_size, this_size, i = 0, errors = 0;
<br>+
<br>+        err = RegQueryInfoKeyW(key, NULL, NULL, NULL, NULL, NULL, NULL,
<br>+            &count, &max_size, NULL, NULL, NULL);
<br>+        if (err != ERROR_SUCCESS)
<br>         {
<br>-            /* FIXME: failure */
<br>-            RegCloseKey(subkey);
<br>+            RegCloseKey(key);
<br>+            reg_message(STRING_ERROR);
<br>             return 1;
<br>         }
<br>-        maxValue++;
<br>-        szValue = HeapAlloc(GetProcessHeap(),0,maxValue*sizeof(WCHAR));
<br>  <br>-        while (1)
<br>+        enum_v_name = HeapAlloc(GetProcessHeap(), 0, ++max_size * sizeof(WCHAR));
<br>+
<br>+        while (i < count)
<br>         {
<br>-            count = maxValue;
<br>-            rc = RegEnumValueW(subkey, 0, szValue, &count, NULL, NULL, NULL, NULL);
<br>-            if (rc == ERROR_SUCCESS)
<br>+            this_size = max_size;
<br>+
<br>+            err = RegEnumValueW(key, i, enum_v_name, &this_size, NULL, NULL, NULL, NULL);
<br>+            if (err != ERROR_SUCCESS)
<br>+            {
<br>+                i++;
<br>+                errors++;
<br>+                continue;
<br>+            }
<br>+
<br>+            err = RegDeleteValueW(key, enum_v_name);
<br>+            if (err != ERROR_SUCCESS)
<br>             {
<br>-                rc = RegDeleteValueW(subkey, szValue);
<br>-                if (rc != ERROR_SUCCESS)
<br>-                    break;
<br>+                i++;
<br>+                errors++;
<br>+                continue;
<br>             }
<br>-            else break;
<br>+
<br>+            count--;
<br>         }
<br>-        if (rc != ERROR_SUCCESS)
<br>+
<br>+        HeapFree(GetProcessHeap(), 0, enum_v_name);
<br>+
<br>+        if (errors)
<br>         {
<br>-            /* FIXME  delete failed */
<br>+            RegCloseKey(key);
<br>+            reg_message(STRING_ERROR);
<br>+            return 1;
<br>         }
<br>     }
<br>-    else if (value_name)
<br>+    /* Delete subtree only if no /v* option is given */
<br>+    else
<br>     {
<br>-        if (RegDeleteValueW(subkey,value_name) != ERROR_SUCCESS)
<br>+        if (key == path_get_rootkey(key_name))
<br>         {
<br>-            RegCloseKey(subkey);
<br>-            reg_message(STRING_CANNOT_FIND);
<br>+            /* "This works well enough on native to make you regret you pressed enter" - stefand */
<br>+            WINE_FIXME("Deleting a root key is not implemented.\n");
<br>+            RegCloseKey(key);
<br>+            return 1;
<br>+        }
<br>+
<br>+        if (RegDeleteTreeW(key, NULL) != ERROR_SUCCESS || RegDeleteKeyW(key, empty_wstr))
<br>+        {
<br>+            RegCloseKey(key);
<br>+            reg_message(STRING_ERROR);
<br>             return 1;
<br>         }
<br>-    }
<br>-    else if (value_empty)
<br>-    {
<br>-        RegSetValueExW(subkey,NULL,0,REG_SZ,NULL,0);
<br>     }
<br>  <br>-    RegCloseKey(subkey);
<br>+    RegCloseKey(key);
<br>     reg_message(STRING_SUCCESS);
<br>     return 0;
<br> }
<br>diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c
<br>index a3ecdfb..20ef7af 100644
<br>--- a/programs/reg/tests/reg.c
<br>+++ b/programs/reg/tests/reg.c
<br>@@ -388,7 +388,7 @@ static void test_delete(void)
<br>     run_reg_exe("reg delete HKCU\\" KEY_BASE " /ve /f", &r);
<br>     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
<br>     err = RegQueryValueExA(hkey, "", NULL, NULL, NULL, NULL);
<br>-    todo_wine ok(err == ERROR_FILE_NOT_FOUND, "got %d\n", err);
<br>+    ok(err == ERROR_FILE_NOT_FOUND, "got %d\n", err);
<br>  <br>     run_reg_exe("reg delete HKCU\\" KEY_BASE " /va /f", &r);
<br>     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
<br>--  <br>2.5.0<br></span></div>


                                          </div></div>                                        </div></body>
</html>