msi: Execute custom actions in the right script.

Hans Leidekker hans at codeweavers.com
Fri Jan 6 12:29:49 CST 2012


Fixes http://bugs.winehq.org/show_bug.cgi?id=27987
---
 dlls/msi/action.c  |   20 ++++++------
 dlls/msi/custom.c  |   86 ++++++++++++++++++++++++++++++++++-----------------
 dlls/msi/events.c  |    2 +-
 dlls/msi/install.c |    2 +-
 dlls/msi/msi.c     |    6 ++--
 dlls/msi/msipriv.h |   16 +++++----
 dlls/msi/package.c |    2 +-
 7 files changed, 82 insertions(+), 52 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index fb62339..5444dfc 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -524,9 +524,9 @@ static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
     }
 
     if (needs_ui_sequence(package))
-        rc = ACTION_PerformUIAction(package, action, -1);
+        rc = ACTION_PerformUIAction(package, action, SCRIPT_NONE);
     else
-        rc = ACTION_PerformAction(package, action, -1);
+        rc = ACTION_PerformAction(package, action, SCRIPT_NONE);
 
     msi_dialog_check_messages( NULL );
 
@@ -1580,7 +1580,7 @@ static UINT execute_script( MSIPACKAGE *package, UINT script )
         ERR("no script!\n");
         return ERROR_FUNCTION_FAILED;
     }
-    if (script == ROLLBACK_SCRIPT)
+    if (script == SCRIPT_ROLLBACK)
     {
         for (i = package->script->ActionCount[script]; i > 0; i--)
         {
@@ -4916,7 +4916,7 @@ done:
 
 static UINT ACTION_InstallExecute(MSIPACKAGE *package)
 {
-    return execute_script(package,INSTALL_SCRIPT);
+    return execute_script(package, SCRIPT_INSTALL);
 }
 
 static UINT ITERATE_UnpublishIcon( MSIRECORD *row, LPVOID param )
@@ -5028,8 +5028,8 @@ static UINT ACTION_InstallFinalize(MSIPACKAGE *package)
     if (rc != ERROR_SUCCESS)
         return rc;
 
-    /* then handle Commit Actions */
-    rc = execute_script(package,COMMIT_SCRIPT);
+    /* then handle commit actions */
+    rc = execute_script(package, SCRIPT_COMMIT);
     if (rc != ERROR_SUCCESS)
         return rc;
 
@@ -7293,7 +7293,7 @@ static BOOL ACTION_HandleStandardAction( MSIPACKAGE *package, LPCWSTR action, UI
                 if (StandardActions[i].action_rollback && !package->need_rollback)
                 {
                     TRACE("scheduling rollback action\n");
-                    msi_schedule_action( package, ROLLBACK_SCRIPT, StandardActions[i].action_rollback );
+                    msi_schedule_action( package, SCRIPT_ROLLBACK, StandardActions[i].action_rollback );
                 }
             }
             else
@@ -7400,9 +7400,9 @@ static UINT ACTION_PerformActionSequence(MSIPACKAGE *package, UINT seq)
         }
 
         if (needs_ui_sequence(package))
-            rc = ACTION_PerformUIAction(package, action, -1);
+            rc = ACTION_PerformUIAction(package, action, SCRIPT_NONE);
         else
-            rc = ACTION_PerformAction(package, action, -1);
+            rc = ACTION_PerformAction(package, action, SCRIPT_NONE);
 
         msiobj_release(&row->hdr);
     }
