From: xantares 09 Subject: [PATCH 4/4] reg: Clean up reg_delete Message-Id: Date: Fri, 31 Jul 2015 09:48:25 +0000 ---  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); -- 1.7.9.5