Hans Leidekker : msi: Only remove a component if the number of clients drops to zero.
Alexandre Julliard
julliard at winehq.org
Tue Sep 11 16:59:07 CDT 2012
Module: wine
Branch: master
Commit: 1ee3be6e8092af933d5a4e09fc3503fc1bea4001
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1ee3be6e8092af933d5a4e09fc3503fc1bea4001
Author: Hans Leidekker <hans at codeweavers.com>
Date: Tue Sep 11 16:20:59 2012 +0200
msi: Only remove a component if the number of clients drops to zero.
---
dlls/msi/action.c | 47 +++++++++++++++++++++++++++++++++++++++++------
dlls/msi/msipriv.h | 1 +
2 files changed, 42 insertions(+), 6 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index f874528..845a0fd 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -809,6 +809,11 @@ INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp )
return INSTALLSTATE_UNKNOWN;
}
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;
}
@@ -1620,6 +1625,27 @@ static UINT ACTION_FileCost(MSIPACKAGE *package)
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)
{
MSICOMPONENT *comp;
@@ -1983,6 +2009,11 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
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--;
}
return ERROR_SUCCESS;
@@ -2368,6 +2399,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
else
comp->Enabled = TRUE;
}
+ get_client_counts( package );
/* read components states from the registry */
ACTION_GetComponentInstallStates(package);
@@ -3307,9 +3339,9 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
if (package->need_rollback) action = comp->Installed;
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->FullKeypath), comp->RefCount, action);
+ debugstr_w(comp->FullKeypath), comp->RefCount, comp->num_clients, action);
if (action == INSTALLSTATE_LOCAL || action == INSTALLSTATE_SOURCE)
{
@@ -3372,10 +3404,13 @@ static UINT ACTION_ProcessComponents(MSIPACKAGE *package)
}
else if (action == INSTALLSTATE_ABSENT)
{
- if (package->Context == MSIINSTALLCONTEXT_MACHINE)
- MSIREG_DeleteUserDataComponentKey(comp->ComponentId, szLocalSid);
- else
- MSIREG_DeleteUserDataComponentKey(comp->ComponentId, NULL);
+ if (comp->num_clients <= 0)
+ {
+ if (package->Context == MSIINSTALLCONTEXT_MACHINE)
+ MSIREG_DeleteUserDataComponentKey( comp->ComponentId, szLocalSid );
+ else
+ MSIREG_DeleteUserDataComponentKey( comp->ComponentId, NULL );
+ }
}
/* UI stuff */
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 43ac194..73bccecd 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -481,6 +481,7 @@ typedef struct tagMSICOMPONENT
LPWSTR FullKeypath;
LPWSTR AdvertiseString;
MSIASSEMBLY *assembly;
+ int num_clients;
unsigned int anyAbsent:1;
unsigned int hasAdvertiseFeature:1;
More information about the wine-cvs
mailing list