1 /* 2 * Copyright 2021 Hugh McMaster 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 #define COPY_SRC KEY_WINE "\\reg_copy" 22 23 static void test_command_syntax(void) 24 { 25 DWORD r; 26 27 run_reg_exe("reg copy", &r); 28 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 29 30 run_reg_exe("reg copy /?", &r); 31 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 32 33 run_reg_exe("reg copy /h", &r); 34 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 35 36 run_reg_exe("reg copy -H", &r); 37 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 38 39 run_reg_exe("reg copy /? /f", &r); 40 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 41 42 run_reg_exe("reg copy /h /f", &r); 43 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 44 45 run_reg_exe("reg copy /? /s", &r); 46 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 47 48 run_reg_exe("reg copy /h /s", &r); 49 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 50 51 run_reg_exe("reg copy /f", &r); 52 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 53 54 run_reg_exe("reg copy /s", &r); 55 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 56 57 run_reg_exe("reg copy /s /f", &r); 58 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 59 60 run_reg_exe("reg copy /f /s", &r); 61 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 62 63 run_reg_exe("reg copy HKCU\\" COPY_SRC " /f", &r); 64 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 65 66 run_reg_exe("reg copy HKCU\\" COPY_SRC " foo /f", &r); 67 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 68 69 run_reg_exe("reg copy /f HKCU\\" COPY_SRC " HKCU\\" KEY_BASE, &r); 70 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 71 72 run_reg_exe("reg copy HKCU\\" COPY_SRC " /f HKCU\\" KEY_BASE, &r); 73 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 74 75 run_reg_exe("reg copy HKCU\\" COPY_SRC " /s HKCU\\" KEY_BASE, &r); 76 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 77 78 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /a", &r); 79 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 80 81 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f /a", &r); 82 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 83 84 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\", &r); 85 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 86 87 /* Source and destination keys are the same */ 88 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC, &r); 89 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 90 91 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC, &r); 92 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 93 94 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC "\\", &r); 95 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 96 97 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC "\\", &r); 98 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 99 100 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC " /f", &r); 101 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 102 103 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC " /f", &r); 104 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 105 106 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC "\\ /f", &r); 107 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 108 109 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC "\\ /f", &r); 110 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 111 112 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC " /s /f", &r); 113 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 114 115 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC " /s /f", &r); 116 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 117 118 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" COPY_SRC "\\ /s /f", &r); 119 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 120 121 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" COPY_SRC "\\ /s /f", &r); 122 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 123 } 124 125 static void test_copy_empty_key(void) 126 { 127 DWORD r; 128 129 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 130 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 131 132 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, NULL); 133 134 135 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 136 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 137 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 138 139 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg", &r); 140 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 141 ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); 142 143 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 144 145 146 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" KEY_BASE " /f", &r); 147 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 148 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 149 150 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg", &r); 151 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 152 ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); 153 154 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 155 156 157 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE "\\ /f", &r); 158 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 159 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 160 161 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg", &r); 162 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 163 ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); 164 165 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 166 167 168 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" KEY_BASE "\\ /f", &r); 169 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 170 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 171 172 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg", &r); 173 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 174 ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); 175 176 177 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /s /f", &r); 178 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 179 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 180 181 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg", &r); 182 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 183 ok(compare_export("file.reg", empty_key_test, 0), "compare_export() failed\n"); 184 } 185 186 static void test_copy_simple_data(void) 187 { 188 HKEY hkey; 189 DWORD r, dword; 190 191 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 192 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 193 194 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 195 196 dword = 0x100; 197 add_value(hkey, "DWORD", REG_DWORD, &dword, sizeof(dword)); 198 add_value(hkey, "String", REG_SZ, "Your text here...", 18); 199 close_key(hkey); 200 201 202 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 203 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 204 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 205 206 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 207 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 208 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 209 210 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 211 212 213 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" KEY_BASE " /f", &r); 214 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 215 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 216 217 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 218 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 219 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 220 221 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 222 223 224 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE "\\ /f", &r); 225 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 226 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 227 228 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 229 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 230 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 231 232 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 233 234 235 run_reg_exe("reg copy HKCU\\" COPY_SRC "\\ HKCU\\" KEY_BASE "\\ /f", &r); 236 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 237 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 238 239 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 240 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 241 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 242 243 244 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /s /f", &r); 245 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 246 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 247 248 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 249 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 250 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 251 } 252 253 static void test_copy_complex_data(void) 254 { 255 HKEY hkey, subkey; 256 DWORD r, dword; 257 258 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 259 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 260 261 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 262 263 dword = 0x100; 264 add_value(hkey, "DWORD", REG_DWORD, &dword, sizeof(dword)); 265 add_value(hkey, "String", REG_SZ, "Your text here...", 18); 266 267 add_key(hkey, "Subkey1", 0, &subkey); 268 add_value(subkey, "Binary", REG_BINARY, "\x11\x22\x33\x44", 4); 269 add_value(subkey, "Undefined hex", 0x100, "%PATH%", 7); 270 close_key(subkey); 271 272 add_key(hkey, "Subkey2a", 0, &subkey); 273 add_value(subkey, "double\"quote", REG_SZ, "\"Hello, World!\"", 16); 274 dword = 0x8; 275 add_value(subkey, "single'quote", REG_DWORD, &dword, sizeof(dword)); 276 close_key(subkey); 277 278 add_key(hkey, "Subkey2a\\Subkey2b", 0, &subkey); 279 add_value(subkey, NULL, REG_SZ, "Default value name", 19); 280 add_value(subkey, "Multiple strings", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19); 281 close_key(subkey); 282 283 add_key(hkey, "Subkey3a", 0, &subkey); 284 add_value(subkey, "Backslash", REG_SZ, "Use \\\\ to escape a backslash", 29); 285 close_key(subkey); 286 287 add_key(hkey, "Subkey3a\\Subkey3b\\Subkey3c", 0, &subkey); 288 add_value(subkey, "String expansion", REG_EXPAND_SZ, "%HOME%\\%PATH%", 14); 289 add_value(subkey, "Zero data type", REG_NONE, "Value", 6); 290 close_key(subkey); 291 292 add_key(hkey, "Subkey4", 0, &subkey); 293 dword = 0x12345678; 294 add_value(subkey, NULL, REG_DWORD, &dword, sizeof(dword)); 295 add_value(subkey, "43981", 0xabcd, "Value", 6); 296 close_key(subkey); 297 298 close_key(hkey); 299 300 /* Copy values only */ 301 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 302 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 303 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 304 305 run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r); 306 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 307 ok(compare_export("file.reg", simple_data_test, 0), "compare_export() failed\n"); 308 309 /* Copy subkeys and values */ 310 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /s /f", &r); 311 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 312 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 313 314 run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r); 315 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 316 ok(compare_export("file.reg", complex_data_test, 0), "compare_export() failed\n"); 317 } 318 319 static void test_copy_key_order(void) 320 { 321 HKEY hkey; 322 DWORD r; 323 324 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 325 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 326 327 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 328 add_key(hkey, "Subkey2", 0, NULL); 329 add_key(hkey, "Subkey1", 0, NULL); 330 close_key(hkey); 331 332 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /s /f", &r); 333 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 334 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 335 336 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 337 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 338 ok(compare_export("file.reg", key_order_test, 0), "compare_export() failed\n"); 339 } 340 341 static void test_copy_value_order(void) 342 { 343 HKEY hkey; 344 DWORD r; 345 346 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 347 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 348 349 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 350 add_value(hkey, "Value 2", REG_SZ, "I was added first!", 19); 351 add_value(hkey, "Value 1", REG_SZ, "I was added second!", 20); 352 close_key(hkey); 353 354 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 355 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 356 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 357 358 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 359 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 360 ok(compare_export("file.reg", value_order_test, TODO_REG_COMPARE), "compare_export() failed\n"); 361 } 362 363 static void test_copy_hex_data(void) 364 { 365 HKEY hkey; 366 DWORD r; 367 368 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 369 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 370 371 /* Try copying empty hex values */ 372 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 373 add_value(hkey, "Wine1a", REG_NONE, NULL, 0); 374 add_value(hkey, "Wine1b", REG_SZ, NULL, 0); 375 add_value(hkey, "Wine1c", REG_EXPAND_SZ, NULL, 0); 376 add_value(hkey, "Wine1d", REG_BINARY, NULL, 0); 377 add_value(hkey, "Wine1e", REG_DWORD, NULL, 0); 378 add_value(hkey, "Wine1f", REG_MULTI_SZ, NULL, 0); 379 add_value(hkey, "Wine1g", 0x100, NULL, 0); 380 add_value(hkey, "Wine1h", 0xabcd, NULL, 0); 381 close_key(hkey); 382 383 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 384 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 385 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 386 387 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 388 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 389 ok(compare_export("file.reg", empty_hex_test, 0), "compare_export() failed\n"); 390 391 delete_key(HKEY_CURRENT_USER, COPY_SRC, 0); 392 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 393 394 /* Try copying after importing alternative registry data types */ 395 test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" 396 "[HKEY_CURRENT_USER\\" COPY_SRC "]\n" 397 "\"Wine2a\"=hex(1):\n" 398 "\"Wine2b\"=hex(3):\n" 399 "\"Wine2c\"=hex(4):\n\n", &r); 400 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 401 402 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 403 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 404 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 405 406 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 407 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 408 ok(compare_export("file.reg", empty_hex_test2, 0), "compare_export() failed\n"); 409 410 delete_key(HKEY_CURRENT_USER, COPY_SRC, 0); 411 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 412 413 /* Try copying more complex hex data */ 414 test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" 415 "[HKEY_CURRENT_USER\\" COPY_SRC "]\n" 416 "\"Wine3a\"=hex(1):56,00,61,00,6c,00,75,00,65,00,00,00\n" 417 "\"Wine3b\"=hex(3):12,34,56,78\n" 418 "\"Wine3c\"=hex(4):40,30,20,10\n\n", &r); 419 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 420 421 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 422 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 423 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 424 425 run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r); 426 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 427 ok(compare_export("file.reg", hex_types_test, 0), "compare_export() failed\n"); 428 } 429 430 static void test_copy_embedded_null_values(void) 431 { 432 DWORD r; 433 434 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 435 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 436 437 test_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n" 438 "[HKEY_CURRENT_USER\\" COPY_SRC "]\n" 439 "\"Wine4a\"=dword:00000005\n" 440 "\"Wine4b\"=hex(1):00,00,00,00,00,00,00,00\n" 441 "\"Wine4c\"=\"Value\"\n" 442 "\"Wine4d\"=hex(1):00,00,61,00,62,00,63,00\n" 443 "\"Wine4e\"=dword:00000100\n" 444 "\"Wine4f\"=hex(1):00,00,56,00,61,00,6c,00,75,00,65,00,00,00\n" 445 "\"Wine4g\"=\"Value2\"\n" 446 "\"Wine4h\"=hex(1):61,00,62,00,63,00,00,00, \\\n" 447 " 64,00,65,00,66,00,00,00\n\n", &r); 448 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 449 450 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 451 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 452 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 453 454 run_reg_exe("reg export HKEY_CURRENT_USER\\" KEY_BASE " file.reg /y", &r); 455 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 456 ok(compare_export("file.reg", embedded_null_test, 0), "compare_export() failed\n"); 457 } 458 459 static void test_copy_slashes(void) 460 { 461 HKEY hkey; 462 DWORD r; 463 464 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 465 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 466 467 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 468 add_key(hkey, "https://winehq.org", 0, NULL); 469 add_value(hkey, "count/up", REG_SZ, "one/two/three", 14); 470 add_value(hkey, "\\foo\\bar", REG_SZ, "", 1); 471 close_key(hkey); 472 473 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /s /f", &r); 474 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 475 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 476 477 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 478 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 479 ok(compare_export("file.reg", slashes_test, TODO_REG_COMPARE), "compare_export() failed\n"); 480 } 481 482 static void test_copy_escaped_null_values(void) 483 { 484 HKEY hkey; 485 DWORD r; 486 487 delete_tree(HKEY_CURRENT_USER, COPY_SRC, 0); 488 delete_tree(HKEY_CURRENT_USER, KEY_BASE, 0); 489 490 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 491 add_value(hkey, "Wine5a", REG_SZ, "\\0", 3); 492 add_value(hkey, "Wine5b", REG_SZ, "\\0\\0", 5); 493 add_value(hkey, "Wine5c", REG_SZ, "Value1\\0", 9); 494 add_value(hkey, "Wine5d", REG_SZ, "Value2\\0\\0\\0\\0", 15); 495 add_value(hkey, "Wine5e", REG_SZ, "Value3\\0Value4", 15); 496 add_value(hkey, "Wine5f", REG_SZ, "\\0Value5", 9); 497 close_key(hkey); 498 499 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 500 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 501 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 502 503 run_reg_exe("reg export HKCU\\" KEY_BASE " file.reg /y", &r); 504 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 505 ok(compare_export("file.reg", escaped_null_test, 0), "compare_export() failed\n"); 506 507 delete_key(HKEY_CURRENT_USER, COPY_SRC, 0); 508 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 509 } 510 511 static void test_copy_key_class(void) 512 { 513 HKEY hkey; 514 LONG rc; 515 char class[] = "class"; 516 char buf[16]; 517 DWORD buf_size, r; 518 519 rc = RegCreateKeyExA(HKEY_CURRENT_USER, COPY_SRC, 0, class, REG_OPTION_NON_VOLATILE, 520 KEY_READ|KEY_WRITE, NULL, &hkey, NULL); 521 ok(rc == ERROR_SUCCESS, "RegCreateKeyExA failed: got %d, expected 0\n", rc); 522 523 add_value(hkey, "String", REG_SZ, "Data", 5); 524 525 buf_size = sizeof(buf); 526 527 rc = RegQueryInfoKeyA(hkey, buf, &buf_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 528 ok(rc == ERROR_SUCCESS, "RegQueryInfoKeyA failed: got %d, expected 0\n", rc); 529 ok(!strcmp(buf, "class"), "Incorrect key class set; got '%s', expected '%s'\n", buf, class); 530 531 RegCloseKey(hkey); 532 533 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 534 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 535 verify_key(HKEY_CURRENT_USER, KEY_BASE, 0); 536 537 open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); 538 verify_reg(hkey, "String", REG_SZ, "Data", 5, 0); 539 540 memset(buf, 0, sizeof(buf)); 541 buf_size = sizeof(buf); 542 543 rc = RegQueryInfoKeyA(hkey, buf, &buf_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); 544 ok(rc == ERROR_SUCCESS, "RegQueryInfoKeyA failed: got %d, expected 0\n", rc); 545 ok(strlen(buf) == 0, "Key class should not exist\n"); 546 547 RegCloseKey(hkey); 548 549 delete_key(HKEY_CURRENT_USER, COPY_SRC, 0); 550 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 551 } 552 553 static void test_copy_overwrite(void) 554 { 555 HKEY hkey; 556 DWORD r, dword; 557 558 add_key(HKEY_CURRENT_USER, COPY_SRC, 0, &hkey); 559 add_value(hkey, "Wine1", REG_SZ, "def", 4); 560 dword = 0x5; 561 add_value(hkey, "Wine2", REG_DWORD, &dword, sizeof(dword)); 562 add_value(hkey, "Wine3", REG_BINARY, "\x11\x22\x33\x44", 4); 563 add_value(hkey, "Wine4", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19); 564 close_key(hkey); 565 566 add_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); 567 add_value(hkey, "Wine1", REG_SZ, "abc", 4); 568 verify_reg_nonexist(hkey, "Wine2"); 569 add_value(hkey, "Wine3", REG_EXPAND_SZ, "%HOME%\\%PATH%", 14); 570 dword = 0x1; 571 add_value(hkey, "Wine4", REG_DWORD, &dword, sizeof(dword)); 572 add_value(hkey, NULL, REG_SZ, "Constant value", 15); 573 close_key(hkey); 574 575 run_reg_exe("reg copy HKCU\\" COPY_SRC " HKCU\\" KEY_BASE " /f", &r); 576 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 577 578 open_key(HKEY_CURRENT_USER, KEY_BASE, 0, &hkey); 579 verify_reg(hkey, "Wine1", REG_SZ, "def", 4, 0); 580 dword = 0x5; 581 verify_reg(hkey, "Wine2", REG_DWORD, &dword, sizeof(dword), 0); 582 verify_reg(hkey, "Wine3", REG_BINARY, "\x11\x22\x33\x44", 4, 0); 583 verify_reg(hkey, "Wine4", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19, 0); 584 verify_reg(hkey, NULL, REG_SZ, "Constant value", 15, 0); 585 close_key(hkey); 586 587 delete_key(HKEY_CURRENT_USER, COPY_SRC, 0); 588 delete_key(HKEY_CURRENT_USER, KEY_BASE, 0); 589 } 590 591 #if 0 592 static void create_test_key(REGSAM sam) 593 { 594 HKEY hkey, subkey; 595 DWORD dword = 0x100; 596 597 add_key(HKEY_LOCAL_MACHINE, COPY_SRC, sam, &hkey); 598 add_value(hkey, "DWORD", REG_DWORD, &dword, sizeof(dword)); 599 add_value(hkey, "String", REG_SZ, "Your text here...", 18); 600 601 add_key(hkey, "Subkey1", sam, &subkey); 602 add_value(subkey, "Binary", REG_BINARY, "\x11\x22\x33\x44", 4); 603 add_value(subkey, "Undefined hex", 0x100, "%PATH%", 7); 604 close_key(subkey); 605 606 close_key(hkey); 607 } 608 609 static void test_registry_view_win32(void) 610 { 611 DWORD r; 612 BOOL is_wow64, is_win32; 613 614 IsWow64Process(GetCurrentProcess(), &is_wow64); 615 is_win32 = !is_wow64 && (sizeof(void *) == sizeof(int)); 616 617 if (!is_win32) return; 618 619 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 620 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 621 622 /* Try copying registry data in the 32-bit registry view (32-bit Windows) */ 623 create_test_key(KEY_WOW64_32KEY); 624 625 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:32", &r); 626 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 627 628 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:32", &r); 629 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 630 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 631 632 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 633 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 634 635 /* Try copying registry data in the 64-bit registry view, which doesn't exist on 32-bit Windows */ 636 create_test_key(KEY_WOW64_64KEY); 637 638 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:64", &r); 639 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 640 641 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:64", &r); 642 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 643 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 644 645 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 646 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 647 } 648 649 static void test_registry_view_win64(void) 650 { 651 DWORD r; 652 BOOL is_wow64, is_win64; 653 654 IsWow64Process(GetCurrentProcess(), &is_wow64); 655 is_win64 = !is_wow64 && (sizeof(void *) > sizeof(int)); 656 657 if (!is_win64) return; 658 659 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 660 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 661 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 662 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 663 664 /* Try copying registry data in the 32-bit registry view (64-bit Windows) */ 665 create_test_key(KEY_WOW64_32KEY); 666 verify_key_nonexist(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 667 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 668 669 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:32", &r); 670 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 671 672 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:32", &r); 673 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 674 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 675 676 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:64", &r); 677 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 678 679 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 680 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 681 682 /* Try copying registry data in the 64-bit registry view (64-bit Windows) */ 683 create_test_key(KEY_WOW64_64KEY); 684 verify_key_nonexist(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 685 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 686 687 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:64", &r); 688 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 689 690 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:64", &r); 691 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 692 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 693 694 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:32", &r); 695 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 696 697 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 698 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 699 } 700 701 static void test_registry_view_wow64(void) 702 { 703 DWORD r; 704 BOOL is_wow64; 705 706 IsWow64Process(GetCurrentProcess(), &is_wow64); 707 708 if (!is_wow64) return; 709 710 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 711 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 712 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 713 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 714 715 /* Try copying registry data in the 32-bit registry view (WOW64) */ 716 create_test_key(KEY_WOW64_32KEY); 717 verify_key_nonexist(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 718 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 719 720 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:32", &r); 721 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 722 723 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:32", &r); 724 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 725 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 726 727 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:64", &r); 728 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 729 730 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 731 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 732 733 /* Try copying registry data in the 64-bit registry view (WOW64) */ 734 create_test_key(KEY_WOW64_64KEY); 735 verify_key_nonexist(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_32KEY); 736 verify_key_nonexist(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_32KEY); 737 738 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:64", &r); 739 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 740 741 run_reg_exe("reg export HKLM\\" KEY_BASE " file.reg /y /reg:64", &r); 742 ok(r == REG_EXIT_SUCCESS, "got exit code %d, expected 0\n", r); 743 ok(compare_export("file.reg", registry_view_test, 0), "compare_export() failed\n"); 744 745 run_reg_exe("reg copy HKLM\\" COPY_SRC " HKLM\\" KEY_BASE " /s /f /reg:32", &r); 746 ok(r == REG_EXIT_FAILURE, "got exit code %d, expected 1\n", r); 747 748 delete_tree(HKEY_LOCAL_MACHINE, COPY_SRC, KEY_WOW64_64KEY); 749 delete_tree(HKEY_LOCAL_MACHINE, KEY_BASE, KEY_WOW64_64KEY); 750 } 751 #endif 752 753 START_TEST(copy) 754 { 755 DWORD r; 756 757 if (!run_reg_exe("reg.exe /?", &r)) { 758 win_skip("reg.exe not available, skipping 'copy' tests\n"); 759 return; 760 } 761 762 test_command_syntax(); 763 test_copy_empty_key(); 764 test_copy_simple_data(); 765 test_copy_complex_data(); 766 test_copy_key_order(); 767 test_copy_value_order(); 768 test_copy_hex_data(); 769 test_copy_embedded_null_values(); 770 test_copy_slashes(); 771 test_copy_escaped_null_values(); 772 test_copy_key_class(); 773 test_copy_overwrite(); 774 775 /* Check if reg.exe is running with elevated privileges */ 776 if (!is_elevated_process()) 777 { 778 win_skip("reg.exe is not running with elevated privileges; " 779 "skipping registry view tests\n"); 780 return; 781 } 782 783 #if 0 784 test_registry_view_win32(); 785 test_registry_view_win64(); 786 test_registry_view_wow64(); 787 #endif 788 789 } 790