msi: Put the uninstall key for 32-bit packages under Wow6432Node on 64-bit.

Hans Leidekker hans at codeweavers.com
Tue Oct 5 09:37:33 CDT 2010


---
 dlls/msi/action.c        |    4 +-
 dlls/msi/msipriv.h       |    4 +-
 dlls/msi/package.c       |    2 +-
 dlls/msi/registry.c      |   34 ++++++++++---
 dlls/msi/tests/install.c |  119 +++++++++++++++++++++++++++++++++++++---------
 5 files changed, 128 insertions(+), 35 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 5fd371e..b17c074 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -4759,7 +4759,7 @@ static UINT ACTION_RegisterProduct(MSIPACKAGE *package)
     if (!msi_check_publish(package))
         return ERROR_SUCCESS;
 
-    rc = MSIREG_OpenUninstallKey(package->ProductCode, &hkey, TRUE);
+    rc = MSIREG_OpenUninstallKey(package, &hkey, TRUE);
     if (rc != ERROR_SUCCESS)
         return rc;
 
@@ -4839,7 +4839,7 @@ static UINT msi_unpublish_product(MSIPACKAGE *package, WCHAR *remove)
 
     MSIREG_DeleteProductKey(package->ProductCode);
     MSIREG_DeleteUserDataProductKey(package->ProductCode);
-    MSIREG_DeleteUninstallKey(package->ProductCode);
+    MSIREG_DeleteUninstallKey(package);
 
     if (package->Context == MSIINSTALLCONTEXT_MACHINE)
     {
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 2e87918..9149aa6 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -788,8 +788,8 @@ extern BOOL unsquash_guid(LPCWSTR in, LPWSTR out);
 extern BOOL squash_guid(LPCWSTR in, LPWSTR out);
 extern BOOL encode_base85_guid(GUID *,LPWSTR);
 extern BOOL decode_base85_guid(LPCWSTR,GUID*);
-extern UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct);
+extern UINT MSIREG_OpenUninstallKey(MSIPACKAGE *package, HKEY *key, BOOL create);
+extern UINT MSIREG_DeleteUninstallKey(MSIPACKAGE *package);
 extern UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid,
                                   MSIINSTALLCONTEXT context, HKEY* key, BOOL create);
 extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index ecd2632..2b44e64 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -418,7 +418,7 @@ static UINT set_installed_prop( MSIPACKAGE *package )
     HKEY hkey = 0;
     UINT r;
 
