Hans Leidekker : msi: Properly remove the product code from the ugrade codes key.

Alexandre Julliard julliard at winehq.org
Fri Nov 4 15:15:54 CDT 2016


Module: wine
Branch: master
Commit: d17d54e16d5c3e6a33015bc6675e6554e70902c0
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d17d54e16d5c3e6a33015bc6675e6554e70902c0

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Fri Nov  4 13:28:11 2016 +0100

msi: Properly remove the product code from the ugrade codes key.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);
 




More information about the wine-cvs mailing list