From 52aab76eb23d1953c80b3a2b7730dd934e5d5eab Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 5 Oct 2010 16:37:33 +0200 Subject: [PATCH] msi: Put the uninstall key for 32-bit packages under Wow6432Node on 64-bit. --- 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 5fd371e4b6..b17c07414a 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 2e8791853e..9149aa618f 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 ecd263237f..2b44e6460d 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 2a84e11be6..f3580d2245 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 7e60cb54ee..0f985354fd 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@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@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"); -- 2.32.0.93.g670b81a890