diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 9407d365202..bba59368150 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -2023,13 +2023,21 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) component->ActionRequest = INSTALLSTATE_UNKNOWN; } - TRACE("component %s (installed %d request %d action %d)\n", - debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action); - if (component->Action == INSTALLSTATE_LOCAL || component->Action == INSTALLSTATE_SOURCE) component->num_clients++; else if (component->Action == INSTALLSTATE_ABSENT) + { component->num_clients--; + + if (component->num_clients > 0) + { + TRACE("multiple clients uses %s - disallowing uninstallation\n", debugstr_w(component->Component)); + component->Action = INSTALLSTATE_UNKNOWN; + } + } + + TRACE("component %s (installed %d request %d action %d)\n", + debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action); } return ERROR_SUCCESS; diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index 9c8652b353c..d3d8f91306c 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -1209,7 +1209,9 @@ static const char shc_custom_action_dat[] = "Action\tType\tSource\tTarget\tISComments\n" "s72\ti2\tS64\tS0\tS255\n" "CustomAction\tAction\n" - "TestComponentAction\t19\t\twrong component action on install\t\n"; + "TestComponentAction\t19\t\twrong component action on install\t\n" + "TestDisallowedAction\t19\t\twrong component action on disallowed remove\t\n" + "TestRemoveAction\t19\t\twrong component action on remove\t\n"; static const char shc_install_exec_seq_dat[] = "Action\tCondition\tSequence\n" @@ -1219,6 +1221,27 @@ static const char shc_install_exec_seq_dat[] = "CostInitialize\t\t200\n" "FileCost\t\t300\n" "CostFinalize\t\t600\n" + "TestDisallowedAction\tREMOVE AND ($sharedcomponent <> -1)\t700\n" + "InstallValidate\t\t900\n" + "InstallInitialize\t\t1200\n" + "ProcessComponents\t\t1300\n" + "RemoveFiles\t\t1400\n" + "InstallFiles\t\t1500\n" + "TestComponentAction\tNOT REMOVE AND ($sharedcomponent <> 3)\t1600\n" + "RegisterProduct\t\t1700\n" + "PublishFeatures\t\t1800\n" + "PublishProduct\t\t1900\n" + "InstallFinalize\t\t2000\n"; + +static const char shc2_install_exec_seq_dat[] = + "Action\tCondition\tSequence\n" + "s72\tS255\tI2\n" + "InstallExecuteSequence\tAction\n" + "LaunchConditions\t\t100\n" + "CostInitialize\t\t200\n" + "FileCost\t\t300\n" + "CostFinalize\t\t600\n" + "TestRemoveAction\tREMOVE AND ($sharedcomponent <> 2)\t700\n" "InstallValidate\t\t900\n" "InstallInitialize\t\t1200\n" "ProcessComponents\t\t1300\n" @@ -1974,7 +1997,7 @@ static const msi_table shc2_tables[] = ADD_TABLE(shc_feature), ADD_TABLE(shc_feature_comp), ADD_TABLE(shc_custom_action), - ADD_TABLE(shc_install_exec_seq), + ADD_TABLE(shc2_install_exec_seq), ADD_TABLE(shc2_property) };