msi: Improve installation with no argument of already installed product.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2017-10-20 22:18:41 +02:00 committed by Alexandre Julliard
parent c41b8ce5c3
commit 808f3158bb
3 changed files with 41 additions and 45 deletions

View File

@ -1740,7 +1740,7 @@ static BOOL process_overrides( MSIPACKAGE *package, int level )
ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN );
ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED );
if (ret && !package->full_reinstall)
if (ret)
msi_set_property( package->db, szPreselected, szOne, -1 );
return ret;
@ -1795,7 +1795,34 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
level = msi_get_property_int(package->db, szInstallLevel, 1);
if (!msi_get_property_int( package->db, szPreselected, 0 ))
if (msi_get_property_int( package->db, szPreselected, 0 ))
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (!is_feature_selected( feature, level )) continue;
if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{
if (feature->Installed == INSTALLSTATE_ABSENT)
{
feature->Action = INSTALLSTATE_UNKNOWN;
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
}
else
{
feature->Action = feature->Installed;
feature->ActionRequest = feature->Installed;
}
}
}
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (feature->Feature_Parent) continue;
disable_children( feature, level );
follow_parent( feature );
}
}
else if (!msi_get_property_int( package->db, szInstalled, 0 ))
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
@ -1828,33 +1855,6 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
follow_parent( feature );
}
}
else /* preselected */
{
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (!is_feature_selected( feature, level )) continue;
if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{
if (feature->Installed == INSTALLSTATE_ABSENT)
{
feature->Action = INSTALLSTATE_UNKNOWN;
feature->ActionRequest = INSTALLSTATE_UNKNOWN;
}
else
{
feature->Action = feature->Installed;
feature->ActionRequest = feature->Installed;
}
}
}
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
{
if (feature->Feature_Parent) continue;
disable_children( feature, level );
follow_parent( feature );
}
}
/* now we want to set component state based based on feature state */
LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
@ -1903,6 +1903,14 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
else
component->hasLocalFeature = 1;
break;
case INSTALLSTATE_UNKNOWN:
if (feature->Installed == INSTALLSTATE_ADVERTISED)
component->hasAdvertisedFeature = 1;
if (feature->Installed == INSTALLSTATE_SOURCE)
component->hasSourceFeature = 1;
if (feature->Installed == INSTALLSTATE_LOCAL)
component->hasLocalFeature = 1;
break;
default:
break;
}
@ -7965,7 +7973,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
{
static const WCHAR szDisableRollback[] = {'D','I','S','A','B','L','E','R','O','L','L','B','A','C','K',0};
static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
WCHAR *reinstall, *remove, *patch, *productcode, *action;
WCHAR *reinstall = NULL, *productcode, *action;
UINT rc;
DWORD len = 0;
@ -8012,15 +8020,6 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
msi_apply_transforms( package );
msi_apply_patches( package );
patch = msi_dup_property( package->db, szPatch );
remove = msi_dup_property( package->db, szRemove );
reinstall = msi_dup_property( package->db, szReinstall );
if (msi_get_property_int( package->db, szInstalled, 0 ) && !remove && !reinstall && !patch)
{
TRACE("setting REINSTALL property to ALL\n");
msi_set_property( package->db, szReinstall, szAll, -1 );
package->full_reinstall = 1;
}
if (msi_get_property( package->db, szAction, NULL, &len ))
msi_set_property( package->db, szAction, szINSTALL, -1 );
action = msi_dup_property( package->db, szAction );
@ -8067,14 +8066,12 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
/* finish up running custom actions */
ACTION_FinishCustomActions(package);
if (package->need_rollback && !reinstall)
if (package->need_rollback && !(reinstall = msi_dup_property( package->db, szReinstall )))
{
WARN("installation failed, running rollback script\n");
execute_script( package, SCRIPT_ROLLBACK );
}
msi_free( reinstall );
msi_free( remove );
msi_free( patch );
msi_free( action );
if (rc == ERROR_SUCCESS && package->need_reboot_at_end)

View File

@ -445,7 +445,6 @@ typedef struct tagMSIPACKAGE
unsigned char need_reboot_at_end : 1;
unsigned char need_reboot_now : 1;
unsigned char need_rollback : 1;
unsigned char full_reinstall : 1;
} MSIPACKAGE;
typedef struct tagMSIPREVIEW

View File

@ -3576,7 +3576,7 @@ static void test_states(void)
test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE );
test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
MsiCloseHandle(hpkg);
@ -3652,7 +3652,7 @@ static void test_states(void)
test_component_states( __LINE__, hpkg, "phi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "chi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "psi", ERROR_SUCCESS, INSTALLSTATE_SOURCE, INSTALLSTATE_UNKNOWN, FALSE );
test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, TRUE );
test_component_states( __LINE__, hpkg, "upsilon", ERROR_SUCCESS, INSTALLSTATE_LOCAL, INSTALLSTATE_LOCAL, FALSE );
MsiCloseHandle(hpkg);