[PATCH 2/3] msi: Return the correct values from custom actions.

Zebediah Figura z.figura12 at gmail.com
Tue Jul 11 00:18:33 CDT 2017


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/msi/action.c        | 35 +++++++++++++++++++++++++----------
 dlls/msi/dialog.c        | 12 ++++++------
 dlls/msi/msipriv.h       |  2 +-
 dlls/msi/tests/package.c | 41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 3f97c82..2d05ba1 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -172,7 +172,7 @@ static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR descripti
 }
 
 static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start, 
-                          UINT rc)
+                          INT rc)
 {
     MSIRECORD *row;
     WCHAR template[1024];
@@ -189,9 +189,10 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
     if (!row) return;
     MSI_RecordSetStringW(row, 0, message);
     MSI_RecordSetStringW(row, 1, action);
-    MSI_RecordSetInteger(row, 2, start ? package->LastActionResult : !rc);
+    MSI_RecordSetInteger(row, 2, start ? package->LastActionResult : rc);
     MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
     msiobj_release(&row->hdr);
+    if (!start) package->LastActionResult = rc;
 }
 
 enum parse_state
@@ -620,15 +621,30 @@ static UINT ACTION_HandleCustomAction(MSIPACKAGE *package, LPCWSTR action, UINT
         return ERROR_INSTALL_USEREXIT;
     ui_actioninfo(package, action, TRUE, 0);
     arc = ACTION_CustomAction( package, action, script );
+    uirc = !arc;
 
     if (arc == ERROR_FUNCTION_NOT_CALLED && needs_ui_sequence(package))
-        arc = ACTION_ShowDialog(package, action);
-
-    if (arc == ERROR_INSTALL_USEREXIT) /* dialog UI returned -1 */
-        return ERROR_SUCCESS;
+    {
+        uirc = ACTION_ShowDialog(package, action);
+        switch (uirc)
+        {
+        case -1:
+            return ERROR_SUCCESS; /* stop immediately */
+        case 0: arc = ERROR_FUNCTION_NOT_CALLED; break;
+        case 1: arc = ERROR_SUCCESS; break;
+        case 2: arc = ERROR_INSTALL_USEREXIT; break;
+        case 3: arc = ERROR_INSTALL_FAILURE; break;
+        case 4: arc = ERROR_INSTALL_SUSPEND; break;
+        case 5: arc = ERROR_MORE_DATA; break;
+        case 6: arc = ERROR_INVALID_HANDLE_STATE; break;
+        case 7: arc = ERROR_INVALID_DATA; break;
+        case 8: arc = ERROR_INSTALL_ALREADY_RUNNING; break;
+        case 9: arc = ERROR_INSTALL_PACKAGE_REJECTED; break;
+        default: arc = ERROR_FUNCTION_FAILED; break;
+        }
+    }
 
-    ui_actioninfo(package, action, FALSE, arc);
-    package->LastActionResult = !arc;
+    ui_actioninfo(package, action, FALSE, uirc);
 
     return arc;
 }
