From: Jonathan Vollebregt Subject: [PATCH v3 09/10] reg: Clean up reg_add Message-Id: <1415442411-14059-9-git-send-email-jnvsor@gmail.com> Date: Sat, 8 Nov 2014 11:26:50 +0100 You'll notice that bad value input leaves a zombie key after this call, but this is consistant with native. --- programs/reg/reg.c | 92 ++++++++++++++++++++++++++---------------------- programs/reg/tests/reg.c | 22 ++++++------ 2 files changed, 60 insertions(+), 54 deletions(-) diff --git a/programs/reg/reg.c b/programs/reg/reg.c index bcbcdaa..b76fd3c 100755 --- a/programs/reg/reg.c +++ b/programs/reg/reg.c @@ -358,71 +358,70 @@ static LSTATUS sane_path(const WCHAR *key) return ERROR_SUCCESS; } -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; - LONG err; - - reg_printfW(stubW, key_name, value_name, value_empty, type, data, force); - - err = sane_path(key_name); + HKEY key = NULL; + LONG err = sane_path(key_name); if (err != ERROR_SUCCESS) + goto error; + + if (value_name && value_empty) { - reg_print_error(err); - return 1; + err = ERROR_BAD_COMMAND; + goto error; } - err = path_open(key_name, &subkey, TRUE); + err = path_open(key_name, &key, TRUE); if (err != ERROR_SUCCESS) - { - reg_message(STRING_INVALID_KEY); - return 1; - } + goto error; if (value_name || data) { - DWORD reg_type; - DWORD reg_count = 0; - BYTE* reg_data = NULL; + DWORD size, reg_type; + BYTE *data_out; + + if (value_name && !value_name[0]) + value_name = NULL; - if (!force) + if (type && !type[0]) { - if (RegQueryValueW(subkey,value_name,NULL,NULL)==ERROR_SUCCESS) - { - /* FIXME: Prompt for overwrite */ - } + data = NULL; + type = NULL; } - reg_type = wchar_get_type(type); - if (reg_type == ~0u) + if (!force && RegQueryValueExW(key, value_name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) { - RegCloseKey(subkey); - reg_print_error(ERROR_UNSUPPORTED_TYPE); - return 1; + FIXME("Prompt for overwrite\n"); } - if (data) + reg_type = wchar_get_type(type); + if (reg_type == ~0u) { - err = wchar_get_data(data, reg_type, separator, ®_count, ®_data); - if (err != ERROR_SUCCESS) - { - RegCloseKey(subkey); - reg_print_error(err); - return 1; - } + err = ERROR_INVALID_DATATYPE; + goto error; } - RegSetValueExW(subkey,value_name,0,reg_type,reg_data,reg_count); - HeapFree(GetProcessHeap(),0,reg_data); + err = wchar_get_data(data, reg_type, separator, &size, &data_out); + if (err != ERROR_SUCCESS) + goto error; + + err = RegSetValueExW(key, value_name, 0, reg_type, data_out, size); + HeapFree(GetProcessHeap(), 0, data_out); + 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_delete(WCHAR *key_name, WCHAR *value_name, BOOL value_empty, @@ -602,7 +601,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_print_error(ERROR_BAD_COMMAND); + 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/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); -- 2.1.3