Hans Leidekker : msi: Don' t evaluate the condition table when there are overrides.

Alexandre Julliard julliard at winehq.org
Wed Jan 27 12:27:23 CST 2010


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Wed Jan 27 11:18:02 2010 +0100

msi: Don't evaluate the condition table when there are overrides.

---

 dlls/msi/action.c        |  110 +++++++++++++++++++++++----------------------
 dlls/msi/tests/install.c |   31 ++++++++++++-
 2 files changed, 85 insertions(+), 56 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index fef8eae..3280e82 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1585,55 +1585,57 @@ static BOOL process_state_property(MSIPACKAGE* package, int level,
     return TRUE;
 }
 
-UINT MSI_SetFeatureStates(MSIPACKAGE *package)
+static BOOL process_overrides( MSIPACKAGE *package, int level )
 {
-    int level;
-    static const WCHAR szlevel[] =
-        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
     static const WCHAR szAddLocal[] =
         {'A','D','D','L','O','C','A','L',0};
     static const WCHAR szAddSource[] =
         {'A','D','D','S','O','U','R','C','E',0};
     static const WCHAR szAdvertise[] =
         {'A','D','V','E','R','T','I','S','E',0};
-    BOOL override = FALSE;
-    MSICOMPONENT* component;
-    MSIFEATURE *feature;
+    BOOL ret = FALSE;
+
+    /* all these activation/deactivation things happen in order and things
+     * later on the list override things earlier on the list.
+     *
+     *  0  INSTALLLEVEL processing
+     *  1  ADDLOCAL
+     *  2  REMOVE
+     *  3  ADDSOURCE
+     *  4  ADDDEFAULT
+     *  5  REINSTALL
+     *  6  ADVERTISE
+     *  7  COMPADDLOCAL
+     *  8  COMPADDSOURCE
+     *  9  FILEADDLOCAL
+     * 10  FILEADDSOURCE
+     * 11  FILEADDDEFAULT
+     */
+    ret |= process_state_property( package, level, szAddLocal, INSTALLSTATE_LOCAL );
+    ret |= process_state_property( package, level, szRemove, INSTALLSTATE_ABSENT );
+    ret |= process_state_property( package, level, szAddSource, INSTALLSTATE_SOURCE );
+    ret |= process_state_property( package, level, szReinstall, INSTALLSTATE_UNKNOWN );
+    ret |= process_state_property( package, level, szAdvertise, INSTALLSTATE_ADVERTISED );
 
+    if (ret)
+        MSI_SetPropertyW( package, szPreselected, szOne );
 
-    /* I do not know if this is where it should happen.. but */
+    return ret;
+}
+
+UINT MSI_SetFeatureStates(MSIPACKAGE *package)
+{
+    int level;
+    static const WCHAR szlevel[] =
+        {'I','N','S','T','A','L','L','L','E','V','E','L',0};
+    MSICOMPONENT* component;
+    MSIFEATURE *feature;
 
     TRACE("Checking Install Level\n");
 
     level = msi_get_property_int(package, szlevel, 1);
 
-    /* ok here is the _real_ rub
-     * all these activation/deactivation things happen in order and things
-     * later on the list override things earlier on the list.
-     * 0) INSTALLLEVEL processing
-     * 1) ADDLOCAL
-     * 2) REMOVE
-     * 3) ADDSOURCE
-     * 4) ADDDEFAULT
-     * 5) REINSTALL
-     * 6) ADVERTISE
-     * 7) COMPADDLOCAL
-     * 8) COMPADDSOURCE
-     * 9) FILEADDLOCAL
-     * 10) FILEADDSOURCE
-     * 11) FILEADDDEFAULT
-     *
-     * I am still ignoring a lot of these. But that is ok for now, ADDLOCAL and
-     * REMOVE are the big ones, since we don't handle administrative installs
-     * yet anyway.
-     */
-    override |= process_state_property(package, level, szAddLocal, INSTALLSTATE_LOCAL);
-    override |= process_state_property(package, level, szRemove, INSTALLSTATE_ABSENT);
-    override |= process_state_property(package, level, szAddSource, INSTALLSTATE_SOURCE);
-    override |= process_state_property(package, level, szReinstall, INSTALLSTATE_UNKNOWN);
-    override |= process_state_property(package, level, szAdvertise, INSTALLSTATE_ADVERTISED);
-
-    if (!override)
+    if (!msi_get_property_int( package, szPreselected, 0 ))
     {
         LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
         {
@@ -1663,8 +1665,6 @@ UINT MSI_SetFeatureStates(MSIPACKAGE *package)
                 msi_feature_set_state(package, fl->feature, INSTALLSTATE_UNKNOWN);
         }
     }
-    else
-        MSI_SetPropertyW(package, szPreselected, szOne);
 
     /*
      * now we want to enable or disable components base on feature
@@ -1963,7 +1963,7 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
     static const WCHAR szOutOfDiskSpace[] =
         {'O','u','t','O','f','D','i','s','k','S','p','a','c','e',0};
     MSICOMPONENT *comp;
-    UINT rc;
+    UINT rc = ERROR_SUCCESS;
     MSIQUERY * view;
     LPWSTR level;
 
@@ -1984,26 +1984,28 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
     TRACE("File calculations\n");
     msi_check_file_install_states( package );
 
-    TRACE("Evaluating Condition Table\n");
-
-    rc = MSI_DatabaseOpenViewW(package->db, ConditionQuery, &view);
-    if (rc == ERROR_SUCCESS)
+    if (!process_overrides( package, msi_get_property_int( package, szlevel, 1 ) ))
     {
-        rc = MSI_IterateRecords(view, NULL, ITERATE_CostFinalizeConditions,
-                    package);
-        msiobj_release(&view->hdr);
-    }
+        TRACE("Evaluating Condition Table\n");
 
-    TRACE("Enabling or Disabling Components\n");
-    LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
-    {
-        if (MSI_EvaluateConditionW(package, comp->Condition) == MSICONDITION_FALSE)
+        rc = MSI_DatabaseOpenViewW( package->db, ConditionQuery, &view );
+        if (rc == ERROR_SUCCESS)
         {
-            TRACE("Disabling component %s\n", debugstr_w(comp->Component));
-            comp->Enabled = FALSE;
+            rc = MSI_IterateRecords( view, NULL, ITERATE_CostFinalizeConditions, package );
+            msiobj_release( &view->hdr );
+        }
+
+        TRACE("Enabling or Disabling Components\n");
+        LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
+        {
+            if (MSI_EvaluateConditionW( package, comp->Condition ) == MSICONDITION_FALSE)
+            {
+                TRACE("Disabling component %s\n", debugstr_w(comp->Component));
+                comp->Enabled = FALSE;
+            }
+            else
+                comp->Enabled = TRUE;
         }
-        else
-            comp->Enabled = TRUE;
     }
 
     MSI_SetPropertyW(package,szCosting,szOne);
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index 701192b..a3bffe7 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -6885,9 +6885,9 @@ static void test_preselected(void)
     ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
     ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
     ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
-    todo_wine ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
+    ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
     ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
-    todo_wine ok(delete_pf("msitest", FALSE), "File not installed\n");
+    ok(delete_pf("msitest", FALSE), "File not installed\n");
 
     r = MsiInstallProductA(msifile, NULL);
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
@@ -7310,6 +7310,32 @@ static void test_MsiSetExternalUI(void)
     ok(!error, "MsiSetExternalUIRecord failed %u\n", error);
 }
 
+static void test_feature_override(void)
+{
+    UINT r;
+
+    create_test_files();
+    create_database(msifile, tables, sizeof(tables) / sizeof(msi_table));
+
+    r = MsiInstallProductA(msifile, "ADDLOCAL=One");
+    ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r);
+
+    ok(!delete_pf("msitest\\cabout\\new\\five.txt", TRUE), "File installed\n");
+    ok(!delete_pf("msitest\\cabout\\new", FALSE), "File installed\n");
+    ok(!delete_pf("msitest\\cabout\\four.txt", TRUE), "File installed\n");
+    ok(!delete_pf("msitest\\cabout", FALSE), "File installed\n");
+    ok(!delete_pf("msitest\\changed\\three.txt", TRUE), "File installed\n");
+    ok(!delete_pf("msitest\\changed", FALSE), "File installed\n");
+    ok(!delete_pf("msitest\\first\\two.txt", TRUE), "File installed\n");
+    ok(!delete_pf("msitest\\first", FALSE), "File installed\n");
+    ok(!delete_pf("msitest\\filename", TRUE), "File installed\n");
+    ok(delete_pf("msitest\\one.txt", TRUE), "File not installed\n");
+    ok(!delete_pf("msitest\\service.exe", TRUE), "File installed\n");
+    ok(delete_pf("msitest", FALSE), "File not installed\n");
+
+    delete_test_files();
+}
+
 START_TEST(install)
 {
     DWORD len;
@@ -7400,6 +7426,7 @@ START_TEST(install)
     test_file_in_use_cab();
     test_MsiSetExternalUI();
     test_allusers_prop();
+    test_feature_override();
 
     DeleteFileA(log_file);
 




More information about the wine-cvs mailing list