1 /* 2 * Copyright 2014 Akihiro Sagawa 3 * Copyright 2016-2018, 2021 Hugh McMaster 4 * 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. 9 * 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. 14 * 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 18 */ 19 20 #include "reg_test.h" 21 22 static void test_command_syntax(void) 23 { 24 DWORD r; 25 26 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 27 28 run_reg_exe("reg delete", &r); 29 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 30 31 run_reg_exe("reg delete /?", &r); 32 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 33 34 run_reg_exe("reg delete /h", &r); 35 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 36 37 run_reg_exe("reg delete -H", &r); 38 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 39 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 %d, expected 1\n", r); 43 44 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v Wine /va", &r); 45 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 46 47 run_reg_exe("reg delete HKCU\\" KEY_BASE " /ve /ve", &r); 48 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 49 50 run_reg_exe("reg delete HKCU\\" KEY_BASE " /ve /va", &r); 51 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 52 53 run_reg_exe("reg delete HKCU\\" KEY_BASE " /va /va", &r); 54 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 55 56 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v Test /ve /va", &r); 57 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 58 59 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v Wine /v Test /f", &r); 60 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 61 62 /* No /v argument */ 63 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v", &r); 64 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 65 66 run_reg_exe("reg delete HKCU\\" KEY_BASE " /f /v", &r); 67 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 68 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 %d, expected 1\n", r); 72 73 run_reg_exe("reg delete HKCU\\" KEY_BASE " /f /reg:32 /reg:64", &r); 74 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 75 76 run_reg_exe("reg delete HKCU\\" KEY_BASE " /f /reg:64 /reg:64", &r); 77 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 78 } 79 80 static void test_delete(void) 81 { 82 HKEY hkey; 83 DWORD r; 84 const DWORD deadbeef = 0xdeadbeef; 85 86 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 87 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)); 93 94 add_key(hkey, "subkey", 0, NULL); 95 96 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v bar /f", &r); 97 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 98 verify_reg_nonexist(hkey, "bar"); 99 100 run_reg_exe("reg delete HKCU\\" KEY_BASE " /ve /f", &r); 101 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 102 verify_reg_nonexist(hkey, ""); 103 104 run_reg_exe("reg delete HKCU\\" KEY_BASE " /va /f", &r); 105 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 106 verify_reg_nonexist(hkey, "foo"); 107 verify_key(hkey, "subkey", 0); 108 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); 113 114 run_reg_exe("reg delete HKCU\\" KEY_BASE "\\https://winehq.org /f", &r); 115 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 116 verify_key_nonexist(hkey, "https://winehq.org", 0); 117 118 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v count/up /f", &r); 119 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 120 verify_reg_nonexist(hkey, "count/up"); 121 122 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v \\foo\\bar /f", &r); 123 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 124 verify_reg_nonexist(hkey, "\\foo\\bar"); 125 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); 129 130 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v string\\01 /f", &r); 131 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 132 verify_reg_nonexist(hkey, "string\\01"); 133 134 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v string2 /f", &r); 135 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 136 verify_reg_nonexist(hkey, "string2"); 137 138 run_reg_exe("reg delete HKCU\\" KEY_BASE " /v \\0 /f", &r); 139 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 140 verify_reg_nonexist(hkey, "\\0"); 141 142 close_key(hkey); 143 144 run_reg_exe("reg delete HKCU\\" KEY_BASE " /f", &r); 145 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 146 verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE, 0); 147 148 run_reg_exe("reg delete HKCU\\" KEY_BASE " /f", &r); 149 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 150 } 151 152 #if 0 153 static void create_test_key(REGSAM sam) 154 { 155 HKEY hkey, subkey; 156 DWORD dword; 157 158 add_key(HKEY_LOCAL_MACHINE, KEY_BASE, sam, &hkey); 159 160 dword = 0x100; 161 add_value(hkey, "DWORD", REG_DWORD, &dword, sizeof(dword)); 162 add_value(hkey, "String", REG_SZ, "Your text here...", 18); 163 add_value(hkey, NULL, REG_SZ, "Default value name", 19); 164 add_value(hkey, "Multiple Strings", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19); 165 166 add_key(hkey, "Subkey", sam, &subkey); 167 add_value(subkey, "Binary", REG_BINARY, "\x11\x22\x33\x44", 4); 168 add_value(subkey, "Undefined hex", 0x100, "%PATH%", 7); 169 close_key(subkey); 170 171 close_key(hkey); 172 } 173 174 static void test_registry_view_win32(void) 175 { 176 HKEY hkey; 177 DWORD r; 178 BOOL is_wow64, is_win32; 179 180 IsWow64Process(GetCurrentProcess(), &is_wow64); 181 is_win32 = !is_wow64 && (sizeof(void *) == sizeof(int)); 182 183 if (!is_win32) return; 184 185 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 186 187 /* Test deletion from the 32-bit registry view (32-bit Windows) */ 188 create_test_key(KEY_WOW64_32KEY); 189 190 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY, &hkey); 191 192 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:32", &r); 193 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 194 verify_reg_nonexist(hkey, "DWORD"); 195 196 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:32", &r); 197 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 198 verify_reg_nonexist(hkey, NULL); 199 200 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:32", &r); 201 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 202 verify_reg_nonexist(hkey, "String"); 203 verify_reg_nonexist(hkey, "Multiple Strings"); 204 verify_key(hkey, "Subkey", KEY_WOW64_32KEY); 205 206 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:32", &r); 207 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 208 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_32KEY); 209 210 close_key(hkey); 211 212 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:32", &r); 213 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 214 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 215 216 /* Test deletion from the 64-bit registry view, which doesn't exist on 32-bit Windows */ 217 create_test_key(KEY_WOW64_64KEY); 218 219 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY, &hkey); 220 221 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:64", &r); 222 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 223 verify_reg_nonexist(hkey, "DWORD"); 224 225 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:64", &r); 226 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 227 verify_reg_nonexist(hkey, NULL); 228 229 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:64", &r); 230 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 231 verify_reg_nonexist(hkey, "String"); 232 verify_reg_nonexist(hkey, "Multiple Strings"); 233 verify_key(hkey, "Subkey", KEY_WOW64_64KEY); 234 235 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:64", &r); 236 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 237 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_64KEY); 238 239 close_key(hkey); 240 241 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:64", &r); 242 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 243 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 244 } 245 246 static void test_registry_view_win64(void) 247 { 248 HKEY hkey; 249 DWORD r; 250 BOOL is_wow64, is_win64; 251 252 IsWow64Process(GetCurrentProcess(), &is_wow64); 253 is_win64 = !is_wow64 && (sizeof(void *) > sizeof(int)); 254 255 if (!is_win64) return; 256 257 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 258 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 259 260 /* Test deletion from the 32-bit registry view (64-bit Windows) */ 261 create_test_key(KEY_WOW64_32KEY); 262 263 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 264 265 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY, &hkey); 266 267 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:32", &r); 268 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 269 verify_reg_nonexist(hkey, "DWORD"); 270 271 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:32", &r); 272 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 273 verify_reg_nonexist(hkey, NULL); 274 275 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:32", &r); 276 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 277 verify_reg_nonexist(hkey, "String"); 278 verify_reg_nonexist(hkey, "Multiple Strings"); 279 verify_key(hkey, "Subkey", KEY_WOW64_32KEY); 280 281 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:32", &r); 282 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 283 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_32KEY); 284 285 close_key(hkey); 286 287 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:32", &r); 288 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 289 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 290 291 /* Test deletion from the 64-bit registry view (64-bit Windows) */ 292 create_test_key(KEY_WOW64_64KEY); 293 294 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 295 296 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY, &hkey); 297 298 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:64", &r); 299 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 300 verify_reg_nonexist(hkey, "DWORD"); 301 302 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:64", &r); 303 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 304 verify_reg_nonexist(hkey, NULL); 305 306 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:64", &r); 307 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 308 verify_reg_nonexist(hkey, "String"); 309 verify_reg_nonexist(hkey, "Multiple Strings"); 310 verify_key(hkey, "Subkey", KEY_WOW64_64KEY); 311 312 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:64", &r); 313 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 314 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_64KEY); 315 316 close_key(hkey); 317 318 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:64", &r); 319 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 320 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 321 } 322 323 static void test_registry_view_wow64(void) 324 { 325 HKEY hkey; 326 DWORD r; 327 BOOL is_wow64; 328 329 IsWow64Process(GetCurrentProcess(), &is_wow64); 330 331 if (!is_wow64) return; 332 333 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 334 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 335 336 /* Test deletion from the 32-bit registry view (WOW64) */ 337 create_test_key(KEY_WOW64_32KEY); 338 339 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 340 341 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY, &hkey); 342 343 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:32", &r); 344 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 345 verify_reg_nonexist(hkey, "DWORD"); 346 347 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:32", &r); 348 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 349 verify_reg_nonexist(hkey, NULL); 350 351 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:32", &r); 352 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 353 verify_reg_nonexist(hkey, "String"); 354 verify_reg_nonexist(hkey, "Multiple Strings"); 355 verify_key(hkey, "Subkey", KEY_WOW64_32KEY); 356 357 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:32", &r); 358 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 359 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_32KEY); 360 361 close_key(hkey); 362 363 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:32", &r); 364 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 365 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 366 367 /* Test deletion from the 64-bit registry view (WOW64) */ 368 create_test_key(KEY_WOW64_64KEY); 369 370 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 371 372 open_key(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY, &hkey); 373 374 run_reg_exe("reg delete HKLM\\" KEY_BASE " /v DWORD /f /reg:64", &r); 375 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 376 verify_reg_nonexist(hkey, "DWORD"); 377 378 run_reg_exe("reg delete HKLM\\" KEY_BASE " /ve /f /reg:64", &r); 379 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 380 verify_reg_nonexist(hkey, NULL); 381 382 run_reg_exe("reg delete HKLM\\" KEY_BASE " /va /f /reg:64", &r); 383 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 384 verify_reg_nonexist(hkey, "String"); 385 verify_reg_nonexist(hkey, "Multiple Strings"); 386 verify_key(hkey, "Subkey", KEY_WOW64_64KEY); 387 388 run_reg_exe("reg delete HKLM\\" KEY_BASE "\\Subkey /f /reg:64", &r); 389 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 390 verify_key_nonexist(hkey, "Subkey", KEY_WOW64_64KEY); 391 392 close_key(hkey); 393 394 run_reg_exe("reg delete HKLM\\" KEY_BASE " /f /reg:64", &r); 395 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 396 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 397 } 398 #endif 399 400 START_TEST(delete) 401 { 402 DWORD r; 403 404 if (!run_reg_exe("reg.exe /?", &r)) { 405 win_skip("reg.exe not available, skipping 'delete' tests\n"); 406 return; 407 } 408 409 test_command_syntax(); 410 test_delete(); 411 412 /* Check if reg.exe is running with elevated privileges */ 413 if (!is_elevated_process()) 414 { 415 win_skip("reg.exe is not running with elevated privileges; " 416 "skipping registry view tests\n"); 417 return; 418 } 419 420 #if 0 421 test_registry_view_win32(); 422 test_registry_view_win64(); 423 test_registry_view_wow64(); 424 #endif 425 426 } 427