xref: /reactos/modules/rostests/winetests/reg/add.c (revision 44774b38)
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;
129ba10b11fSwinesync     HKEY new_key;
130a09c8c41Swinesync 
131a09c8c41Swinesync     err = RegCreateKeyExA(hkey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
132ba10b11fSwinesync                           KEY_READ|KEY_WRITE, NULL, &new_key, NULL);
133a09c8c41Swinesync     lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: %d\n", err);
134ba10b11fSwinesync 
135ba10b11fSwinesync     if (subkey)
136ba10b11fSwinesync         *subkey = new_key;
137ba10b11fSwinesync     else
138ba10b11fSwinesync         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);
314f42b63fdSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
315f42b63fdSwinesync     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);
318f42b63fdSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
319f42b63fdSwinesync     verify_reg_nonexist(HKEY_CURRENT_USER, "Value2");
3203969dcc3Swinesync }
321a1330deaSwinesync 
3223969dcc3Swinesync static void test_add(void)
3233969dcc3Swinesync {
324ba10b11fSwinesync     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 
33200ef8711Swinesync     /* The Default value is initialized if no parameters are specified */
33300ef8711Swinesync     todo_wine verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
33400ef8711Swinesync     todo_wine delete_value(hkey, NULL);
33500ef8711Swinesync 
33600ef8711Swinesync     /* This also occurs when specifying a registry type and passing data */
33700ef8711Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /d 0x5 /f", &r);
33800ef8711Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
33900ef8711Swinesync     dword = 0x5;
34000ef8711Swinesync     verify_reg(hkey, NULL, REG_DWORD, &dword, sizeof(dword), 0);
34100ef8711Swinesync 
34200ef8711Swinesync     /* The Default value can also be overwritten as an empty string */
34300ef8711Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
34400ef8711Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
34500ef8711Swinesync     verify_reg(hkey, NULL, REG_SZ, "", 1, TODO_REG_TYPE|TODO_REG_SIZE|TODO_REG_DATA);
34600ef8711Swinesync 
34700ef8711Swinesync     close_key(hkey);
34800ef8711Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
34900ef8711Swinesync 
35000ef8711Swinesync     /* Specifying a value name doesn't initialize the Default value in a new key */
35100ef8711Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test /t REG_SZ /d \"Just me here\" /f", &r);
35200ef8711Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
35300ef8711Swinesync 
35400ef8711Swinesync     open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
35500ef8711Swinesync 
35600ef8711Swinesync     verify_reg(hkey, "Test", REG_SZ, "Just me here", 13, 0);
35700ef8711Swinesync     verify_reg_nonexist(hkey, NULL);
35800ef8711Swinesync 
35900ef8711Swinesync     close_key(hkey);
36000ef8711Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
36100ef8711Swinesync 
36200ef8711Swinesync     /* Adding a registry key via WinAPI doesn't initialize the Default value... */
36300ef8711Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
36400ef8711Swinesync     verify_reg_nonexist(hkey, NULL);
36500ef8711Swinesync 
36600ef8711Swinesync     /* ... but we can add it without passing [/f] to reg.exe */
36700ef8711Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE, &r);
36800ef8711Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
36900ef8711Swinesync     todo_wine verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
37000ef8711Swinesync     todo_wine delete_value(hkey, NULL);
37100ef8711Swinesync 
3723969dcc3Swinesync     /* Test whether overwriting a registry key modifies existing keys and values */
373ba10b11fSwinesync     add_key(hkey, "Subkey", NULL);
3743969dcc3Swinesync     add_value(hkey, "Test1", REG_SZ, "Value1", 7);
3753969dcc3Swinesync     dword = 0x123;
3763969dcc3Swinesync     add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
3773969dcc3Swinesync 
3783969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
3793969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
3803969dcc3Swinesync 
3813969dcc3Swinesync     verify_key(HKEY_CURRENT_USER, KEY_BASE);
3823969dcc3Swinesync     verify_key(hkey, "Subkey");
3833969dcc3Swinesync     verify_reg(hkey, "Test1", REG_SZ, "Value1", 7, 0);
3843969dcc3Swinesync     verify_reg(hkey, "Test2", REG_DWORD, &dword, sizeof(dword), 0);
38500ef8711Swinesync     todo_wine verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
3863969dcc3Swinesync 
38740d62f3cSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_NONE /d Test /f", &r);
38840d62f3cSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
38940d62f3cSwinesync 
39040d62f3cSwinesync     verify_key(HKEY_CURRENT_USER, KEY_BASE);
39140d62f3cSwinesync     verify_key(hkey, "Subkey");
39240d62f3cSwinesync     verify_reg(hkey, "Test1", REG_SZ, "Value1", 7, 0);
39340d62f3cSwinesync     verify_reg(hkey, "Test2", REG_DWORD, &dword, sizeof(dword), 0);
39440d62f3cSwinesync     verify_reg(hkey, NULL, REG_NONE, "T\0e\0s\0t\0\0", 10, 0);
39540d62f3cSwinesync 
3963969dcc3Swinesync     close_key(hkey);
3973969dcc3Swinesync     delete_tree(HKEY_CURRENT_USER, KEY_BASE);
3983969dcc3Swinesync }
3993969dcc3Swinesync 
4003969dcc3Swinesync static void test_reg_none(void)
4013969dcc3Swinesync {
4023969dcc3Swinesync     HKEY hkey;
4033969dcc3Swinesync     DWORD r;
4043969dcc3Swinesync 
4053969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
4063969dcc3Swinesync 
4075e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_NONE /f", &r);
4085e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4095e7302ebSwinesync     todo_wine verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
4105e7302ebSwinesync 
4115e7302ebSwinesync     todo_wine delete_value(hkey, NULL);
4125e7302ebSwinesync 
4135e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_NONE /f", &r);
4145e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4155e7302ebSwinesync     verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
4165e7302ebSwinesync 
417a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v none0 /d deadbeef /t REG_NONE /f", &r);
4182d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
419a09c8c41Swinesync     verify_reg(hkey, "none0", REG_NONE, "d\0e\0a\0d\0b\0e\0e\0f\0\0", 18, 0);
420a09c8c41Swinesync 
421a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v none1 /t REG_NONE /f", &r);
422a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
423a09c8c41Swinesync     verify_reg(hkey, "none1", REG_NONE, "\0", 2, 0);
424a09c8c41Swinesync 
4253969dcc3Swinesync     close_key(hkey);
4263969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
4273969dcc3Swinesync }
4283969dcc3Swinesync 
4293969dcc3Swinesync static void test_reg_sz(void)
4303969dcc3Swinesync {
4313969dcc3Swinesync     HKEY hkey;
4323969dcc3Swinesync     DWORD r;
4333969dcc3Swinesync 
4343969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
4353969dcc3Swinesync 
4365e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /f", &r);
4375e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4385e7302ebSwinesync     todo_wine verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
4395e7302ebSwinesync 
440a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /d WineTest /f", &r);
441a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
442a09c8c41Swinesync        "got exit code %d, expected 0\n", r);
443a09c8c41Swinesync     if (r == REG_EXIT_SUCCESS)
444a09c8c41Swinesync         verify_reg(hkey, "", REG_SZ, "WineTest", 9, 0);
445a09c8c41Swinesync     else
446a09c8c41Swinesync         win_skip("broken reg.exe detected\n");
447a09c8c41Swinesync 
4488789d866Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f", &r);
4498789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4508789d866Swinesync     verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
4518789d866Swinesync 
45226226dc5Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f /ve", &r);
453cb66fe28Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
45426226dc5Swinesync 
4558789d866Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /d WineTEST /f", &r);
4568789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4578789d866Swinesync     verify_reg(hkey, "", REG_SZ, "WineTEST", 9, 0);
4588789d866Swinesync 
4598789d866Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_SZ /f", &r);
4608789d866Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4618789d866Swinesync     verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
4628789d866Swinesync 
463bfe2251bSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /d deadbeef /f", &r);
464a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
465bfe2251bSwinesync     verify_reg(hkey, "test0", REG_SZ, "deadbeef", 9, 0);
466a09c8c41Swinesync 
467bfe2251bSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /f", &r);
468a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
469bfe2251bSwinesync     verify_reg(hkey, "test0", REG_SZ, "", 1, 0);
470a09c8c41Swinesync 
471a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v test1 /t REG_SZ /f /d", &r);
472a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
473a09c8c41Swinesync 
474a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test2 /f", &r);
475a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
476a09c8c41Swinesync     verify_reg(hkey, "test2", REG_SZ, "", 1, 0);
477a09c8c41Swinesync 
478a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test3 /f /d \"\"", &r);
479a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
480a09c8c41Swinesync     verify_reg(hkey, "test3", REG_SZ, "", 1, 0);
481a09c8c41Swinesync 
4821e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v string\\04 /t REG_SZ /d \"Value\" /f", &r);
4831e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4841e0e137fSwinesync     verify_reg(hkey, "string\\04", REG_SZ, "Value", 6, 0);
4851e0e137fSwinesync 
4861e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v string5 /t REG_SZ /d \"foo\\0bar\" /f", &r);
4871e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4881e0e137fSwinesync     verify_reg(hkey, "string5", REG_SZ, "foo\\0bar", 9, 0);
4891e0e137fSwinesync 
4901e0e137fSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\0 /t REG_SZ /d \"Value\" /f", &r);
4911e0e137fSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
4921e0e137fSwinesync     verify_reg(hkey, "\\0", REG_SZ, "Value", 6, 0);
4931e0e137fSwinesync 
4943969dcc3Swinesync     /* Test support for forward and back slashes in value names */
4953969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v count/up /d one/two/three /f", &r);
4963969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
4973969dcc3Swinesync     verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
4983969dcc3Swinesync 
4993969dcc3Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\foo\\bar /f", &r);
5003969dcc3Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
5013969dcc3Swinesync     verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
5023969dcc3Swinesync 
5033969dcc3Swinesync     close_key(hkey);
5043969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
5053969dcc3Swinesync }
5063969dcc3Swinesync 
5073969dcc3Swinesync static void test_reg_expand_sz(void)
5083969dcc3Swinesync {
5093969dcc3Swinesync     HKEY hkey;
5103969dcc3Swinesync     DWORD r;
5113969dcc3Swinesync 
5123969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
5133969dcc3Swinesync 
5145e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /f", &r);
5155e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
5165e7302ebSwinesync     todo_wine verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
5175e7302ebSwinesync 
5185e7302ebSwinesync     todo_wine delete_value(hkey, NULL);
5195e7302ebSwinesync 
5205e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_EXPAND_SZ /f", &r);
5215e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
5225e7302ebSwinesync     verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
5235e7302ebSwinesync 
524a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand0 /t REG_EXpand_sz /d \"dead%PATH%beef\" /f", &r);
5252d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
526a09c8c41Swinesync     verify_reg(hkey, "expand0", REG_EXPAND_SZ, "dead%PATH%beef", 15, 0);
527a09c8c41Swinesync 
528a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand1 /t REG_EXpand_sz /d \"dead^%PATH^%beef\" /f", &r);
5292d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
530a09c8c41Swinesync     verify_reg(hkey, "expand1", REG_EXPAND_SZ, "dead^%PATH^%beef", 17, 0);
531a09c8c41Swinesync 
532a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand2 /f", &r);
5332d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
534a09c8c41Swinesync     verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, 0);
535a09c8c41Swinesync 
536a09c8c41Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_EXPAND_SZ /d WineTEST /f", &r);
5372d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
538a09c8c41Swinesync     verify_reg(hkey, "", REG_EXPAND_SZ, "WineTEST", 9, 0);
539a09c8c41Swinesync 
540a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand3 /f /d \"\"", &r);
5412d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
542a09c8c41Swinesync     verify_reg(hkey, "expand3", REG_EXPAND_SZ, "", 1, 0);
543a09c8c41Swinesync 
5443969dcc3Swinesync     close_key(hkey);
5453969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
5463969dcc3Swinesync }
5473969dcc3Swinesync 
5483969dcc3Swinesync static void test_reg_binary(void)
5493969dcc3Swinesync {
5503969dcc3Swinesync     HKEY hkey;
5513969dcc3Swinesync     DWORD r, dword, type, size;
5523969dcc3Swinesync     char buffer[22];
5533969dcc3Swinesync     LONG err;
5543969dcc3Swinesync 
5553969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
5563969dcc3Swinesync 
5575e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /f", &r);
5582d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
5595e7302ebSwinesync     todo_wine verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
5605e7302ebSwinesync 
5615e7302ebSwinesync     todo_wine delete_value(hkey, NULL);
5625e7302ebSwinesync 
5635e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_BINARY /f", &r);
5645e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
5655e7302ebSwinesync     verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
566a09c8c41Swinesync 
567a09c8c41Swinesync     run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_BINARY /d deadbeef /f", &r);
5682d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
569a09c8c41Swinesync     dword = 0xefbeadde;
570a09c8c41Swinesync     verify_reg(hkey, "", REG_BINARY, &dword, sizeof(DWORD), 0);
571a09c8c41Swinesync 
5725e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin0 /f", &r);
5735e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
5745e7302ebSwinesync     verify_reg(hkey, "bin0", REG_BINARY, buffer, 0, 0);
5755e7302ebSwinesync 
576a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin1 /f /d 0xDeAdBeEf", &r);
5772d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
578a09c8c41Swinesync 
579a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin2 /f /d x01", &r);
5802d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
581a09c8c41Swinesync 
582a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin3 /f /d 01x", &r);
5832d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
584a09c8c41Swinesync 
585a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin4 /f /d DeAdBeEf0DD", &r);
5862d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
587a09c8c41Swinesync     /* Remaining nibble prefixed */
588a09c8c41Swinesync     buffer[0] = 0x0d; buffer[1] = 0xea; buffer[2] = 0xdb;
589a09c8c41Swinesync     buffer[3] = 0xee; buffer[4] = 0xf0; buffer[5] = 0xdd;
5903969dcc3Swinesync     /* Remaining nibble suffixed on WinXP */
591a09c8c41Swinesync     buffer[6] = 0xde; buffer[7] = 0xad; buffer[8] = 0xbe;
592a09c8c41Swinesync     buffer[9] = 0xef; buffer[10] = 0x0d; buffer[11] = 0xd0;
593a09c8c41Swinesync     size = 6;
594a09c8c41Swinesync     err = RegQueryValueExA(hkey, "bin4", NULL, &type, (void *) (buffer+12), &size);
595a09c8c41Swinesync     ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
596a09c8c41Swinesync     ok(type == REG_BINARY, "got wrong type %u\n", type);
597a09c8c41Swinesync     ok(size == 6, "got wrong size %u\n", size);
598a09c8c41Swinesync     ok(memcmp(buffer, buffer+12, 6) == 0 ||
599a09c8c41Swinesync         broken(memcmp(buffer+6, buffer+12, 6) == 0 /* WinXP */), "got wrong data\n");
600a09c8c41Swinesync 
601a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin5 /d \"\" /f", &r);
6022d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
603a09c8c41Swinesync     verify_reg(hkey, "bin5", REG_BINARY, buffer, 0, 0);
604a09c8c41Swinesync 
605a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v bin6 /t REG_BINARY /f /d", &r);
606a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
607a09c8c41Swinesync 
6083969dcc3Swinesync     close_key(hkey);
6093969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
6103969dcc3Swinesync }
6113969dcc3Swinesync 
6123969dcc3Swinesync static void test_reg_dword(void)
6133969dcc3Swinesync {
6143969dcc3Swinesync     HKEY hkey;
6153969dcc3Swinesync     DWORD r, dword, type, size;
6163969dcc3Swinesync     LONG err;
6173969dcc3Swinesync 
6183969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
6193969dcc3Swinesync 
620a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /f /d 12345678", &r);
621a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
622a09c8c41Swinesync        "got exit code %d, expected 0\n", r);
623a09c8c41Swinesync     dword = 12345678;
624a09c8c41Swinesync     if (r == REG_EXIT_SUCCESS)
625a09c8c41Swinesync         verify_reg(hkey, "", REG_DWORD, &dword, sizeof(dword), 0);
626a09c8c41Swinesync     else
627a09c8c41Swinesync         win_skip("broken reg.exe detected\n");
628a09c8c41Swinesync 
6295e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD /f", &r);
6305e7302ebSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
6315e7302ebSwinesync 
632a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword0 /t REG_DWORD /f /d", &r);
633a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
634a09c8c41Swinesync 
635a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword1 /t REG_DWORD /f", &r);
636a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
637a09c8c41Swinesync        "got exit code %d, expected 1\n", r);
638a09c8c41Swinesync 
639a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword2 /t REG_DWORD /d zzz /f", &r);
640a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
641a09c8c41Swinesync 
642a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword3 /t REG_DWORD /d deadbeef /f", &r);
643a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
644a09c8c41Swinesync 
645a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword4 /t REG_DWORD /d 123xyz /f", &r);
646a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
647a09c8c41Swinesync 
648a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword5 /t reg_dword /d 12345678 /f", &r);
649a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
650a09c8c41Swinesync     dword = 12345678;
651a09c8c41Swinesync     verify_reg(hkey, "dword5", REG_DWORD, &dword, sizeof(dword), 0);
652a09c8c41Swinesync 
653a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword6 /t REG_DWORD /D 0123 /f", &r);
654a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
655a09c8c41Swinesync     size = sizeof(dword);
656a09c8c41Swinesync     err = RegQueryValueExA(hkey, "dword6", NULL, &type, (LPBYTE)&dword, &size);
657a09c8c41Swinesync     ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
658a09c8c41Swinesync     ok(type == REG_DWORD, "got wrong type %d, expected %d\n", type, REG_DWORD);
659a09c8c41Swinesync     ok(size == sizeof(DWORD), "got wrong size %d, expected %d\n", size, (int)sizeof(DWORD));
660a09c8c41Swinesync     ok(dword == 123 || broken(dword == 0123 /* WinXP */), "got wrong data %d, expected 123\n", dword);
661a09c8c41Swinesync 
662a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword7 /t reg_dword /d 0xabcdefg /f", &r);
663a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
664a09c8c41Swinesync 
665a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0xdeadbeef /f", &r);
666a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
667a09c8c41Swinesync     dword = 0xdeadbeef;
668a09c8c41Swinesync     verify_reg(hkey, "dword8", REG_DWORD, &dword, sizeof(dword), 0);
669a09c8c41Swinesync 
670a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword9 /f /d -1", &r);
6712d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
672a09c8c41Swinesync 
673a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword10 /f /d -0x1", &r);
6742d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
675a09c8c41Swinesync 
676a260ccceSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword11 /t REG_dword /d 0x01ffffffff /f", &r);
6772d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
678a09c8c41Swinesync 
679a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword12 /t REG_DWORD /d 0xffffffff /f", &r);
680a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
681a09c8c41Swinesync     dword = ~0u;
682a09c8c41Swinesync     verify_reg(hkey, "dword12", REG_DWORD, &dword, sizeof(dword), 0);
683a09c8c41Swinesync 
684a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword13 /t REG_DWORD /d 00x123 /f", &r);
685a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
686a09c8c41Swinesync 
687a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword14 /t REG_DWORD /d 0X123 /f", &r);
688a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
689a09c8c41Swinesync     dword = 0x123;
690a09c8c41Swinesync     verify_reg(hkey, "dword14", REG_DWORD, &dword, sizeof(dword), 0);
691a09c8c41Swinesync 
692a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword15 /t REG_DWORD /d 4294967296 /f", &r);
6932d45084dSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
694a09c8c41Swinesync 
695*44774b38Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword16 /t REG_DWORD /d 456 /f", &r);
696*44774b38Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
697*44774b38Swinesync     dword = 456;
698*44774b38Swinesync     verify_reg(hkey, "dword16", REG_DWORD, &dword, sizeof(dword), 0);
699*44774b38Swinesync 
700*44774b38Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword17 /t REG_DWORD /d 0x456 /f", &r);
701*44774b38Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
702*44774b38Swinesync     dword = 0x456;
703*44774b38Swinesync     verify_reg(hkey, "dword17", REG_DWORD, &dword, sizeof(dword), 0);
704*44774b38Swinesync 
705a09c8c41Swinesync     /* REG_DWORD_LITTLE_ENDIAN */
706a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_LE /t REG_DWORD_LITTLE_ENDIAN /d 456 /f", &r);
707a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
708a09c8c41Swinesync     dword = 456;
709a09c8c41Swinesync     verify_reg(hkey, "DWORD_LE", REG_DWORD_LITTLE_ENDIAN, &dword, sizeof(dword), 0);
710a09c8c41Swinesync 
711fe627c0eSwinesync     close_key(hkey);
712fe627c0eSwinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
713fe627c0eSwinesync }
714a09c8c41Swinesync 
715fe627c0eSwinesync /* REG_DWORD_BIG_ENDIAN is broken in every version of Windows. It behaves
716fe627c0eSwinesync  * like an ordinary REG_DWORD, which is little endian.
717fe627c0eSwinesync  */
718fe627c0eSwinesync static void test_reg_dword_big_endian(void)
719fe627c0eSwinesync {
720fe627c0eSwinesync     HKEY hkey;
721fe627c0eSwinesync     DWORD r, dword;
722a09c8c41Swinesync 
723a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD_BIG_ENDIAN /f", &r);
724fe627c0eSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
725fe627c0eSwinesync 
726fe627c0eSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test1 /t REG_DWORD_BIG_ENDIAN /f /d", &r);
727fe627c0eSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
728fe627c0eSwinesync 
729fe627c0eSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test2 /t REG_DWORD_BIG_ENDIAN /f", &r);
730fe627c0eSwinesync     ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
731fe627c0eSwinesync 
732fe627c0eSwinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
733fe627c0eSwinesync 
734fe627c0eSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test3 /t REG_DWORD_BIG_ENDIAN /d 456 /f", &r);
735fe627c0eSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
736fe627c0eSwinesync     dword = 456;
737fe627c0eSwinesync     verify_reg(hkey, "Test3", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
738fe627c0eSwinesync 
739fe627c0eSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test4 /t REG_DWORD_BIG_ENDIAN /d 0x456 /f", &r);
740fe627c0eSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
741fe627c0eSwinesync     dword = 0x456;
742fe627c0eSwinesync     verify_reg(hkey, "Test4", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
743a09c8c41Swinesync 
7443969dcc3Swinesync     close_key(hkey);
7453969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
7463969dcc3Swinesync }
7473969dcc3Swinesync 
7483969dcc3Swinesync static void test_reg_multi_sz(void)
7493969dcc3Swinesync {
7503969dcc3Swinesync     HKEY hkey;
7513969dcc3Swinesync     DWORD r;
7523969dcc3Swinesync 
7533969dcc3Swinesync     add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
7543969dcc3Swinesync 
7555e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /f", &r);
7565e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7576802956eSwinesync     todo_wine verify_reg(hkey, NULL, REG_MULTI_SZ, "", 1, 0);
7585e7302ebSwinesync 
7595e7302ebSwinesync     todo_wine delete_value(hkey, NULL);
7605e7302ebSwinesync 
7615e7302ebSwinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_MULTI_SZ /f", &r);
7625e7302ebSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7636802956eSwinesync     verify_reg(hkey, NULL, REG_MULTI_SZ, "", 1, 0);
7645e7302ebSwinesync 
765a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi0 /t REG_MULTI_SZ /d \"three\\0little\\0strings\" /f", &r);
766a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7676802956eSwinesync     verify_reg(hkey, "multi0", REG_MULTI_SZ, "three\0little\0strings\0", 22, 0);
768a09c8c41Swinesync 
769a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi1 /s \"#\" /d \"three#little#strings\" /f", &r);
770a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7716802956eSwinesync     verify_reg(hkey, "multi1", REG_MULTI_SZ, "three\0little\0strings\0", 22, 0);
772a09c8c41Swinesync 
773a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi2 /d \"\" /f", &r);
774a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7756802956eSwinesync     verify_reg(hkey, "multi2", REG_MULTI_SZ, "", 1, 0);
776a09c8c41Swinesync 
777a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi3 /f", &r);
7782d45084dSwinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
7796802956eSwinesync     verify_reg(hkey, "multi3", REG_MULTI_SZ, "", 1, 0);
780a09c8c41Swinesync 
781a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi4 /s \"#\" /d \"threelittlestrings\" /f", &r);
782a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
783a09c8c41Swinesync     verify_reg(hkey, "multi4", REG_MULTI_SZ, "threelittlestrings\0", 20, 0);
784a09c8c41Swinesync 
785a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi5 /s \"#randomgibberish\" /d \"three#little#strings\" /f", &r);
7862d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
787a09c8c41Swinesync 
788a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi6 /s \"\\0\" /d \"three\\0little\\0strings\" /f", &r);
7892d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
790a09c8c41Swinesync 
791a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi7 /s \"\" /d \"three#little#strings\" /f", &r);
7922d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
793a09c8c41Swinesync 
794a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi8 /s \"#\" /d \"##\" /f", &r);
7952d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
796a09c8c41Swinesync 
797a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi9 /s \"#\" /d \"two##strings\" /f", &r);
7982d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
799a09c8c41Swinesync 
800a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi10 /s \"#\" /d \"#a\" /f", &r);
8012d45084dSwinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
802a09c8c41Swinesync 
803a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi11 /s \"#\" /d \"a#\" /f", &r);
804a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
8056802956eSwinesync     verify_reg(hkey, "multi11", REG_MULTI_SZ, "a\0", 3, 0);
806a09c8c41Swinesync 
807a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi12 /t REG_MULTI_SZ /f /d", &r);
808a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
809a09c8c41Swinesync 
810a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi13 /t REG_MULTI_SZ /f /s", &r);
811a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
812a09c8c41Swinesync 
813a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi14 /t REG_MULTI_SZ /d \"\\0a\" /f", &r);
814a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
815a09c8c41Swinesync 
816a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi15 /t REG_MULTI_SZ /d \"a\\0\" /f", &r);
817a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
8186802956eSwinesync     verify_reg(hkey, "multi15", REG_MULTI_SZ, "a\0", 3, 0);
819a09c8c41Swinesync 
820a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi16 /d \"two\\0\\0strings\" /f", &r);
821a09c8c41Swinesync     ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
822a09c8c41Swinesync 
823a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi17 /t REG_MULTI_SZ /s \"#\" /d \"#\" /f", &r);
824a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
8256802956eSwinesync     verify_reg(hkey, "multi17", REG_MULTI_SZ, "\0", 2, 0);
826a09c8c41Swinesync 
827a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi18 /t REG_MULTI_SZ /d \"\\0\" /f", &r);
828a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
8296802956eSwinesync     verify_reg(hkey, "multi18", REG_MULTI_SZ, "\0", 2, 0);
830a09c8c41Swinesync 
831a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi19 /t REG_MULTI_SZ /s \"#\" /d \"two\\0#strings\" /f", &r);
832a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
833a09c8c41Swinesync     verify_reg(hkey, "multi19", REG_MULTI_SZ, "two\\0\0strings\0", 15, 0);
834a09c8c41Swinesync 
835a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi20 /t REG_MULTI_SZ /s \"#\" /d \"two#\\0strings\" /f", &r);
836a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
837a09c8c41Swinesync     verify_reg(hkey, "multi20", REG_MULTI_SZ, "two\0\\0strings\0", 15, 0);
838a09c8c41Swinesync 
839a09c8c41Swinesync     run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi21 /t REG_MULTI_SZ /s \"#\" /d \"two\\0\\0strings\" /f", &r);
840a09c8c41Swinesync     ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
841a09c8c41Swinesync     verify_reg(hkey, "multi21", REG_MULTI_SZ, "two\\0\\0strings\0", 16, 0);
842a09c8c41Swinesync 
843a09c8c41Swinesync     close_key(hkey);
8443969dcc3Swinesync     delete_key(HKEY_CURRENT_USER, KEY_BASE);
845a09c8c41Swinesync }
846a09c8c41Swinesync 
847a09c8c41Swinesync START_TEST(add)
848a09c8c41Swinesync {
849a09c8c41Swinesync     DWORD r;
850a09c8c41Swinesync 
851a09c8c41Swinesync     if (!run_reg_exe("reg.exe /?", &r)) {
8522161165dSwinesync         win_skip("reg.exe not available, skipping 'add' tests\n");
853a09c8c41Swinesync         return;
854a09c8c41Swinesync     }
855a09c8c41Swinesync 
8563969dcc3Swinesync     test_command_syntax();
8573969dcc3Swinesync     test_key_formats();
858a09c8c41Swinesync     test_add();
8593969dcc3Swinesync     test_reg_none();
8603969dcc3Swinesync     test_reg_sz();
8613969dcc3Swinesync     test_reg_expand_sz();
8623969dcc3Swinesync     test_reg_binary();
8633969dcc3Swinesync     test_reg_dword();
864fe627c0eSwinesync     test_reg_dword_big_endian();
8653969dcc3Swinesync     test_reg_multi_sz();
866a09c8c41Swinesync }
867