-    r = MSIREG_OpenUninstallKey( package->ProductCode, &hkey, FALSE );
+    r = MSIREG_OpenUninstallKey( package, &hkey, FALSE );
     if (r == ERROR_SUCCESS)
     {
         RegCloseKey( hkey );
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index 2a84e11..f3580d2 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -40,6 +40,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 
+static const BOOL is_64bit = sizeof(void *) > sizeof(int);
 
 /* 
  * This module will be all the helper functions for registry access by the
@@ -103,6 +104,15 @@ static const WCHAR szUninstall_fmt[] = {
 'U','n','i','n','s','t','a','l','l','\\',
 '%','s',0 };
 
+static const WCHAR szUninstall_32node_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'W','o','w','6','4','3','2','N','o','d','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'U','n','i','n','s','t','a','l','l','\\',
+'%','s',0 };
+
 static const WCHAR szUserProduct[] = {
 'S','o','f','t','w','a','r','e','\\',
 'M','i','c','r','o','s','o','f','t','\\',
@@ -509,28 +519,36 @@ static UINT get_user_sid(LPWSTR *usersid)
     return ERROR_SUCCESS;
 }
 
-UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+UINT MSIREG_OpenUninstallKey(MSIPACKAGE *package, HKEY *key, BOOL create)
 {
     UINT rc;
     WCHAR keypath[0x200];
-    TRACE("%s\n",debugstr_w(szProduct));
 
-    sprintfW(keypath,szUninstall_fmt,szProduct);
+    TRACE("%s\n", debugstr_w(package->ProductCode));
+
+    if (is_64bit && package->platform == PLATFORM_INTEL)
+        sprintfW(keypath, szUninstall_32node_fmt, package->ProductCode);
+    else
+        sprintfW(keypath, szUninstall_fmt, package->ProductCode);
 
     if (create)
-        rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+        rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, KEY_ALL_ACCESS, NULL, key, NULL);
     else
-        rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+        rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, KEY_ALL_ACCESS, key);
 
     return rc;
 }
 
-UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct)
+UINT MSIREG_DeleteUninstallKey(MSIPACKAGE *package)
 {
     WCHAR keypath[0x200];
-    TRACE("%s\n",debugstr_w(szProduct));
 
-    sprintfW(keypath,szUninstall_fmt,szProduct);
+    TRACE("%s\n", debugstr_w(package->ProductCode));
+
+    if (is_64bit && package->platform == PLATFORM_INTEL)
+        sprintfW(keypath, szUninstall_32node_fmt, package->ProductCode);
+    else
+        sprintfW(keypath, szUninstall_fmt, package->ProductCode);
 
     return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
 }
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 7e60cb5..0f98535 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -54,6 +54,7 @@ static BOOL (WINAPI *pSRRemoveRestorePoint)(DWORD);
 static BOOL (WINAPI *pSRSetRestorePointA)(RESTOREPOINTINFOA*, STATEMGRSTATUS*);
 
 static BOOL on_win9x = FALSE;
+static const BOOL is_64bit = sizeof(void *) > sizeof(int);
 
 static const char *msifile = "msitest.msi";
 static const char *msifile2 = "winetest2.msi";
@@ -5009,10 +5010,12 @@ static void test_publish_registerproduct(void)
     char temp[MAX_PATH];
     char keypath[MAX_PATH];
     REGSAM access = KEY_ALL_ACCESS;
-    BOOL wow64;
+    BOOL wow64 = FALSE;
 
     static const CHAR uninstall[] = "Software\\Microsoft\\Windows\\CurrentVersion"
                                     "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
+    static const CHAR uninstall_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion"
+                                           "\\Uninstall\\{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
     static const CHAR userdata[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
                                    "\\UserData\\%s\\Products\\84A88FD7F6998CE40A22FB59F6B9C2BB";
     static const CHAR ugkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Installer"
@@ -5056,8 +5059,16 @@ static void test_publish_registerproduct(void)
     res = RegOpenKeyA(HKEY_CURRENT_USER, userugkey, &hkey);
     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
 
-    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, access, &hkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
@@ -5155,8 +5166,16 @@ static void test_publish_registerproduct(void)
     res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, userugkey, 0, access, &hkey);
     ok(res == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", res);
 
-    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, access, &hkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall_32node, 0, KEY_ALL_ACCESS, &hkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, uninstall, 0, KEY_ALL_ACCESS, &hkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_DEL_REG_STR(hkey, "DisplayName", "MSITEST");
     CHECK_DEL_REG_STR(hkey, "DisplayVersion", "1.1.1");
@@ -5555,7 +5574,7 @@ static void test_publish_publishfeatures(void)
     RegCloseKey(hkey);
 
     sprintf(keypath, udpath, usersid);
-    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
+    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82 at JU1j_KE");
@@ -5590,7 +5609,7 @@ static void test_publish_publishfeatures(void)
     RegCloseKey(hkey);
 
     sprintf(keypath, udpath, "S-1-5-18");
-    res = RegOpenKeyA(HKEY_LOCAL_MACHINE, keypath, &hkey);
+    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, keypath, 0, access, &hkey);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
     CHECK_REG_STR(hkey, "feature", "VGtfp^p+,?82 at JU1j_KE");
@@ -5905,14 +5924,15 @@ static void test_publish(void)
 {
     UINT r;
     LONG res;
-    HKEY uninstall, prodkey;
+    HKEY uninstall, prodkey, uninstall_32node = NULL;
     INSTALLSTATE state;
     CHAR prodcode[] = "{7DF88A48-996F-4EC8-A022-BF956F9B2CBB}";
     char date[MAX_PATH], temp[MAX_PATH];
     REGSAM access = KEY_ALL_ACCESS;
-    BOOL wow64;
+    BOOL wow64 = FALSE;
 
     static const CHAR subkey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
+    static const CHAR subkey_32node[] = "Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
 
     if (!pMsiQueryComponentStateA)
     {
@@ -5931,9 +5951,15 @@ static void test_publish(void)
     if (pIsWow64Process && pIsWow64Process(GetCurrentProcess(), &wow64) && wow64)
         access |= KEY_WOW64_64KEY;
 
-    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, access, &uninstall);
+    res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey, 0, KEY_ALL_ACCESS, &uninstall);
     ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
 
+    if (is_64bit)
+    {
+        res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, subkey_32node, 0, KEY_ALL_ACCESS, &uninstall_32node);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+
     CreateDirectoryA("msitest", NULL);
     create_file("msitest\\maximus", 500);
 
@@ -6006,8 +6032,16 @@ static void test_publish(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);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6080,8 +6114,16 @@ static void test_publish(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6155,8 +6197,16 @@ static void test_publish(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6207,8 +6257,16 @@ static void test_publish(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6259,8 +6317,16 @@ static void test_publish(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6334,8 +6400,16 @@ static void test_publish(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok(state == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", state);
 
-    res = RegOpenKeyExA(uninstall, prodcode, 0, access, &prodkey);
-    ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    if (is_64bit && !wow64)
+    {
+        res = RegOpenKeyExA(uninstall_32node, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
+    else
+    {
+        res = RegOpenKeyExA(uninstall, prodcode, 0, KEY_ALL_ACCESS, &prodkey);
+        ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", res);
+    }
 
     CHECK_REG_STR(prodkey, "DisplayName", "MSITEST");
     CHECK_REG_STR(prodkey, "DisplayVersion", "1.1.1");
@@ -6394,6 +6468,7 @@ static void test_publish(void)
 
 error:
     RegCloseKey(uninstall);
+    RegCloseKey(uninstall_32node);
     DeleteFile(msifile);
     DeleteFile("msitest\\maximus");
     RemoveDirectory("msitest");
-- 
1.7.1







More information about the wine-patches mailing list