[9/9] msi: Properly remove the product code from the ugrade codes key.
Hans Leidekker
hans at codeweavers.com
Fri Nov 4 07:28:11 CDT 2016
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/msi/action.c | 47 +++++++++++++++++++++++++++++++++++--------
dlls/msi/msipriv.h | 1 +
dlls/msi/registry.c | 12 +++++++++++
dlls/msi/tests/install.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 104 insertions(+), 8 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 751462b..4d7e8b9 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -5285,9 +5285,46 @@ static UINT msi_unpublish_icons( MSIPACKAGE *package )
return ERROR_SUCCESS;
}
+static void remove_product_upgrade_code( MSIPACKAGE *package )
+{
+ WCHAR *code, product[SQUASHED_GUID_SIZE];
+ HKEY hkey;
+ LONG res;
+ DWORD count;
+
+ squash_guid( package->ProductCode, product );
+ if (!(code = msi_dup_property( package->db, szUpgradeCode )))
+ {
+ WARN( "upgrade code not found\n" );
+ return;
+ }
+ if (!MSIREG_OpenUpgradeCodesKey( code, &hkey, FALSE ))
+ {
+ RegDeleteValueW( hkey, product );
+ res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL, NULL );
+ RegCloseKey( hkey );
+ if (!res && !count) MSIREG_DeleteUpgradeCodesKey( code );
+ }
+ if (!MSIREG_OpenUserUpgradeCodesKey( code, &hkey, FALSE ))
+ {
+ RegDeleteValueW( hkey, product );
+ res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL, NULL );
+ RegCloseKey( hkey );
+ if (!res && !count) MSIREG_DeleteUserUpgradeCodesKey( code );
+ }
+ if (!MSIREG_OpenClassesUpgradeCodesKey( code, &hkey, FALSE ))
+ {
+ RegDeleteValueW( hkey, product );
+ res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL, NULL );
+ RegCloseKey( hkey );
+ if (!res && !count) MSIREG_DeleteClassesUpgradeCodesKey( code );
+ }
+
+ msi_free( code );
+}
+
static UINT ACTION_UnpublishProduct(MSIPACKAGE *package)
{
- WCHAR *upgrade;
MSIPATCHINFO *patch;
MSIREG_DeleteProductKey(package->ProductCode);
@@ -5299,13 +5336,7 @@ static UINT ACTION_UnpublishProduct(MSIPACKAGE *package)
MSIREG_DeleteUserProductKey(package->ProductCode);
MSIREG_DeleteUserFeaturesKey(package->ProductCode);
- upgrade = msi_dup_property(package->db, szUpgradeCode);
- if (upgrade)
- {
- MSIREG_DeleteUserUpgradeCodesKey(upgrade);
- MSIREG_DeleteClassesUpgradeCodesKey(upgrade);
- msi_free(upgrade);
- }
+ remove_product_upgrade_code( package );
LIST_FOR_EACH_ENTRY(patch, &package->patches, MSIPATCHINFO, entry)
{
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index a2939b3..56ba725 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -919,6 +919,7 @@ extern UINT MSIREG_DeleteUserDataProductKey(LPCWSTR, MSIINSTALLCONTEXT) DECLSPEC
extern UINT MSIREG_DeleteUserFeaturesKey(LPCWSTR szProduct) DECLSPEC_HIDDEN;
extern UINT MSIREG_DeleteUserDataComponentKey(LPCWSTR szComponent, LPCWSTR szUserSid) DECLSPEC_HIDDEN;
extern UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode) DECLSPEC_HIDDEN;
+extern UINT MSIREG_DeleteUpgradeCodesKey(const WCHAR *) DECLSPEC_HIDDEN;
extern UINT MSIREG_DeleteClassesUpgradeCodesKey(LPCWSTR szUpgradeCode) DECLSPEC_HIDDEN;
extern UINT MSIREG_OpenClassesUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL create) DECLSPEC_HIDDEN;
extern UINT MSIREG_DeleteLocalClassesProductKey(LPCWSTR szProductCode) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/registry.c b/dlls/msi/registry.c
index 8852f57..1f87cbb 100644
--- a/dlls/msi/registry.c
+++ b/dlls/msi/registry.c
@@ -940,6 +940,18 @@ UINT MSIREG_OpenUserUpgradeCodesKey(LPCWSTR szUpgradeCode, HKEY* key, BOOL creat
return RegOpenKeyW(HKEY_CURRENT_USER, keypath, key);
}
+UINT MSIREG_DeleteUpgradeCodesKey( const WCHAR *code )
+{
+ WCHAR squashed_code[SQUASHED_GUID_SIZE], keypath[0x200];
+
+ if (!squash_guid( code, squashed_code )) return ERROR_FUNCTION_FAILED;
+ TRACE( "%s squashed %s\n", debugstr_w(code), debugstr_w(squashed_code) );
+
+ strcpyW( keypath, szInstaller_UpgradeCodes );
+ strcatW( keypath, squashed_code );
+ return RegDeleteTreeW( HKEY_LOCAL_MACHINE, keypath );
+}
+
UINT MSIREG_DeleteUserUpgradeCodesKey(LPCWSTR szUpgradeCode)
{
WCHAR squashed_uc[SQUASHED_GUID_SIZE], keypath[0x200];
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index e1113e7..a377184 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -5888,6 +5888,57 @@ static void test_shared_component(void)
DeleteFileA(msifile2);
}
+static void test_remove_upgrade_code(void)
+{
+ UINT r;
+ LONG res;
+ HKEY hkey;
+ REGSAM access = KEY_ALL_ACCESS;
+ DWORD type, size;
+ char buf[1];
+
+ if (is_process_limited())
+ {
+ skip( "process is limited\n" );
+ return;
+ }
+ if (is_wow64) access |= KEY_WOW64_64KEY;
+
+ create_test_files();
+ create_database( msifile, icon_base_tables, sizeof(icon_base_tables)/sizeof(icon_base_tables[0]) );
+
+ MsiSetInternalUI( INSTALLUILEVEL_NONE, NULL );
+
+ r = MsiInstallProductA( msifile, "FULL=1" );
+ ok(r == ERROR_SUCCESS, "got %u\n", r);
+
+ res = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2",
+ 0, access, &hkey );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+
+ type = 0xdeadbeef;
+ buf[0] = 0x55;
+ size = sizeof(buf);
+ res = RegQueryValueExA( hkey, "94A88FD7F6998CE40A22FB59F6B9C2BB", NULL, &type, (BYTE *)buf, &size );
+ ok( res == ERROR_SUCCESS, "got %d\n", res );
+ ok( type == REG_SZ, "got %u\n", type );
+ ok( size == 1, "got %u\n", size );
+ ok( !buf[0], "wrong data\n" );
+ RegCloseKey( hkey );
+
+ r = MsiInstallProductA( msifile, "REMOVE=ALL" );
+ ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+ res = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UpgradeCodes\\51AAE0C44620A5E4788506E91F249BD2",
+ 0, access, &hkey );
+ ok( res == ERROR_FILE_NOT_FOUND, "got %d\n", res );
+
+ RemoveDirectoryA( "msitest" );
+ DeleteFileA( msifile );
+}
+
START_TEST(install)
{
DWORD len;
@@ -5974,6 +6025,7 @@ START_TEST(install)
test_mixed_package();
test_volume_props();
test_shared_component();
+ test_remove_upgrade_code();
DeleteFileA(log_file);
--
2.1.4
More information about the wine-patches
mailing list