xref: /reactos/modules/rostests/winetests/reg/add.c (revision ba10b11f)
1a09c8c41Swinesync /*
2a09c8c41Swinesync  * Copyright 2014 Akihiro Sagawa
3a09c8c41Swinesync  *
4a09c8c41Swinesync  * This library is free software; you can redistribute it and/or
5a09c8c41Swinesync  * modify it under the terms of the GNU Lesser General Public
6a09c8c41Swinesync  * License as published by the Free Software Foundation; either
7a09c8c41Swinesync  * version 2.1 of the License, or (at your option) any later version.
8a09c8c41Swinesync  *
9a09c8c41Swinesync  * This library is distributed in the hope that it will be useful,
10a09c8c41Swinesync  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11a09c8c41Swinesync  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12a09c8c41Swinesync  * Lesser General Public License for more details.
13a09c8c41Swinesync  *
14a09c8c41Swinesync  * You should have received a copy of the GNU Lesser General Public
15a09c8c41Swinesync  * License along with this library; if not, write to the Free Software
16a09c8c41Swinesync  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17a09c8c41Swinesync  */
18a09c8c41Swinesync 
19a09c8c41Swinesync #include "reg_test.h"
20a09c8c41Swinesync 
2107907552Swinesync BOOL run_reg_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
22a09c8c41Swinesync {
23a09c8c41Swinesync     STARTUPINFOA si = {sizeof(STARTUPINFOA)};
24a09c8c41Swinesync     PROCESS_INFORMATION pi;
25a09c8c41Swinesync     BOOL bret;
26a09c8c41Swinesync     DWORD ret;
27a09c8c41Swinesync     char cmdline[256];
28a09c8c41Swinesync 
29a09c8c41Swinesync     si.dwFlags = STARTF_USESTDHANDLES;
30a09c8c41Swinesync     si.hStdInput  = INVALID_HANDLE_VALUE;
31a09c8c41Swinesync     si.hStdOutput = INVALID_HANDLE_VALUE;
32a09c8c41Swinesync     si.hStdError  = INVALID_HANDLE_VALUE;
33a09c8c41Swinesync 
34a09c8c41Swinesync     strcpy(cmdline, cmd);
35a09c8c41Swinesync     if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
36a09c8c41Swinesync         return FALSE;
37a09c8c41Swinesync 
38a09c8c41Swinesync     ret = WaitForSingleObject(pi.hProcess, 10000);
39a09c8c41Swinesync     if (ret == WAIT_TIMEOUT)
40a09c8c41Swinesync         TerminateProcess(pi.hProcess, 1);
41a09c8c41Swinesync 
42a09c8c41Swinesync     bret = GetExitCodeProcess(pi.hProcess, rc);
43a09c8c41Swinesync     lok(bret, "GetExitCodeProcess failed: %d\n", GetLastError());
44a09c8c41Swinesync 
45a09c8c41Swinesync     CloseHandle(pi.hThread);
46a09c8c41Swinesync     CloseHandle(pi.hProcess);
47a09c8c41Swinesync     return bret;
48a09c8c41Swinesync }
49a09c8c41Swinesync 
5007907552Swinesync void verify_reg_(const char *file, unsigned line, HKEY hkey, const char *value,
5107907552Swinesync                  DWORD exp_type, const void *exp_data, DWORD exp_size, DWORD todo)
52a09c8c41Swinesync {
53a09c8c41Swinesync     DWORD type, size;
54a09c8c41Swinesync     BYTE data[256];
55a09c8c41Swinesync     LONG err;
56a09c8c41Swinesync 
57a09c8c41Swinesync     size = sizeof(data);
58a09c8c41Swinesync     memset(data, 0xdd, size);
59a09c8c41Swinesync     err = RegQueryValueExA(hkey, value, NULL, &type, data, &size);
60a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
61a09c8c41Swinesync     if (err != ERROR_SUCCESS)
62a09c8c41Swinesync         return;
63a09c8c41Swinesync 
64a09c8c41Swinesync     todo_wine_if (todo & TODO_REG_TYPE)
65a09c8c41Swinesync         lok(type == exp_type, "got wrong type %d, expected %d\n", type, exp_type);
66a09c8c41Swinesync     todo_wine_if (todo & TODO_REG_SIZE)
67a09c8c41Swinesync         lok(size == exp_size, "got wrong size %d, expected %d\n", size, exp_size);
68a09c8c41Swinesync     if (exp_data)
69a09c8c41Swinesync     {
70a09c8c41Swinesync         todo_wine_if (todo & TODO_REG_DATA)
71a09c8c41Swinesync             lok(memcmp(data, exp_data, size) == 0, "got wrong data\n");
72a09c8c41Swinesync     }
73a09c8c41Swinesync }
74a09c8c41Swinesync 
7507907552Swinesync void verify_reg_nonexist_(const char *file, unsigned line, HKEY hkey, const char *value)
76a09c8c41Swinesync {
77a09c8c41Swinesync     LONG err;
78a09c8c41Swinesync 
79a09c8c41Swinesync     err = RegQueryValueExA(hkey, value, NULL, NULL, NULL, NULL);
80a09c8c41Swinesync     lok(err == ERROR_FILE_NOT_FOUND, "registry value '%s' shouldn't exist; got %d, expected 2\n",
81a09c8c41Swinesync         (value && *value) ? value : "(Default)", err);
82a09c8c41Swinesync }
83a09c8c41Swinesync 
8407907552Swinesync void open_key_(const char *file, unsigned line, const HKEY base, const char *path,
8507907552Swinesync                const DWORD sam, HKEY *hkey)
86a09c8c41Swinesync {
87a09c8c41Swinesync     LONG err;
88a09c8c41Swinesync 
89a09c8c41Swinesync     err = RegOpenKeyExA(base, path, 0, KEY_READ|sam, hkey);
90a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", err);
91a09c8c41Swinesync }
92a09c8c41Swinesync 
9307907552Swinesync void close_key_(const char *file, unsigned line, HKEY hkey)
94a09c8c41Swinesync {
95a09c8c41Swinesync     LONG err;
96a09c8c41Swinesync 
97a09c8c41Swinesync     err = RegCloseKey(hkey);
98a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegCloseKey failed: %d\n", err);
99a09c8c41Swinesync }
100a09c8c41Swinesync 
10107907552Swinesync void verify_key_(const char *file, unsigned line, HKEY key_base, const char *subkey)
102a09c8c41Swinesync {
103a09c8c41Swinesync     HKEY hkey;
104a09c8c41Swinesync     LONG err;
105a09c8c41Swinesync 
106a09c8c41Swinesync     err = RegOpenKeyExA(key_base, subkey, 0, KEY_READ, &hkey);
107a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %d\n", err);
108a09c8c41Swinesync 
109a09c8c41Swinesync     if (hkey)
110a09c8c41Swinesync         RegCloseKey(hkey);
111a09c8c41Swinesync }
112a09c8c41Swinesync 
11307907552Swinesync void verify_key_nonexist_(const char *file, unsigned line, HKEY key_base, const char *subkey)
114a09c8c41Swinesync {
115a09c8c41Swinesync     HKEY hkey;
116a09c8c41Swinesync     LONG err;
117a09c8c41Swinesync 
118a09c8c41Swinesync     err = RegOpenKeyExA(key_base, subkey, 0, KEY_READ, &hkey);
119a09c8c41Swinesync     lok(err == ERROR_FILE_NOT_FOUND, "registry key '%s' shouldn't exist; got %d, expected 2\n",
120a09c8c41Swinesync         subkey, err);
121a09c8c41Swinesync 
122a09c8c41Swinesync     if (hkey)
123a09c8c41Swinesync         RegCloseKey(hkey);
124a09c8c41Swinesync }
125a09c8c41Swinesync 
12607907552Swinesync void add_key_(const char *file, unsigned line, const HKEY hkey, const char *path, HKEY *subkey)
127a09c8c41Swinesync {
128a09c8c41Swinesync     LONG err;
129*ba10b11fSwinesync     HKEY new_key;
130a09c8c41Swinesync 
131a09c8c41Swinesync     err = RegCreateKeyExA(hkey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
132*ba10b11fSwinesync                           KEY_READ|KEY_WRITE, NULL, &new_key, NULL);
133a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: %d\n", err);
134*ba10b11fSwinesync 
135*ba10b11fSwinesync     if (subkey)
136*ba10b11fSwinesync         *subkey = new_key;
137*ba10b11fSwinesync     else
138*ba10b11fSwinesync         RegCloseKey(new_key);
139a09c8c41Swinesync }
140a09c8c41Swinesync 
14107907552Swinesync void delete_key_(const char *file, unsigned line, const HKEY hkey, const char *path)
142a09c8c41Swinesync {
143a09c8c41Swinesync     if (path && *path)
144a09c8c41Swinesync     {
145a09c8c41Swinesync         LONG err;
146a09c8c41Swinesync 
147a09c8c41Swinesync         err = RegDeleteKeyA(hkey, path);
148a09c8c41Swinesync         lok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", err);
149a09c8c41Swinesync     }
150a09c8c41Swinesync }
151a09c8c41Swinesync 
152a09c8c41Swinesync LONG delete_tree(const HKEY key, const char *subkey)
153a09c8c41Swinesync {
154a09c8c41Swinesync     HKEY hkey;
155a09c8c41Swinesync     LONG ret;
156a09c8c41Swinesync     char *subkey_name = NULL;
157a09c8c41Swinesync     DWORD max_subkey_len, subkey_len;
158a09c8c41Swinesync     static const char empty[1];
159a09c8c41Swinesync 
160a09c8c41Swinesync     ret = RegOpenKeyExA(key, subkey, 0, KEY_READ, &hkey);
161a09c8c41Swinesync     if (ret) return ret;
162a09c8c41Swinesync 
163a09c8c41Swinesync     ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &max_subkey_len,
164a09c8c41Swinesync                            NULL, NULL, NULL, NULL, NULL, NULL);
165a09c8c41Swinesync     if (ret) goto cleanup;
166a09c8c41Swinesync 
167a09c8c41Swinesync     max_subkey_len++;
168a09c8c41Swinesync 
169a09c8c41Swinesync     subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len);
170a09c8c41Swinesync     if (!subkey_name)
171a09c8c41Swinesync     {
172a09c8c41Swinesync         ret = ERROR_NOT_ENOUGH_MEMORY;
173a09c8c41Swinesync         goto cleanup;
174a09c8c41Swinesync     }
175a09c8c41Swinesync 
176a09c8c41Swinesync     for (;;)
177a09c8c41Swinesync     {
178a09c8c41Swinesync         subkey_len = max_subkey_len;
179a09c8c41Swinesync         ret = RegEnumKeyExA(hkey, 0, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
180a09c8c41Swinesync         if (ret == ERROR_NO_MORE_ITEMS) break;
181a09c8c41Swinesync         if (ret) goto cleanup;
182a09c8c41Swinesync         ret = delete_tree(hkey, subkey_name);
183a09c8c41Swinesync         if (ret) goto cleanup;
184a09c8c41Swinesync     }
185a09c8c41Swinesync 
186a09c8c41Swinesync     ret = RegDeleteKeyA(hkey, empty);
187a09c8c41Swinesync 
188a09c8c41Swinesync cleanup:
189a09c8c41Swinesync     HeapFree(GetProcessHeap(), 0, subkey_name);
190a09c8c41Swinesync     RegCloseKey(hkey);
191a09c8c41Swinesync     return ret;
192a09c8c41Swinesync }
193a09c8c41Swinesync 
19407907552Swinesync void add_value_(const char *file, unsigned line, HKEY hkey, const char *name,
19507907552Swinesync                 DWORD type, const void *data, size_t size)
196a09c8c41Swinesync {
197a09c8c41Swinesync     LONG err;
198a09c8c41Swinesync 
199a09c8c41Swinesync     err = RegSetValueExA(hkey, name, 0, type, (const BYTE *)data, size);
200a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", err);
201a09c8c41Swinesync }
202a09c8c41Swinesync 
20307907552Swinesync void delete_value_(const char *file, unsigned line, const HKEY hkey, const char *name)
204a09c8c41Swinesync {
205a09c8c41Swinesync     LONG err;
206a09c8c41Swinesync 
207a09c8c41Swinesync     err = RegDeleteValueA(hkey, name);
208a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegDeleteValueA failed: %d\n", err);
209a09c8c41Swinesync }
210a09c8c41Swinesync 
211a09c8c41Swinesync /* Unit tests */
212a09c8c41Swinesync 
2133969dcc3Swinesync static void test_command_syntax(void)
214a09c8c41Swinesync {
2153969dcc3Swinesync     DWORD r;
216a09c8c41Swinesync 
217a09c8c41Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE);
218a09c8c41Swinesync     verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
219a09c8c41Swinesync 
220a09c8c41Swinesync     run_reg_exe("reg add", &r);
221a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
222a09c8c41Swinesync 
223a09c8c41Swinesync     run_reg_exe("reg add /?", &r);
224a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
225a09c8c41Swinesync 
226a09c8c41Swinesync     run_reg_exe("reg add /h", &r);
227a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
228a09c8c41Swinesync 
229a09c8c41Swinesync     run_reg_exe("reg add -H", &r);
230a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
231a09c8c41Swinesync 
2323969dcc3Swinesync     /* Duplicate switches */
2333969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /t REG_DWORD /d 0x1 /v Test /f", &r);
2343969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2353969dcc3Swinesync 
2363969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup1 /t REG_DWORD /d 123 /f /t REG_SZ", &r);
2373969dcc3Swinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
2383969dcc3Swinesync        "got exit code %d, expected 1\n", r);
2393969dcc3Swinesync 
2403969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup2 /t REG_DWORD /d 123 /f /d 456", &r);
2413969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
242a09c8c41Swinesync 
24326226dc5Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /f /f", &r);
244cb66fe28Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
24526226dc5Swinesync 
2463969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /ve", &r);
2473969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2483969dcc3Swinesync 
2493969dcc3Swinesync     /* No /v argument */
2503969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v", &r);
2513969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2523969dcc3Swinesync 
2533969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /d Test /f /v", &r);
2543969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2553969dcc3Swinesync 
2563969dcc3Swinesync     /* Test invalid switches */
2573969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid1 /a", &r);
2583969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2593969dcc3Swinesync 
2603969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid2 /ae", &r);
2613969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2623969dcc3Swinesync 
2633969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid3 /", &r);
2643969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2653969dcc3Swinesync 
2663969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid4 -", &r);
2673969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
268a09c8c41Swinesync 
269a09c8c41Swinesync     /* Test empty type */
270a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v emptyType /t \"\" /d WineTest /f", &r);
2713969dcc3Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
2723969dcc3Swinesync }
273a09c8c41Swinesync 
2743969dcc3Swinesync static void test_key_formats(void)
2753969dcc3Swinesync {
2763969dcc3Swinesync     HKEY hkey;
2773969dcc3Swinesync     DWORD r;
2783969dcc3Swinesync     LONG err;
2793969dcc3Swinesync 
2803969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
2813969dcc3Swinesync 
282a09c8c41Swinesync     run_reg_exe("reg add \\HKCU\\" KEY_BASE "\\keytest0 /f", &r);
2832d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
284a09c8c41Swinesync     verify_key_nonexist(hkey, "keytest0");
285a09c8c41Swinesync 
286a09c8c41Swinesync     run_reg_exe("reg add \\\\HKCU\\" KEY_BASE "\\keytest1 /f", &r);
2872d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
288a09c8c41Swinesync     verify_key_nonexist(hkey, "keytest1");
289a09c8c41Swinesync 
290a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest2\\\\ /f", &r);
291a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
2922d45084dSwinesync         "got exit code %u, expected 1\n", r);
293a09c8c41Swinesync     err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\keytest2");
294a09c8c41Swinesync     ok(err == ERROR_FILE_NOT_FOUND || broken(err == ERROR_SUCCESS /* WinXP */),
2952d45084dSwinesync         "got exit code %d, expected 2\n", err);
296a09c8c41Swinesync 
297a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest3\\ /f", &r);
2982d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
299a09c8c41Swinesync     verify_key(hkey, "keytest3");
300a09c8c41Swinesync 
301a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest4 /f", &r);
3022d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
303a09c8c41Swinesync     verify_key(hkey, "keytest4");
304a09c8c41Swinesync 
3053969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE "\\https://winehq.org /f", &r);
3063969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3073969dcc3Swinesync     verify_key(hkey, "https://winehq.org");
3083969dcc3Swinesync 
3093969dcc3Swinesync     close_key(hkey);
3103969dcc3Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE);
3113969dcc3Swinesync 
3123969dcc3Swinesync     /* Test validity of trailing backslash after system key */
313a1330deaSwinesync     run_reg_exe("reg add HKCU\\ /v Value1 /t REG_SZ /d foo /f", &r);
314a1330deaSwinesync     todo_wine ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
315a1330deaSwinesync     todo_wine verify_reg_nonexist(HKEY_CURRENT_USER, "Value1");
316a1330deaSwinesync 
317a1330deaSwinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\ /v Value2 /t REG_SZ /d bar /f", &r);
318a1330deaSwinesync     todo_wine ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
319a1330deaSwinesync     todo_wine verify_reg_nonexist(HKEY_CURRENT_USER, "Value2");
3203969dcc3Swinesync }
321a1330deaSwinesync 
3223969dcc3Swinesync static void test_add(void)
3233969dcc3Swinesync {
324*ba10b11fSwinesync     HKEY hkey;
3253969dcc3Swinesync     DWORD r, dword;
3263969dcc3Swinesync 
3273969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
3283969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3293969dcc3Swinesync 
3303969dcc3Swinesync     open_key(HKEY_CURRENT_USER, KEY_BASE, KEY_WRITE, &hkey);
3313969dcc3Swinesync 
3323969dcc3Swinesync     /* Test whether overwriting a registry key modifies existing keys and values */
333*ba10b11fSwinesync     add_key(hkey, "Subkey", NULL);
3343969dcc3Swinesync     add_value(hkey, "Test1", REG_SZ, "Value1", 7);
3353969dcc3Swinesync     dword = 0x123;
3363969dcc3Swinesync     add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
3373969dcc3Swinesync 
3383969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
3393969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3403969dcc3Swinesync 
3413969dcc3Swinesync     verify_key(HKEY_CURRENT_USER, KEY_BASE);
3423969dcc3Swinesync     verify_key(hkey, "Subkey");
3433969dcc3Swinesync     verify_reg(hkey, "Test1", REG_SZ, "Value1", 7, 0);
3443969dcc3Swinesync     verify_reg(hkey, "Test2", REG_DWORD, &dword, sizeof(dword), 0);
3453969dcc3Swinesync 
3463969dcc3Swinesync     close_key(hkey);
3473969dcc3Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE);
3483969dcc3Swinesync }
3493969dcc3Swinesync 
3503969dcc3Swinesync static void test_reg_none(void)
3513969dcc3Swinesync {
3523969dcc3Swinesync     HKEY hkey;
3533969dcc3Swinesync     DWORD r;
3543969dcc3Swinesync 
3553969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
3563969dcc3Swinesync 
357a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v none0 /d deadbeef /t REG_NONE /f", &r);
3582d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
359a09c8c41Swinesync     verify_reg(hkey, "none0", REG_NONE, "d\0e\0a\0d\0b\0e\0e\0f\0\0", 18, 0);
360a09c8c41Swinesync 
361a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v none1 /t REG_NONE /f", &r);
362a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
363a09c8c41Swinesync     verify_reg(hkey, "none1", REG_NONE, "\0", 2, 0);
364a09c8c41Swinesync 
365a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_NONE /f", &r);
366a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
367a09c8c41Swinesync     verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
368a09c8c41Swinesync 
3693969dcc3Swinesync     close_key(hkey);
3703969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
3713969dcc3Swinesync }
3723969dcc3Swinesync 
3733969dcc3Swinesync static void test_reg_sz(void)
3743969dcc3Swinesync {
3753969dcc3Swinesync     HKEY hkey;
3763969dcc3Swinesync     DWORD r;
3773969dcc3Swinesync 
3783969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
3793969dcc3Swinesync 
380a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /d WineTest /f", &r);
381a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
382a09c8c41Swinesync        "got exit code %d, expected 0\n", r);
383a09c8c41Swinesync     if (r == REG_EXIT_SUCCESS)
384a09c8c41Swinesync         verify_reg(hkey, "", REG_SZ, "WineTest", 9, 0);
385a09c8c41Swinesync     else
386a09c8c41Swinesync         win_skip("broken reg.exe detected\n");
387a09c8c41Swinesync 
3888789d866Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f", &r);
3898789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
3908789d866Swinesync     verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
3918789d866Swinesync 
39226226dc5Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f /ve", &r);
393cb66fe28Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
39426226dc5Swinesync 
3958789d866Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /d WineTEST /f", &r);
3968789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3978789d866Swinesync     verify_reg(hkey, "", REG_SZ, "WineTEST", 9, 0);
3988789d866Swinesync 
3998789d866Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_SZ /f", &r);
4008789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4018789d866Swinesync     verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
4028789d866Swinesync 
403bfe2251bSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /d deadbeef /f", &r);
404a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
405bfe2251bSwinesync     verify_reg(hkey, "test0", REG_SZ, "deadbeef", 9, 0);
406a09c8c41Swinesync 
407bfe2251bSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /f", &r);
408a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
409bfe2251bSwinesync     verify_reg(hkey, "test0", REG_SZ, "", 1, 0);
410a09c8c41Swinesync 
411a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test1 /t REG_SZ /f /d", &r);
412a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
413a09c8c41Swinesync 
414a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test2 /f", &r);
415a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
416a09c8c41Swinesync     verify_reg(hkey, "test2", REG_SZ, "", 1, 0);
417a09c8c41Swinesync 
418a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test3 /f /d \"\"", &r);
419a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
420a09c8c41Swinesync     verify_reg(hkey, "test3", REG_SZ, "", 1, 0);
421a09c8c41Swinesync 
4221e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v string\\04 /t REG_SZ /d \"Value\" /f", &r);
4231e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4241e0e137fSwinesync     verify_reg(hkey, "string\\04", REG_SZ, "Value", 6, 0);
4251e0e137fSwinesync 
4261e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v string5 /t REG_SZ /d \"foo\\0bar\" /f", &r);
4271e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4281e0e137fSwinesync     verify_reg(hkey, "string5", REG_SZ, "foo\\0bar", 9, 0);
4291e0e137fSwinesync 
4301e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\0 /t REG_SZ /d \"Value\" /f", &r);
4311e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4321e0e137fSwinesync     verify_reg(hkey, "\\0", REG_SZ, "Value", 6, 0);
4331e0e137fSwinesync 
4343969dcc3Swinesync     /* Test support for forward and back slashes in value names */
4353969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v count/up /d one/two/three /f", &r);
4363969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4373969dcc3Swinesync     verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
4383969dcc3Swinesync 
4393969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\foo\\bar /f", &r);
4403969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4413969dcc3Swinesync     verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
4423969dcc3Swinesync 
4433969dcc3Swinesync     close_key(hkey);
4443969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
4453969dcc3Swinesync }
4463969dcc3Swinesync 
4473969dcc3Swinesync static void test_reg_expand_sz(void)
4483969dcc3Swinesync {
4493969dcc3Swinesync     HKEY hkey;
4503969dcc3Swinesync     DWORD r;
4513969dcc3Swinesync 
4523969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
4533969dcc3Swinesync 
454a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand0 /t REG_EXpand_sz /d \"dead%PATH%beef\" /f", &r);
4552d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
456a09c8c41Swinesync     verify_reg(hkey, "expand0", REG_EXPAND_SZ, "dead%PATH%beef", 15, 0);
457a09c8c41Swinesync 
458a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand1 /t REG_EXpand_sz /d \"dead^%PATH^%beef\" /f", &r);
4592d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
460a09c8c41Swinesync     verify_reg(hkey, "expand1", REG_EXPAND_SZ, "dead^%PATH^%beef", 17, 0);
461a09c8c41Swinesync 
462a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand2 /f", &r);
4632d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
464a09c8c41Swinesync     verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, 0);
465a09c8c41Swinesync 
466a09c8c41Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_EXPAND_SZ /d WineTEST /f", &r);
4672d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
468a09c8c41Swinesync     verify_reg(hkey, "", REG_EXPAND_SZ, "WineTEST", 9, 0);
469a09c8c41Swinesync 
470a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand3 /f /d \"\"", &r);
4712d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
472a09c8c41Swinesync     verify_reg(hkey, "expand3", REG_EXPAND_SZ, "", 1, 0);
473a09c8c41Swinesync 
474a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_EXPAND_SZ /f", &r);
475a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
476a09c8c41Swinesync     verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
477a09c8c41Swinesync 
4783969dcc3Swinesync     close_key(hkey);
4793969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
4803969dcc3Swinesync }
4813969dcc3Swinesync 
4823969dcc3Swinesync static void test_reg_binary(void)
4833969dcc3Swinesync {
4843969dcc3Swinesync     HKEY hkey;
4853969dcc3Swinesync     DWORD r, dword, type, size;
4863969dcc3Swinesync     char buffer[22];
4873969dcc3Swinesync     LONG err;
4883969dcc3Swinesync 
4893969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
4903969dcc3Swinesync 
491a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin0 /f", &r);
4922d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
493a09c8c41Swinesync     verify_reg(hkey, "bin0", REG_BINARY, buffer, 0, 0);
494a09c8c41Swinesync 
495a09c8c41Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_BINARY /d deadbeef /f", &r);
4962d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
497a09c8c41Swinesync     dword = 0xefbeadde;
498a09c8c41Swinesync     verify_reg(hkey, "", REG_BINARY, &dword, sizeof(DWORD), 0);
499a09c8c41Swinesync 
500a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin1 /f /d 0xDeAdBeEf", &r);
5012d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
502a09c8c41Swinesync 
503a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin2 /f /d x01", &r);
5042d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
505a09c8c41Swinesync 
506a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin3 /f /d 01x", &r);
5072d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
508a09c8c41Swinesync 
509a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin4 /f /d DeAdBeEf0DD", &r);
5102d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
511a09c8c41Swinesync     /* Remaining nibble prefixed */
512a09c8c41Swinesync     buffer[0] = 0x0d; buffer[1] = 0xea; buffer[2] = 0xdb;
513a09c8c41Swinesync     buffer[3] = 0xee; buffer[4] = 0xf0; buffer[5] = 0xdd;
5143969dcc3Swinesync     /* Remaining nibble suffixed on WinXP */
515a09c8c41Swinesync     buffer[6] = 0xde; buffer[7] = 0xad; buffer[8] = 0xbe;
516a09c8c41Swinesync     buffer[9] = 0xef; buffer[10] = 0x0d; buffer[11] = 0xd0;
517a09c8c41Swinesync     size = 6;
518a09c8c41Swinesync     err = RegQueryValueExA(hkey, "bin4", NULL, &type, (void *) (buffer+12), &size);
519a09c8c41Swinesync     ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
520a09c8c41Swinesync     ok(type == REG_BINARY, "got wrong type %u\n", type);
521a09c8c41Swinesync     ok(size == 6, "got wrong size %u\n", size);
522a09c8c41Swinesync     ok(memcmp(buffer, buffer+12, 6) == 0 ||
523a09c8c41Swinesync         broken(memcmp(buffer+6, buffer+12, 6) == 0 /* WinXP */), "got wrong data\n");
524a09c8c41Swinesync 
525a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin5 /d \"\" /f", &r);
5262d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
527a09c8c41Swinesync     verify_reg(hkey, "bin5", REG_BINARY, buffer, 0, 0);
528a09c8c41Swinesync 
529a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v bin6 /t REG_BINARY /f /d", &r);
530a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
531a09c8c41Swinesync 
532a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_BINARY /f", &r);
533a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
534a09c8c41Swinesync     verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
535a09c8c41Swinesync 
5363969dcc3Swinesync     close_key(hkey);
5373969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
5383969dcc3Swinesync }
5393969dcc3Swinesync 
5403969dcc3Swinesync static void test_reg_dword(void)
5413969dcc3Swinesync {
5423969dcc3Swinesync     HKEY hkey;
5433969dcc3Swinesync     DWORD r, dword, type, size;
5443969dcc3Swinesync     LONG err;
5453969dcc3Swinesync 
5463969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
5473969dcc3Swinesync 
548a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /f /d 12345678", &r);
549a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
550a09c8c41Swinesync        "got exit code %d, expected 0\n", r);
551a09c8c41Swinesync     dword = 12345678;
552a09c8c41Swinesync     if (r == REG_EXIT_SUCCESS)
553a09c8c41Swinesync         verify_reg(hkey, "", REG_DWORD, &dword, sizeof(dword), 0);
554a09c8c41Swinesync     else
555a09c8c41Swinesync         win_skip("broken reg.exe detected\n");
556a09c8c41Swinesync 
557a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword0 /t REG_DWORD /f /d", &r);
558a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
559a09c8c41Swinesync 
560a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword1 /t REG_DWORD /f", &r);
561a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
562a09c8c41Swinesync        "got exit code %d, expected 1\n", r);
563a09c8c41Swinesync 
564a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword2 /t REG_DWORD /d zzz /f", &r);
565a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
566a09c8c41Swinesync 
567a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword3 /t REG_DWORD /d deadbeef /f", &r);
568a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
569a09c8c41Swinesync 
570a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword4 /t REG_DWORD /d 123xyz /f", &r);
571a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
572a09c8c41Swinesync 
573a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword5 /t reg_dword /d 12345678 /f", &r);
574a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
575a09c8c41Swinesync     dword = 12345678;
576a09c8c41Swinesync     verify_reg(hkey, "dword5", REG_DWORD, &dword, sizeof(dword), 0);
577a09c8c41Swinesync 
578a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword6 /t REG_DWORD /D 0123 /f", &r);
579a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
580a09c8c41Swinesync     size = sizeof(dword);
581a09c8c41Swinesync     err = RegQueryValueExA(hkey, "dword6", NULL, &type, (LPBYTE)&dword, &size);
582a09c8c41Swinesync     ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
583a09c8c41Swinesync     ok(type == REG_DWORD, "got wrong type %d, expected %d\n", type, REG_DWORD);
584a09c8c41Swinesync     ok(size == sizeof(DWORD), "got wrong size %d, expected %d\n", size, (int)sizeof(DWORD));
585a09c8c41Swinesync     ok(dword == 123 || broken(dword == 0123 /* WinXP */), "got wrong data %d, expected 123\n", dword);
586a09c8c41Swinesync 
587a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword7 /t reg_dword /d 0xabcdefg /f", &r);
588a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
589a09c8c41Swinesync 
590a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0xdeadbeef /f", &r);
591a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
592a09c8c41Swinesync     dword = 0xdeadbeef;
593a09c8c41Swinesync     verify_reg(hkey, "dword8", REG_DWORD, &dword, sizeof(dword), 0);
594a09c8c41Swinesync 
595a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword9 /f /d -1", &r);
5962d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
597a09c8c41Swinesync 
598a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword10 /f /d -0x1", &r);
5992d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
600a09c8c41Swinesync 
601a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0x01ffffffff /f", &r);
6022d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
603a09c8c41Swinesync 
604a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword12 /t REG_DWORD /d 0xffffffff /f", &r);
605a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
606a09c8c41Swinesync     dword = ~0u;
607a09c8c41Swinesync     verify_reg(hkey, "dword12", REG_DWORD, &dword, sizeof(dword), 0);
608a09c8c41Swinesync 
609a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword13 /t REG_DWORD /d 00x123 /f", &r);
610a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
611a09c8c41Swinesync 
612a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword14 /t REG_DWORD /d 0X123 /f", &r);
613a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
614a09c8c41Swinesync     dword = 0x123;
615a09c8c41Swinesync     verify_reg(hkey, "dword14", REG_DWORD, &dword, sizeof(dword), 0);
616a09c8c41Swinesync 
617a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword15 /t REG_DWORD /d 4294967296 /f", &r);
6182d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
619a09c8c41Swinesync 
620a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD /f", &r);
6212d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
622a09c8c41Swinesync 
623a09c8c41Swinesync     /* REG_DWORD_LITTLE_ENDIAN */
624a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_LE /t REG_DWORD_LITTLE_ENDIAN /d 456 /f", &r);
625a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
626a09c8c41Swinesync     dword = 456;
627a09c8c41Swinesync     verify_reg(hkey, "DWORD_LE", REG_DWORD_LITTLE_ENDIAN, &dword, sizeof(dword), 0);
628a09c8c41Swinesync 
629a09c8c41Swinesync     /* REG_DWORD_BIG_ENDIAN */
630a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE /t REG_DWORD_BIG_ENDIAN /d 456 /f", &r);
6312d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
632a09c8c41Swinesync     dword = 456;
633a09c8c41Swinesync     verify_reg(hkey, "DWORD_BE", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
634a09c8c41Swinesync     /* REG_DWORD_BIG_ENDIAN is broken in every version of windows. It behaves like
635a09c8c41Swinesync      * an ordinary REG_DWORD - that is little endian. GG */
636a09c8c41Swinesync 
637a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE2 /t REG_DWORD_BIG_ENDIAN /f /d", &r);
638a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
639a09c8c41Swinesync 
640a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE3 /t REG_DWORD_BIG_ENDIAN /f", &r);
6412d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
642a09c8c41Swinesync 
643a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD_BIG_ENDIAN /f", &r);
6442d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
645a09c8c41Swinesync 
6463969dcc3Swinesync     close_key(hkey);
6473969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
6483969dcc3Swinesync }
6493969dcc3Swinesync 
6503969dcc3Swinesync static void test_reg_multi_sz(void)
6513969dcc3Swinesync {
6523969dcc3Swinesync     HKEY hkey;
6533969dcc3Swinesync     DWORD r;
6543969dcc3Swinesync     char buffer[22];
6553969dcc3Swinesync 
6563969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
6573969dcc3Swinesync 
658a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi0 /t REG_MULTI_SZ /d \"three\\0little\\0strings\" /f", &r);
659a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
660a09c8c41Swinesync     memcpy(buffer, "three\0little\0strings\0", 22);
661a09c8c41Swinesync     verify_reg(hkey, "multi0", REG_MULTI_SZ, buffer, 22, 0);
662a09c8c41Swinesync 
663a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi1 /s \"#\" /d \"three#little#strings\" /f", &r);
664a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
665a09c8c41Swinesync     verify_reg(hkey, "multi1", REG_MULTI_SZ, buffer, 22, 0);
666a09c8c41Swinesync 
667a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi2 /d \"\" /f", &r);
668a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
669a09c8c41Swinesync     verify_reg(hkey, "multi2", REG_MULTI_SZ, &buffer[21], 1, 0);
670a09c8c41Swinesync 
671a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi3 /f", &r);
6722d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
673a09c8c41Swinesync     verify_reg(hkey, "multi3", REG_MULTI_SZ, &buffer[21], 1, 0);
674a09c8c41Swinesync 
675a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi4 /s \"#\" /d \"threelittlestrings\" /f", &r);
676a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
677a09c8c41Swinesync     verify_reg(hkey, "multi4", REG_MULTI_SZ, "threelittlestrings\0", 20, 0);
678a09c8c41Swinesync 
679a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi5 /s \"#randomgibberish\" /d \"three#little#strings\" /f", &r);
6802d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
681a09c8c41Swinesync 
682a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi6 /s \"\\0\" /d \"three\\0little\\0strings\" /f", &r);
6832d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
684a09c8c41Swinesync 
685a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi7 /s \"\" /d \"three#little#strings\" /f", &r);
6862d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
687a09c8c41Swinesync 
688a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi8 /s \"#\" /d \"##\" /f", &r);
6892d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
690a09c8c41Swinesync 
691a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi9 /s \"#\" /d \"two##strings\" /f", &r);
6922d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
693a09c8c41Swinesync 
694a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi10 /s \"#\" /d \"#a\" /f", &r);
6952d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
696a09c8c41Swinesync 
697a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi11 /s \"#\" /d \"a#\" /f", &r);
698a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
699a09c8c41Swinesync     buffer[0]='a'; buffer[1]=0; buffer[2]=0;
700a09c8c41Swinesync     verify_reg(hkey, "multi11", REG_MULTI_SZ, buffer, 3, 0);
701a09c8c41Swinesync 
702a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi12 /t REG_MULTI_SZ /f /d", &r);
703a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
704a09c8c41Swinesync 
705a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi13 /t REG_MULTI_SZ /f /s", &r);
706a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
707a09c8c41Swinesync 
708a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi14 /t REG_MULTI_SZ /d \"\\0a\" /f", &r);
709a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
710a09c8c41Swinesync 
711a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi15 /t REG_MULTI_SZ /d \"a\\0\" /f", &r);
712a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
713a09c8c41Swinesync     verify_reg(hkey, "multi15", REG_MULTI_SZ, buffer, 3, 0);
714a09c8c41Swinesync 
715a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi16 /d \"two\\0\\0strings\" /f", &r);
716a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
717a09c8c41Swinesync 
718a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi17 /t REG_MULTI_SZ /s \"#\" /d \"#\" /f", &r);
719a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
720a09c8c41Swinesync     buffer[0] = 0; buffer[1] = 0;
721a09c8c41Swinesync     verify_reg(hkey, "multi17", REG_MULTI_SZ, buffer, 2, 0);
722a09c8c41Swinesync 
723a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi18 /t REG_MULTI_SZ /d \"\\0\" /f", &r);
724a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
725a09c8c41Swinesync     verify_reg(hkey, "multi18", REG_MULTI_SZ, buffer, 2, 0);
726a09c8c41Swinesync 
727a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi19 /t REG_MULTI_SZ /s \"#\" /d \"two\\0#strings\" /f", &r);
728a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
729a09c8c41Swinesync     verify_reg(hkey, "multi19", REG_MULTI_SZ, "two\\0\0strings\0", 15, 0);
730a09c8c41Swinesync 
731a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi20 /t REG_MULTI_SZ /s \"#\" /d \"two#\\0strings\" /f", &r);
732a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
733a09c8c41Swinesync     verify_reg(hkey, "multi20", REG_MULTI_SZ, "two\0\\0strings\0", 15, 0);
734a09c8c41Swinesync 
735a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi21 /t REG_MULTI_SZ /s \"#\" /d \"two\\0\\0strings\" /f", &r);
736a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
737a09c8c41Swinesync     verify_reg(hkey, "multi21", REG_MULTI_SZ, "two\\0\\0strings\0", 16, 0);
738a09c8c41Swinesync 
739a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_MULTI_SZ /f", &r);
740a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
741a09c8c41Swinesync     verify_reg(hkey, NULL, REG_MULTI_SZ, buffer, 1, 0);
742a09c8c41Swinesync 
743a09c8c41Swinesync     close_key(hkey);
7443969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
745a09c8c41Swinesync }
746a09c8c41Swinesync 
747a09c8c41Swinesync START_TEST(add)
748a09c8c41Swinesync {
749a09c8c41Swinesync     DWORD r;
750a09c8c41Swinesync 
751a09c8c41Swinesync     if (!run_reg_exe("reg.exe /?", &r)) {
7522161165dSwinesync         win_skip("reg.exe not available, skipping 'add' tests\n");
753a09c8c41Swinesync         return;
754a09c8c41Swinesync     }
755a09c8c41Swinesync 
7563969dcc3Swinesync     test_command_syntax();
7573969dcc3Swinesync     test_key_formats();
758a09c8c41Swinesync     test_add();
7593969dcc3Swinesync     test_reg_none();
7603969dcc3Swinesync     test_reg_sz();
7613969dcc3Swinesync     test_reg_expand_sz();
7623969dcc3Swinesync     test_reg_binary();
7633969dcc3Swinesync     test_reg_dword();
7643969dcc3Swinesync     test_reg_multi_sz();
765a09c8c41Swinesync }
766