<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'>






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


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