Mike McCormack : msi: Examine the attributes of all features before setting a component's state.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 5 04:51:05 CST 2006


Module: wine
Branch: master
Commit: 97419aea801be27ad519eb2dba631b48335095f2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=97419aea801be27ad519eb2dba631b48335095f2

Author: Mike McCormack <mike at codeweavers.com>
Date:   Tue Dec  5 18:24:39 2006 +0900

msi: Examine the attributes of all features before setting a component's state.

---

 dlls/msi/action.c  |  108 ++++++++++++++++++++++++++++++++-------------------
 dlls/msi/msipriv.h |    4 ++
 2 files changed, 72 insertions(+), 40 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index cd5bf4b..a90a81a 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1786,7 +1786,19 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *pa
         ComponentList *cl;
 
         TRACE("Examining Feature %s (Installed %i, Action %i)\n",
-            debugstr_w(feature->Feature), feature->Installed, feature->Action);
+              debugstr_w(feature->Feature), feature->Installed, feature->Action);
+
+        /* features with components that have compressed files are made local */
+        LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
+        {
+            if (cl->component->Enabled &&
+                cl->component->ForceLocalState &&
+                feature->Action == INSTALLSTATE_SOURCE)
+            {
+                msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+                break;
+            }
+        }
 
         LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
         {
@@ -1795,53 +1807,69 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *pa
             if (!component->Enabled)
                 continue;
 
-            if (component->Attributes & msidbComponentAttributesOptional)
-                msi_component_set_state( component, INSTALLSTATE_DEFAULT );
-            else
+            switch (feature->Action)
             {
-                if (component->Attributes & msidbComponentAttributesSourceOnly)
-                    msi_component_set_state( component, INSTALLSTATE_SOURCE );
+            case INSTALLSTATE_ADVERTISED:
+                component->hasAdvertiseFeature = 1;
+                break;
+            case INSTALLSTATE_SOURCE:
+                component->hasSourceFeature = 1;
+                break;
+            case INSTALLSTATE_LOCAL:
+                component->hasLocalFeature = 1;
+                break;
+            case INSTALLSTATE_DEFAULT:
+                if (feature->Attributes & msidbFeatureAttributesFavorAdvertise)
+                    component->hasAdvertiseFeature = 1;
+                else if (feature->Attributes & msidbFeatureAttributesFavorSource)
+                    component->hasSourceFeature = 1;
                 else
-                    msi_component_set_state( component, INSTALLSTATE_LOCAL );
+                    component->hasLocalFeature = 1;
+                break;
+            default:
+                break;
             }
+        }
+    }
 
-            if (component->ForceLocalState)
+    LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
+    {
+        /* if the component isn't enabled, leave it alone */
+        if (!component->Enabled)
+            continue;
+
+        /* check if it's local or source */
+        if (!(component->Attributes & msidbComponentAttributesOptional) &&
+             (component->hasLocalFeature || component->hasSourceFeature))
+        {
+            if ((component->Attributes & msidbComponentAttributesSourceOnly) &&
+                 !component->ForceLocalState)
+                msi_component_set_state( component, INSTALLSTATE_SOURCE );
+            else
                 msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            continue;
+        }
 
-            if (feature->Attributes == msidbFeatureAttributesFavorAdvertise)
-            {
-                msi_component_set_state( component, INSTALLSTATE_ADVERTISED );
-            }
-            else if (feature->Attributes == msidbFeatureAttributesFavorLocal)
-            {
-                if (!(component->Attributes & msidbComponentAttributesSourceOnly))
-                    msi_component_set_state( component, INSTALLSTATE_LOCAL );
-            }
-            else if (feature->Attributes == msidbFeatureAttributesFavorSource)
-            {
-                if ((component->Action == INSTALLSTATE_UNKNOWN) ||
-                    (component->Action == INSTALLSTATE_ABSENT) ||
-                    (component->Action == INSTALLSTATE_ADVERTISED) ||
-                    (component->Action == INSTALLSTATE_DEFAULT))
-                    msi_component_set_state( component, INSTALLSTATE_SOURCE );
-            }
-            else if (feature->ActionRequest == INSTALLSTATE_ADVERTISED)
-            {
-                if ((component->Action == INSTALLSTATE_UNKNOWN) ||
-                    (component->Action == INSTALLSTATE_ABSENT))
-                    msi_component_set_state( component, INSTALLSTATE_ADVERTISED );
-            }
-            else if (feature->ActionRequest == INSTALLSTATE_ABSENT)
-            {
-                if (component->Action == INSTALLSTATE_UNKNOWN)
-                    msi_component_set_state( component, INSTALLSTATE_ABSENT );
-            }
-            else if (feature->ActionRequest == INSTALLSTATE_UNKNOWN)
-                msi_component_set_state( component, INSTALLSTATE_UNKNOWN );
+        /* if any feature is local, the component must be local too */
+        if (component->hasLocalFeature)
+        {
+            msi_component_set_state( component, INSTALLSTATE_LOCAL );
+            continue;
+        }
 
-            if (component->ForceLocalState && feature->Action == INSTALLSTATE_SOURCE)
-                msi_feature_set_state( feature, INSTALLSTATE_LOCAL );
+        if (component->hasSourceFeature)
+        {
+            msi_component_set_state( component, INSTALLSTATE_SOURCE );
+            continue;
         }
+
+        if (component->hasAdvertiseFeature)
+        {
+            msi_component_set_state( component, INSTALLSTATE_ADVERTISED );
+            continue;
+        }
+
+        TRACE("nobody wants component %s\n", debugstr_w(component->Component));
     }
 
     LIST_FOR_EACH_ENTRY( component, &package->components, MSICOMPONENT, entry )
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index f6089da..815b70c 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -300,6 +300,10 @@ typedef struct tagMSICOMPONENT
     INT  RefCount;
     LPWSTR FullKeypath;
     LPWSTR AdvertiseString;
+
+    int hasAdvertiseFeature:1;
+    int hasLocalFeature:1;
+    int hasSourceFeature:1;
 } MSICOMPONENT;
 
 typedef struct tagComponentList




More information about the wine-cvs mailing list