@@ -7765,8 +7781,7 @@ static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action)
             {
                 ui_actioninfo( package, action, TRUE, 0 );
                 rc = StandardActions[i].handler( package );
-                ui_actioninfo( package, action, FALSE, rc );
-                package->LastActionResult = !rc;
+                ui_actioninfo( package, action, FALSE, !rc );
 
                 if (StandardActions[i].action_rollback && !package->need_rollback)
                 {
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index ac2b29b..6c215b1 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -4507,20 +4507,21 @@ static UINT event_reset( msi_dialog *dialog, const WCHAR *argument )
     return ERROR_SUCCESS;
 }
 
-UINT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
+INT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
 {
     static const WCHAR szDialog[] = {'D','i','a','l','o','g',0};
     MSIRECORD *row;
     INT rc;
 
-    if (!TABLE_Exists(package->db, szDialog)) return ERROR_FUNCTION_NOT_CALLED;
+    if (!TABLE_Exists(package->db, szDialog)) return 0;
 
     row = MSI_CreateRecord(0);
-    if (!row) return ERROR_OUTOFMEMORY;
+    if (!row) return -1;
     MSI_RecordSetStringW(row, 0, dialog);
     rc = MSI_ProcessMessage(package, INSTALLMESSAGE_SHOWDIALOG, row);
     msiobj_release(&row->hdr);
-    if (rc == -1) return ERROR_INSTALL_USEREXIT;
+
+    if (rc == -2) rc = 0;
 
     if (!rc)
     {
@@ -4540,9 +4541,8 @@ UINT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
         MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
 
         msiobj_release(&row->hdr);
-        return ERROR_FUNCTION_NOT_CALLED;
     }
-    return ERROR_SUCCESS;
+    return rc;
 }
 
 /* Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 600800c..84e53ff 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -802,7 +802,7 @@ extern void msi_free_patchinfo( MSIPATCHINFO *patch ) DECLSPEC_HIDDEN;
 
 /* action internals */
 extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN;
-extern UINT ACTION_ShowDialog( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN;
+extern INT ACTION_ShowDialog( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN;
 extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN;
 extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN;
 extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN;
diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c
index e15dc57..1173c92 100644
--- a/dlls/msi/tests/package.c
+++ b/dlls/msi/tests/package.c
@@ -9389,6 +9389,11 @@ static const struct externalui_message doaction_custom_fullui_sequence[] = {
     {0}
 };
 
+static const struct externalui_message doaction_custom_cancel_sequence[] = {
+    {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
+    {0}
+};
+
 static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
     {INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
     {INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
@@ -9415,6 +9420,22 @@ static const struct externalui_message doaction_dialog_error_sequence[] = {
     {0}
 };
 
+static const struct externalui_message doaction_dialog_3_sequence[] = {
+    {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
+    {INSTALLMESSAGE_INFO, 2, {"", "dialog", "0"}, {0, 1, 1}},
+    {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
+    {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
+    {0}
+};
+
+static const struct externalui_message doaction_dialog_12345_sequence[] = {
+    {INSTALLMESSAGE_ACTIONSTART, 3, {"", "dialog", "", ""}, {0, 1, 1, 1}},
+    {INSTALLMESSAGE_INFO, 2, {"", "dialog", "3"}, {0, 1, 1}},
+    {INSTALLMESSAGE_SHOWDIALOG, 0, {"dialog"}, {1}},
+    {INSTALLMESSAGE_INFO, 2, {"", "dialog", "12345"}, {0, 1, 1}},
+    {0}
+};
+
 static const struct externalui_message closehandle_sequence[] = {
     {INSTALLMESSAGE_TERMINATE, -1},
     {0}
@@ -9577,6 +9598,11 @@ static void test_externalui_message(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
 
+    retval = 2;
+    r = MsiDoActionA(hpkg, "custom");
+    ok(r == ERROR_INSTALL_USEREXIT, "Expected ERROR_INSTALL_USEREXIT, got %d\n", r);
+    ok_sequence(doaction_custom_cancel_sequence, "MsiDoAction(\"custom\")", FALSE);
+
     retval = 0;
     r = MsiDoActionA(hpkg, "custom");
     ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
@@ -9595,6 +9621,21 @@ static void test_externalui_message(void)
     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
     ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
 
+    retval = -2;
+    r = MsiDoActionA(hpkg, "custom");
+    ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
+    ok_sequence(doaction_dialog_nonexistent_sequence, "MsiDoAction(\"custom\")", FALSE);
+
+    retval = 3;
+    r = MsiDoActionA(hpkg, "dialog");
+    ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
+    ok_sequence(doaction_dialog_3_sequence, "MsiDoAction(\"dialog\")", FALSE);
+
+    retval = 12345;
+    r = MsiDoActionA(hpkg, "dialog");
+    ok(r == ERROR_FUNCTION_FAILED, "Expected ERROR_INSTALL_FAILURE, got %d\n", r);
+    ok_sequence(doaction_dialog_12345_sequence, "MsiDoAction(\"dialog\")", FALSE);
+
     MsiCloseHandle(hpkg);
     ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
 
-- 
2.7.4




More information about the wine-patches mailing list