msi: Return the correct values from custom actions.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f348c7c04c
commit
16f0dffd01
@ -172,7 +172,7 @@ static INT ui_actionstart(MSIPACKAGE *package, LPCWSTR action, LPCWSTR descripti
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
|
static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
|
||||||
UINT rc)
|
INT rc)
|
||||||
{
|
{
|
||||||
MSIRECORD *row;
|
MSIRECORD *row;
|
||||||
WCHAR template[1024];
|
WCHAR template[1024];
|
||||||
@ -189,9 +189,10 @@ static void ui_actioninfo(MSIPACKAGE *package, LPCWSTR action, BOOL start,
|
|||||||
if (!row) return;
|
if (!row) return;
|
||||||
MSI_RecordSetStringW(row, 0, message);
|
MSI_RecordSetStringW(row, 0, message);
|
||||||
MSI_RecordSetStringW(row, 1, action);
|
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);
|
MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
|
||||||
msiobj_release(&row->hdr);
|
msiobj_release(&row->hdr);
|
||||||
|
if (!start) package->LastActionResult = rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum parse_state
|
enum parse_state
|
||||||
@ -620,15 +621,30 @@ static UINT ACTION_HandleCustomAction(MSIPACKAGE *package, LPCWSTR action, UINT
|
|||||||
return ERROR_INSTALL_USEREXIT;
|
return ERROR_INSTALL_USEREXIT;
|
||||||
ui_actioninfo(package, action, TRUE, 0);
|
ui_actioninfo(package, action, TRUE, 0);
|
||||||
arc = ACTION_CustomAction( package, action, script );
|
arc = ACTION_CustomAction( package, action, script );
|
||||||
|
uirc = !arc;
|
||||||
|
|
||||||
if (arc == ERROR_FUNCTION_NOT_CALLED && needs_ui_sequence(package))
|
if (arc == ERROR_FUNCTION_NOT_CALLED && needs_ui_sequence(package))
|
||||||
arc = ACTION_ShowDialog(package, action);
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (arc == ERROR_INSTALL_USEREXIT) /* dialog UI returned -1 */
|
ui_actioninfo(package, action, FALSE, uirc);
|
||||||
return ERROR_SUCCESS;
|
|
||||||
|
|
||||||
ui_actioninfo(package, action, FALSE, arc);
|
|
||||||
package->LastActionResult = !arc;
|
|
||||||
|
|
||||||
return arc;
|
return arc;
|
||||||
}
|
}
|
||||||
@ -7765,8 +7781,7 @@ static UINT ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action)
|
|||||||
{
|
{
|
||||||
ui_actioninfo( package, action, TRUE, 0 );
|
ui_actioninfo( package, action, TRUE, 0 );
|
||||||
rc = StandardActions[i].handler( package );
|
rc = StandardActions[i].handler( package );
|
||||||
ui_actioninfo( package, action, FALSE, rc );
|
ui_actioninfo( package, action, FALSE, !rc );
|
||||||
package->LastActionResult = !rc;
|
|
||||||
|
|
||||||
if (StandardActions[i].action_rollback && !package->need_rollback)
|
if (StandardActions[i].action_rollback && !package->need_rollback)
|
||||||
{
|
{
|
||||||
|
@ -4507,20 +4507,21 @@ static UINT event_reset( msi_dialog *dialog, const WCHAR *argument )
|
|||||||
return ERROR_SUCCESS;
|
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};
|
static const WCHAR szDialog[] = {'D','i','a','l','o','g',0};
|
||||||
MSIRECORD *row;
|
MSIRECORD *row;
|
||||||
INT rc;
|
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);
|
row = MSI_CreateRecord(0);
|
||||||
if (!row) return ERROR_OUTOFMEMORY;
|
if (!row) return -1;
|
||||||
MSI_RecordSetStringW(row, 0, dialog);
|
MSI_RecordSetStringW(row, 0, dialog);
|
||||||
rc = MSI_ProcessMessage(package, INSTALLMESSAGE_SHOWDIALOG, row);
|
rc = MSI_ProcessMessage(package, INSTALLMESSAGE_SHOWDIALOG, row);
|
||||||
msiobj_release(&row->hdr);
|
msiobj_release(&row->hdr);
|
||||||
if (rc == -1) return ERROR_INSTALL_USEREXIT;
|
|
||||||
|
if (rc == -2) rc = 0;
|
||||||
|
|
||||||
if (!rc)
|
if (!rc)
|
||||||
{
|
{
|
||||||
@ -4540,9 +4541,8 @@ UINT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
|
|||||||
MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
|
MSI_ProcessMessage(package, INSTALLMESSAGE_INFO, row);
|
||||||
|
|
||||||
msiobj_release(&row->hdr);
|
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
|
/* Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
|
||||||
|
@ -802,7 +802,7 @@ extern void msi_free_patchinfo( MSIPATCHINFO *patch ) DECLSPEC_HIDDEN;
|
|||||||
|
|
||||||
/* action internals */
|
/* action internals */
|
||||||
extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN;
|
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_DialogBox( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN;
|
||||||
extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN;
|
extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN;
|
||||||
extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN;
|
extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN;
|
||||||
|
@ -9389,6 +9389,11 @@ static const struct externalui_message doaction_custom_fullui_sequence[] = {
|
|||||||
{0}
|
{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[] = {
|
static const struct externalui_message doaction_dialog_nonexistent_sequence[] = {
|
||||||
{INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
|
{INSTALLMESSAGE_ACTIONSTART, 3, {"", "custom", "", ""}, {0, 1, 1, 1}},
|
||||||
{INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
|
{INSTALLMESSAGE_INFO, 2, {"", "custom", "1"}, {0, 1, 1}},
|
||||||
@ -9415,6 +9420,22 @@ static const struct externalui_message doaction_dialog_error_sequence[] = {
|
|||||||
{0}
|
{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[] = {
|
static const struct externalui_message closehandle_sequence[] = {
|
||||||
{INSTALLMESSAGE_TERMINATE, -1},
|
{INSTALLMESSAGE_TERMINATE, -1},
|
||||||
{0}
|
{0}
|
||||||
@ -9577,6 +9598,11 @@ static void test_externalui_message(void)
|
|||||||
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
ok_sequence(doaction_custom_fullui_sequence, "MsiDoAction(\"custom\")", FALSE);
|
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;
|
retval = 0;
|
||||||
r = MsiDoActionA(hpkg, "custom");
|
r = MsiDoActionA(hpkg, "custom");
|
||||||
ok(r == ERROR_FUNCTION_NOT_CALLED, "Expected ERROR_FUNCTION_NOT_CALLED, got %d\n", r);
|
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(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
|
||||||
ok_sequence(doaction_dialog_error_sequence, "MsiDoAction(\"error\")", FALSE);
|
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);
|
MsiCloseHandle(hpkg);
|
||||||
ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
|
ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user