ReactOS  0.4.15-dev-5459-gb85f005
add.c
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Akihiro Sagawa
3  *
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.
8  *
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.
13  *
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
17  */
18 
19 #include "reg_test.h"
20 
21 BOOL run_reg_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
22 {
23  STARTUPINFOA si = {sizeof(STARTUPINFOA)};
25  BOOL bret;
26  DWORD ret;
27  char cmdline[256];
28 
33 
34  strcpy(cmdline, cmd);
35  if (!CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
36  return FALSE;
37 
38  ret = WaitForSingleObject(pi.hProcess, 10000);
39  if (ret == WAIT_TIMEOUT)
40  TerminateProcess(pi.hProcess, 1);
41 
42  bret = GetExitCodeProcess(pi.hProcess, rc);
43  lok(bret, "GetExitCodeProcess failed: %d\n", GetLastError());
44 
45  CloseHandle(pi.hThread);
46  CloseHandle(pi.hProcess);
47  return bret;
48 }
49 
50 void verify_reg_(const char *file, unsigned line, HKEY hkey, const char *value,
51  DWORD exp_type, const void *exp_data, DWORD exp_size, DWORD todo)
52 {
53  DWORD type, size;
54  BYTE data[256];
55  LONG err;
56 
57  size = sizeof(data);
58  memset(data, 0xdd, size);
59  err = RegQueryValueExA(hkey, value, NULL, &type, data, &size);
60  lok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got error %d\n", err);
61  if (err != ERROR_SUCCESS)
62  return;
63 
65  lok(type == exp_type, "got registry type %d, expected %d\n", type, exp_type);
67  lok(size == exp_size, "got data size %d, expected %d\n", size, exp_size);
68  if (exp_data)
69  {
71  lok(memcmp(data, exp_data, size) == 0, "registry data does not match\n");
72  }
73 }
74 
75 void verify_reg_nonexist_(const char *file, unsigned line, HKEY hkey, const char *value)
76 {
77  LONG err;
78 
80  lok(err == ERROR_FILE_NOT_FOUND, "registry value '%s' shouldn't exist; got %d, expected 2\n",
81  (value && *value) ? value : "(Default)", err);
82 }
83 
84 void open_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam, HKEY *hkey)
85 {
86  LONG err;
87 
88  err = RegOpenKeyExA(root, path, 0, KEY_READ|sam, hkey);
89  lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got error %d\n", err);
90 }
91 
92 void close_key_(const char *file, unsigned line, HKEY hkey)
93 {
94  LONG err;
95 
96  err = RegCloseKey(hkey);
97  lok(err == ERROR_SUCCESS, "RegCloseKey failed: got error %d\n", err);
98 }
99 
100 void verify_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
101 {
102  HKEY hkey;
103  LONG err;
104 
105  err = RegOpenKeyExA(root, path, 0, KEY_READ|sam, &hkey);
106  lok(err == ERROR_SUCCESS, "RegOpenKeyExA failed: got error %d\n", err);
107 
108  if (hkey)
109  RegCloseKey(hkey);
110 }
111 
112 void verify_key_nonexist_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
113 {
114  HKEY hkey;
115  LONG err;
116 
117  err = RegOpenKeyExA(root, path, 0, KEY_READ|sam, &hkey);
118  lok(err == ERROR_FILE_NOT_FOUND, "registry key '%s' shouldn't exist; got %d, expected 2\n", path, err);
119 
120  if (hkey)
121  RegCloseKey(hkey);
122 }
123 
124 void add_key_(const char *file, unsigned line, const HKEY root, const char *path, REGSAM sam, HKEY *hkey)
125 {
126  LONG err;
127  HKEY new_key;
128 
131  lok(err == ERROR_SUCCESS, "RegCreateKeyExA failed: got error %d\n", err);
132 
133  if (hkey)
134  *hkey = new_key;
135  else
137 }
138 
139 void delete_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
140 {
141  LONG err;
142 
143  if (!path) return;
144 
145  if (!sam)
146  {
148  lok(err == ERROR_SUCCESS, "RegDeleteKeyA failed: got error %d\n", err);
149  }
150  else
151  {
152  err = RegDeleteKeyExA(root, path, sam, 0);
153  lok(err == ERROR_SUCCESS, "RegDeleteKeyExA failed: got error %d\n", err);
154  }
155 }
156 
157 LONG delete_tree_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
158 {
159  HKEY hkey;
160  LONG ret;
161  char *subkey_name = NULL;
162  DWORD max_subkey_len, subkey_len;
163  static const char empty[1];
164 
165  ret = RegOpenKeyExA(root, path, 0, KEY_READ|sam, &hkey);
166  lok(!ret || ret == ERROR_FILE_NOT_FOUND, "RegOpenKeyExA failed, got error %d\n", ret);
167  if (ret) return ret;
168 
169  ret = RegQueryInfoKeyA(hkey, NULL, NULL, NULL, NULL, &max_subkey_len,
170  NULL, NULL, NULL, NULL, NULL, NULL);
171  if (ret) goto cleanup;
172 
173  max_subkey_len++;
174 
175  subkey_name = HeapAlloc(GetProcessHeap(), 0, max_subkey_len);
176  if (!subkey_name)
177  {
179  goto cleanup;
180  }
181 
182  for (;;)
183  {
184  subkey_len = max_subkey_len;
185  ret = RegEnumKeyExA(hkey, 0, subkey_name, &subkey_len, NULL, NULL, NULL, NULL);
186  if (ret == ERROR_NO_MORE_ITEMS) break;
187  if (ret) goto cleanup;
188  ret = delete_tree_(file, line, hkey, subkey_name, sam);
189  if (ret) goto cleanup;
190  }
191 
192  if (!sam)
193  ret = RegDeleteKeyA(hkey, empty);
194  else
195  ret = RegDeleteKeyExA(hkey, empty, sam, 0);
196 
197 cleanup:
198  lok(!ret, "Failed to delete registry key, got error %d\n", ret);
199  HeapFree(GetProcessHeap(), 0, subkey_name);
200  RegCloseKey(hkey);
201  return ret;
202 }
203 
204 void add_value_(const char *file, unsigned line, HKEY hkey, const char *name,
205  DWORD type, const void *data, size_t size)
206 {
207  LONG err;
208 
209  err = RegSetValueExA(hkey, name, 0, type, (const BYTE *)data, size);
210  lok(err == ERROR_SUCCESS, "RegSetValueExA failed: got error %d\n", err);
211 }
212 
213 void delete_value_(const char *file, unsigned line, HKEY hkey, const char *name)
214 {
215  LONG err;
216 
217  err = RegDeleteValueA(hkey, name);
218  lok(err == ERROR_SUCCESS, "RegDeleteValueA failed: got error %d\n", err);
219 }
220 
221 /* Unit tests */
222 
223 static void test_command_syntax(void)
224 {
225  DWORD r;
226 
228 
229  run_reg_exe("reg add", &r);
230  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
231 
232  run_reg_exe("reg add /?", &r);
233  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
234 
235  run_reg_exe("reg add /h", &r);
236  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
237 
238  run_reg_exe("reg add -H", &r);
239  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
240 
241  /* Duplicate switches */
242  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /t REG_DWORD /d 0x1 /v Test /f", &r);
243  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
244 
245  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup1 /t REG_DWORD /d 123 /f /t REG_SZ", &r);
246  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
247  "got exit code %d, expected 1\n", r);
248 
249  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dup2 /t REG_DWORD /d 123 /f /d 456", &r);
250  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
251 
252  run_reg_exe("reg add HKCU\\" KEY_BASE " /f /f", &r);
253  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
254 
255  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Wine /ve", &r);
256  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
257 
258  /* No /v argument */
259  run_reg_exe("reg add HKCU\\" KEY_BASE " /v", &r);
260  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
261 
262  run_reg_exe("reg add HKCU\\" KEY_BASE " /d Test /f /v", &r);
263  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
264 
265  /* Test invalid switches */
266  run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid1 /a", &r);
267  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
268 
269  run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid2 /ae", &r);
270  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
271 
272  run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid3 /", &r);
273  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
274 
275  run_reg_exe("reg add HKCU\\" KEY_BASE " /v invalid4 -", &r);
276  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
277 
278  /* Test empty type */
279  run_reg_exe("reg add HKCU\\" KEY_BASE " /v emptyType /t \"\" /d WineTest /f", &r);
280  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
281 
282  /* Test registry view */
283  run_reg_exe("reg add HKCU\\" KEY_BASE " /v abc /d 123 /f /reg:32 /reg:32", &r);
284  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
285 
286  run_reg_exe("reg add HKCU\\" KEY_BASE " /v abc /d 123 /f /reg:32 /reg:64", &r);
287  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
288 
289  run_reg_exe("reg add HKCU\\" KEY_BASE " /v abc /d 123 /f /reg:64 /reg:64", &r);
290  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
291 }
292 
293 static void test_key_formats(void)
294 {
295  HKEY hkey;
296  DWORD r;
297  LONG err;
298 
299  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
300 
301  run_reg_exe("reg add \\HKCU\\" KEY_BASE "\\keytest0 /f", &r);
302  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
303  verify_key_nonexist(hkey, "keytest0", 0);
304 
305  run_reg_exe("reg add \\\\HKCU\\" KEY_BASE "\\keytest1 /f", &r);
306  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
307  verify_key_nonexist(hkey, "keytest1", 0);
308 
309  run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest2\\\\ /f", &r);
310  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
311  "got exit code %u, expected 1\n", r);
312  err = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE "\\keytest2");
313  ok(err == ERROR_FILE_NOT_FOUND || broken(err == ERROR_SUCCESS /* WinXP */),
314  "got exit code %d, expected 2\n", err);
315 
316  run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest3\\ /f", &r);
317  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
318  verify_key(hkey, "keytest3", 0);
319 
320  run_reg_exe("reg add HKCU\\" KEY_BASE "\\keytest4 /f", &r);
321  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
322  verify_key(hkey, "keytest4", 0);
323 
324  run_reg_exe("reg add HKCU\\" KEY_BASE "\\https://winehq.org /f", &r);
325  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
326  verify_key(hkey, "https://winehq.org", 0);
327 
328  close_key(hkey);
330 
331  /* Test validity of trailing backslash after system key */
332  run_reg_exe("reg add HKCU\\ /v Value1 /t REG_SZ /d foo /f", &r);
333  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
335 
336  run_reg_exe("reg add HKEY_CURRENT_USER\\ /v Value2 /t REG_SZ /d bar /f", &r);
337  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
339 }
340 
341 static void test_add(void)
342 {
343  HKEY hkey;
344  DWORD r, dword;
345 
346  run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
347  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
348 
350 
351  /* The Default value is initialized if no parameters are specified */
352  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
353  delete_value(hkey, NULL);
354 
355  /* This also occurs when specifying a registry type and passing data */
356  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /d 0x5 /f", &r);
357  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
358  dword = 0x5;
359  verify_reg(hkey, NULL, REG_DWORD, &dword, sizeof(dword), 0);
360 
361  /* The Default value can also be overwritten as an empty string */
362  run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
363  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
364  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
365 
366  close_key(hkey);
368 
369  /* Specifying a value name doesn't initialize the Default value in a new key */
370  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test /t REG_SZ /d \"Just me here\" /f", &r);
371  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
372 
373  open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
374 
375  verify_reg(hkey, "Test", REG_SZ, "Just me here", 13, 0);
376  verify_reg_nonexist(hkey, NULL);
377 
378  close_key(hkey);
380 
381  /* Adding a registry key via WinAPI doesn't initialize the Default value... */
382  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
383  verify_reg_nonexist(hkey, NULL);
384 
385  /* ... but we can add it without passing [/f] to reg.exe */
386  run_reg_exe("reg add HKCU\\" KEY_BASE, &r);
387  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
388  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
389  delete_value(hkey, NULL);
390 
391  /* Test whether overwriting a registry key modifies existing keys and values */
392  add_key(hkey, "Subkey", 0, NULL);
393  add_value(hkey, "Test1", REG_SZ, "Value1", 7);
394  dword = 0x123;
395  add_value(hkey, "Test2", REG_DWORD, &dword, sizeof(dword));
396 
397  run_reg_exe("reg add HKCU\\" KEY_BASE " /f", &r);
398  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
399 
401  verify_key(hkey, "Subkey", 0);
402  verify_reg(hkey, "Test1", REG_SZ, "Value1", 7, 0);
403  verify_reg(hkey, "Test2", REG_DWORD, &dword, sizeof(dword), 0);
404  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
405 
406  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_NONE /d Test /f", &r);
407  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
408 
410  verify_key(hkey, "Subkey", 0);
411  verify_reg(hkey, "Test1", REG_SZ, "Value1", 7, 0);
412  verify_reg(hkey, "Test2", REG_DWORD, &dword, sizeof(dword), 0);
413  verify_reg(hkey, NULL, REG_NONE, "T\0e\0s\0t\0\0", 10, 0);
414 
415  close_key(hkey);
417 }
418 
419 static void test_reg_none(void)
420 {
421  HKEY hkey;
422  DWORD r;
423 
424  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
425 
426  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_NONE /f", &r);
427  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
428  verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
429 
430  delete_value(hkey, NULL);
431 
432  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_NONE /f", &r);
433  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
434  verify_reg(hkey, NULL, REG_NONE, "\0", 2, 0);
435 
436  run_reg_exe("reg add HKCU\\" KEY_BASE " /v none0 /d deadbeef /t REG_NONE /f", &r);
437  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
438  verify_reg(hkey, "none0", REG_NONE, "d\0e\0a\0d\0b\0e\0e\0f\0\0", 18, 0);
439 
440  run_reg_exe("reg add HKCU\\" KEY_BASE " /v none1 /t REG_NONE /f", &r);
441  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
442  verify_reg(hkey, "none1", REG_NONE, "\0", 2, 0);
443 
444  close_key(hkey);
446 }
447 
448 static void test_reg_sz(void)
449 {
450  HKEY hkey;
451  DWORD r;
452 
453  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
454 
455  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /f", &r);
456  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
457  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
458 
459  run_reg_exe("reg add HKCU\\" KEY_BASE " /d WineTest /f", &r);
460  ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
461  "got exit code %d, expected 0\n", r);
462  if (r == REG_EXIT_SUCCESS)
463  verify_reg(hkey, "", REG_SZ, "WineTest", 9, 0);
464  else
465  win_skip("broken reg.exe detected\n");
466 
467  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f", &r);
468  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
469  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
470 
471  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /f /ve", &r);
472  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
473 
474  run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /d WineTEST /f", &r);
475  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
476  verify_reg(hkey, "", REG_SZ, "WineTEST", 9, 0);
477 
478  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_SZ /f", &r);
479  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
480  verify_reg(hkey, NULL, REG_SZ, "", 1, 0);
481 
482  run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /d deadbeef /f", &r);
483  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
484  verify_reg(hkey, "test0", REG_SZ, "deadbeef", 9, 0);
485 
486  run_reg_exe("reg add HKCU\\" KEY_BASE " /v test0 /f", &r);
487  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
488  verify_reg(hkey, "test0", REG_SZ, "", 1, 0);
489 
490  run_reg_exe("reg add HKCU\\" KEY_BASE " /v test1 /t REG_SZ /f /d", &r);
491  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
492 
493  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test2 /f", &r);
494  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
495  verify_reg(hkey, "test2", REG_SZ, "", 1, 0);
496 
497  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_SZ /v test3 /f /d \"\"", &r);
498  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
499  verify_reg(hkey, "test3", REG_SZ, "", 1, 0);
500 
501  run_reg_exe("reg add HKCU\\" KEY_BASE " /v string\\04 /t REG_SZ /d \"Value\" /f", &r);
502  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
503  verify_reg(hkey, "string\\04", REG_SZ, "Value", 6, 0);
504 
505  run_reg_exe("reg add HKCU\\" KEY_BASE " /v string5 /t REG_SZ /d \"foo\\0bar\" /f", &r);
506  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
507  verify_reg(hkey, "string5", REG_SZ, "foo\\0bar", 9, 0);
508 
509  run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\0 /t REG_SZ /d \"Value\" /f", &r);
510  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
511  verify_reg(hkey, "\\0", REG_SZ, "Value", 6, 0);
512 
513  /* Test support for forward and back slashes in value names */
514  run_reg_exe("reg add HKCU\\" KEY_BASE " /v count/up /d one/two/three /f", &r);
515  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
516  verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
517 
518  run_reg_exe("reg add HKCU\\" KEY_BASE " /v \\foo\\bar /f", &r);
519  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
520  verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
521 
522  close_key(hkey);
524 }
525 
526 static void test_reg_expand_sz(void)
527 {
528  HKEY hkey;
529  DWORD r;
530 
531  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
532 
533  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /f", &r);
534  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
535  verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
536 
537  delete_value(hkey, NULL);
538 
539  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_EXPAND_SZ /f", &r);
540  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
541  verify_reg(hkey, NULL, REG_EXPAND_SZ, "", 1, 0);
542 
543  run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand0 /t REG_EXpand_sz /d \"dead%PATH%beef\" /f", &r);
544  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
545  verify_reg(hkey, "expand0", REG_EXPAND_SZ, "dead%PATH%beef", 15, 0);
546 
547  run_reg_exe("reg add HKCU\\" KEY_BASE " /v expand1 /t REG_EXpand_sz /d \"dead^%PATH^%beef\" /f", &r);
548  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
549  verify_reg(hkey, "expand1", REG_EXPAND_SZ, "dead^%PATH^%beef", 17, 0);
550 
551  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand2 /f", &r);
552  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
553  verify_reg(hkey, "expand2", REG_EXPAND_SZ, "", 1, 0);
554 
555  run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_EXPAND_SZ /d WineTEST /f", &r);
556  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
557  verify_reg(hkey, "", REG_EXPAND_SZ, "WineTEST", 9, 0);
558 
559  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_EXPAND_SZ /v expand3 /f /d \"\"", &r);
560  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
561  verify_reg(hkey, "expand3", REG_EXPAND_SZ, "", 1, 0);
562 
563  close_key(hkey);
565 }
566 
567 static void test_reg_binary(void)
568 {
569  HKEY hkey;
570  DWORD r, dword, type, size;
571  char buffer[22];
572  LONG err;
573 
574  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
575 
576  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /f", &r);
577  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
578  verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
579 
580  delete_value(hkey, NULL);
581 
582  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_BINARY /f", &r);
583  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
584  verify_reg(hkey, NULL, REG_BINARY, buffer, 0, 0);
585 
586  run_reg_exe("reg add HKEY_CURRENT_USER\\" KEY_BASE " /ve /t REG_BINARY /d deadbeef /f", &r);
587  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
588  dword = 0xefbeadde;
589  verify_reg(hkey, "", REG_BINARY, &dword, sizeof(DWORD), 0);
590 
591  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin0 /f", &r);
592  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
593  verify_reg(hkey, "bin0", REG_BINARY, buffer, 0, 0);
594 
595  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin1 /f /d 0xDeAdBeEf", &r);
596  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
597 
598  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin2 /f /d x01", &r);
599  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
600 
601  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin3 /f /d 01x", &r);
602  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
603 
604  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin4 /f /d DeAdBeEf0DD", &r);
605  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
606  /* Remaining nibble prefixed */
607  buffer[0] = 0x0d; buffer[1] = 0xea; buffer[2] = 0xdb;
608  buffer[3] = 0xee; buffer[4] = 0xf0; buffer[5] = 0xdd;
609  /* Remaining nibble suffixed on WinXP */
610  buffer[6] = 0xde; buffer[7] = 0xad; buffer[8] = 0xbe;
611  buffer[9] = 0xef; buffer[10] = 0x0d; buffer[11] = 0xd0;
612  size = 6;
613  err = RegQueryValueExA(hkey, "bin4", NULL, &type, (void *) (buffer+12), &size);
614  ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
615  ok(type == REG_BINARY, "got wrong type %u\n", type);
616  ok(size == 6, "got wrong size %u\n", size);
617  ok(memcmp(buffer, buffer+12, 6) == 0 ||
618  broken(memcmp(buffer+6, buffer+12, 6) == 0 /* WinXP */), "got wrong data\n");
619 
620  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_BINARY /v bin5 /d \"\" /f", &r);
621  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
622  verify_reg(hkey, "bin5", REG_BINARY, buffer, 0, 0);
623 
624  run_reg_exe("reg add HKCU\\" KEY_BASE " /v bin6 /t REG_BINARY /f /d", &r);
625  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
626 
627  close_key(hkey);
629 }
630 
631 static void test_reg_dword(void)
632 {
633  HKEY hkey;
634  DWORD r, dword, type, size;
635  LONG err;
636 
637  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
638 
639  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /f /d 12345678", &r);
640  ok(r == REG_EXIT_SUCCESS || broken(r == REG_EXIT_FAILURE /* WinXP */),
641  "got exit code %d, expected 0\n", r);
642  dword = 12345678;
643  if (r == REG_EXIT_SUCCESS)
644  verify_reg(hkey, "", REG_DWORD, &dword, sizeof(dword), 0);
645  else
646  win_skip("broken reg.exe detected\n");
647 
648  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD /f", &r);
649  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
650 
651  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword0 /t REG_DWORD /f /d", &r);
652  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
653 
654  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword1 /t REG_DWORD /f", &r);
655  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */),
656  "got exit code %d, expected 1\n", r);
657 
658  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword2 /t REG_DWORD /d zzz /f", &r);
659  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
660 
661  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword3 /t REG_DWORD /d deadbeef /f", &r);
662  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
663 
664  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword4 /t REG_DWORD /d 123xyz /f", &r);
665  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
666 
667  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword5 /t reg_dword /d 12345678 /f", &r);
668  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
669  dword = 12345678;
670  verify_reg(hkey, "dword5", REG_DWORD, &dword, sizeof(dword), 0);
671 
672  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword6 /t REG_DWORD /D 0123 /f", &r);
673  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
674  size = sizeof(dword);
675  err = RegQueryValueExA(hkey, "dword6", NULL, &type, (LPBYTE)&dword, &size);
676  ok(err == ERROR_SUCCESS, "RegQueryValueEx failed: got %d\n", err);
677  ok(type == REG_DWORD, "got wrong type %d, expected %d\n", type, REG_DWORD);
678  ok(size == sizeof(DWORD), "got wrong size %d, expected %d\n", size, (int)sizeof(DWORD));
679  ok(dword == 123 || broken(dword == 0123 /* WinXP */), "got wrong data %d, expected 123\n", dword);
680 
681  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword7 /t reg_dword /d 0xabcdefg /f", &r);
682  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
683 
684  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword8 /t REG_dword /d 0xdeadbeef /f", &r);
685  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
686  dword = 0xdeadbeef;
687  verify_reg(hkey, "dword8", REG_DWORD, &dword, sizeof(dword), 0);
688 
689  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword9 /f /d -1", &r);
690  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
691 
692  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_DWORD /v dword10 /f /d -0x1", &r);
693  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
694 
695  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword11 /t REG_dword /d 0x01ffffffff /f", &r);
696  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
697 
698  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword12 /t REG_DWORD /d 0xffffffff /f", &r);
699  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
700  dword = ~0u;
701  verify_reg(hkey, "dword12", REG_DWORD, &dword, sizeof(dword), 0);
702 
703  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword13 /t REG_DWORD /d 00x123 /f", &r);
704  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
705 
706  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword14 /t REG_DWORD /d 0X123 /f", &r);
707  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
708  dword = 0x123;
709  verify_reg(hkey, "dword14", REG_DWORD, &dword, sizeof(dword), 0);
710 
711  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword15 /t REG_DWORD /d 4294967296 /f", &r);
712  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %u, expected 1\n", r);
713 
714  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword16 /t REG_DWORD /d 456 /f", &r);
715  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
716  dword = 456;
717  verify_reg(hkey, "dword16", REG_DWORD, &dword, sizeof(dword), 0);
718 
719  run_reg_exe("reg add HKCU\\" KEY_BASE " /v dword17 /t REG_DWORD /d 0x456 /f", &r);
720  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
721  dword = 0x456;
722  verify_reg(hkey, "dword17", REG_DWORD, &dword, sizeof(dword), 0);
723 
724  /* REG_DWORD_LITTLE_ENDIAN */
725  run_reg_exe("reg add HKCU\\" KEY_BASE " /v DWORD_LE /t REG_DWORD_LITTLE_ENDIAN /d 456 /f", &r);
726  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
727  dword = 456;
728  verify_reg(hkey, "DWORD_LE", REG_DWORD_LITTLE_ENDIAN, &dword, sizeof(dword), 0);
729 
730  close_key(hkey);
732 }
733 
734 /* REG_DWORD_BIG_ENDIAN is broken in every version of Windows. It behaves
735  * like an ordinary REG_DWORD, which is little endian.
736  */
737 static void test_reg_dword_big_endian(void)
738 {
739  HKEY hkey;
740  DWORD r, dword;
741 
742  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_DWORD_BIG_ENDIAN /f", &r);
743  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
744 
745  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test1 /t REG_DWORD_BIG_ENDIAN /f /d", &r);
746  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
747 
748  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test2 /t REG_DWORD_BIG_ENDIAN /f", &r);
749  ok(r == REG_EXIT_FAILURE || broken(r == REG_EXIT_SUCCESS /* WinXP */), "got exit code %d, expected 1\n", r);
750 
751  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
752 
753  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test3 /t REG_DWORD_BIG_ENDIAN /d 456 /f", &r);
754  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
755  dword = 456;
756  verify_reg(hkey, "Test3", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
757 
758  run_reg_exe("reg add HKCU\\" KEY_BASE " /v Test4 /t REG_DWORD_BIG_ENDIAN /d 0x456 /f", &r);
759  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
760  dword = 0x456;
761  verify_reg(hkey, "Test4", REG_DWORD_BIG_ENDIAN, &dword, sizeof(dword), 0);
762 
763  close_key(hkey);
765 }
766 
767 static void test_reg_multi_sz(void)
768 {
769  HKEY hkey;
770  DWORD r;
771 
772  add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey);
773 
774  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /f", &r);
775  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
776  verify_reg(hkey, NULL, REG_MULTI_SZ, "", 1, 0);
777 
778  delete_value(hkey, NULL);
779 
780  run_reg_exe("reg add HKCU\\" KEY_BASE " /ve /t REG_MULTI_SZ /f", &r);
781  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
782  verify_reg(hkey, NULL, REG_MULTI_SZ, "", 1, 0);
783 
784  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi0 /t REG_MULTI_SZ /d \"three\\0little\\0strings\" /f", &r);
785  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
786  verify_reg(hkey, "multi0", REG_MULTI_SZ, "three\0little\0strings\0", 22, 0);
787 
788  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi1 /s \"#\" /d \"three#little#strings\" /f", &r);
789  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
790  verify_reg(hkey, "multi1", REG_MULTI_SZ, "three\0little\0strings\0", 22, 0);
791 
792  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi2 /d \"\" /f", &r);
793  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
794  verify_reg(hkey, "multi2", REG_MULTI_SZ, "", 1, 0);
795 
796  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi3 /f", &r);
797  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
798  verify_reg(hkey, "multi3", REG_MULTI_SZ, "", 1, 0);
799 
800  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi4 /s \"#\" /d \"threelittlestrings\" /f", &r);
801  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
802  verify_reg(hkey, "multi4", REG_MULTI_SZ, "threelittlestrings\0", 20, 0);
803 
804  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi5 /s \"#randomgibberish\" /d \"three#little#strings\" /f", &r);
805  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
806 
807  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi6 /s \"\\0\" /d \"three\\0little\\0strings\" /f", &r);
808  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
809 
810  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi7 /s \"\" /d \"three#little#strings\" /f", &r);
811  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
812 
813  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi8 /s \"#\" /d \"##\" /f", &r);
814  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
815 
816  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi9 /s \"#\" /d \"two##strings\" /f", &r);
817  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
818 
819  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi10 /s \"#\" /d \"#a\" /f", &r);
820  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
821 
822  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi11 /s \"#\" /d \"a#\" /f", &r);
823  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
824  verify_reg(hkey, "multi11", REG_MULTI_SZ, "a\0", 3, 0);
825 
826  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi12 /t REG_MULTI_SZ /f /d", &r);
827  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
828 
829  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi13 /t REG_MULTI_SZ /f /s", &r);
830  ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r);
831 
832  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi14 /t REG_MULTI_SZ /d \"\\0a\" /f", &r);
833  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
834 
835  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi15 /t REG_MULTI_SZ /d \"a\\0\" /f", &r);
836  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
837  verify_reg(hkey, "multi15", REG_MULTI_SZ, "a\0", 3, 0);
838 
839  run_reg_exe("reg add HKCU\\" KEY_BASE " /t REG_MULTI_SZ /v multi16 /d \"two\\0\\0strings\" /f", &r);
840  ok(r == REG_EXIT_FAILURE, "got exit code %u, expected 1\n", r);
841 
842  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi17 /t REG_MULTI_SZ /s \"#\" /d \"#\" /f", &r);
843  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
844  verify_reg(hkey, "multi17", REG_MULTI_SZ, "\0", 2, 0);
845 
846  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi18 /t REG_MULTI_SZ /d \"\\0\" /f", &r);
847  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
848  verify_reg(hkey, "multi18", REG_MULTI_SZ, "\0", 2, 0);
849 
850  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi19 /t REG_MULTI_SZ /s \"#\" /d \"two\\0#strings\" /f", &r);
851  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
852  verify_reg(hkey, "multi19", REG_MULTI_SZ, "two\\0\0strings\0", 15, 0);
853 
854  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi20 /t REG_MULTI_SZ /s \"#\" /d \"two#\\0strings\" /f", &r);
855  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
856  verify_reg(hkey, "multi20", REG_MULTI_SZ, "two\0\\0strings\0", 15, 0);
857 
858  run_reg_exe("reg add HKCU\\" KEY_BASE " /v multi21 /t REG_MULTI_SZ /s \"#\" /d \"two\\0\\0strings\" /f", &r);
859  ok(r == REG_EXIT_SUCCESS, "got exit code %u, expected 0\n", r);
860  verify_reg(hkey, "multi21", REG_MULTI_SZ, "two\\0\\0strings\0", 16, 0);
861 
862  close_key(hkey);
864 }
865 
866 #if 0
867 static void test_registry_view_win32(void)
868 {
869  HKEY hkey;
870  DWORD r;
871  BOOL is_wow64, is_win32;
872 
874  is_win32 = !is_wow64 && (sizeof(void *) == sizeof(int));
875 
876  if (!is_win32) return;
877 
878  /* Try adding to the 32-bit registry view (32-bit Windows) */
879  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine32 /d Test /f /reg:32", &r);
880  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
881 
883  verify_reg(hkey, "Wine32", REG_SZ, "Test", 5, 0);
884  close_key(hkey);
885 
887  verify_reg(hkey, "Wine32", REG_SZ, "Test", 5, 0);
888  close_key(hkey);
889 
891 
892  /* Try adding to the 64-bit registry view, which doesn't exist on 32-bit Windows */
893  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine64 /d Test /f /reg:64", &r);
894  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
895 
897  verify_reg(hkey, "Wine64", REG_SZ, "Test", 5, 0);
898  close_key(hkey);
899 
901  verify_reg(hkey, "Wine64", REG_SZ, "Test", 5, 0);
902  close_key(hkey);
903 
905 }
906 
907 static void test_registry_view_win64(void)
908 {
909  HKEY hkey;
910  DWORD r;
912 
914  is_win64 = !is_wow64 && (sizeof(void *) > sizeof(int));
915 
916  if (!is_win64) return;
917 
918  /* Try adding to the 32-bit registry view (64-bit Windows) */
919  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine32 /d Test /f /reg:32", &r);
920  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
921 
923  verify_reg(hkey, "Wine32", REG_SZ, "Test", 5, 0);
924  close_key(hkey);
926 
928 
929  /* Try adding to the 64-bit registry view (64-bit Windows) */
930  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine64 /d Test /f /reg:64", &r);
931  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
932 
934  verify_reg(hkey, "Wine64", REG_SZ, "Test", 5, 0);
935  close_key(hkey);
937 
939 }
940 
941 static void test_registry_view_wow64(void)
942 {
943  HKEY hkey;
944  DWORD r;
945  BOOL is_wow64;
946 
948 
949  if (!is_wow64) return;
950 
951  /* Try adding to the 32-bit registry view (WOW64) */
952  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine32 /d Test /f /reg:32", &r);
953  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
954 
956  verify_reg(hkey, "Wine32", REG_SZ, "Test", 5, 0);
957  close_key(hkey);
959 
961 
962  /* Try adding to the 64-bit registry view (WOW64) */
963  run_reg_exe("reg add HKLM\\" KEY_BASE " /v Wine64 /d Test /f /reg:64", &r);
964  ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r);
965 
967  verify_reg(hkey, "Wine64", REG_SZ, "Test", 5, 0);
968  close_key(hkey);
970 
972 }
973 #endif
974 
976 {
977  DWORD r;
978 
979  if (!run_reg_exe("reg.exe /?", &r)) {
980  win_skip("reg.exe not available, skipping 'add' tests\n");
981  return;
982  }
983 
986  test_add();
987  test_reg_none();
988  test_reg_sz();
990  test_reg_binary();
991  test_reg_dword();
994 
995  /* Check if reg.exe is running with elevated privileges */
996  if (!is_elevated_process())
997  {
998  win_skip("reg.exe is not running with elevated privileges; "
999  "skipping registry view tests\n");
1000  return;
1001  }
1002 
1003 #if 0
1004  test_registry_view_win32();
1005  test_registry_view_win64();
1006  test_registry_view_wow64();
1007 #endif
1008 
1009 }
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define TODO_REG_TYPE
Definition: reg_test.h:33
#define lok
Definition: registry.c:202
struct _STARTUPINFOA STARTUPINFOA
void close_key_(const char *file, unsigned line, HKEY hkey)
Definition: add.c:92
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4027
void verify_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
Definition: add.c:100
Definition: pdh_main.c:93
#define CloseHandle
Definition: compat.h:739
#define run_reg_exe(c, r)
Definition: reg_test.h:39
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static void test_reg_expand_sz(void)
Definition: add.c:526
void add_value_(const char *file, unsigned line, HKEY hkey, const char *name, DWORD type, const void *data, size_t size)
Definition: add.c:204
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL is_wow64
Definition: msi.c:54
#define TODO_REG_DATA
Definition: reg_test.h:35
void verify_reg_(const char *file, unsigned line, HKEY hkey, const char *value, DWORD exp_type, const void *exp_data, DWORD exp_size, DWORD todo)
Definition: add.c:50
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
LONG WINAPI RegDeleteKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ REGSAM samDesired, _In_ DWORD Reserved)
Definition: reg.c:1252
#define REG_EXIT_FAILURE
Definition: reg_test.h:31
#define REG_BINARY
Definition: nt_native.h:1496
Definition: ftp_var.h:139
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
LONG WINAPI RegQueryInfoKeyA(HKEY hKey, LPSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3611
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
void verify_reg_nonexist_(const char *file, unsigned line, HKEY hkey, const char *value)
Definition: add.c:75
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL run_reg_exe_(const char *file, unsigned line, const char *cmd, DWORD *rc)
Definition: add.c:21
#define close_key(k)
Definition: reg_test.h:52
BOOL todo
Definition: filedlg.c:313
LONG WINAPI RegOpenKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD ulOptions, _In_ REGSAM samDesired, _Out_ PHKEY phkResult)
Definition: reg.c:3321
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
GLuint buffer
Definition: glext.h:5915
DWORD dwFlags
Definition: winbase.h:842
TCHAR * cmdline
Definition: stretchblt.cpp:32
static void test_add(void)
Definition: add.c:341
#define delete_tree(r, p, s)
Definition: reg_test.h:67
#define open_key(r, p, s, k)
Definition: reg_test.h:49
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
START_TEST(add)
Definition: add.c:975
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
static void test_key_formats(void)
Definition: add.c:293
#define REG_MULTI_SZ
Definition: nt_native.h:1501
struct ChNotifyTest * exp_data
Definition: shlfolder.c:4868
static const BOOL is_win64
Definition: shellpath.c:59
Definition: parser.c:48
static void test_command_syntax(void)
Definition: add.c:223
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define verify_reg(k, v, t, d, s, todo)
Definition: reg_test.h:42
static void test_reg_multi_sz(void)
Definition: add.c:767
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
BOOL WINAPI IsWow64Process(IN HANDLE hProcess, OUT PBOOL Wow64Process)
Definition: proc.c:1975
#define KEY_WRITE
Definition: nt_native.h:1031
#define KEY_WOW64_64KEY
Definition: cmtypes.h:46
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
void delete_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
Definition: add.c:139
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:736
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
void open_key_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam, HKEY *hkey)
Definition: add.c:84
#define delete_key(r, p, s)
Definition: reg_test.h:64
static void test_reg_none(void)
Definition: add.c:419
static refpint_t pi[]
Definition: server.c:96
#define todo_wine_if(is_todo)
Definition: custom.c:76
void add_key_(const char *file, unsigned line, const HKEY root, const char *path, REGSAM sam, HKEY *hkey)
Definition: add.c:124
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4743
unsigned long DWORD
Definition: ntddk_ex.h:95
HANDLE hStdOutput
Definition: winbase.h:847
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define WAIT_TIMEOUT
Definition: dderror.h:14
int ret
#define REG_DWORD_LITTLE_ENDIAN
Definition: nt_native.h:1498
static void test_reg_dword(void)
Definition: add.c:631
LONG delete_tree_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
Definition: add.c:157
void verify_key_nonexist_(const char *file, unsigned line, HKEY root, const char *path, REGSAM sam)
Definition: add.c:112
#define GetCurrentProcess()
Definition: compat.h:759
#define err(...)
unsigned char BYTE
Definition: xxhash.c:193
#define broken(x)
Definition: _sntprintf.h:21
#define REG_DWORD_BIG_ENDIAN
Definition: nt_native.h:1499
#define verify_reg_nonexist(k, v)
Definition: reg_test.h:46
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1222
static void test_reg_binary(void)
Definition: add.c:567
#define REG_EXIT_SUCCESS
Definition: reg_test.h:30
HANDLE hStdInput
Definition: winbase.h:846
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
#define REG_EXPAND_SZ
Definition: nt_native.h:1494
#define ok(value,...)
Definition: atltest.h:57
#define delete_value(k, n)
Definition: reg_test.h:74
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2319
ACCESS_MASK REGSAM
Definition: winreg.h:69
#define NULL
Definition: types.h:112
BOOL empty
Definition: button.c:170
#define KEY_BASE
Definition: reg_test.h:29
Definition: name.c:38
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static REGSAM sam
Definition: query.c:143
char * cleanup(char *str)
Definition: wpickclick.c:99
#define KEY_WOW64_32KEY
Definition: cmtypes.h:45
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4816
#define add_key(r, p, s, k)
Definition: reg_test.h:61
#define REG_NONE
Definition: nt_native.h:1492
void delete_value_(const char *file, unsigned line, HKEY hkey, const char *name)
Definition: add.c:213
LONG WINAPI RegCreateKeyExA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey, _In_ DWORD Reserved, _In_ LPSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_ LPDWORD lpdwDisposition)
Definition: reg.c:1029
#define TODO_REG_SIZE
Definition: reg_test.h:34
#define verify_key_nonexist(r, p, s)
Definition: reg_test.h:58
static void test_reg_sz(void)
Definition: add.c:448
#define verify_key(r, p, s)
Definition: reg_test.h:55
#define memset(x, y, z)
Definition: compat.h:39
static void test_reg_dword_big_endian(void)
Definition: add.c:737
#define REG_DWORD
Definition: sdbapi.c:596
#define win_skip
Definition: test.h:160
#define add_value(k, n, t, d, s)
Definition: reg_test.h:70
HANDLE hStdError
Definition: winbase.h:848
#define HeapFree(x, y, z)
Definition: compat.h:735
#define RegCloseKey(hKey)
Definition: registry.h:47
LONG WINAPI RegEnumKeyExA(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2442
BOOL is_elevated_process(void)
Definition: import.c:21
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTKEY **ppCryptKey)
Definition: rsaenh.c:794
Definition: fci.c:126
#define REG_SZ
Definition: layer.c:22