advapi32: add HKCU\Software\Classes and HKLM\Software\Classes merge tests (try 2)

Damjan Jovanovic damjan.jov at gmail.com
Mon Jun 7 07:00:11 CDT 2010


Changelog:
* advapi32: add HKCU\Software\Classes and HKLM\Software\Classes merge tests

Try 2's tests skip on machines without HKCU\Software\Classes (eg. Windows NT).

Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 30dda7e..c04d2a5 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -1985,6 +1985,136 @@ static void test_delete_value(void)
        "expect ERROR_FILE_NOT_FOUND, got %i\n", res);
 }
 
+static void test_hkcr_merge(void)
+{
+    DWORD ret;
+    HKEY user_classes = NULL;
+    HKEY machine_classes = NULL;
+    HKEY user_guid_key =  NULL;
+    HKEY machine_guid_key = NULL;
+    HKEY hkcr_guid_key = NULL;
+    HKEY machine_subkey = NULL;
+    HKEY user_subkey = NULL;
+    DWORD value;
+    DWORD size;
+    static const char *guid = "{42290b44-c2b1-45e8-8fe8-fbe645a70de9}";
+
+    ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Classes", &user_classes);
+    ok(ret == ERROR_SUCCESS || broken(GetLastError() == ERROR_FILE_NOT_FOUND) /* Windows NT */,
+        "could not open user class key, error %d\n", ret);
+    if (ret != ERROR_SUCCESS)
+    {
+        skip("this version of Windows doesn't have HKCU\\Software\\Classes, skipping test\n");
+        goto end;
+    }
+
+    ret = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Classes", &machine_classes);
+    ok(ret == ERROR_SUCCESS, "could not open machine class key, error %d\n", ret);
+
+    ret = RegCreateKeyA(user_classes, guid, &user_guid_key);
+    ok(ret == ERROR_SUCCESS, "could not create guid key, error %d\n", ret);
+
+    ret = RegOpenKey(HKEY_CLASSES_ROOT, guid, &hkcr_guid_key);
+    todo_wine ok(ret == ERROR_SUCCESS || broken(ret), /* Windows < Win2k */
+        "HKCU\\Software\\Classes not merged into HKCR\n");
+
+    if (ret != ERROR_SUCCESS)
+    {
+        skip("this version of Windows doesn't merge HKCU\\Software\\Classes into HKCR\n");
+        goto end;
+    }
+
+    ret = RegCreateKeyA(machine_classes, guid, &machine_guid_key);
+    ok(ret == ERROR_SUCCESS, "error %d creating machine guid key\n", ret);
+
+    /* if a key exists under both machine classes and user classes,
+     * the values from both get merged into the HKCR key,
+     * with user values overriding machine values of the same name.
+     */
+    value = 1;
+    ret = RegSetValueExA(machine_guid_key, "machine_value", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting machine guid value failed, error %d\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(hkcr_guid_key, NULL, "machine_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret == ERROR_SUCCESS, "couldn't find value in machine key, error %d\n", ret);
+
+    value = 2;
+    ret = RegSetValueExA(user_guid_key, "user_value", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting user guid value failed, error %d\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(hkcr_guid_key, NULL, "user_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret == ERROR_SUCCESS, "couldn't find value in user key, error %d\n", ret);
+
+    value = 3;
+    ret = RegSetValueExA(user_guid_key, "machine_value", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting user value failed, error %d\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(hkcr_guid_key, NULL, "machine_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret == ERROR_SUCCESS, "error %d getting value\n", ret);
+    ok(value == 3, "user value didn't override machine value\n");
+
+    /* when both machine and user keys exist for a HKCR key,
+     * new values written to HKCR key go to the user key.
+     */
+    value = 1;
+    ret = RegSetValueExA(hkcr_guid_key, "hkcr_value", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting hkcr value failed, error %d\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(user_guid_key, NULL, "hkcr_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret == ERROR_SUCCESS, "hkcr write went to machine key\n");
+    ret = pRegGetValueA(machine_guid_key, NULL, "hkcr_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret != ERROR_SUCCESS, "hkcr write didn't go to machine key, error %d\n", ret);
+
+    /* when both machine and user keys exist for a HKCR key,
+     * values existing only in machine key still get "overwritten" to user.
+     */
+    value = 1;
+    ret = RegSetValueExA(machine_guid_key, "machine_value2", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting machine value failed, error %d\n", ret);
+    value = 2;
+    ret = RegSetValueExA(hkcr_guid_key, "machine_value2", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting hkcr value failed, error %d\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(user_guid_key, NULL, "machine_value2", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret == ERROR_SUCCESS, "value didn't get written to user key, fetching it got error %d\n", ret);
+
+    /* when both machine and user keys exist for a HKCR key,
+     * subkeys created in the HKCR key go to the machine key. */
+    ret = RegCreateKeyA(hkcr_guid_key, "subkey", &machine_subkey);
+    ok(ret == ERROR_SUCCESS, "creating hkcr subkey failed, error %d\n", ret);
+    ret = RegOpenKeyA(user_guid_key, "subkey", &user_subkey);
+    ok(ret != ERROR_SUCCESS, "subkey got created in user key\n");
+
+    /* when both machine and user keys exist for a HKCR key,
+     * the immediate subkeys of the user key hide the immediate subkeys of machine with the same name.
+     * MSDN claims this rule applies to a list of other subkeys too.
+     */
+    value = 1;
+    ret = RegSetValueExA(machine_subkey, "subkey_value", 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));
+    ok(ret == ERROR_SUCCESS, "setting subkey value failed, error %d\n", ret);
+    ret = RegCreateKeyA(user_guid_key, "subkey", &user_subkey);
+    ok(ret == ERROR_SUCCESS, "creating user subkey failed, error %d\n", ret);
+    RegCloseKey(machine_subkey);
+    machine_subkey = NULL;
+    ret = RegOpenKeyA(hkcr_guid_key, "subkey", &machine_subkey);
+    ok(ret == ERROR_SUCCESS, "error %d opening hkcr subkey\n", ret);
+    size = sizeof(DWORD);
+    ret = pRegGetValueA(user_subkey, NULL, "subkey_value", RRF_RT_REG_DWORD, NULL, &value, &size);
+    ok(ret != ERROR_SUCCESS, "machine subkey wasn't hidden\n");
+
+end:
+    delete_key(user_guid_key);
+    delete_key(machine_guid_key);
+
+    RegCloseKey(user_classes);
+    RegCloseKey(machine_classes);
+    RegCloseKey(user_guid_key);
+    RegCloseKey(machine_guid_key);
+    RegCloseKey(hkcr_guid_key);
+    RegCloseKey(machine_subkey);
+    RegCloseKey(user_subkey);
+}
+
 START_TEST(registry)
 {
     /* Load pointers for functions that are not available in all Windows versions */
@@ -2022,6 +2152,8 @@ START_TEST(registry)
     test_deleted_key();
     test_delete_value();
 
+    test_hkcr_merge();
+
     /* cleanup */
     delete_key( hkey_main );
     


More information about the wine-patches mailing list