From: xantares 09 Subject: [PATCH 3/4] reg: Clean up reg_add Message-Id: Date: Fri, 31 Jul 2015 09:47:54 +0000 You'll notice that bad value input leaves a zombie key after this call, but this is consistant with native. ---  programs/reg/reg.c       |   77 ++++++++++++++++++++++++++++------------------  programs/reg/reg.h       |    1 +  programs/reg/reg.rc      |    1 +  programs/reg/tests/reg.c |   22 ++++++-------  4 files changed, 60 insertions(+), 41 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index b2447fc..86c2e20 100644 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -335,61 +335,71 @@ static BOOL sane_path(const WCHAR *key)      return TRUE;  }   -static int reg_add(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, -    WCHAR *type, WCHAR separator, WCHAR *data, BOOL force) +static int reg_add(const WCHAR *key_name, const WCHAR *value_name, const BOOL value_empty, +    const WCHAR *type, const WCHAR separator, const WCHAR *data, const BOOL force)  { -    static const WCHAR stubW[] = {'A','D','D',' ','-',' ','%','s', -        ' ','%','s',' ','%','d',' ','%','s',' ','%','s',' ','%','d','\n',0}; -    HKEY subkey; - -    reg_printfW(stubW, key_name, value_name, value_empty, type, data, force); +    HKEY key = NULL; +    LONG err;        if (!sane_path(key_name))          return 1;   -    subkey = path_open(key_name, TRUE); -    if (!subkey) +    if (value_name && value_empty) +    { +        reg_message(STRING_INVALID_CMDLINE); +        return 1; +    } + +    key = path_open(key_name, TRUE); +    if (!key)          return 1;        if (value_name || data)      { -        DWORD reg_type; -        DWORD reg_count = 0; -        BYTE* reg_data = NULL; +        DWORD size, reg_type; +        BYTE *data_out;   -        if (!force) +        if (value_name && !value_name[0]) +            value_name = NULL; + +        if (type && !type[0])          { -            if (RegQueryValueW(subkey,value_name,NULL,NULL)==ERROR_SUCCESS) -            { -                /* FIXME:  Prompt for overwrite */ -            } +            data = NULL; +            type = NULL; +        } + +        if (!force && RegQueryValueExW(key, value_name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) +        { +            WINE_FIXME("Prompt for overwrite\n");          }            reg_type = wchar_get_type(type);          if (reg_type == ~0u)          { -            RegCloseKey(subkey);              reg_message(STRING_UNSUPPORTED_TYPE); +            RegCloseKey(key);              return 1;          }   -        if (data) +        data_out = wchar_get_data(data, reg_type, separator, &size); +        if (!data_out)          { -            reg_data = wchar_get_data(data, reg_type, separator, ®_count); -            if (!reg_data) -            { -                RegCloseKey(subkey); -                return 1; -            } +            RegCloseKey(key); +            return 1;          }   -        RegSetValueExW(subkey,value_name,0,reg_type,reg_data,reg_count); -        HeapFree(GetProcessHeap(),0,reg_data); +        err = RegSetValueExW(key, value_name, 0, reg_type, data_out, size); +        HeapFree(GetProcessHeap(), 0, data_out); + +        if (err != ERROR_SUCCESS){ +            RegCloseKey(key); +            reg_message(STRING_ERROR); +            return 1; +        }      }   -    RegCloseKey(subkey); +    RegCloseKey(key);      reg_message(STRING_SUCCESS); -      return 0;  }   @@ -563,7 +573,14 @@ int wmain(int argc, WCHAR *argvW[])              else if (!lstrcmpiW(argvW[i], slashTW))                  type = argvW[++i];              else if (!lstrcmpiW(argvW[i], slashSW)) -                separator = argvW[++i][0]; +            { +                if (!argvW[++i][0] || argvW[i][1]) +                { +                    reg_message(STRING_INVALID_CMDLINE); +                    return 1; +                } +                separator = argvW[i][0]; +            }              else if (!lstrcmpiW(argvW[i], slashDW))                  data = argvW[++i];              else if (!lstrcmpiW(argvW[i], slashFW)) diff --git a/programs/reg/reg.h b/programs/reg/reg.h index c6fb151..c5d82a3 100644 --- a/programs/reg/reg.h +++ b/programs/reg/reg.h @@ -32,3 +32,4 @@  #define STRING_CANNOT_FIND      109  #define STRING_UNSUPPORTED_TYPE 110  #define STRING_INVALID_DWORD    111 +#define STRING_ERROR            112 diff --git a/programs/reg/reg.rc b/programs/reg/reg.rc index dbd92ea..228dec6 100644 --- a/programs/reg/reg.rc +++ b/programs/reg/reg.rc @@ -37,4 +37,5 @@ STRINGTABLE      STRING_CANNOT_FIND, "Error: The system was unable to find the specified registry key or value\n"      STRING_UNSUPPORTED_TYPE, "Error: Unsupported type\n"      STRING_INVALID_DWORD, "Error: /d must be positive number\n" +    STRING_ERROR, "An unexpected error occurred\n"  } diff --git a/programs/reg/tests/reg.c b/programs/reg/tests/reg.c index 99b4813..a3ecdfb 100644 --- a/programs/reg/tests/reg.c +++ b/programs/reg/tests/reg.c @@ -110,12 +110,12 @@ static void test_add(void)        /* Test empty type */      run_reg_exe("reg add HKCU\\" KEY_BASE " /v emptyType /t \"\" /d WineTest /f", &r); -    todo_wine ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */), +    ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),          "got exit code %u\n", r);      if (r == REG_EXIT_SUCCESS) -        todo_wine verify_reg(hkey, "emptyType", REG_SZ, "", 1, 0); +        verify_reg(hkey, "emptyType", REG_SZ, "", 1, 0);      else -        todo_wine win_skip("broken reg.exe detected\n"); +        win_skip("broken reg.exe detected\n");        /* Test input key formats */      run_reg_exe("reg add \\HKCU\\" KEY_BASE "\\keytest0 /f", &r); @@ -171,7 +171,7 @@ static void test_add(void)        run_reg_exe("reg add HKCU\\" KEY_BASE " /v test /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); -    verify_reg(hkey, "test", REG_SZ, "", 1, TODO_REG_SIZE); +    verify_reg(hkey, "test", REG_SZ, "", 1, 0);        run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /d WineTEST /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); @@ -179,7 +179,7 @@ static void test_add(void)        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test2 /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); -    verify_reg(hkey, "test2", REG_SZ, "", 1, TODO_REG_SIZE); +    verify_reg(hkey, "test2", REG_SZ, "", 1, 0);        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test3 /f /d \"\"", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); @@ -196,7 +196,7 @@ static void test_add(void)        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand2 /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r); -    verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, TODO_REG_SIZE); +    verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, 0);        run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_EXPAND_SZ /d WineTEST /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r); @@ -254,7 +254,7 @@ static void test_add(void)          win_skip("broken reg.exe detected\n");        run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword1 /t REG_DWORD /f", &r); -    todo_wine ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), +    ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),         "got exit code %d, expected 0\n", r);      run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword2 /t REG_DWORD /d zzz /f", &r);      ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); @@ -324,18 +324,18 @@ static void test_add(void)        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi3 /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r); -    verify_reg(hkey, "multi3", REG_MULTI_SZ, &buffer[21], 1, TODO_REG_SIZE); +    verify_reg(hkey, "multi3", REG_MULTI_SZ, &buffer[21], 1, 0);        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi4 /s \"#\" /d \"threelittlestrings\" /f", &r);      ok(r == REG_EXIT_SUCCESS, "got exit code %u\n", r);      verify_reg(hkey, "multi4", REG_MULTI_SZ, "threelittlestrings\0", 20, 0);        run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi5 /s \"#randomgibberish\" /d \"three#little#strings\" /f", &r); -    todo_wine ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r); +    ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r);      run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi6 /s \"\\0\" /d \"three\\0little\\0strings\" /f", &r); -    todo_wine ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r); +    ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r);      run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi7 /s \"\" /d \"three#little#strings\" /f", &r); -    todo_wine ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r); +    ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r);      run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi8 /s \"#\" /d \"##\" /f", &r);      ok(r == REG_EXIT_FAILURE, "got exit code %u\n", r);      run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi9 /s \"#\" /d \"two##strings\" /f", &r); -- 1.7.9.5