2 * Copyright 2014 Akihiro Sagawa
3 * Copyright 2016-2018, 2021 Hugh McMaster
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 static void test_command_syntax(void)
26 delete_tree(HKEY_CURRENT_USER
, KEY_BASE
, 0);
28 run_reg_exe("reg delete", &r
);
29 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
31 run_reg_exe("reg delete /?", &r
);
32 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
34 run_reg_exe("reg delete /h", &r
);
35 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
37 run_reg_exe("reg delete -H", &r
);
38 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
40 /* Multiple /v* switches */
41 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v Wine /ve", &r
);
42 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
44 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v Wine /va", &r
);
45 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
47 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /ve /ve", &r
);
48 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
50 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /ve /va", &r
);
51 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
53 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /va /va", &r
);
54 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
56 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v Test /ve /va", &r
);
57 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
59 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v Wine /v Test /f", &r
);
60 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
63 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v", &r
);
64 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
66 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f /v", &r
);
67 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
69 /* Test registry view */
70 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f /reg:32 /reg:32", &r
);
71 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
73 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f /reg:32 /reg:64", &r
);
74 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
76 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f /reg:64 /reg:64", &r
);
77 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
80 static void test_delete(void)
84 const DWORD deadbeef
= 0xdeadbeef;
86 delete_tree(HKEY_CURRENT_USER
, KEY_BASE
, 0);
88 /* Create a test key */
89 add_key(HKEY_CURRENT_USER
, KEY_BASE
, 0, &hkey
);
90 add_value(hkey
, "foo", REG_DWORD
, &deadbeef
, sizeof(deadbeef
));
91 add_value(hkey
, "bar", REG_DWORD
, &deadbeef
, sizeof(deadbeef
));
92 add_value(hkey
, NULL
, REG_DWORD
, &deadbeef
, sizeof(deadbeef
));
94 add_key(hkey
, "subkey", 0, NULL
);
96 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v bar /f", &r
);
97 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
98 verify_reg_nonexist(hkey
, "bar");
100 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /ve /f", &r
);
101 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
102 verify_reg_nonexist(hkey
, "");
104 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /va /f", &r
);
105 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
106 verify_reg_nonexist(hkey
, "foo");
107 verify_key(hkey
, "subkey", 0);
109 /* Test forward and back slashes */
110 add_key(hkey
, "https://winehq.org", 0, NULL
);
111 add_value(hkey
, "count/up", REG_SZ
, "one/two/three", 14);
112 add_value(hkey
, "\\foo\\bar", REG_SZ
, "", 1);
114 run_reg_exe("reg delete HKCU\\" KEY_BASE
"\\https://winehq.org /f", &r
);
115 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
116 verify_key_nonexist(hkey
, "https://winehq.org", 0);
118 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v count/up /f", &r
);
119 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
120 verify_reg_nonexist(hkey
, "count/up");
122 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v \\foo\\bar /f", &r
);
123 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
124 verify_reg_nonexist(hkey
, "\\foo\\bar");
126 add_value(hkey
, "string\\01", REG_SZ
, "Value", 6);
127 add_value(hkey
, "string2", REG_SZ
, "foo\\0bar", 9);
128 add_value(hkey
, "\\0", REG_SZ
, "Value", 6);
130 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v string\\01 /f", &r
);
131 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
132 verify_reg_nonexist(hkey
, "string\\01");
134 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v string2 /f", &r
);
135 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
136 verify_reg_nonexist(hkey
, "string2");
138 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /v \\0 /f", &r
);
139 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
140 verify_reg_nonexist(hkey
, "\\0");
144 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f", &r
);
145 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
146 verify_key_nonexist(HKEY_CURRENT_USER
, KEY_BASE
, 0);
148 run_reg_exe("reg delete HKCU\\" KEY_BASE
" /f", &r
);
149 ok(r
== REG_EXIT_FAILURE
, "got exit code %ld, expected 1\n", r
);
152 static void create_test_key(REGSAM sam
)
157 add_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, sam
, &hkey
);
160 add_value(hkey
, "DWORD", REG_DWORD
, &dword
, sizeof(dword
));
161 add_value(hkey
, "String", REG_SZ
, "Your text here...", 18);
162 add_value(hkey
, NULL
, REG_SZ
, "Default value name", 19);
163 add_value(hkey
, "Multiple Strings", REG_MULTI_SZ
, "Line1\0Line2\0Line3\0", 19);
165 add_key(hkey
, "Subkey", sam
, &subkey
);
166 add_value(subkey
, "Binary", REG_BINARY
, "\x11\x22\x33\x44", 4);
167 add_value(subkey
, "Undefined hex", 0x100, "%PATH%", 7);
173 static void test_registry_view_win32(void)
177 BOOL is_wow64
, is_win32
;
179 IsWow64Process(GetCurrentProcess(), &is_wow64
);
180 is_win32
= !is_wow64
&& (sizeof(void *) == sizeof(int));
182 if (!is_win32
) return;
184 delete_tree(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
186 /* Test deletion from the 32-bit registry view (32-bit Windows) */
187 create_test_key(KEY_WOW64_32KEY
);
189 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
, &hkey
);
191 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:32", &r
);
192 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
193 verify_reg_nonexist(hkey
, "DWORD");
195 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:32", &r
);
196 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
197 verify_reg_nonexist(hkey
, NULL
);
199 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:32", &r
);
200 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
201 verify_reg_nonexist(hkey
, "String");
202 verify_reg_nonexist(hkey
, "Multiple Strings");
203 verify_key(hkey
, "Subkey", KEY_WOW64_32KEY
);
205 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:32", &r
);
206 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
207 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_32KEY
);
211 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:32", &r
);
212 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
213 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
215 /* Test deletion from the 64-bit registry view, which doesn't exist on 32-bit Windows */
216 create_test_key(KEY_WOW64_64KEY
);
218 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
, &hkey
);
220 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:64", &r
);
221 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
222 verify_reg_nonexist(hkey
, "DWORD");
224 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:64", &r
);
225 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
226 verify_reg_nonexist(hkey
, NULL
);
228 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:64", &r
);
229 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
230 verify_reg_nonexist(hkey
, "String");
231 verify_reg_nonexist(hkey
, "Multiple Strings");
232 verify_key(hkey
, "Subkey", KEY_WOW64_64KEY
);
234 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:64", &r
);
235 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
236 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_64KEY
);
240 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:64", &r
);
241 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
242 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
245 static void test_registry_view_win64(void)
249 BOOL is_wow64
, is_win64
;
251 IsWow64Process(GetCurrentProcess(), &is_wow64
);
252 is_win64
= !is_wow64
&& (sizeof(void *) > sizeof(int));
254 if (!is_win64
) return;
256 delete_tree(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
257 delete_tree(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
259 /* Test deletion from the 32-bit registry view (64-bit Windows) */
260 create_test_key(KEY_WOW64_32KEY
);
262 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
264 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
, &hkey
);
266 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:32", &r
);
267 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
268 verify_reg_nonexist(hkey
, "DWORD");
270 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:32", &r
);
271 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
272 verify_reg_nonexist(hkey
, NULL
);
274 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:32", &r
);
275 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
276 verify_reg_nonexist(hkey
, "String");
277 verify_reg_nonexist(hkey
, "Multiple Strings");
278 verify_key(hkey
, "Subkey", KEY_WOW64_32KEY
);
280 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:32", &r
);
281 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
282 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_32KEY
);
286 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:32", &r
);
287 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
288 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
290 /* Test deletion from the 64-bit registry view (64-bit Windows) */
291 create_test_key(KEY_WOW64_64KEY
);
293 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
295 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
, &hkey
);
297 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:64", &r
);
298 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
299 verify_reg_nonexist(hkey
, "DWORD");
301 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:64", &r
);
302 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
303 verify_reg_nonexist(hkey
, NULL
);
305 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:64", &r
);
306 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
307 verify_reg_nonexist(hkey
, "String");
308 verify_reg_nonexist(hkey
, "Multiple Strings");
309 verify_key(hkey
, "Subkey", KEY_WOW64_64KEY
);
311 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:64", &r
);
312 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
313 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_64KEY
);
317 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:64", &r
);
318 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
319 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
322 static void test_registry_view_wow64(void)
328 IsWow64Process(GetCurrentProcess(), &is_wow64
);
330 if (!is_wow64
) return;
332 delete_tree(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
333 delete_tree(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
335 /* Test deletion from the 32-bit registry view (WOW64) */
336 create_test_key(KEY_WOW64_32KEY
);
338 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
340 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
, &hkey
);
342 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:32", &r
);
343 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
344 verify_reg_nonexist(hkey
, "DWORD");
346 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:32", &r
);
347 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
348 verify_reg_nonexist(hkey
, NULL
);
350 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:32", &r
);
351 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
352 verify_reg_nonexist(hkey
, "String");
353 verify_reg_nonexist(hkey
, "Multiple Strings");
354 verify_key(hkey
, "Subkey", KEY_WOW64_32KEY
);
356 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:32", &r
);
357 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
358 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_32KEY
);
362 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:32", &r
);
363 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
364 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
366 /* Test deletion from the 64-bit registry view (WOW64) */
367 create_test_key(KEY_WOW64_64KEY
);
369 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_32KEY
);
371 open_key(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
, &hkey
);
373 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /v DWORD /f /reg:64", &r
);
374 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
375 verify_reg_nonexist(hkey
, "DWORD");
377 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /ve /f /reg:64", &r
);
378 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
379 verify_reg_nonexist(hkey
, NULL
);
381 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /va /f /reg:64", &r
);
382 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
383 verify_reg_nonexist(hkey
, "String");
384 verify_reg_nonexist(hkey
, "Multiple Strings");
385 verify_key(hkey
, "Subkey", KEY_WOW64_64KEY
);
387 run_reg_exe("reg delete HKLM\\" KEY_BASE
"\\Subkey /f /reg:64", &r
);
388 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
389 verify_key_nonexist(hkey
, "Subkey", KEY_WOW64_64KEY
);
393 run_reg_exe("reg delete HKLM\\" KEY_BASE
" /f /reg:64", &r
);
394 ok(r
== REG_EXIT_SUCCESS
, "got exit code %ld, expected 0\n", r
);
395 verify_key_nonexist(HKEY_LOCAL_MACHINE
, KEY_BASE
, KEY_WOW64_64KEY
);
402 if (!run_reg_exe("reg.exe /?", &r
)) {
403 win_skip("reg.exe not available, skipping 'delete' tests\n");
407 test_command_syntax();
410 /* Check if reg.exe is running with elevated privileges */
411 if (!is_elevated_process())
413 win_skip("reg.exe is not running with elevated privileges; "
414 "skipping registry view tests\n");
418 test_registry_view_win32();
419 test_registry_view_win64();
420 test_registry_view_wow64();