[REGEDIT] Partially sync Regedit to Wine-7.17 (#4717)

* [REGEDIT] Partially Sync to Wine 7.17

- regproc.c and regedit.c are now in sync.
- some other mostly depending fixes for the remaining files

* [REGEDIT_WINETEST] Sync to Wine-7.0
This commit is contained in:
Robert Naumann 2022-11-02 19:02:14 +01:00 committed by GitHub
parent 66030257b1
commit 36a7f0dc7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 3473 additions and 1869 deletions

View file

@ -152,6 +152,15 @@ static void open_key_(unsigned line, const HKEY base, const char *path, const DW
lok(lr == ERROR_SUCCESS, "RegOpenKeyExA failed: %d\n", lr);
}
#define close_key(k) close_key_(__LINE__,k)
static void close_key_(unsigned line, HKEY hkey)
{
LONG lr;
lr = RegCloseKey(hkey);
lok(lr == ERROR_SUCCESS, "RegCloseKey failed: %d\n", lr);
}
#define verify_key(k,s) verify_key_(__LINE__,k,s)
static void verify_key_(unsigned line, HKEY key_base, const char *subkey)
{
@ -273,9 +282,8 @@ static void test_basic_import(void)
char buffer[256];
BYTE hex[8];
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND,
"RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -483,18 +491,16 @@ static void test_basic_import(void)
"\"Wine\\\\31\"=\"Test value\"\n\n");
open_key(hkey, "Subkey\"1", 0, &subkey);
verify_reg(subkey, "Wine\\31", REG_SZ, "Test value", 11, 0);
lr = RegCloseKey(subkey);
ok(lr == ERROR_SUCCESS, "got %d, expected 0\n", lr);
delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1");
close_key(subkey);
delete_key(hkey, "Subkey\"1");
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey/2]\n"
"\"123/\\\"4;'5\"=\"Random value name\"\n\n");
open_key(hkey, "Subkey/2", 0, &subkey);
verify_reg(subkey, "123/\"4;'5", REG_SZ, "Random value name", 18, 0);
lr = RegCloseKey(subkey);
ok(lr == ERROR_SUCCESS, "got %d, expected 0\n", lr);
delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2");
close_key(subkey);
delete_key(hkey, "Subkey/2");
/* Test the accepted range of the hex-based data types */
exec_import_str("REGEDIT4\n\n"
@ -671,9 +677,35 @@ static void test_basic_import(void)
verify_reg(hkey, "Wine22h", REG_BINARY, NULL, 0, 0);
verify_reg(hkey, "Wine22i", REG_NONE, NULL, 0, 0);
RegCloseKey(hkey);
/* Test with escaped null characters */
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"Wine23a\"=\"\\\\0\"\n"
"\"Wine23b\"=\"\\\\0\\\\0\"\n"
"\"Wine23c\"=\"Value1\\\\0\"\n"
"\"Wine23d\"=\"Value2\\\\0\\\\0\\\\0\\\\0\"\n"
"\"Wine23e\"=\"Value3\\\\0Value4\"\n"
"\"Wine23f\"=\"\\\\0Value5\"\n\n");
verify_reg(hkey, "Wine23a", REG_SZ, "\\0", 3, 0);
verify_reg(hkey, "Wine23b", REG_SZ, "\\0\\0", 5, 0);
verify_reg(hkey, "Wine23c", REG_SZ, "Value1\\0", 9, 0);
verify_reg(hkey, "Wine23d", REG_SZ, "Value2\\0\\0\\0\\0", 15, 0);
verify_reg(hkey, "Wine23e", REG_SZ, "Value3\\0Value4", 15, 0);
verify_reg(hkey, "Wine23f", REG_SZ, "\\0Value5", 9, 0);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test forward and back slashes */
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"count/up\"=\"one/two/three\"\n"
"\"\\\\foo\\\\bar\"=\"\"\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "\\https://winehq.org]\n\n");
verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
verify_key(hkey, "https://winehq.org");
close_key(hkey);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
}
static void test_basic_import_unicode(void)
@ -685,8 +717,8 @@ static void test_basic_import_unicode(void)
char buffer[256];
BYTE hex[8];
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -895,18 +927,16 @@ static void test_basic_import_unicode(void)
"\"Wine\\\\31\"=\"Test value\"\n\n");
open_key(hkey, "Subkey\"1", 0, &subkey);
verify_reg(subkey, "Wine\\31", REG_SZ, "Test value", 11, 0);
lr = RegCloseKey(subkey);
ok(lr == ERROR_SUCCESS, "got %d, expected 0\n", lr);
delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey\"1");
close_key(subkey);
delete_key(hkey, "Subkey\"1");
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "\\Subkey/2]\n"
"\"123/\\\"4;'5\"=\"Random value name\"\n\n");
open_key(hkey, "Subkey/2", 0, &subkey);
verify_reg(subkey, "123/\"4;'5", REG_SZ, "Random value name", 18, 0);
lr = RegCloseKey(subkey);
ok(lr == ERROR_SUCCESS, "got %d, expected 0\n", lr);
delete_key(HKEY_CURRENT_USER, KEY_BASE "\\Subkey/2");
close_key(subkey);
delete_key(hkey, "Subkey/2");
/* Test the accepted range of the hex-based data types */
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
@ -1086,29 +1116,47 @@ static void test_basic_import_unicode(void)
verify_reg(hkey, "Wine22h", REG_BINARY, NULL, 0, 0);
verify_reg(hkey, "Wine22i", REG_NONE, NULL, 0, 0);
RegCloseKey(hkey);
/* Test with escaped null characters */
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"Wine23a\"=\"\\\\0\"\n"
"\"Wine23b\"=\"\\\\0\\\\0\"\n"
"\"Wine23c\"=\"Value1\\\\0\"\n"
"\"Wine23d\"=\"Value2\\\\0\\\\0\\\\0\\\\0\"\n"
"\"Wine23e\"=\"Value3\\\\0Value4\"\n"
"\"Wine23f\"=\"\\\\0Value5\"\n\n");
verify_reg(hkey, "Wine23a", REG_SZ, "\\0", 3, 0);
verify_reg(hkey, "Wine23b", REG_SZ, "\\0\\0", 5, 0);
verify_reg(hkey, "Wine23c", REG_SZ, "Value1\\0", 9, 0);
verify_reg(hkey, "Wine23d", REG_SZ, "Value2\\0\\0\\0\\0", 15, 0);
verify_reg(hkey, "Wine23e", REG_SZ, "Value3\\0Value4", 15, 0);
verify_reg(hkey, "Wine23f", REG_SZ, "\\0Value5", 9, 0);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test forward and back slashes */
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"count/up\"=\"one/two/three\"\n"
"\"\\\\foo\\\\bar\"=\"\"\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "\\https://winehq.org]\n\n");
verify_reg(hkey, "count/up", REG_SZ, "one/two/three", 14, 0);
verify_reg(hkey, "\\foo\\bar", REG_SZ, "", 1, 0);
verify_key(hkey, "https://winehq.org");
close_key(hkey);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
}
static void test_basic_import_31(void)
{
HKEY hkey;
LONG lr;
DWORD dispos;
lr = RegDeleteKeyA(HKEY_CLASSES_ROOT, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND,
"RegDeleteKeyA failed: %d\n", lr);
RegCreateKeyExA(HKEY_CLASSES_ROOT, KEY_BASE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ|KEY_SET_VALUE, NULL, &hkey, &dispos);
/* Check if regedit.exe is running with elevated privileges */
lr = RegCreateKeyExA(HKEY_CLASSES_ROOT, KEY_BASE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ, NULL, &hkey, NULL);
if (lr == ERROR_ACCESS_DENIED)
{
win_skip("regedit.exe is not running with elevated privileges; "
"skipping Windows 3.1 import tests\n");
return;
}
if (dispos == REG_OPENED_EXISTING_KEY)
delete_value(hkey, NULL);
/* Test simple value */
exec_import_str("REGEDIT\r\n"
@ -1148,19 +1196,18 @@ static void test_basic_import_31(void)
"HKEY_CLASSES_ROOT\\" KEY_BASE " = No newline");
verify_reg(hkey, "", REG_SZ, "No newline", 11, 0);
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CLASSES_ROOT, KEY_BASE);
}
static void test_invalid_import(void)
{
LONG lr;
HKEY hkey;
DWORD dword = 0x8;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -1641,12 +1688,12 @@ static void test_invalid_import(void)
/* Test with embedded null characters */
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"Wine33a\"=\"\\0\n"
"\"Wine33b\"=\"\\0\\0\n"
"\"Wine33c\"=\"Value1\\0\n"
"\"Wine33d\"=\"Value2\\0\\0\\0\\0\n"
"\"Wine33e\"=\"Value3\\0Value4\n"
"\"Wine33f\"=\"\\0Value4\n\n");
"\"Wine33a\"=\"\\0\"\n"
"\"Wine33b\"=\"\\0\\0\"\n"
"\"Wine33c\"=\"Value1\\0\"\n"
"\"Wine33d\"=\"Value2\\0\\0\\0\\0\"\n"
"\"Wine33e\"=\"Value3\\0Value4\"\n"
"\"Wine33f\"=\"\\0Value5\"\n\n");
verify_reg_nonexist(hkey, "Wine33a");
verify_reg_nonexist(hkey, "Wine33b");
verify_reg_nonexist(hkey, "Wine33c");
@ -1654,19 +1701,18 @@ static void test_invalid_import(void)
verify_reg_nonexist(hkey, "Wine33e");
verify_reg_nonexist(hkey, "Wine33f");
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
static void test_invalid_import_unicode(void)
{
LONG lr;
HKEY hkey;
DWORD dword = 0x8;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -2153,12 +2199,12 @@ static void test_invalid_import_unicode(void)
/* Test with embedded null characters */
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
"\"Wine33a\"=\"\\0\n"
"\"Wine33b\"=\"\\0\\0\n"
"\"Wine33c\"=\"Value1\\0\n"
"\"Wine33d\"=\"Value2\\0\\0\\0\\0\n"
"\"Wine33e\"=\"Value3\\0Value4\n"
"\"Wine33f\"=\"\\0Value4\n\n");
"\"Wine33a\"=\"\\0\"\n"
"\"Wine33b\"=\"\\0\\0\"\n"
"\"Wine33c\"=\"Value1\\0\"\n"
"\"Wine33d\"=\"Value2\\0\\0\\0\\0\"\n"
"\"Wine33e\"=\"Value3\\0Value4\"\n"
"\"Wine33f\"=\"\\0Value5\"\n\n");
verify_reg_nonexist(hkey, "Wine33a");
verify_reg_nonexist(hkey, "Wine33b");
verify_reg_nonexist(hkey, "Wine33c");
@ -2166,7 +2212,7 @@ static void test_invalid_import_unicode(void)
verify_reg_nonexist(hkey, "Wine33e");
verify_reg_nonexist(hkey, "Wine33f");
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -2174,17 +2220,13 @@ static void test_invalid_import_unicode(void)
static void test_invalid_import_31(void)
{
HKEY hkey;
LONG lr;
DWORD dispos;
/* Check if regedit.exe is running with elevated privileges */
lr = RegCreateKeyExA(HKEY_CLASSES_ROOT, KEY_BASE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ, NULL, &hkey, NULL);
if (lr == ERROR_ACCESS_DENIED)
{
win_skip("regedit.exe is not running with elevated privileges; "
"skipping Windows 3.1 invalid import tests\n");
return;
}
RegCreateKeyExA(HKEY_CLASSES_ROOT, KEY_BASE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ|KEY_SET_VALUE, NULL, &hkey, &dispos);
if (dispos == REG_OPENED_EXISTING_KEY)
delete_value(hkey, NULL);
/* Test character validity at the start of the line */
exec_import_str("REGEDIT\r\n"
@ -2220,19 +2262,18 @@ static void test_invalid_import_31(void)
"Hkey_Classes_Root\\" KEY_BASE " = Value3c\r\n");
verify_reg_nonexist(hkey, "");
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CLASSES_ROOT, KEY_BASE);
}
static void test_comments(void)
{
LONG lr;
HKEY hkey;
DWORD dword;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -2459,19 +2500,18 @@ static void test_comments(void)
" 61,74,69,6f,6e,00,00\n\n");
verify_reg_nonexist(hkey, "Wine29d");
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
static void test_comments_unicode(void)
{
LONG lr;
HKEY hkey;
DWORD dword;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n"
@ -2700,7 +2740,7 @@ static void test_comments_unicode(void)
" 61,00,74,00,69,00,6f,00,6e,00,00,00,00,00\n\n");
verify_reg_nonexist(hkey, "Wine29d");
RegCloseKey(hkey);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -2708,11 +2748,10 @@ static void test_comments_unicode(void)
static void test_import_with_whitespace(void)
{
HKEY hkey;
LONG lr;
DWORD dword;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str(" REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -2847,8 +2886,7 @@ static void test_import_with_whitespace(void)
" 61,74,69,6f,6e,00,00\n\n");
verify_reg(hkey, "Wine10b", REG_MULTI_SZ, "Line concatenation\0", 20, 0);
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -2856,11 +2894,10 @@ static void test_import_with_whitespace(void)
static void test_import_with_whitespace_unicode(void)
{
HKEY hkey;
LONG lr;
DWORD dword;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbf Windows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -2995,8 +3032,7 @@ static void test_import_with_whitespace_unicode(void)
" 61,00,74,00,69,00,6f,00,6e,00,00,00,00,00\n\n");
verify_reg(hkey, "Wine10b", REG_MULTI_SZ, "Line concatenation\0", 20, 0);
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -3004,10 +3040,9 @@ static void test_import_with_whitespace_unicode(void)
static void test_key_creation_and_deletion(void)
{
HKEY hkey, subkey;
LONG lr;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -3048,7 +3083,7 @@ static void test_key_creation_and_deletion(void)
verify_key(hkey, "Subkey1e");
open_key(hkey, "Subkey1e", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1e");
exec_import_str("REGEDIT4\n\n"
@ -3059,7 +3094,7 @@ static void test_key_creation_and_deletion(void)
verify_key(hkey, "Subkey1f");
open_key(hkey, "Subkey1f\\\\", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1f\\\\");
exec_import_str("REGEDIT4\n\n"
@ -3071,7 +3106,7 @@ static void test_key_creation_and_deletion(void)
verify_key(hkey, "Subkey1g");
open_key(hkey, "Subkey1g\\\\", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1g\\\\");
/* Test key deletion. We start by creating some registry keys. */
@ -3135,8 +3170,7 @@ static void test_key_creation_and_deletion(void)
verify_key_nonexist(hkey, "Subkey4b");
verify_reg_nonexist(hkey, "Wine1b");
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -3144,10 +3178,9 @@ static void test_key_creation_and_deletion(void)
static void test_key_creation_and_deletion_unicode(void)
{
HKEY hkey, subkey;
LONG lr;
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -3188,7 +3221,7 @@ static void test_key_creation_and_deletion_unicode(void)
verify_key(hkey, "Subkey1e");
open_key(hkey, "Subkey1e", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1e");
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
@ -3199,7 +3232,7 @@ static void test_key_creation_and_deletion_unicode(void)
verify_key(hkey, "Subkey1f");
open_key(hkey, "Subkey1f\\\\", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1f\\\\");
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
@ -3211,7 +3244,7 @@ static void test_key_creation_and_deletion_unicode(void)
verify_key(hkey, "Subkey1g");
open_key(hkey, "Subkey1g\\\\", 0, &subkey);
verify_reg(subkey, "Wine", REG_SZ, "Test value", 11, 0);
RegCloseKey(subkey);
close_key(subkey);
delete_key(hkey, "Subkey1g\\\\");
/* Test key deletion. We start by creating some registry keys. */
@ -3275,8 +3308,7 @@ static void test_key_creation_and_deletion_unicode(void)
verify_key_nonexist(hkey, "Subkey4b");
verify_reg_nonexist(hkey, "Wine1b");
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -3284,12 +3316,11 @@ static void test_key_creation_and_deletion_unicode(void)
static void test_value_deletion(void)
{
HKEY hkey;
LONG lr;
DWORD dword = 0x8;
BYTE hex[4] = {0x11, 0x22, 0x33, 0x44};
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_str("REGEDIT4\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -3328,8 +3359,7 @@ static void test_value_deletion(void)
verify_reg_nonexist(hkey, "Wine46e");
verify_reg(hkey, "Wine46f", REG_NONE, "V\0a\0l\0u\0e\0\0", 12, 0);
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -3338,12 +3368,11 @@ static void test_value_deletion(void)
static void test_value_deletion_unicode(void)
{
HKEY hkey;
LONG lr;
DWORD dword = 0x8;
BYTE hex[4] = {0x11, 0x22, 0x33, 0x44};
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\n\n");
@ -3383,8 +3412,7 @@ static void test_value_deletion_unicode(void)
verify_reg_nonexist(hkey, "Wine46e");
verify_reg(hkey, "Wine46f", REG_NONE, "V\0a\0l\0u\0e\0\0", 12, 0);
lr = RegCloseKey(hkey);
ok(lr == ERROR_SUCCESS, "RegCloseKey failed: got %d, expected 0\n", lr);
close_key(hkey);
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
@ -3436,7 +3464,6 @@ error:
static void test_export(void)
{
LONG lr;
HKEY hkey, subkey;
DWORD dword;
BYTE hex[4];
@ -3527,8 +3554,25 @@ static void test_export(void)
"\"Wine4g\"=\"Value2\"\r\n"
"\"Wine4h\"=\"abc\"\r\n\r\n";
lr = RegDeleteKeyA(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS || lr == ERROR_FILE_NOT_FOUND, "RegDeleteKeyA failed: %d\n", lr);
const char *slashes_test =
"\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n"
"\"count/up\"=\"one/two/three\"\r\n"
"\"\\\\foo\\\\bar\"=\"\"\r\n\r\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "\\https://winehq.org]\r\n\r\n";
const char *escaped_null_test =
"\xef\xbb\xbfWindows Registry Editor Version 5.00\r\n\r\n"
"[HKEY_CURRENT_USER\\" KEY_BASE "]\r\n"
"\"Wine5a\"=\"\\\\0\"\r\n"
"\"Wine5b\"=\"\\\\0\\\\0\"\r\n"
"\"Wine5c\"=\"Value1\\\\0\"\r\n"
"\"Wine5d\"=\"Value2\\\\0\\\\0\\\\0\\\\0\"\r\n"
"\"Wine5e\"=\"Value3\\\\0Value4\"\r\n"
"\"Wine5f\"=\"\\\\0Value5\"\r\n\r\n";
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
verify_key_nonexist(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export with an empty key */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
@ -3548,52 +3592,48 @@ static void test_export(void)
add_key(hkey, "Subkey1", &subkey);
add_value(subkey, "Binary", REG_BINARY, "\x11\x22\x33\x44", 4);
add_value(subkey, "Undefined hex", 0x100, "%PATH%", 7);
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey2a", &subkey);
add_value(subkey, "double\"quote", REG_SZ, "\"Hello, World!\"", 16);
dword = 0x8;
add_value(subkey, "single'quote", REG_DWORD, &dword, sizeof(dword));
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey2a\\Subkey2b", &subkey);
add_value(subkey, NULL, REG_SZ, "Default value name", 19);
add_value(subkey, "Multiple strings", REG_MULTI_SZ, "Line1\0Line2\0Line3\0", 19);
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey3a", &subkey);
add_value(subkey, "Backslash", REG_SZ, "Use \\\\ to escape a backslash", 29);
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey3a\\Subkey3b\\Subkey3c", &subkey);
add_value(subkey, "String expansion", REG_EXPAND_SZ, "%HOME%\\%PATH%", 14);
add_value(subkey, "Zero data type", REG_NONE, "Value", 6);
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey4", &subkey);
dword = 0x12345678;
add_value(subkey, NULL, REG_DWORD, &dword, sizeof(dword));
add_value(subkey, "43981", 0xabcd, "Value", 6);
RegCloseKey(subkey);
RegCloseKey(hkey);
close_key(subkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", complex_test, 0), "compare_export() failed\n");
lr = delete_tree(HKEY_CURRENT_USER, KEY_BASE);
ok(lr == ERROR_SUCCESS, "delete_tree() failed: %d\n", lr);
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
/* Test the export order of registry keys */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
add_key(hkey, "Subkey2", &subkey);
RegCloseKey(subkey);
close_key(subkey);
add_key(hkey, "Subkey1", &subkey);
RegCloseKey(subkey);
close_key(subkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", key_order_test, 0), "compare_export() failed\n");
delete_key(hkey, "Subkey1");
delete_key(hkey, "Subkey2");
@ -3602,12 +3642,10 @@ static void test_export(void)
*/
add_value(hkey, "Value 2", REG_SZ, "I was added first!", 19);
add_value(hkey, "Value 1", REG_SZ, "I was added second!", 20);
RegCloseKey(hkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", value_order_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export with empty hex data */
@ -3620,11 +3658,10 @@ static void test_export(void)
add_value(hkey, "Wine1f", REG_MULTI_SZ, NULL, 0);
add_value(hkey, "Wine1g", 0x100, NULL, 0);
add_value(hkey, "Wine1h", 0xabcd, NULL, 0);
RegCloseKey(hkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", empty_hex_test, 0), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export after importing alternative registry data types */
@ -3637,11 +3674,10 @@ static void test_export(void)
verify_reg(hkey, "Wine2a", REG_SZ, NULL, 0, 0);
verify_reg(hkey, "Wine2b", REG_BINARY, NULL, 0, 0);
verify_reg(hkey, "Wine2c", REG_DWORD, NULL, 0, 0);
RegCloseKey(hkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", empty_hex_test2, 0), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export with embedded null characters */
@ -3656,11 +3692,10 @@ static void test_export(void)
verify_reg(hkey, "Wine3b", REG_BINARY, hex, 4, 0);
dword = 0x10203040;
verify_reg(hkey, "Wine3c", REG_DWORD, &dword, sizeof(dword), 0);
RegCloseKey(hkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", hex_types_test, 0), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
exec_import_wstr("\xef\xbb\xbfWindows Registry Editor Version 5.00\n\n"
@ -3685,26 +3720,62 @@ static void test_export(void)
verify_reg(hkey, "Wine4f", REG_SZ, "\0Value", 7, 0);
verify_reg(hkey, "Wine4g", REG_SZ, "Value2", 7, 0);
verify_reg(hkey, "Wine4h", REG_SZ, "abc\0def", 8, 0);
RegCloseKey(hkey);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", embedded_null_test, 0), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export with forward and back slashes */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
add_key(hkey, "https://winehq.org", &subkey);
close_key(subkey);
add_value(hkey, "count/up", REG_SZ, "one/two/three", 14);
add_value(hkey, "\\foo\\bar", REG_SZ, "", 1);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", slashes_test, TODO_REG_COMPARE), "compare_export() failed\n");
delete_tree(HKEY_CURRENT_USER, KEY_BASE);
/* Test registry export with escaped null characters */
add_key(HKEY_CURRENT_USER, KEY_BASE, &hkey);
add_value(hkey, "Wine5a", REG_SZ, "\\0", 3);
add_value(hkey, "Wine5b", REG_SZ, "\\0\\0", 5);
add_value(hkey, "Wine5c", REG_SZ, "Value1\\0", 9);
add_value(hkey, "Wine5d", REG_SZ, "Value2\\0\\0\\0\\0", 15);
add_value(hkey, "Wine5e", REG_SZ, "Value3\\0Value4", 15);
add_value(hkey, "Wine5f", REG_SZ, "\\0Value5", 9);
close_key(hkey);
run_regedit_exe("regedit.exe /e file.reg HKEY_CURRENT_USER\\" KEY_BASE);
ok(compare_export("file.reg", escaped_null_test, 0), "compare_export() failed\n");
delete_key(HKEY_CURRENT_USER, KEY_BASE);
}
START_TEST(regedit)
{
if(!exec_import_str("REGEDIT4\r\n\r\n")){
win_skip("regedit not available, skipping regedit tests\n");
return;
}
HKEY hkey;
LONG err;
if (!run_regedit_exe("regedit.exe /s test.reg") && GetLastError() == ERROR_ELEVATION_REQUIRED)
/* Check if regedit.exe is running with elevated privileges */
err = RegDeleteKeyA(HKEY_CLASSES_ROOT, KEY_BASE);
if (err == ERROR_ACCESS_DENIED)
{
win_skip("User is a non-elevated admin; skipping regedit tests.\n");
return;
}
if (err == ERROR_FILE_NOT_FOUND)
{
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, KEY_BASE, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_READ, NULL, &hkey, NULL))
{
win_skip("User is a non-elevated admin; skipping regedit tests.\n");
return;
}
RegCloseKey(hkey);
RegDeleteKeyA(HKEY_CLASSES_ROOT, KEY_BASE);
}
test_basic_import();
test_basic_import_unicode();