Commit 1ee3be6e authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Only remove a component if the number of clients drops to zero.

parent 7ee9bb5c
...@@ -809,6 +809,11 @@ INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp ) ...@@ -809,6 +809,11 @@ INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp )
return INSTALLSTATE_UNKNOWN; return INSTALLSTATE_UNKNOWN;
} }
if (package->need_rollback) return comp->Installed; if (package->need_rollback) return comp->Installed;
if (comp->num_clients > 0 && comp->ActionRequest == INSTALLSTATE_ABSENT)
{
TRACE("%s has %u clients left\n", debugstr_w(comp->Component), comp->num_clients);
return comp->Installed;
}
return comp->ActionRequest; return comp->ActionRequest;
} }
...@@ -1620,6 +1625,27 @@ static UINT ACTION_FileCost(MSIPACKAGE *package) ...@@ -1620,6 +1625,27 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static void get_client_counts( MSIPACKAGE *package )
{
MSICOMPONENT *comp;
HKEY hkey;
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
if (!comp->ComponentId) continue;
if (MSIREG_OpenUserDataComponentKey( comp->ComponentId, szLocalSid, &hkey, FALSE ) &&
MSIREG_OpenUserDataComponentKey( comp->ComponentId, NULL, &hkey, FALSE ))
{
comp->num_clients = 0;
continue;
}
RegQueryInfoKeyW( hkey, NULL, NULL, NULL, NULL, NULL, NULL, (DWORD *)&comp->num_clients,
NULL, NULL, NULL, NULL );
RegCloseKey( hkey );
}
}
static void ACTION_GetComponentInstallStates(MSIPACKAGE *package) static void ACTION_GetComponentInstallStates(MSIPACKAGE *package)
{ {
MSICOMPONENT *comp; MSICOMPONENT *comp;
...@@ -1983,6 +2009,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package) ...@@ -1983,6 +2009,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
TRACE("component %s (installed %d request %d action %d)\n", TRACE("component %s (installed %d request %d action %d)\n",
debugstr_w(component->Component), component->Installed, component->ActionRequest, component->Action); 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--;
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -2368,6 +2399,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package) ...@@ -2368,6 +2399,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
else else
comp->Enabled = TRUE; comp->Enabled = TRUE;
} }
get_client_counts( package );
/* read components states from the registry */ /* read components states from the registry */
ACTION_GetComponentInstallStates(package); ACTION_GetComponentInstallStates(package);
...@@ -3307,9 +3339,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -3307,9 +3339,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (package->need_rollback) action = comp->Installed; if (package->need_rollback) action = comp->Installed;
else action = comp->ActionRequest; else action = comp->ActionRequest;
TRACE("Component %s (%s), Keypath=%s, RefCount=%u Action=%u\n", TRACE("Component %s (%s) Keypath=%s RefCount=%u Clients=%u Action=%u\n",
debugstr_w(comp->Component), debugstr_w(squished_cc), debugstr_w(comp->Component), debugstr_w(squished_cc),
debugstr_w(comp->FullKeypath), comp->RefCount, action); debugstr_w(comp->FullKeypath), comp->RefCount, comp->num_clients, action);
if (action == INSTALLSTATE_LOCAL || action == INSTALLSTATE_SOURCE) if (action == INSTALLSTATE_LOCAL || action == INSTALLSTATE_SOURCE)
{ {
...@@ -3372,10 +3404,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package) ...@@ -3372,10 +3404,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
} }
else if (action == INSTALLSTATE_ABSENT) else if (action == INSTALLSTATE_ABSENT)
{ {
if (package->Context == MSIINSTALLCONTEXT_MACHINE) if (comp->num_clients <= 0)
MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid); {
else if (package->Context == MSIINSTALLCONTEXT_MACHINE)
MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL); MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid );
else
MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL );
}
} }
/* UI stuff */ /* UI stuff */
......
...@@ -481,6 +481,7 @@ typedef struct tagMSICOMPONENT ...@@ -481,6 +481,7 @@ typedef struct tagMSICOMPONENT
LPWSTR FullKeypath; LPWSTR FullKeypath;
LPWSTR AdvertiseString; LPWSTR AdvertiseString;
MSIASSEMBLY *assembly; MSIASSEMBLY *assembly;
int num_clients;
unsigned int anyAbsent:1; unsigned int anyAbsent:1;
unsigned int hasAdvertiseFeature:1; unsigned int hasAdvertiseFeature:1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment