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

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2016-11-04 13:28:11 +01:00 committed by Alexandre Julliard
parent d4814f98c8
commit d17d54e16d
4 changed files with 104 additions and 8 deletions

View File

@ -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)
{

View File

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

View File

@ -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];

View File

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