[MSI_WINETEST]
[reactos.git] / rostests / winetests / msi / msi.c
index b377320..da6b446 100644 (file)
 
 #include "wine/test.h"
 
+static BOOL is_wow64;
 static const char msifile[] = "winetest.msi";
 
 static BOOL (WINAPI *pConvertSidToStringSidA)(PSID, LPSTR*);
+static LONG (WINAPI *pRegDeleteKeyExA)(HKEY, LPCSTR, REGSAM, DWORD);
+static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
 
 static INSTALLSTATE (WINAPI *pMsiGetComponentPathA)
     (LPCSTR, LPCSTR, LPSTR, DWORD*);
@@ -52,11 +55,16 @@ static INSTALLSTATE (WINAPI *pMsiUseFeatureExA)
     (LPCSTR, LPCSTR ,DWORD, DWORD);
 static UINT (WINAPI *pMsiGetPatchInfoExA)
     (LPCSTR, LPCSTR, LPCSTR, MSIINSTALLCONTEXT, LPCSTR, LPSTR, DWORD *);
+static UINT (WINAPI *pMsiEnumProductsExA)
+    (LPCSTR, LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
+static UINT (WINAPI *pMsiEnumComponentsExA)
+    (LPCSTR, DWORD, DWORD, CHAR[39], MSIINSTALLCONTEXT *, LPSTR, LPDWORD);
 
 static void init_functionpointers(void)
 {
     HMODULE hmsi = GetModuleHandleA("msi.dll");
     HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
+    HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
 
 #define GET_PROC(dll, func) \
     p ## func = (void *)GetProcAddress(dll, #func); \
@@ -72,8 +80,12 @@ static void init_functionpointers(void)
     GET_PROC(hmsi, MsiQueryComponentStateA)
     GET_PROC(hmsi, MsiUseFeatureExA)
     GET_PROC(hmsi, MsiGetPatchInfoExA)
+    GET_PROC(hmsi, MsiEnumProductsExA)
+    GET_PROC(hmsi, MsiEnumComponentsExA)
 
     GET_PROC(hadvapi32, ConvertSidToStringSidA)
+    GET_PROC(hadvapi32, RegDeleteKeyExA)
+    GET_PROC(hkernel32, IsWow64Process)
 
 #undef GET_PROC
 }
@@ -223,6 +235,13 @@ static void test_usefeature(void)
     ok( r == INSTALLSTATE_INVALIDARG, "wrong return val\n");
 }
 
+static LONG delete_key( HKEY key, LPCSTR subkey, REGSAM access )
+{
+    if (pRegDeleteKeyExA)
+        return pRegDeleteKeyExA( key, subkey, access, 0 );
+    return RegDeleteKeyA( key, subkey );
+}
+
 static void test_null(void)
 {
     MSIHANDLE hpkg;
@@ -231,6 +250,10 @@ static void test_null(void)
     DWORD dwType, cbData;
     LPBYTE lpData = NULL;
     INSTALLSTATE state;
+    REGSAM access = KEY_ALL_ACCESS;
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     r = pMsiOpenPackageExW(NULL, 0, &hpkg);
     ok( r == ERROR_INVALID_PARAMETER,"wrong error\n");
@@ -257,7 +280,12 @@ static void test_null(void)
      * necessary registry values */
 
     /* empty product string */
-    r = RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", &hkey);
+    r = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", 0, access, &hkey);
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 
     r = RegQueryValueExA(hkey, NULL, 0, &dwType, lpData, &cbData);
@@ -275,6 +303,13 @@ static void test_null(void)
     }
 
     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        HeapFree(GetProcessHeap(), 0, lpData);
+        RegCloseKey(hkey);
+        return;
+    }
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 
     r = MsiGetProductInfoA("", "", NULL, NULL);
@@ -297,7 +332,8 @@ static void test_null(void)
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 
     /* empty attribute */
-    r = RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}", &hkey);
+    r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
+                        0, NULL, 0, access, NULL, &hkey, NULL);
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 
     r = RegSetValueA(hkey, NULL, REG_SZ, "test", strlen("test"));
@@ -309,7 +345,8 @@ static void test_null(void)
     r = RegCloseKey(hkey);
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 
-    r = RegDeleteKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}");
+    r = delete_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{F1C3AF50-8B56-4A69-A00C-00773FE42F30}",
+                   access & KEY_WOW64_64KEY);
     ok( r == ERROR_SUCCESS, "wrong error %d\n", r);
 }
 