@@ -7528,7 +7528,7 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
     if (package->need_rollback && !(reinstall = msi_dup_property( package->db, szReinstall )))
     {
         WARN("installation failed, running rollback script\n");
-        execute_script( package, ROLLBACK_SCRIPT );
+        execute_script( package, SCRIPT_ROLLBACK );
     }
     msi_free( reinstall );
 
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c
index cb7461b..7543767 100644
--- a/dlls/msi/custom.c
+++ b/dlls/msi/custom.c
@@ -69,7 +69,7 @@ UINT msi_schedule_action( MSIPACKAGE *package, UINT script, const WCHAR *action
     UINT count;
     WCHAR **newbuf = NULL;
 
-    if (script >= TOTAL_SCRIPTS)
+    if (script >= SCRIPT_MAX)
     {
         FIXME("Unknown script requested %u\n", script);
         return ERROR_FUNCTION_FAILED;
@@ -1164,6 +1164,60 @@ static UINT HANDLE_CustomType53_54(MSIPACKAGE *package, LPCWSTR source,
     return wait_thread_handle( info );
 }
 
+static BOOL action_type_matches_script( MSIPACKAGE *package, UINT type, UINT script )
+{
+    switch (script)
+    {
+    case SCRIPT_NONE:
+    case SCRIPT_INSTALL:
+        return !(type & msidbCustomActionTypeCommit) && !(type & msidbCustomActionTypeRollback);
+    case SCRIPT_COMMIT:
+        return (type & msidbCustomActionTypeCommit);
+    case SCRIPT_ROLLBACK:
+        return (type & msidbCustomActionTypeRollback);
+    default:
+        ERR("unhandled script %u\n", script);
+    }
+    return FALSE;
+}
+
+static UINT defer_custom_action( MSIPACKAGE *package, const WCHAR *action, UINT type )
+{
+    WCHAR *actiondata = msi_dup_property( package->db, action );
+    WCHAR *usersid = msi_dup_property( package->db, szUserSID );
+    WCHAR *prodcode = msi_dup_property( package->db, szProductCode );
+    WCHAR *deferred = msi_get_deferred_action( action, actiondata, usersid, prodcode );
+
+    if (!deferred)
+    {
+        msi_free( actiondata );
+        msi_free( usersid );
+        msi_free( prodcode );
+        return ERROR_OUTOFMEMORY;
+    }
+    if (type & msidbCustomActionTypeCommit)
+    {
+        TRACE("deferring commit action\n");
+        msi_schedule_action( package, SCRIPT_COMMIT, deferred );
+    }
+    else if (type & msidbCustomActionTypeRollback)
+    {
+        TRACE("deferring rollback action\n");
+        msi_schedule_action( package, SCRIPT_ROLLBACK, deferred );
+    }
+    else
+    {
+        TRACE("deferring install action\n");
+        msi_schedule_action( package, SCRIPT_INSTALL, deferred );
+    }
+
+    msi_free( actiondata );
+    msi_free( usersid );
+    msi_free( prodcode );
+    msi_free( deferred );
+    return ERROR_SUCCESS;
+}
+
 UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL execute)
 {
     static const WCHAR query[] = {
@@ -1192,7 +1246,6 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL
     }
 
     type = MSI_RecordGetInteger(row,2);
-
     source = MSI_RecordGetString(row,3);
     target = MSI_RecordGetString(row,4);
 
@@ -1208,34 +1261,9 @@ UINT ACTION_CustomAction(MSIPACKAGE *package, LPCWSTR action, UINT script, BOOL
         if (type & msidbCustomActionTypeNoImpersonate)
             WARN("msidbCustomActionTypeNoImpersonate not handled\n");
 
-        if (!execute)
+        if (!execute || !action_type_matches_script( package, type, script ))
         {
-            LPWSTR actiondata = msi_dup_property(package->db, action);
-            LPWSTR usersid = msi_dup_property(package->db, szUserSID);
-            LPWSTR prodcode = msi_dup_property(package->db, szProductCode);
-            LPWSTR deferred = msi_get_deferred_action(action, actiondata, usersid, prodcode);
-
-            if (type & msidbCustomActionTypeCommit)
-            {
-                TRACE("Deferring commit action\n");
-                msi_schedule_action(package, COMMIT_SCRIPT, deferred);
-            }
-            else if (type & msidbCustomActionTypeRollback)
-            {
-                TRACE("Deferring rollback action\n");
-                msi_schedule_action(package, ROLLBACK_SCRIPT, deferred);
-            }
-            else
-            {
-                TRACE("Deferring action\n");
-                msi_schedule_action(package, INSTALL_SCRIPT, deferred);
-            }
-
-            rc = ERROR_SUCCESS;
-            msi_free(actiondata);
-            msi_free(usersid);
-            msi_free(prodcode);
-            msi_free(deferred);
+            rc = defer_custom_action( package, action, type );
             goto end;
         }
         else
diff --git a/dlls/msi/events.c b/dlls/msi/events.c
index 785d98a..d42ac5b 100644
--- a/dlls/msi/events.c
+++ b/dlls/msi/events.c
@@ -160,7 +160,7 @@ static UINT ControlEvent_SpawnWaitDialog(MSIPACKAGE* package, LPCWSTR argument,
 static UINT ControlEvent_DoAction(MSIPACKAGE* package, LPCWSTR argument, 
                                   msi_dialog* dialog)
 {
-    ACTION_PerformAction(package, argument, -1);
+    ACTION_PerformAction(package, argument, SCRIPT_NONE);
     return ERROR_SUCCESS;
 }
 
diff --git a/dlls/msi/install.c b/dlls/msi/install.c
index fc5a625..86e3979 100644
--- a/dlls/msi/install.c
+++ b/dlls/msi/install.c
@@ -105,7 +105,7 @@ UINT WINAPI MsiDoActionW( MSIHANDLE hInstall, LPCWSTR szAction )
         return ERROR_SUCCESS;
     }
  
-    ret = ACTION_PerformUIAction( package, szAction, -1 );
+    ret = ACTION_PerformUIAction( package, szAction, SCRIPT_NONE );
     msiobj_release( &package->hdr );
 
     return ret;
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index bdcb17a..fd2315f 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -3534,7 +3534,7 @@ UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
     if (!package)
         return ERROR_CALL_NOT_IMPLEMENTED;
 
-    rc = ACTION_PerformUIAction(package, szFirstRun, -1);
+    rc = ACTION_PerformUIAction(package, szFirstRun, SCRIPT_NONE);
     msiobj_release( &package->hdr );
 
     MsiCloseHandle(handle);
@@ -3560,7 +3560,7 @@ UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
     if (!package)
         return ERROR_CALL_NOT_IMPLEMENTED;
 
-    rc = ACTION_PerformUIAction(package, szFirstRun, -1);
+    rc = ACTION_PerformUIAction(package, szFirstRun, SCRIPT_NONE);
     msiobj_release( &package->hdr );
 
     MsiCloseHandle(handle);
@@ -3641,7 +3641,7 @@ UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLST
 
     MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
 
-    r = ACTION_PerformUIAction( package, szCostInitialize, -1 );
+    r = ACTION_PerformUIAction( package, szCostInitialize, SCRIPT_NONE );
     if (r != ERROR_SUCCESS)
         goto end;
 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 2a15a52..589e4a1 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -658,11 +658,13 @@ struct tagMSIMIME
     BOOL InstallMe;
 };
 
-enum SCRIPTS {
-    INSTALL_SCRIPT = 0,
-    COMMIT_SCRIPT = 1,
-    ROLLBACK_SCRIPT = 2,
-    TOTAL_SCRIPTS = 3
+enum SCRIPTS
+{
+    SCRIPT_NONE     = -1,
+    SCRIPT_INSTALL  = 0,
+    SCRIPT_COMMIT   = 1,
+    SCRIPT_ROLLBACK = 2,
+    SCRIPT_MAX      = 3
 };
 
 #define SEQUENCE_UI       0x1
@@ -671,8 +673,8 @@ enum SCRIPTS {
 
 typedef struct tagMSISCRIPT
 {
-    LPWSTR  *Actions[TOTAL_SCRIPTS];
-    UINT    ActionCount[TOTAL_SCRIPTS];
+    LPWSTR  *Actions[SCRIPT_MAX];
+    UINT    ActionCount[SCRIPT_MAX];
     BOOL    ExecuteSequenceRun;
     BOOL    CurrentlyScripting;
     UINT    InWhatSequence;
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 756be42..89da1da 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -283,7 +283,7 @@ static void free_package_structures( MSIPACKAGE *package )
 
     if (package->script)
     {
-        for (i = 0; i < TOTAL_SCRIPTS; i++)
+        for (i = 0; i < SCRIPT_MAX; i++)
             msi_free_action_script( package, i );
 
         for (i = 0; i < package->script->UniqueActionsCount; i++)
-- 
1.7.7.3






More information about the wine-patches mailing list