From 700ebc86a9ffd12028692fe8f2217c5d85fe82ba Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sun, 23 Jul 2017 15:50:56 -0500 Subject: [PATCH] msi: Return the correct values from dialogs. Signed-off-by: Zebediah Figura Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/msi/action.c | 3 --- dlls/msi/dialog.c | 53 ++++++++++++++++++++++------------------ dlls/msi/msipriv.h | 3 +-- dlls/msi/package.c | 4 +-- dlls/msi/tests/package.c | 6 ++--- 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/dlls/msi/action.c b/dlls/msi/action.c index 18ec7c3ff77..b521925d429 100644 --- a/dlls/msi/action.c +++ b/dlls/msi/action.c @@ -498,9 +498,6 @@ static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param) msi_dialog_check_messages( NULL ); - if (package->CurrentInstallState != ERROR_SUCCESS) - rc = package->CurrentInstallState; - if (rc == ERROR_FUNCTION_NOT_CALLED) rc = ERROR_SUCCESS; diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c index 0c46efde6ce..1d24acd217b 100644 --- a/dlls/msi/dialog.c +++ b/dlls/msi/dialog.c @@ -103,6 +103,7 @@ struct msi_dialog_tag LPWSTR control_cancel; event_handler pending_event; LPWSTR pending_argument; + INT retval; WCHAR name[1]; }; @@ -4245,10 +4246,11 @@ struct control_event static UINT dialog_event_handler( msi_dialog *, const WCHAR *, const WCHAR * ); /* create a dialog box and run it if it's modal */ -static UINT event_do_dialog( MSIPACKAGE *package, const WCHAR *name, msi_dialog *parent, BOOL destroy_modeless ) +static INT event_do_dialog( MSIPACKAGE *package, const WCHAR *name, msi_dialog *parent, BOOL destroy_modeless ) { msi_dialog *dialog; UINT r; + INT retval; /* create a new dialog */ dialog = dialog_create( package, name, parent, dialog_event_handler ); @@ -4264,12 +4266,18 @@ static UINT event_do_dialog( MSIPACKAGE *package, const WCHAR *name, msi_dialog /* modeless dialogs return an error message */ r = dialog_run_message_loop( dialog ); if (r == ERROR_SUCCESS) + { + retval = dialog->retval; msi_dialog_destroy( dialog ); + return retval; + } else + { package->dialog = dialog; + return IDOK; + } } - else r = ERROR_FUNCTION_FAILED; - return r; + else return 0; } /* end a modal dialog box */ @@ -4281,17 +4289,17 @@ static UINT event_end_dialog( msi_dialog *dialog, const WCHAR *argument ) static const WCHAR returnW[] = {'R','e','t','u','r','n',0}; if (!strcmpW( argument, exitW )) - dialog->package->CurrentInstallState = ERROR_INSTALL_USEREXIT; + dialog->retval = IDCANCEL; else if (!strcmpW( argument, retryW )) - dialog->package->CurrentInstallState = ERROR_INSTALL_SUSPEND; + dialog->retval = IDRETRY; else if (!strcmpW( argument, ignoreW )) - dialog->package->CurrentInstallState = ERROR_SUCCESS; + dialog->retval = IDOK; else if (!strcmpW( argument, returnW )) - dialog->package->CurrentInstallState = ERROR_SUCCESS; + dialog->retval = 0; else { ERR("Unknown argument string %s\n", debugstr_w(argument)); - dialog->package->CurrentInstallState = ERROR_FUNCTION_FAILED; + dialog->retval = IDABORT; } event_cleanup_subscriptions( dialog->package, dialog->name ); msi_dialog_end_dialog( dialog ); @@ -4327,10 +4335,14 @@ static UINT pending_event_new_dialog( msi_dialog *dialog, const WCHAR *argument /* create a new child dialog of an existing modal dialog */ static UINT event_spawn_dialog( msi_dialog *dialog, const WCHAR *argument ) { + INT r; /* don't destroy a modeless dialogs that might be our parent */ - event_do_dialog( dialog->package, argument, dialog, FALSE ); - if (dialog->package->CurrentInstallState != ERROR_SUCCESS) + r = event_do_dialog( dialog->package, argument, dialog, FALSE ); + if (r != 0) + { + dialog->retval = r; msi_dialog_end_dialog( dialog ); + } else msi_dialog_update_all_controls(dialog); @@ -4472,26 +4484,20 @@ INT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog ) return rc; } -/* Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED - * if the given parameter is not a dialog box - */ -UINT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog ) +INT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog ) { - UINT r; + INT r; if (package->next_dialog) ERR("Already got next dialog... ignoring it\n"); package->next_dialog = NULL; - /* Dialogs are chained by filling in the next_dialog member - * of the package structure, then terminating the current dialog. - * The code below sees the next_dialog member set, and runs the - * next dialog. - * We fall out of the loop below if we come across a modeless - * dialog, as it returns ERROR_IO_PENDING when we try to run - * its message loop. + /* Dialogs are chained through NewDialog, which sets the next_dialog member. + * We fall out of the loop if we reach a modeless dialog, which immediately + * returns IDOK, or an EndDialog event, which returns the value corresponding + * to its argument. */ r = event_do_dialog( package, dialog, NULL, TRUE ); - while (r == ERROR_SUCCESS && package->next_dialog) + while (package->next_dialog) { WCHAR *name = package->next_dialog; @@ -4499,7 +4505,6 @@ UINT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog ) r = event_do_dialog( package, name, NULL, TRUE ); msi_free( name ); } - if (r == ERROR_IO_PENDING) r = ERROR_SUCCESS; return r; } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 14006037504..f316c0cce74 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -414,7 +414,6 @@ typedef struct tagMSIPACKAGE BOOL delete_on_close; INSTALLUILEVEL ui_level; - UINT CurrentInstallState; msi_dialog *dialog; LPWSTR next_dialog; float center_x; @@ -803,7 +802,7 @@ extern void msi_free_patchinfo( MSIPATCHINFO *patch ) DECLSPEC_HIDDEN; /* action internals */ extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN; extern INT ACTION_ShowDialog( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN; -extern UINT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN; +extern INT ACTION_DialogBox( MSIPACKAGE*, LPCWSTR) DECLSPEC_HIDDEN; extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN; extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN; extern UINT MSI_SetFeatureStates( MSIPACKAGE *package ) DECLSPEC_HIDDEN; diff --git a/dlls/msi/package.c b/dlls/msi/package.c index cc3ee35a232..47164613209 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -1767,9 +1767,9 @@ static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType, case INSTALLMESSAGE_SHOWDIALOG: { LPWSTR dialog = msi_dup_record_field(record, 0); - UINT rc = ACTION_DialogBox(package, dialog); + INT rc = ACTION_DialogBox(package, dialog); msi_free(dialog); - return (rc == ERROR_SUCCESS); + return rc; } case INSTALLMESSAGE_ACTIONSTART: { diff --git a/dlls/msi/tests/package.c b/dlls/msi/tests/package.c index 32af6a10fe9..c10488a68c9 100644 --- a/dlls/msi/tests/package.c +++ b/dlls/msi/tests/package.c @@ -9806,14 +9806,12 @@ static void test_controlevent(void) ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE); r = MsiDoActionA(hpkg, "spawn"); - todo_wine ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); - ok_sequence(controlevent_spawn_sequence, "control event: spawn", TRUE); + ok_sequence(controlevent_spawn_sequence, "control event: spawn", FALSE); r = MsiDoActionA(hpkg, "spawn2"); - todo_wine ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r); - ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", TRUE); + ok_sequence(controlevent_spawn2_sequence, "control event: spawn2", FALSE); MsiCloseHandle(hpkg); ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);