@@ -380,6 +417,12 @@ static const struct
     MSIFILEHASHINFO hash;
 } hash_data[] =
 {
+    { "", 0,
+      { HASHSIZE,
+        { 0, 0, 0, 0 },
+      },
+    },
+
     { "abc", 0,
       { HASHSIZE,
         { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 },
@@ -453,9 +496,7 @@ static void test_MsiGetFileHash(void)
         ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
         ret = memcmp(&hash, &hash_data[i].hash, HASHSIZE);
-        ok(ret == 0 ||
-           broken(ret != 0), /* win95 */
-           "Hash incorrect\n");
+        ok(!ret, "Hash incorrect\n");
 
         DeleteFile(name);
     }
@@ -509,27 +550,30 @@ static void create_test_guid(LPSTR prodcode, LPSTR squashed)
     ok(size == 39, "Expected 39, got %d\n", hr);
 
     WideCharToMultiByte(CP_ACP, 0, guidW, size, prodcode, MAX_PATH, NULL, NULL);
-    squash_guid(guidW, squashedW);
-    WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
+    if (squashed)
+    {
+        squash_guid(guidW, squashedW);
+        WideCharToMultiByte(CP_ACP, 0, squashedW, -1, squashed, MAX_PATH, NULL, NULL);
+    }
 }
 
-static void get_user_sid(LPSTR *usersid)
+static char *get_user_sid(void)
 {
     HANDLE token;
-    DWORD size;
-    PTOKEN_USER user;
+    DWORD size = 0;
+    TOKEN_USER *user;
+    char *usersid = NULL;
 
     OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
-
-    size = 0;
     GetTokenInformation(token, TokenUser, NULL, size, &size);
-    user = HeapAlloc(GetProcessHeap(), 0, size);
 
+    user = HeapAlloc(GetProcessHeap(), 0, size);
     GetTokenInformation(token, TokenUser, user, size, &size);
-    pConvertSidToStringSidA(user->User.Sid, usersid);
-
+    pConvertSidToStringSidA(user->User.Sid, &usersid);
     HeapFree(GetProcessHeap(), 0, user);
+
     CloseHandle(token);
+    return usersid;
 }
 
 static void test_MsiQueryProductState(void)
@@ -542,39 +586,66 @@ static void test_MsiQueryProductState(void)
     LONG res;
     HKEY userkey, localkey, props;
     HKEY prodkey;
-    DWORD data;
+    DWORD data, error;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(NULL);
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* empty prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA("");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* garbage prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA("garbage");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* guid without brackets */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* guid with brackets */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     /* same length as guid, but random */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
@@ -583,75 +654,114 @@ static void test_MsiQueryProductState(void)
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\");
     lstrcatA(keypath, prodcode);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        RegDeleteKeyA(userkey, "");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local uninstall key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     data = 1;
     res = RegSetValueExA(localkey, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* WindowsInstaller value exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     RegDeleteValueA(localkey, "WindowsInstaller");
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, usersid);
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local product key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* install properties key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     data = 1;
     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* WindowsInstaller value exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     data = 2;
     res = RegSetValueExA(props, "WindowsInstaller", 0, REG_DWORD, (const BYTE *)&data, sizeof(DWORD));
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* WindowsInstaller value is not 1 */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     RegDeleteKeyA(userkey, "");
 
     /* user product key does not exist */
+    SetLastError(0xdeadbeef);
     state = MsiQueryProductStateA(prodcode);
+    error = GetLastError();
     ok(state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     RegDeleteValueA(props, "WindowsInstaller");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(localkey);
     RegDeleteKeyA(userkey, "");
     RegCloseKey(userkey);
@@ -663,7 +773,7 @@ static void test_MsiQueryProductState(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
@@ -675,14 +785,14 @@ static void test_MsiQueryProductState(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
     ok(state == INSTALLSTATE_ADVERTISED,
        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
@@ -698,11 +808,11 @@ static void test_MsiQueryProductState(void)
     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
 
     RegDeleteValueA(props, "WindowsInstaller");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(localkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_MACHINE */
@@ -710,7 +820,7 @@ static void test_MsiQueryProductState(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
@@ -720,14 +830,14 @@ static void test_MsiQueryProductState(void)
     lstrcatA(keypath, "S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
     ok(state == INSTALLSTATE_ADVERTISED,
        "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryProductStateA(prodcode);
@@ -743,11 +853,11 @@ static void test_MsiQueryProductState(void)
     ok(state == INSTALLSTATE_DEFAULT, "Expected INSTALLSTATE_DEFAULT, got %d\n", state);
 
     RegDeleteValueA(props, "WindowsInstaller");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(localkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     LocalFree(usersid);
@@ -817,47 +927,82 @@ static void test_MsiQueryFeatureState(void)
     INSTALLSTATE state;
     LPSTR usersid;
     LONG res;
+    REGSAM access = KEY_ALL_ACCESS;
+    DWORD error;
 
     create_test_guid(prodcode, prod_squashed);
     compose_base85_guid(component, comp_base85, comp_squashed);
     compose_base85_guid(component, comp_base85 + 20, comp_squashed2);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(NULL, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* empty prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA("", "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* garbage prodcode */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA("garbage", "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* guid without brackets */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA("6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D", "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* guid with brackets */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA("{6700E8CF-95AB-4D9C-BC2C-15840DEA7A5D}", "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_ALREADY_EXISTS) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     /* same length as guid, but random */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA("A938G02JF-2NF3N93-VN3-2NNF-3KGKALDNF93", "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* NULL szFeature */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, NULL);
+    error = GetLastError();
     ok(state == INSTALLSTATE_INVALIDARG, "Expected INSTALLSTATE_INVALIDARG, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* empty szFeature */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     /* feature key does not exist yet */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
 
@@ -868,15 +1013,23 @@ static void test_MsiQueryFeatureState(void)
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* feature key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(userkey, "feature", 0, REG_SZ, (const BYTE *)"", 2);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* feature value exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, usersid);
@@ -884,43 +1037,71 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\Features");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        RegDeleteKeyA(userkey, "");
+        RegCloseKey(userkey);
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* userdata features key exists */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaa", 20);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_BADCONFIG, "Expected INSTALLSTATE_BADCONFIG, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaa", 21);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)"aaaaaaaaaaaaaaaaaaaaa", 22);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(localkey, "feature", 0, REG_SZ, (const BYTE *)comp_base85, 41);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, usersid);
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
@@ -928,63 +1109,95 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed2);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 1);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"apple", 6);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_ADVERTISED, "Expected INSTALLSTATE_ADVERTISED, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey2, prod_squashed, 0, REG_SZ, (const BYTE *)"orange", 7);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_LOCAL */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_SOURCE */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* bad INSTALLSTATE_SOURCE */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_SOURCE */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* bad INSTALLSTATE_SOURCE */
+    SetLastError(0xdeadbeef);
     state = MsiQueryFeatureStateA(prodcode, "feature");
+    error = GetLastError();
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* win2k */,
+       "expected ERROR_SUCCESS, got %u\n", error);
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey2, prod_squashed);
-    RegDeleteKeyA(compkey, "");
-    RegDeleteKeyA(compkey2, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
+    delete_key(compkey2, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(localkey, "feature");
     RegDeleteValueA(userkey, "feature");
     RegDeleteKeyA(userkey, "");
@@ -1000,7 +1213,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, "\\Installer\\Features\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* feature key exists */
@@ -1020,7 +1233,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\Features");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* userdata features key exists */
@@ -1056,7 +1269,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
@@ -1064,7 +1277,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed2);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryFeatureStateA(prodcode, "feature");
@@ -1090,11 +1303,11 @@ static void test_MsiQueryFeatureState(void)
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey2, prod_squashed);
-    RegDeleteKeyA(compkey, "");
-    RegDeleteKeyA(compkey2, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
+    delete_key(compkey2, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(localkey, "feature");
     RegDeleteValueA(userkey, "feature");
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     RegCloseKey(compkey2);
     RegCloseKey(localkey);
@@ -1105,7 +1318,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Features\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* feature key exists */
@@ -1124,7 +1337,7 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\Features");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* userdata features key exists */
@@ -1159,14 +1372,14 @@ static void test_MsiQueryFeatureState(void)
     lstrcatA(keypath, "S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
     lstrcatA(keypath, "S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed2);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey2);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey2, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MsiQueryFeatureStateA(prodcode, "feature");
@@ -1192,11 +1405,11 @@ static void test_MsiQueryFeatureState(void)
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey2, prod_squashed);
-    RegDeleteKeyA(compkey, "");
-    RegDeleteKeyA(compkey2, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
+    delete_key(compkey2, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(localkey, "feature");
     RegDeleteValueA(userkey, "feature");
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     RegCloseKey(compkey2);
     RegCloseKey(localkey);
@@ -1217,6 +1430,8 @@ static void test_MsiQueryComponentState(void)
     LPSTR usersid;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
+    DWORD error;
 
     static const INSTALLSTATE MAGIC_ERROR = 0xdeadbeef;
 
@@ -1228,61 +1443,94 @@ static void test_MsiQueryComponentState(void)
 
     create_test_guid(prodcode, prod_squashed);
     compose_base85_guid(component, comp_base85, comp_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProductCode */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(NULL, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* empty szProductCode */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA("", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* random szProductCode */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA("random", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* GUID-length szProductCode */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA("DJANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KDE", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* GUID-length with brackets */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA("{JANE93KNDNAS-2KN2NR93KMN3LN13=L1N3KD}", NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* actual GUID */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* create local system product key */
@@ -1290,101 +1538,130 @@ static void test_MsiQueryComponentState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local system product key exists */
     state = MAGIC_ERROR;
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_PRODUCT, "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected 0xdeadbeef, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* LocalPackage value exists */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* component key exists */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"", 0);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* component\product exists */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    error = GetLastError();
     ok(state == INSTALLSTATE_NOTUSED || state == INSTALLSTATE_LOCAL,
        "Expected INSTALLSTATE_NOTUSED or INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     /* NULL component, product exists */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, NULL, &state);
+    error = GetLastError();
     ok(r == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", r);
     ok(state == MAGIC_ERROR, "Expected state not changed, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"hi", 2);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_LOCAL */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01\\", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_SOURCE */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* bad INSTALLSTATE_SOURCE */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01a", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* INSTALLSTATE_SOURCE */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
-    res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01", 3);
+    res = RegSetValueExA(compkey, prod_squashed, 0, REG_SZ, (const BYTE *)"01:", 4);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    /* bad INSTALLSTATE_SOURCE */
+    /* registry component */
     state = MAGIC_ERROR;
+    SetLastError(0xdeadbeef);
     r = pMsiQueryComponentStateA(prodcode, NULL, MSIINSTALLCONTEXT_MACHINE, component, &state);
+    error = GetLastError();
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
+    ok(error == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", error);
 
     RegDeleteValueA(prodkey, "LocalPackage");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegCloseKey(compkey);
 
@@ -1415,7 +1692,7 @@ static void test_MsiQueryComponentState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     res = RegSetValueExA(prodkey, "LocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
@@ -1433,7 +1710,7 @@ static void test_MsiQueryComponentState(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* component key exists */
@@ -1486,7 +1763,7 @@ static void test_MsiQueryComponentState(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     state = MAGIC_ERROR;
@@ -1494,7 +1771,7 @@ static void test_MsiQueryComponentState(void)
     ok(r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r);
     ok(state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
@@ -1503,7 +1780,7 @@ static void test_MsiQueryComponentState(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     res = RegSetValueExA(prodkey, "ManagedLocalPackage", 0, REG_SZ, (const BYTE *)"msitest.msi", 11);
@@ -1516,9 +1793,9 @@ static void test_MsiQueryComponentState(void)
 
     RegDeleteValueA(prodkey, "LocalPackage");
     RegDeleteValueA(prodkey, "ManagedLocalPackage");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegCloseKey(compkey);
     LocalFree(usersid);
@@ -1537,11 +1814,15 @@ static void test_MsiGetComponentPath(void)
     INSTALLSTATE state;
     LPSTR usersid;
     DWORD size, val;
+    REGSAM access = KEY_ALL_ACCESS;
     LONG res;
 
     create_test_guid(prodcode, prod_squashed);
     compose_base85_guid(component, comp_base85, comp_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProduct */
     size = MAX_PATH;
@@ -1597,7 +1878,13 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local system component key exists */
@@ -1634,7 +1921,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     val = 1;
@@ -1674,9 +1961,9 @@ static void test_MsiGetComponentPath(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(installprop, "WindowsInstaller");
-    RegDeleteKeyA(installprop, "");
+    delete_key(installprop, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     RegCloseKey(installprop);
     DeleteFileA("C:\\imapath");
@@ -1687,7 +1974,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed component key exists */
@@ -1724,7 +2011,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     val = 1;
@@ -1764,9 +2051,9 @@ static void test_MsiGetComponentPath(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(installprop, "WindowsInstaller");
-    RegDeleteKeyA(installprop, "");
+    delete_key(installprop, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     RegCloseKey(installprop);
     DeleteFileA("C:\\imapath");
@@ -1777,7 +2064,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed product key exists */
@@ -1797,7 +2084,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed component key exists */
@@ -1834,7 +2121,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, prod_squashed);
     lstrcatA(keypath, "\\InstallProperties");
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &installprop);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &installprop, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     val = 1;
@@ -1874,10 +2161,10 @@ static void test_MsiGetComponentPath(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(prodkey, "");
-    RegDeleteKeyA(compkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(installprop, "WindowsInstaller");
-    RegDeleteKeyA(installprop, "");
+    delete_key(installprop, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegCloseKey(compkey);
     RegCloseKey(installprop);
@@ -1906,7 +2193,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user unmanaged component key exists */
@@ -1957,7 +2244,7 @@ static void test_MsiGetComponentPath(void)
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteKeyA(prodkey, "");
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegCloseKey(compkey);
     DeleteFileA("C:\\imapath");
@@ -1965,7 +2252,7 @@ static void test_MsiGetComponentPath(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local classes product key exists */
@@ -1983,7 +2270,7 @@ static void test_MsiGetComponentPath(void)
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user component key exists */
@@ -2033,8 +2320,8 @@ static void test_MsiGetComponentPath(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(compkey, prod_squashed);
-    RegDeleteKeyA(prodkey, "");
-    RegDeleteKeyA(compkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegCloseKey(compkey);
     DeleteFileA("C:\\imapath");
@@ -2056,11 +2343,15 @@ static void test_MsiGetProductCode(void)
     LPSTR usersid;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(prodcode2, prod2_squashed);
     compose_base85_guid(component, comp_base85, comp_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* szComponent is NULL */
     lstrcpyA(product, "prod");
@@ -2110,7 +2401,13 @@ static void test_MsiGetProductCode(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user unmanaged component key exists */
@@ -2137,7 +2434,7 @@ static void test_MsiGetProductCode(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed product key of first product exists */
@@ -2146,7 +2443,7 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
@@ -2167,7 +2464,7 @@ static void test_MsiGetProductCode(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local classes product key exists */
@@ -2176,7 +2473,7 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
@@ -2185,7 +2482,7 @@ static void test_MsiGetProductCode(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod2_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed product key of second product exists */
@@ -2194,18 +2491,18 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey, prod2_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user component key exists */
@@ -2232,7 +2529,7 @@ static void test_MsiGetProductCode(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed product key of first product exists */
@@ -2241,7 +2538,7 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
@@ -2262,7 +2559,7 @@ static void test_MsiGetProductCode(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local classes product key exists */
@@ -2271,7 +2568,7 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode), "Expected %s, got %s\n", prodcode, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
@@ -2280,7 +2577,7 @@ static void test_MsiGetProductCode(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod2_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user managed product key of second product exists */
@@ -2289,11 +2586,11 @@ static void test_MsiGetProductCode(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(!lstrcmpA(product, prodcode2), "Expected %s, got %s\n", prodcode2, product);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey, prod2_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     LocalFree(usersid);
 }
@@ -2313,11 +2610,15 @@ static void test_MsiEnumClients(void)
     LPSTR usersid;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(prodcode2, prod2_squashed);
     compose_base85_guid(component, comp_base85, comp_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szComponent */
     product[0] = '\0';
@@ -2347,7 +2648,13 @@ static void test_MsiEnumClients(void)
     lstrcatA(keypath, "\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user unmanaged component key exists */
@@ -2410,14 +2717,14 @@ static void test_MsiEnumClients(void)
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey, prod2_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\");
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Components\\");
     lstrcatA(keypath, comp_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &compkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &compkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user local component key exists */
@@ -2480,7 +2787,7 @@ static void test_MsiEnumClients(void)
 
     RegDeleteValueA(compkey, prod_squashed);
     RegDeleteValueA(compkey, prod2_squashed);
-    RegDeleteKeyA(compkey, "");
+    delete_key(compkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(compkey);
     LocalFree(usersid);
 }
@@ -2753,10 +3060,14 @@ static void test_MsiGetProductInfo(void)
     CHAR keypath[MAX_PATH];
     LPSTR usersid;
     DWORD sz, val = 42;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(packcode, pack_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProduct */
     sz = MAX_PATH;
@@ -2856,7 +3167,13 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product code exists */
@@ -2868,7 +3185,7 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\");
@@ -2876,7 +3193,7 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user product code exists */
@@ -2893,7 +3210,7 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* both local and managed product code exist */
@@ -2905,7 +3222,7 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -2974,9 +3291,9 @@ static void test_MsiGetProductInfo(void)
 
     RegDeleteValueA(propkey, "IMadeThis");
     RegDeleteValueA(propkey, "HelpLink");
-    RegDeleteKeyA(propkey, "");
-    RegDeleteKeyA(localkey, "");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(propkey);
     RegCloseKey(localkey);
     RegCloseKey(prodkey);
@@ -3001,7 +3318,7 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user product key exists */
@@ -3013,7 +3330,7 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -3036,8 +3353,8 @@ static void test_MsiGetProductInfo(void)
     ok(sz == 4, "Expected 4, got %d\n", sz);
 
     RegDeleteValueA(propkey, "HelpLink");
-    RegDeleteKeyA(propkey, "");
-    RegDeleteKeyA(localkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegDeleteKeyA(prodkey, "");
     RegCloseKey(propkey);
     RegCloseKey(localkey);
@@ -3046,7 +3363,7 @@ static void test_MsiGetProductInfo(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* classes product key exists */
@@ -3063,7 +3380,7 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user product key exists */
@@ -3075,7 +3392,7 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -3087,8 +3404,8 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    RegDeleteKeyA(propkey, "");
-    RegDeleteKeyA(localkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(propkey);
     RegCloseKey(localkey);
 
@@ -3096,7 +3413,7 @@ static void test_MsiGetProductInfo(void)
     lstrcatA(keypath, "S-1-5-18\\\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Local System product key exists */
@@ -3108,7 +3425,7 @@ static void test_MsiGetProductInfo(void)
     ok(!lstrcmpA(buf, "apple"), "Expected \"apple\", got \"%s\"\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -3877,7 +4194,7 @@ static void test_MsiGetProductInfo(void)
        "Expected buf to be unchanged, got \"%s\"\n", buf);
     ok(sz == MAX_PATH, "Expected sz to be unchanged, got %d\n", sz);
 
-    res = RegCreateKeyA(prodkey, "SourceList", &source);
+    res = RegCreateKeyExA(prodkey, "SourceList", 0, NULL, 0, access, NULL, &source, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* SourceList key exists, but PackageName val does not exist */
@@ -3994,8 +4311,8 @@ static void test_MsiGetProductInfo(void)
     RegDeleteValueA(propkey, "Version");
     RegDeleteValueA(propkey, "ProductIcon");
     RegDeleteValueA(propkey, "AuthorizedLUAApp");
-    RegDeleteKeyA(propkey, "");
-    RegDeleteKeyA(localkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegDeleteValueA(prodkey, "InstanceType");
     RegDeleteValueA(prodkey, "Transforms");
     RegDeleteValueA(prodkey, "Language");
@@ -4006,8 +4323,8 @@ static void test_MsiGetProductInfo(void)
     RegDeleteValueA(prodkey, "ProductIcon");
     RegDeleteValueA(prodkey, "AuthorizedLUAApp");
     RegDeleteValueA(source, "PackageName");
-    RegDeleteKeyA(source, "");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(source, "", access & KEY_WOW64_64KEY);
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(propkey);
     RegCloseKey(localkey);
     RegCloseKey(source);
@@ -4029,6 +4346,7 @@ static void test_MsiGetProductInfoEx(void)
     CHAR keypath[MAX_PATH];
     LPSTR usersid;
     DWORD sz;
+    REGSAM access = KEY_ALL_ACCESS;
 
     if (!pMsiGetProductInfoExA)
     {
@@ -4038,7 +4356,10 @@ static void test_MsiGetProductInfoEx(void)
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(packcode, pack_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProductCode */
     sz = MAX_PATH;
@@ -4162,7 +4483,13 @@ static void test_MsiGetProductInfoEx(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user product key exists */
@@ -4176,7 +4503,7 @@ static void test_MsiGetProductInfoEx(void)
     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -4658,7 +4985,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
@@ -4678,7 +5005,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_CURRENT_USER, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_CURRENT_USER, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     sz = MAX_PATH;
@@ -4686,7 +5013,14 @@ static void test_MsiGetProductInfoEx(void)
     r = pMsiGetProductInfoExA(prodcode, usersid,
                               MSIINSTALLCONTEXT_USERUNMANAGED,
                               INSTALLPROPERTY_PRODUCTSTATE, buf, &sz);
-    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+    ok(r == ERROR_SUCCESS || broken(r == ERROR_UNKNOWN_PRODUCT), "Expected ERROR_SUCCESS, got %d\n", r);
+    if (r == ERROR_UNKNOWN_PRODUCT)
+    {
+        win_skip("skipping remaining tests for MsiGetProductInfoEx\n");
+        delete_key(prodkey, "", access);
+        RegCloseKey(prodkey);
+        return;
+    }
     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
     ok(sz == 1, "Expected 1, got %d\n", sz);
 
@@ -5069,7 +5403,7 @@ static void test_MsiGetProductInfoEx(void)
     RegDeleteValueA(prodkey, "HelpTelephone");
     RegDeleteValueA(prodkey, "HelpLink");
     RegDeleteValueA(prodkey, "LocalPackage");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_USERMANAGED */
@@ -5079,7 +5413,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local user product key exists */
@@ -5093,7 +5427,7 @@ static void test_MsiGetProductInfoEx(void)
     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -5482,9 +5816,9 @@ static void test_MsiGetProductInfoEx(void)
     RegDeleteValueA(propkey, "HelpTelephone");
     RegDeleteValueA(propkey, "HelpLink");
     RegDeleteValueA(propkey, "ManagedLocalPackage");
-    RegDeleteKeyA(propkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(propkey);
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(localkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
@@ -5492,7 +5826,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
@@ -5505,7 +5839,7 @@ static void test_MsiGetProductInfoEx(void)
     ok(!lstrcmpA(buf, "1"), "Expected \"1\", got \"%s\"\n", buf);
     ok(sz == 1, "Expected 1, got %d\n", sz);
 
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
 
     lstrcpyA(keypath, "Software\\Microsoft\\Installer\\Products\\");
@@ -5544,7 +5878,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     res = RegSetValueExA(userkey, "HelpLink", 0, REG_SZ, (LPBYTE)"link", 5);
@@ -5925,9 +6259,9 @@ static void test_MsiGetProductInfoEx(void)
     RegDeleteValueA(userkey, "InstallDate");
     RegDeleteValueA(userkey, "HelpTelephone");
     RegDeleteValueA(userkey, "HelpLink");
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_MACHINE */
@@ -5946,7 +6280,7 @@ static void test_MsiGetProductInfoEx(void)
     lstrcpyA(keypath, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &localkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &localkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local system product key exists */
@@ -5960,7 +6294,7 @@ static void test_MsiGetProductInfoEx(void)
     ok(!lstrcmpA(buf, "apple"), "Expected buf to be unchanged, got %s\n", buf);
     ok(sz == MAX_PATH, "Expected MAX_PATH, got %d\n", sz);
 
-    res = RegCreateKeyA(localkey, "InstallProperties", &propkey);
+    res = RegCreateKeyExA(localkey, "InstallProperties", 0, NULL, 0, access, NULL, &propkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -6349,15 +6683,15 @@ static void test_MsiGetProductInfoEx(void)
     RegDeleteValueA(propkey, "HelpTelephone");
     RegDeleteValueA(propkey, "HelpLink");
     RegDeleteValueA(propkey, "LocalPackage");
-    RegDeleteKeyA(propkey, "");
+    delete_key(propkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(propkey);
-    RegDeleteKeyA(localkey, "");
+    delete_key(localkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(localkey);
 
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local classes product key exists */
@@ -6748,7 +7082,7 @@ static void test_MsiGetProductInfoEx(void)
     RegDeleteValueA(prodkey, "InstallDate");
     RegDeleteValueA(prodkey, "HelpTelephone");
     RegDeleteValueA(prodkey, "HelpLink");
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     LocalFree(usersid);
 }
@@ -6772,9 +7106,13 @@ static void test_MsiGetUserInfo(void)
     HKEY prodkey, userprod, props;
     LPSTR usersid;
     LONG res;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProduct */
     INIT_USERINFO();
@@ -6942,7 +7280,13 @@ static void test_MsiGetUserInfo(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -6963,10 +7307,10 @@ static void test_MsiGetUserInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    res = RegCreateKeyA(userprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7089,11 +7433,11 @@ static void test_MsiGetUserInfo(void)
     RegDeleteValueA(props, "ProductID");
     RegDeleteValueA(props, "RegCompany");
     RegDeleteValueA(props, "RegOwner");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userprod, "");
+    delete_key(userprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userprod);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
@@ -7123,10 +7467,10 @@ static void test_MsiGetUserInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    res = RegCreateKeyA(userprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7207,9 +7551,9 @@ static void test_MsiGetUserInfo(void)
     RegDeleteValueA(props, "ProductID");
     RegDeleteValueA(props, "RegCompany");
     RegDeleteValueA(props, "RegOwner");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userprod, "");
+    delete_key(userprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userprod);
     RegDeleteKeyA(prodkey, "");
     RegCloseKey(prodkey);
@@ -7220,7 +7564,7 @@ static void test_MsiGetUserInfo(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* product key exists */
@@ -7240,10 +7584,10 @@ static void test_MsiGetUserInfo(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    res = RegCreateKeyA(userprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(userprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7324,11 +7668,11 @@ static void test_MsiGetUserInfo(void)
     RegDeleteValueA(props, "ProductID");
     RegDeleteValueA(props, "RegCompany");
     RegDeleteValueA(props, "RegOwner");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userprod, "");
+    delete_key(userprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userprod);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     LocalFree(usersid);
 }
@@ -7346,12 +7690,16 @@ static void test_MsiOpenProduct(void)
     DWORD size;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     GetCurrentDirectoryA(MAX_PATH, path);
     lstrcatA(path, "\\");
 
     create_test_guid(prodcode, prod_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     hdb = create_package_db(prodcode);
     MsiCloseHandle(hdb);
@@ -7413,7 +7761,13 @@ static void test_MsiOpenProduct(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -7429,7 +7783,7 @@ static void test_MsiOpenProduct(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
@@ -7439,7 +7793,7 @@ static void test_MsiOpenProduct(void)
        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
 
-    res = RegCreateKeyA(userkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7470,11 +7824,11 @@ static void test_MsiOpenProduct(void)
     MsiCloseHandle(hprod);
 
     RegDeleteValueA(props, "ManagedLocalPackage");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
@@ -7498,7 +7852,7 @@ static void test_MsiOpenProduct(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
@@ -7508,7 +7862,7 @@ static void test_MsiOpenProduct(void)
        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
 
-    res = RegCreateKeyA(userkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7539,9 +7893,9 @@ static void test_MsiOpenProduct(void)
     MsiCloseHandle(hprod);
 
     RegDeleteValueA(props, "LocalPackage");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
     RegDeleteKeyA(prodkey, "");
     RegCloseKey(prodkey);
@@ -7551,7 +7905,7 @@ static void test_MsiOpenProduct(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -7565,7 +7919,7 @@ static void test_MsiOpenProduct(void)
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* user product key exists */
@@ -7575,7 +7929,7 @@ static void test_MsiOpenProduct(void)
        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
 
-    res = RegCreateKeyA(userkey, "InstallProperties", &props);
+    res = RegCreateKeyExA(userkey, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -7612,6 +7966,11 @@ static void test_MsiOpenProduct(void)
     /* LocalPackage has just the package name */
     hprod = 0xdeadbeef;
     r = MsiOpenProductA(prodcode, &hprod);
+    if (r == ERROR_INSTALL_PACKAGE_REJECTED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
     ok(r == ERROR_INSTALL_PACKAGE_OPEN_FAILED || r == ERROR_SUCCESS,
        "Expected ERROR_INSTALL_PACKAGE_OPEN_FAILED or ERROR_SUCCESS, got %d\n", r);
     if (r == ERROR_SUCCESS)
@@ -7634,12 +7993,13 @@ static void test_MsiOpenProduct(void)
        "Expected ERROR_UNKNOWN_PRODUCT, got %d\n", r);
     ok(hprod == 0xdeadbeef, "Expected hprod to be unchanged\n");
 
+error:
     RegDeleteValueA(props, "LocalPackage");
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     DeleteFileA(msifile);
@@ -7657,10 +8017,14 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
     DWORD size, data;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(patch, patch_squashed);
 
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
+
     /* MSIPATCHSTATE_APPLIED */
 
     lstrcpyA(patchcode, "apple");
@@ -7671,6 +8035,11 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
     r = pMsiEnumPatchesExA(prodcode, usersid, MSIINSTALLCONTEXT_USERMANAGED,
                            MSIPATCHSTATE_APPLIED, 0, patchcode, targetprod,
                            &context, targetsid, &size);
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok(r == ERROR_NO_MORE_ITEMS, "Expected ERROR_NO_MORE_ITEMS, got %d\n", r);
     ok(!lstrcmpA(patchcode, "apple"),
        "Expected patchcode to be unchanged, got %s\n", patchcode);
@@ -7687,7 +8056,12 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -7710,7 +8084,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &patches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* patches key exists */
@@ -8031,7 +8405,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData product key exists */
@@ -8054,7 +8428,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &udpatch);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData patches key exists */
@@ -8077,7 +8451,7 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* specific UserData patch key exists */
@@ -8221,16 +8595,16 @@ static void test_MsiEnumPatchesEx_usermanaged(LPCSTR usersid, LPCSTR expectedsid
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     RegDeleteValueA(hpatch, "State");
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
     RegDeleteValueA(patches, "Patches");
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 }
 
@@ -8246,10 +8620,14 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
     DWORD size, data;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(patch, patch_squashed);
 
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
+
     /* MSIPATCHSTATE_APPLIED */
 
     lstrcpyA(patchcode, "apple");
@@ -8371,9 +8749,10 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
+    patch_squashed[lstrlenA(patch_squashed) + 1] = 0;
     res = RegSetValueExA(patches, "Patches", 0, REG_MULTI_SZ,
                          (const BYTE *)patch_squashed,
-                         lstrlenA(patch_squashed) + 1);
+                         lstrlenA(patch_squashed) + 2);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches value exists */
@@ -8429,7 +8808,12 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
     lstrcatA(keypath, "\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        goto error;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* userdata patch key exists */
@@ -8479,7 +8863,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData product key exists */
@@ -8502,7 +8886,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &udpatch);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData patches key exists */
@@ -8525,7 +8909,7 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* specific UserData patch key exists */
@@ -8669,16 +9053,18 @@ static void test_MsiEnumPatchesEx_userunmanaged(LPCSTR usersid, LPCSTR expecteds
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     RegDeleteValueA(hpatch, "State");
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
     RegDeleteValueA(patches, patch_squashed);
     RegDeleteValueA(patches, "Patches");
+
+error:
     RegDeleteKeyA(patches, "");
     RegCloseKey(patches);
     RegDeleteKeyA(prodkey, "");
@@ -8697,10 +9083,14 @@ static void test_MsiEnumPatchesEx_machine(void)
     DWORD size, data;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(patch, patch_squashed);
 
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
+
     /* MSIPATCHSTATE_APPLIED */
 
     lstrcpyA(patchcode, "apple");
@@ -8725,7 +9115,12 @@ static void test_MsiEnumPatchesEx_machine(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local product key exists */
@@ -8748,7 +9143,7 @@ static void test_MsiEnumPatchesEx_machine(void)
        "Expected targetsid to be unchanged, got %s\n", targetsid);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &patches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -8875,7 +9270,7 @@ static void test_MsiEnumPatchesEx_machine(void)
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData product key exists */
@@ -8898,7 +9293,7 @@ static void test_MsiEnumPatchesEx_machine(void)
        "Expected \"\", got \"%s\"\n", targetsid);
     ok(size == 0, "Expected 0, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &udpatch);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData Patches key exists */
@@ -8921,7 +9316,7 @@ static void test_MsiEnumPatchesEx_machine(void)
        "Expected \"\", got \"%s\"\n", targetsid);
     ok(size == 0, "Expected 0, got %d\n", size);
 
-    res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData Product patch key exists */
@@ -9105,16 +9500,16 @@ static void test_MsiEnumPatchesEx_machine(void)
 
     RegDeleteValueA(patches, patch_squashed);
     RegDeleteValueA(patches, "Patches");
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
     RegDeleteValueA(hpatch, "State");
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 }
 
@@ -9135,7 +9530,7 @@ static void test_MsiEnumPatchesEx(void)
     }
 
     create_test_guid(prodcode, prod_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
 
     /* empty szProductCode */
     lstrcpyA(patchcode, "apple");
@@ -9392,10 +9787,14 @@ static void test_MsiEnumPatches(void)
     LPSTR usersid;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(patchcode, patch_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szProduct */
     size = MAX_PATH;
@@ -9497,7 +9896,13 @@ static void test_MsiEnumPatches(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -9512,7 +9917,7 @@ static void test_MsiEnumPatches(void)
        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &patches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* patches key exists */
@@ -9671,9 +10076,9 @@ static void test_MsiEnumPatches(void)
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
     RegDeleteValueA(patches, "Patches");
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
@@ -9807,7 +10212,7 @@ static void test_MsiEnumPatches(void)
     lstrcatA(keypath, "\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &userkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &userkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* userdata patch key exists */
@@ -9822,7 +10227,7 @@ static void test_MsiEnumPatches(void)
        "Expected \"whatever\", got \"%s\"\n", transforms);
     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
 
-    RegDeleteKeyA(userkey, "");
+    delete_key(userkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(userkey);
     RegDeleteValueA(patches, patch_squashed);
     RegDeleteValueA(patches, "Patches");
@@ -9848,7 +10253,7 @@ static void test_MsiEnumPatches(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local product key exists */
@@ -9863,7 +10268,7 @@ static void test_MsiEnumPatches(void)
        "Expected lpTransformsBuf to be unchanged, got \"%s\"\n", transforms);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &patches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -9957,7 +10362,7 @@ static void test_MsiEnumPatches(void)
     lstrcatA(keypath, "Installer\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData product key exists */
@@ -9972,7 +10377,7 @@ static void test_MsiEnumPatches(void)
        "Expected \"whatever\", got \"%s\"\n", transforms);
     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &udpatch);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData Patches key exists */
@@ -9987,7 +10392,7 @@ static void test_MsiEnumPatches(void)
        "Expected \"whatever\", got \"%s\"\n", transforms);
     ok(size == 8 || size == MAX_PATH, "Expected 8 or MAX_PATH, got %d\n", size);
 
-    res = RegCreateKeyA(udpatch, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(udpatch, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData Product patch key exists */
@@ -10057,16 +10462,16 @@ static void test_MsiEnumPatches(void)
 
     RegDeleteValueA(patches, patch_squashed);
     RegDeleteValueA(patches, "Patches");
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
     RegDeleteValueA(hpatch, "State");
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
     LocalFree(usersid);
 }
@@ -10082,6 +10487,7 @@ static void test_MsiGetPatchInfoEx(void)
     DWORD size;
     LONG res;
     UINT r;
+    REGSAM access = KEY_ALL_ACCESS;
 
     if (!pMsiGetPatchInfoExA)
     {
@@ -10091,7 +10497,10 @@ static void test_MsiGetPatchInfoEx(void)
 
     create_test_guid(prodcode, prod_squashed);
     create_test_guid(patchcode, patch_squashed);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     /* NULL szPatchCode */
     lstrcpyA(val, "apple");
@@ -10334,7 +10743,13 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData product key exists */
@@ -10349,7 +10764,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -10363,7 +10778,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &patches);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10377,7 +10792,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(patches, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10396,7 +10811,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* managed product key exists */
@@ -10410,7 +10825,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10444,7 +10859,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData Patches key exists */
@@ -10630,9 +11045,9 @@ static void test_MsiGetPatchInfoEx(void)
     ok(size == 16, "Expected 16, got %d\n", size);
 
     RegDeleteValueA(prodpatches, patch_squashed);
-    RegDeleteKeyA(prodpatches, "");
+    delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodpatches);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* UserData is sufficient for all properties
@@ -10665,15 +11080,15 @@ static void test_MsiGetPatchInfoEx(void)
     RegDeleteValueA(hpatch, "Uninstallable");
     RegDeleteValueA(hpatch, "Installed");
     RegDeleteValueA(udpatch, "ManagedLocalPackage");
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
 
     /* MSIINSTALLCONTEXT_USERUNMANAGED */
@@ -10694,7 +11109,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData product key exists */
@@ -10709,7 +11124,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -10723,7 +11138,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &patches);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10737,7 +11152,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(patches, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10802,7 +11217,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData Patches key exists */
@@ -10839,7 +11254,7 @@ static void test_MsiGetPatchInfoEx(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(prodpatches, patch_squashed);
-    RegDeleteKeyA(prodpatches, "");
+    delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodpatches);
     RegDeleteKeyA(prodkey, "");
     RegCloseKey(prodkey);
@@ -10869,15 +11284,15 @@ static void test_MsiGetPatchInfoEx(void)
     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
 
     RegDeleteValueA(udpatch, "LocalPackage");
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
 
     /* MSIINSTALLCONTEXT_MACHINE */
@@ -10897,7 +11312,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udprod);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udprod, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local UserData product key exists */
@@ -10912,7 +11327,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "InstallProperties", &props);
+    res = RegCreateKeyExA(udprod, "InstallProperties", 0, NULL, 0, access, NULL, &props, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* InstallProperties key exists */
@@ -10926,7 +11341,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(udprod, "Patches", &patches);
+    res = RegCreateKeyExA(udprod, "Patches", 0, NULL, 0, access, NULL, &patches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10940,7 +11355,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(patches, patch_squashed, &hpatch);
+    res = RegCreateKeyExA(patches, patch_squashed, 0, NULL, 0, access, NULL, &hpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -10957,7 +11372,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &prodkey);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &prodkey, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* local product key exists */
@@ -10971,7 +11386,7 @@ static void test_MsiGetPatchInfoEx(void)
        "Expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "Expected size to be unchanged, got %d\n", size);
 
-    res = RegCreateKeyA(prodkey, "Patches", &prodpatches);
+    res = RegCreateKeyExA(prodkey, "Patches", 0, NULL, 0, access, NULL, &prodpatches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* Patches key exists */
@@ -11004,7 +11419,7 @@ static void test_MsiGetPatchInfoEx(void)
     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &udpatch);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &udpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData Patches key exists */
@@ -11041,9 +11456,9 @@ static void test_MsiGetPatchInfoEx(void)
     ok(size == 10, "Expected 10, got %d\n", size);
 
     RegDeleteValueA(prodpatches, patch_squashed);
-    RegDeleteKeyA(prodpatches, "");
+    delete_key(prodpatches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodpatches);
-    RegDeleteKeyA(prodkey, "");
+    delete_key(prodkey, "", access & KEY_WOW64_64KEY);
     RegCloseKey(prodkey);
 
     /* UserData is sufficient for all properties
@@ -11071,15 +11486,15 @@ static void test_MsiGetPatchInfoEx(void)
     ok(size == MAX_PATH, "Expected MAX_PATH, got %d\n", size);
 
     RegDeleteValueA(udpatch, "LocalPackage");
-    RegDeleteKeyA(udpatch, "");
+    delete_key(udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udpatch);
-    RegDeleteKeyA(hpatch, "");
+    delete_key(hpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hpatch);
-    RegDeleteKeyA(patches, "");
+    delete_key(patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(patches);
-    RegDeleteKeyA(props, "");
+    delete_key(props, "", access & KEY_WOW64_64KEY);
     RegCloseKey(props);
-    RegDeleteKeyA(udprod, "");
+    delete_key(udprod, "", access & KEY_WOW64_64KEY);
     RegCloseKey(udprod);
     LocalFree(usersid);
 }
@@ -11094,11 +11509,15 @@ static void test_MsiGetPatchInfo(void)
     HKEY hkey_udpatch, hkey_udpatches, hkey_udproductpatches, hkey_udproductpatch;
     DWORD size;
     LONG res;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(patch_code, patch_squashed);
     create_test_guid(prod_code, prod_squashed);
     MultiByteToWideChar(CP_ACP, 0, patch_code, -1, patch_codeW, MAX_PATH);
 
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
+
     r = MsiGetPatchInfoA(NULL, NULL, NULL, NULL);
     ok(r == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", r);
 
@@ -11118,7 +11537,12 @@ static void test_MsiGetPatchInfo(void)
     lstrcpyA(keypath, "Software\\Classes\\Installer\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_product);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_product, NULL);
+    if (res == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        return;
+    }
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     /* product key exists */
@@ -11129,7 +11553,7 @@ static void test_MsiGetPatchInfo(void)
     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
 
-    res = RegCreateKeyA(hkey_product, "Patches", &hkey_patches);
+    res = RegCreateKeyExA(hkey_product, "Patches", 0, NULL, 0, access, NULL, &hkey_patches, NULL);
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     /* patches key exists */
@@ -11140,7 +11564,7 @@ static void test_MsiGetPatchInfo(void)
     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
 
-    res = RegCreateKeyA(hkey_patches, patch_squashed, &hkey_patch);
+    res = RegCreateKeyExA(hkey_patches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_patch, NULL);
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     /* patch key exists */
@@ -11155,7 +11579,7 @@ static void test_MsiGetPatchInfo(void)
     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Products\\");
     lstrcatA(keypath, prod_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udproduct);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udproduct, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %d\n", res);
 
     /* UserData product key exists */
@@ -11166,7 +11590,7 @@ static void test_MsiGetPatchInfo(void)
     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
 
-    res = RegCreateKeyA(hkey_udproduct, "InstallProperties", &hkey_udprops);
+    res = RegCreateKeyExA(hkey_udproduct, "InstallProperties", 0, NULL, 0, access, NULL, &hkey_udprops, NULL);
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     /* InstallProperties key exists */
@@ -11177,7 +11601,7 @@ static void test_MsiGetPatchInfo(void)
     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged, got \"%s\"\n", val);
     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
 
-    res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udpatches);
+    res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udpatches, NULL);
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     /* UserData Patches key exists */
@@ -11188,10 +11612,10 @@ static void test_MsiGetPatchInfo(void)
     ok(!lstrcmpA(val, "apple"), "expected val to be unchanged got \"%s\"\n", val);
     ok(size == MAX_PATH, "expected size to be unchanged got %u\n", size);
 
-    res = RegCreateKeyA(hkey_udproduct, "Patches", &hkey_udproductpatches);
+    res = RegCreateKeyExA(hkey_udproduct, "Patches", 0, NULL, 0, access, NULL, &hkey_udproductpatches, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
-    res = RegCreateKeyA(hkey_udproductpatches, patch_squashed, &hkey_udproductpatch);
+    res = RegCreateKeyExA(hkey_udproductpatches, patch_squashed, 0, NULL, 0, access, NULL, &hkey_udproductpatch, NULL);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     /* UserData product patch key exists */
@@ -11206,7 +11630,7 @@ static void test_MsiGetPatchInfo(void)
     lstrcatA(keypath, "\\UserData\\S-1-5-18\\Patches\\");
     lstrcatA(keypath, patch_squashed);
 
-    res = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey_udpatch);
+    res = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, access, NULL, &hkey_udpatch, NULL);
     ok(res == ERROR_SUCCESS, "expected ERROR_SUCCESS got %d\n", res);
 
     res = RegSetValueExA(hkey_udpatch, "LocalPackage", 0, REG_SZ, (const BYTE *)"c:\\test.msp", 12);
@@ -11241,23 +11665,23 @@ static void test_MsiGetPatchInfo(void)
     ok(valW[0], "expected > 0 got %u\n", valW[0]);
     ok(size == 11, "expected 11 got %u\n", size);
 
-    RegDeleteKeyA(hkey_udproductpatch, "");
+    delete_key(hkey_udproductpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udproductpatch);
-    RegDeleteKeyA(hkey_udproductpatches, "");
+    delete_key(hkey_udproductpatches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udproductpatches);
-    RegDeleteKeyA(hkey_udpatch, "");
+    delete_key(hkey_udpatch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udpatch);
-    RegDeleteKeyA(hkey_patches, "");
+    delete_key(hkey_patches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_patches);
-    RegDeleteKeyA(hkey_product, "");
+    delete_key(hkey_product, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_product);
-    RegDeleteKeyA(hkey_patch, "");
+    delete_key(hkey_patch, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_patch);
-    RegDeleteKeyA(hkey_udpatches, "");
+    delete_key(hkey_udpatches, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udpatches);
-    RegDeleteKeyA(hkey_udprops, "");
+    delete_key(hkey_udprops, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udprops);
-    RegDeleteKeyA(hkey_udproduct, "");
+    delete_key(hkey_udproduct, "", access & KEY_WOW64_64KEY);
     RegCloseKey(hkey_udproduct);
 }
 
@@ -11271,16 +11695,26 @@ static void test_MsiEnumProducts(void)
     char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
     char *usersid;
     HKEY key1, key2, key3;
+    REGSAM access = KEY_ALL_ACCESS;
 
     create_test_guid(product1, product_squashed1);
     create_test_guid(product2, product_squashed2);
     create_test_guid(product3, product_squashed3);
-    get_user_sid(&usersid);
+    usersid = get_user_sid();
+
+    if (is_wow64)
+        access |= KEY_WOW64_64KEY;
 
     strcpy(keypath1, "Software\\Classes\\Installer\\Products\\");
     strcat(keypath1, product_squashed1);
 
-    r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath1, &key1);
+    r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL);
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip("Not enough rights to perform tests\n");
+        LocalFree(usersid);
+        return;
+    }
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     strcpy(keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\");
@@ -11288,7 +11722,7 @@ static void test_MsiEnumProducts(void)
     strcat(keypath2, "\\Installer\\Products\\");
     strcat(keypath2, product_squashed2);
 
-    r = RegCreateKeyA(HKEY_LOCAL_MACHINE, keypath2, &key2);
+    r = RegCreateKeyExA(HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
 
     strcpy(keypath3, "Software\\Microsoft\\Installer\\Products\\");
@@ -11325,8 +11759,8 @@ static void test_MsiEnumProducts(void)
     ok(found2, "product2 not found\n");
     ok(found3, "product3 not found\n");
 
-    RegDeleteKeyA(key1, "");
-    RegDeleteKeyA(key2, "");
+    delete_key(key1, "", access & KEY_WOW64_64KEY);
+    delete_key(key2, "", access & KEY_WOW64_64KEY);
     RegDeleteKeyA(key3, "");
     RegCloseKey(key1);
     RegCloseKey(key2);
@@ -11334,10 +11768,382 @@ static void test_MsiEnumProducts(void)
     LocalFree(usersid);
 }
 
+static void test_MsiGetFileSignatureInformation(void)
+{
+    HRESULT hr;
+    const CERT_CONTEXT *cert;
+    DWORD len;
+
+    hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
+    todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr);
+
+    create_file( "signature.bin", "signature", sizeof("signature") );
+
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len );
+    ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr);
+
+    cert = (const CERT_CONTEXT *)0xdeadbeef;
+    hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len );
+    todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr);
+    ok(cert == NULL, "got %p\n", cert);
+
+    DeleteFileA( "signature.bin" );
+}
+
+static void test_MsiEnumProductsEx(void)
+{
+    UINT r;
+    DWORD len, index;
+    MSIINSTALLCONTEXT context;
+    char product0[39], product1[39], product2[39], product3[39], guid[39], sid[128];
+    char product_squashed1[33], product_squashed2[33], product_squashed3[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH], keypath3[MAX_PATH];
+    HKEY key1 = NULL, key2 = NULL, key3 = NULL;
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+
+    if (!pMsiEnumProductsExA)
+    {
+        win_skip("MsiEnumProductsExA not implemented\n");
+        return;
+    }
+
+    create_test_guid( product0, NULL );
+    create_test_guid( product1, product_squashed1 );
+    create_test_guid( product2, product_squashed2 );
+    create_test_guid( product3, product_squashed3 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Classes\\Installer\\Products\\" );
+    strcat( keypath1, product_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\Managed\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Installer\\Products\\" );
+    strcat( keypath2, product_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath3, usersid );
+    strcat( keypath3, "\\Software\\Microsoft\\Installer\\Products\\" );
+    strcat( keypath3, product_squashed3 );
+
+    r = RegCreateKeyExA( HKEY_USERS, keypath3, 0, NULL, 0, access, NULL, &key3, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, NULL, 0, 0, NULL, NULL, NULL, &len );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+
+    r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( product0, NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( product0, usersid, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_NO_MORE_ITEMS, "got %u\n", r );
+    ok( len == sizeof(sid), "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    sid[0] = 0;
+    len = 0;
+    r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_USERUNMANAGED, 0, NULL, NULL, sid, &len );
+    ok( r == ERROR_MORE_DATA, "got %u\n", r );
+    ok( len, "length unchanged\n" );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, NULL, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, usersid, MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    r = pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, 0, guid, &context, sid, &len );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    ok( guid[0], "empty guid\n" );
+    ok( context != 0xdeadbeef, "context unchanged\n" );
+    ok( !len, "got %u\n", len );
+    ok( !sid[0], "got %s\n", sid );
+
+    index = 0;
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    while (!pMsiEnumProductsExA( NULL, "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
+    {
+        if (!strcmp( product1, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
+            ok( !sid[0], "got \"%s\"\n", sid );
+            ok( !len, "unexpected length %u\n", len );
+        }
+        if (!strcmp( product2, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+        }
+        if (!strcmp( product3, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+        }
+        index++;
+        guid[0] = 0;
+        context = 0xdeadbeef;
+        sid[0] = 0;
+        len = sizeof(sid);
+    }
+
+done:
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    delete_key( key3, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    RegCloseKey( key3 );
+    LocalFree( usersid );
+}
+
+static void test_MsiEnumComponents(void)
+{
+    UINT r;
+    int found1, found2;
+    DWORD index;
+    char comp1[39], comp2[39], guid[39];
+    char comp_squashed1[33], comp_squashed2[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH];
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+    HKEY key1 = NULL, key2 = NULL;
+
+    create_test_guid( comp1, comp_squashed1 );
+    create_test_guid( comp2, comp_squashed2 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath1, "S-1-5-18\\Components\\" );
+    strcat( keypath1, comp_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Components\\" );
+    strcat( keypath2, comp_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+
+    r = MsiEnumComponentsA( 0, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    index = 0;
+    guid[0] = 0;
+    found1 = found2 = 0;
+    while (!MsiEnumComponentsA( index, guid ))
+    {
+        if (!strcmp( guid, comp1 )) found1 = 1;
+        if (!strcmp( guid, comp2 )) found2 = 1;
+        ok( guid[0], "empty guid\n" );
+        guid[0] = 0;
+        index++;
+    }
+    ok( found1, "comp1 not found\n" );
+    ok( found2, "comp2 not found\n" );
+
+done:
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    LocalFree( usersid );
+}
+
+static void test_MsiEnumComponentsEx(void)
+{
+    UINT r;
+    int found1, found2;
+    DWORD len, index;
+    MSIINSTALLCONTEXT context;
+    char comp1[39], comp2[39], guid[39], sid[128];
+    char comp_squashed1[33], comp_squashed2[33];
+    char keypath1[MAX_PATH], keypath2[MAX_PATH];
+    HKEY key1 = NULL, key2 = NULL;
+    REGSAM access = KEY_ALL_ACCESS;
+    char *usersid = get_user_sid();
+
+    if (!pMsiEnumComponentsExA)
+    {
+        win_skip( "MsiEnumComponentsExA not implemented\n" );
+        return;
+    }
+    create_test_guid( comp1, comp_squashed1 );
+    create_test_guid( comp2, comp_squashed2 );
+
+    if (is_wow64) access |= KEY_WOW64_64KEY;
+
+    strcpy( keypath1, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath1, "S-1-5-18\\Components\\" );
+    strcat( keypath1, comp_squashed1 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath1, 0, NULL, 0, access, NULL, &key1, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    strcpy( keypath2, "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\" );
+    strcat( keypath2, usersid );
+    strcat( keypath2, "\\Components\\" );
+    strcat( keypath2, comp_squashed2 );
+
+    r = RegCreateKeyExA( HKEY_LOCAL_MACHINE, keypath2, 0, NULL, 0, access, NULL, &key2, NULL );
+    if (r == ERROR_ACCESS_DENIED)
+    {
+        skip( "insufficient rights\n" );
+        goto done;
+    }
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+    r = RegSetValueExA( key2, comp_squashed2, 0, REG_SZ, (const BYTE *)"c:\\doesnotexist",
+                        sizeof("c:\\doesnotexist"));
+    ok( r == ERROR_SUCCESS, "got %u\n", r );
+
+    index = 0;
+    guid[0] = 0;
+    context = 0xdeadbeef;
+    sid[0] = 0;
+    len = sizeof(sid);
+    found1 = found2 = 0;
+    while (!pMsiEnumComponentsExA( "S-1-1-0", MSIINSTALLCONTEXT_ALL, index, guid, &context, sid, &len ))
+    {
+        if (!strcmp( comp1, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_MACHINE, "got %u\n", context );
+            ok( !sid[0], "got \"%s\"\n", sid );
+            ok( !len, "unexpected length %u\n", len );
+            found1 = 1;
+        }
+        if (!strcmp( comp2, guid ))
+        {
+            ok( context == MSIINSTALLCONTEXT_USERUNMANAGED, "got %u\n", context );
+            ok( sid[0], "empty sid\n" );
+            ok( len == strlen(sid), "unexpected length %u\n", len );
+            found2 = 1;
+        }
+        index++;
+        guid[0] = 0;
+        context = 0xdeadbeef;
+        sid[0] = 0;
+        len = sizeof(sid);
+    }
+    ok( found1, "comp1 not found\n" );
+    ok( found2, "comp2 not found\n" );
+
+    r = pMsiEnumComponentsExA( NULL, 0, 0, NULL, NULL, NULL, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+    r = pMsiEnumComponentsExA( NULL, MSIINSTALLCONTEXT_ALL, 0, NULL, NULL, sid, NULL );
+    ok( r == ERROR_INVALID_PARAMETER, "got %u\n", r );
+
+done:
+    RegDeleteValueA( key2, comp_squashed2 );
+    delete_key( key1, "", access );
+    delete_key( key2, "", access );
+    RegCloseKey( key1 );
+    RegCloseKey( key2 );
+    LocalFree( usersid );
+}
+
 START_TEST(msi)
 {
     init_functionpointers();
 
+    if (pIsWow64Process)
+        pIsWow64Process(GetCurrentProcess(), &is_wow64);
+
     test_usefeature();
     test_null();
     test_getcomponentpath();
@@ -11363,7 +12169,10 @@ START_TEST(msi)
         test_MsiGetPatchInfoEx();
         test_MsiGetPatchInfo();
         test_MsiEnumProducts();
+        test_MsiEnumProductsEx();
+        test_MsiEnumComponents();
+        test_MsiEnumComponentsEx();
     }
-
     test_MsiGetFileVersion();
+    test_MsiGetFileSignatureInformation();
 }