reg/tests: Always specify the expected exit code in error messages.
[wine.git] / programs / reg / tests / add.c
blob6d513f14fbd44cbb92f14b830a04924a9a7b28de
1 /*
2 * Copyright 2014 Akihiro Sagawa
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include "reg_test.h"
21 #define TODO_REG_TYPE (0x0001u)
22 #define TODO_REG_SIZE (0x0002u)
23 #define TODO_REG_DATA (0x0004u)
25 BOOL run_reg_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
27 STARTUPINFOA si = {sizeof(STARTUPINFOA)};
28 PROCESS_INFORMATION pi;
29 BOOL bret;
30 DWORD ret;
31 char cmdline[256];
33 si.dwFlags = STARTF_USESTDHANDLES;
34 si.hStdInput = INVALID_HANDLE_VALUE;
35 si.hStdOutput = INVALID_HANDLE_VALUE;
36 si.hStdError = INVALID_HANDLE_VALUE;
38 strcpy(cmdline, cmd);
39 if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
40 return FALSE;
42 ret = WaitForSingleObject(pi.hProcess, 10000);
43 if (ret == WAIT_TIMEOUT)
44 TerminateProcess(pi.hProcess, 1);
46 bret = GetExitCodeProcess(pi.hProcess, rc);
47 lok(bret, "GetExitCodeProcess failed: %d\n", GetLastError());
49 CloseHandle(pi.hThread);
50 CloseHandle(pi.hProcess);
51 return bret;
54 void verify_reg_(const char *file, unsigned line, HKEY hkey, const char *value,
55 DWORD exp_type, const void *exp_data, DWORD exp_size, DWORD todo)
57 DWORD type, size;
58 BYTE data[256];
59 LONG err;
61 size = sizeof(data);
62 memset(data, 0xdd, size);
63 err = RegQueryValueExA(hkey, value, NULL, &type, data, &size);
64 lok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
65 if (err != ERROR_SUCCESS)
66 return;
68 todo_wine_if (todo & TODO_REG_TYPE)
69 lok(type == exp_type, "got wrong type %d, expected %d\n", type, exp_type);
70 todo_wine_if (todo & TODO_REG_SIZE)
71 lok(size == exp_size, "got wrong size %d, expected %d\n", size, exp_size);
72 if (exp_data)
74 todo_wine_if (todo & TODO_REG_DATA)
75 lok(memcmp(data, exp_data, size) == 0, "got wrong data\n");
79 void verify_reg_nonexist_(const char *file, unsigned line, HKEY hkey, const char *value)
81 LONG err;
83 err = RegQueryValueExA(hkey, value, NULL, NULL, NULL, NULL);
84 lok(err == ERROR_FILE_NOT_FOUND, "registry value '%s' shouldn't exist; got %d, expected 2\n",
85 (value && *value) ? value : "(Default)", err);
88 void open_key_(const char *file, unsigned line, const HKEY base, const char *path,
89 const DWORD sam, HKEY *hkey)
91 LONG err;
93 err = RegOpenKeyExA(base, path, 0, KEY_READ|sam, hkey);
94 lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", err);
97 void close_key_(const char *file, unsigned line, HKEY hkey)
99 LONG err;
101 err = RegCloseKey(hkey);
102 lok(err == ERROR_SUCCESS, "RegCloseKey failed: %d\n", err);
105 void verify_key_(const char *file, unsigned line, HKEY key_base, const char *subkey)
107 HKEY hkey;
108 LONG err;
110 err = RegOpenKeyExA(key_base, subkey, 0, KEY_READ, &hkey);
111 lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got %d\n", err);
113 if (hkey)
114 RegCloseKey(hkey);
117 void verify_key_nonexist_(const char *file, unsigned line, HKEY key_base, const char *subkey)
119 HKEY hkey;
120 LONG err;
122 err = RegOpenKeyExA(key_base, subkey, 0, KEY_READ, &hkey);
123 lok(err == ERROR_FILE_NOT_FOUND, "registry key '%s' shouldn't exist; got %d, expected 2\n",
124 subkey, err);
126 if (hkey)
127 RegCloseKey(hkey);
130 void add_key_(const char *file, unsigned line, const HKEY hkey, const char *path, HKEY *subkey)
132 LONG err;
134 err = RegCreateKeyExA(hkey, path, 0, NULL, REG_OPTION_NON_VOLATILE,
135 KEY_READ|KEY_WRITE, NULL, subkey, NULL);
136 lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: %d\n", err);
139 void delete_key_(const char *file, unsigned line, const HKEY hkey, const char *path)
141 if (path && *path)
143 LONG err;
145 err = RegDeleteKeyA(hkey, path);
146 lok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: %d\n", err);
150 LONG delete_tree(const HKEY key, const char *subkey)
152 HKEY hkey;
153 LONG ret;
154 char *subkey_name = NULL;
155 DWORD max_subkey_len, subkey_len;
156 static const char empty[1];
158 ret = RegOpenKeyExA(key, subkey, 0, KEY_READ, &hkey);
159 if (ret) return ret;
161 ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &max_subkey_len,
162 NULL, NULL, NULL, NULL, NULL, NULL);
163 if (ret) goto cleanup;
165 max_subkey_len++;
167 subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len);
168 if (!subkey_name)
170 ret = ERROR_NOT_ENOUGH_MEMORY;
171 goto cleanup;
174 for (;;)
176 subkey_len = max_subkey_len;
177 ret = RegEnumKeyExA(hkey, 0, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
178 if (ret == ERROR_NO_MORE_ITEMS) break;
179 if (ret) goto cleanup;
180 ret = delete_tree(hkey, subkey_name);
181 if (ret) goto cleanup;
184 ret = RegDeleteKeyA(hkey, empty);
186 cleanup:
187 HeapFree(GetProcessHeap(), 0, subkey_name);
188 RegCloseKey(hkey);
189 return ret;
192 void add_value_(const char *file, unsigned line, HKEY hkey, const char *name,
193 DWORD type, const void *data, size_t size)
195 LONG err;
197 err = RegSetValueExA(hkey, name, 0, type, (const BYTE *)data, size);
198 lok(err == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", err);
201 void delete_value_(const char *file, unsigned line, const HKEY hkey, const char *name)
203 LONG err;
205 err = RegDeleteValueA(hkey, name);
206 lok(err == ERROR_SUCCESS, "RegDeleteValueA failed: %d\n", err);
209 /* Unit tests */
211 static void test_add(void)
213 HKEY hkey;
214 LONG err;
215 DWORD r, dword, type, size;
216 char buffer[22];
218 delete_tree(HKEY_CURRENT_USER, KEY_BASE);
219 verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
221 run_reg_exe("reg add", &r);
222 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
224 run_reg_exe("reg add /?", &r);
225 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
227 run_reg_exe("reg add /h", &r);
228 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
230 run_reg_exe("reg add -H", &r);
231 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
233 run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
234 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
236 open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
238 /* Test empty type */
239 run_reg_exe("reg add HKCU\\" KEY_BASE " /v emptyType /t \"\" /d WineTest /f", &r);
240 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
242 /* Test input key formats */
243 run_reg_exe("reg add \\HKCU\\" KEY_BASE "\\keytest0 /f", &r);
244 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
245 verify_key_nonexist(hkey, "keytest0");
247 run_reg_exe("reg add \\\\HKCU\\" KEY_BASE "\\keytest1 /f", &r);
248 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
249 verify_key_nonexist(hkey, "keytest1");
251 run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest2\\\\ /f", &r);
252 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
253 "got exit code %u, expected 1\n", r);
254 err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\keytest2");
255 ok(err == ERROR_FILE_NOT_FOUND || broken(err == ERROR_SUCCESS /* WinXP */),
256 "got exit code %d, expected 2\n", err);
258 run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest3\\ /f", &r);
259 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
260 verify_key(hkey, "keytest3");
261 delete_key(hkey, "keytest3");
263 run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest4 /f", &r);
264 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
265 verify_key(hkey, "keytest4");
266 delete_key(hkey, "keytest4");
268 /* REG_NONE */
269 run_reg_exe("reg add HKCU\\" KEY_BASE " /v none0 /d deadbeef /t REG_NONE /f", &r);
270 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
271 verify_reg(hkey, "none0", REG_NONE, "d\0e\0a\0d\0b\0e\0e\0f\0\0", 18, 0);
273 run_reg_exe("reg add HKCU\\" KEY_BASE " /v none1 /t REG_NONE /f", &r);
274 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
275 verify_reg(hkey, "none1", REG_NONE, "\0", 2, 0);
277 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_NONE /f", &r);
278 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
279 verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
281 /* REG_SZ */
282 run_reg_exe("reg add HKCU\\" KEY_BASE " /d WineTest /f", &r);
283 ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
284 "got exit code %d, expected 0\n", r);
285 if (r == REG_EXIT_SUCCESS)
286 verify_reg(hkey, "", REG_SZ, "WineTest", 9, 0);
287 else
288 win_skip("broken reg.exe detected\n");
290 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f", &r);
291 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
292 verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
294 run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /d WineTEST /f", &r);
295 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
296 verify_reg(hkey, "", REG_SZ, "WineTEST", 9, 0);
298 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_SZ /f", &r);
299 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
300 verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
302 run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /d deadbeef /f", &r);
303 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
304 verify_reg(hkey, "test0", REG_SZ, "deadbeef", 9, 0);
306 run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /f", &r);
307 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
308 verify_reg(hkey, "test0", REG_SZ, "", 1, 0);
310 run_reg_exe("reg add HKCU\\" KEY_BASE " /v test1 /t REG_SZ /f /d", &r);
311 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
313 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test2 /f", &r);
314 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
315 verify_reg(hkey, "test2", REG_SZ, "", 1, 0);
317 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test3 /f /d \"\"", &r);
318 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
319 verify_reg(hkey, "test3", REG_SZ, "", 1, 0);
321 run_reg_exe("reg add HKCU\\" KEY_BASE " /v string\\04 /t REG_SZ /d \"Value\" /f", &r);
322 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
323 verify_reg(hkey, "string\\04", REG_SZ, "Value", 6, 0);
325 run_reg_exe("reg add HKCU\\" KEY_BASE " /v string5 /t REG_SZ /d \"foo\\0bar\" /f", &r);
326 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
327 verify_reg(hkey, "string5", REG_SZ, "foo\\0bar", 9, 0);
329 run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\0 /t REG_SZ /d \"Value\" /f", &r);
330 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
331 verify_reg(hkey, "\\0", REG_SZ, "Value", 6, 0);
333 /* REG_EXPAND_SZ */
334 run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand0 /t REG_EXpand_sz /d \"dead%PATH%beef\" /f", &r);
335 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
336 verify_reg(hkey, "expand0", REG_EXPAND_SZ, "dead%PATH%beef", 15, 0);
338 run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand1 /t REG_EXpand_sz /d \"dead^%PATH^%beef\" /f", &r);
339 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
340 verify_reg(hkey, "expand1", REG_EXPAND_SZ, "dead^%PATH^%beef", 17, 0);
342 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand2 /f", &r);
343 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
344 verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, 0);
346 run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_EXPAND_SZ /d WineTEST /f", &r);
347 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
348 verify_reg(hkey, "", REG_EXPAND_SZ, "WineTEST", 9, 0);
350 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand3 /f /d \"\"", &r);
351 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
352 verify_reg(hkey, "expand3", REG_EXPAND_SZ, "", 1, 0);
354 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_EXPAND_SZ /f", &r);
355 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
356 verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
358 /* REG_BINARY */
359 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin0 /f", &r);
360 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
361 verify_reg(hkey, "bin0", REG_BINARY, buffer, 0, 0);
363 run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_BINARY /d deadbeef /f", &r);
364 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
365 dword = 0xefbeadde;
366 verify_reg(hkey, "", REG_BINARY, &dword, sizeof(DWORD), 0);
368 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin1 /f /d 0xDeAdBeEf", &r);
369 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
371 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin2 /f /d x01", &r);
372 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
374 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin3 /f /d 01x", &r);
375 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
377 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin4 /f /d DeAdBeEf0DD", &r);
378 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
379 /* Remaining nibble prefixed */
380 buffer[0] = 0x0d; buffer[1] = 0xea; buffer[2] = 0xdb;
381 buffer[3] = 0xee; buffer[4] = 0xf0; buffer[5] = 0xdd;
382 /* Remaining nibble suffixed on winXP */
383 buffer[6] = 0xde; buffer[7] = 0xad; buffer[8] = 0xbe;
384 buffer[9] = 0xef; buffer[10] = 0x0d; buffer[11] = 0xd0;
385 size = 6;
386 err = RegQueryValueExA(hkey, "bin4", NULL, &type, (void *) (buffer+12), &size);
387 ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
388 ok(type == REG_BINARY, "got wrong type %u\n", type);
389 ok(size == 6, "got wrong size %u\n", size);
390 ok(memcmp(buffer, buffer+12, 6) == 0 ||
391 broken(memcmp(buffer+6, buffer+12, 6) == 0 /* WinXP */), "got wrong data\n");
393 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin5 /d \"\" /f", &r);
394 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
395 verify_reg(hkey, "bin5", REG_BINARY, buffer, 0, 0);
397 run_reg_exe("reg add HKCU\\" KEY_BASE " /v bin6 /t REG_BINARY /f /d", &r);
398 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
400 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_BINARY /f", &r);
401 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
402 verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
404 /* REG_DWORD */
405 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /f /d 12345678", &r);
406 ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
407 "got exit code %d, expected 0\n", r);
408 dword = 12345678;
409 if (r == REG_EXIT_SUCCESS)
410 verify_reg(hkey, "", REG_DWORD, &dword, sizeof(dword), 0);
411 else
412 win_skip("broken reg.exe detected\n");
414 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword0 /t REG_DWORD /f /d", &r);
415 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
417 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword1 /t REG_DWORD /f", &r);
418 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
419 "got exit code %d, expected 1\n", r);
421 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword2 /t REG_DWORD /d zzz /f", &r);
422 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
424 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword3 /t REG_DWORD /d deadbeef /f", &r);
425 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
427 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword4 /t REG_DWORD /d 123xyz /f", &r);
428 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
430 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword5 /t reg_dword /d 12345678 /f", &r);
431 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
432 dword = 12345678;
433 verify_reg(hkey, "dword5", REG_DWORD, &dword, sizeof(dword), 0);
435 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword6 /t REG_DWORD /D 0123 /f", &r);
436 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
437 size = sizeof(dword);
438 err = RegQueryValueExA(hkey, "dword6", NULL, &type, (LPBYTE)&dword, &size);
439 ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
440 ok(type == REG_DWORD, "got wrong type %d, expected %d\n", type, REG_DWORD);
441 ok(size == sizeof(DWORD), "got wrong size %d, expected %d\n", size, (int)sizeof(DWORD));
442 ok(dword == 123 || broken(dword == 0123 /* WinXP */), "got wrong data %d, expected 123\n", dword);
444 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword7 /t reg_dword /d 0xabcdefg /f", &r);
445 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
447 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0xdeadbeef /f", &r);
448 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
449 dword = 0xdeadbeef;
450 verify_reg(hkey, "dword8", REG_DWORD, &dword, sizeof(dword), 0);
452 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword9 /f /d -1", &r);
453 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
455 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword10 /f /d -0x1", &r);
456 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
458 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0x01ffffffff /f", &r);
459 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
461 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword12 /t REG_DWORD /d 0xffffffff /f", &r);
462 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
463 dword = ~0u;
464 verify_reg(hkey, "dword12", REG_DWORD, &dword, sizeof(dword), 0);
466 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword13 /t REG_DWORD /d 00x123 /f", &r);
467 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
469 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword14 /t REG_DWORD /d 0X123 /f", &r);
470 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
471 dword = 0x123;
472 verify_reg(hkey, "dword14", REG_DWORD, &dword, sizeof(dword), 0);
474 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword15 /t REG_DWORD /d 4294967296 /f", &r);
475 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
477 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD /f", &r);
478 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
480 /* REG_DWORD_LITTLE_ENDIAN */
481 run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_LE /t REG_DWORD_LITTLE_ENDIAN /d 456 /f", &r);
482 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
483 dword = 456;
484 verify_reg(hkey, "DWORD_LE", REG_DWORD_LITTLE_ENDIAN, &dword, sizeof(dword), 0);
486 /* REG_DWORD_BIG_ENDIAN */
487 run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE /t REG_DWORD_BIG_ENDIAN /d 456 /f", &r);
488 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
489 dword = 456;
490 verify_reg(hkey, "DWORD_BE", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
491 /* REG_DWORD_BIG_ENDIAN is broken in every version of windows. It behaves like
492 * an ordinary REG_DWORD - that is little endian. GG */
494 run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE2 /t REG_DWORD_BIG_ENDIAN /f /d", &r);
495 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
497 run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_BE3 /t REG_DWORD_BIG_ENDIAN /f", &r);
498 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
500 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD_BIG_ENDIAN /f", &r);
501 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
503 /* REG_MULTI_SZ */
504 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi0 /t REG_MULTI_SZ /d \"three\\0little\\0strings\" /f", &r);
505 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
506 memcpy(buffer, "three\0little\0strings\0", 22);
507 verify_reg(hkey, "multi0", REG_MULTI_SZ, buffer, 22, 0);
509 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi1 /s \"#\" /d \"three#little#strings\" /f", &r);
510 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
511 verify_reg(hkey, "multi1", REG_MULTI_SZ, buffer, 22, 0);
513 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi2 /d \"\" /f", &r);
514 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
515 verify_reg(hkey, "multi2", REG_MULTI_SZ, &buffer[21], 1, 0);
517 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi3 /f", &r);
518 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
519 verify_reg(hkey, "multi3", REG_MULTI_SZ, &buffer[21], 1, 0);
521 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi4 /s \"#\" /d \"threelittlestrings\" /f", &r);
522 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
523 verify_reg(hkey, "multi4", REG_MULTI_SZ, "threelittlestrings\0", 20, 0);
525 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi5 /s \"#randomgibberish\" /d \"three#little#strings\" /f", &r);
526 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
528 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi6 /s \"\\0\" /d \"three\\0little\\0strings\" /f", &r);
529 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
531 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi7 /s \"\" /d \"three#little#strings\" /f", &r);
532 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
534 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi8 /s \"#\" /d \"##\" /f", &r);
535 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
537 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi9 /s \"#\" /d \"two##strings\" /f", &r);
538 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
540 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi10 /s \"#\" /d \"#a\" /f", &r);
541 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
543 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi11 /s \"#\" /d \"a#\" /f", &r);
544 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
545 buffer[0]='a'; buffer[1]=0; buffer[2]=0;
546 verify_reg(hkey, "multi11", REG_MULTI_SZ, buffer, 3, 0);
548 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi12 /t REG_MULTI_SZ /f /d", &r);
549 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
551 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi13 /t REG_MULTI_SZ /f /s", &r);
552 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
554 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi14 /t REG_MULTI_SZ /d \"\\0a\" /f", &r);
555 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
557 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi15 /t REG_MULTI_SZ /d \"a\\0\" /f", &r);
558 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
559 verify_reg(hkey, "multi15", REG_MULTI_SZ, buffer, 3, 0);
561 run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi16 /d \"two\\0\\0strings\" /f", &r);
562 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
564 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi17 /t REG_MULTI_SZ /s \"#\" /d \"#\" /f", &r);
565 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
566 buffer[0] = 0; buffer[1] = 0;
567 verify_reg(hkey, "multi17", REG_MULTI_SZ, buffer, 2, 0);
569 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi18 /t REG_MULTI_SZ /d \"\\0\" /f", &r);
570 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
571 verify_reg(hkey, "multi18", REG_MULTI_SZ, buffer, 2, 0);
573 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi19 /t REG_MULTI_SZ /s \"#\" /d \"two\\0#strings\" /f", &r);
574 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
575 verify_reg(hkey, "multi19", REG_MULTI_SZ, "two\\0\0strings\0", 15, 0);
577 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi20 /t REG_MULTI_SZ /s \"#\" /d \"two#\\0strings\" /f", &r);
578 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
579 verify_reg(hkey, "multi20", REG_MULTI_SZ, "two\0\\0strings\0", 15, 0);
581 run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi21 /t REG_MULTI_SZ /s \"#\" /d \"two\\0\\0strings\" /f", &r);
582 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
583 verify_reg(hkey, "multi21", REG_MULTI_SZ, "two\\0\\0strings\0", 16, 0);
585 run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_MULTI_SZ /f", &r);
586 ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
587 verify_reg(hkey, NULL, REG_MULTI_SZ, buffer, 1, 0);
589 /* Test forward and back slashes */
590 run_reg_exe("reg add HKCU\\" KEY_BASE "\\https://winehq.org /f", &r);
591 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
592 verify_key(hkey, "https://winehq.org");
594 run_reg_exe("reg add HKCU\\" KEY_BASE " /v count/up /d one/two/three /f", &r);
595 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
596 verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
598 run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\foo\\bar /f", &r);
599 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
600 verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
602 close_key(hkey);
604 /* Test duplicate switches */
605 run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /t REG_DWORD /d 0x1 /v Test /f", &r);
606 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
608 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup1 /t REG_DWORD /d 123 /f /t REG_SZ", &r);
609 ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
610 "got exit code %u, expected 1\n", r);
612 run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup2 /t REG_DWORD /d 123 /f /d 456", &r);
613 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
615 /* Multiple /v* switches */
616 run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /ve", &r);
617 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
619 /* No /v argument */
620 run_reg_exe("reg add HKCU\\" KEY_BASE " /v", &r);
621 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
623 run_reg_exe("reg add HKCU\\" KEY_BASE " /d Test /f /v", &r);
624 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
626 /* Test invalid switches */
627 run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid1 /a", &r);
628 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
630 run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid2 /ae", &r);
631 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
633 run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid3 /", &r);
634 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
636 run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid4 -", &r);
637 ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
639 delete_tree(HKEY_CURRENT_USER, KEY_BASE);
642 START_TEST(add)
644 DWORD r;
646 if (!run_reg_exe("reg.exe /?", &r)) {
647 win_skip("reg.exe not available, skipping 'add' tests\n");
648 return;
651 test_add();