msi: Return the correct values from dialogs.
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
a3dd99c9a3
commit
700ebc86a9
|
@ -498,9 +498,6 @@ static UINT ITERATE_Actions(MSIRECORD *row, LPVOID param)
|
||||||
|
|
||||||
msi_dialog_check_messages( NULL );
|
msi_dialog_check_messages( NULL );
|
||||||
|
|
||||||
if (package->CurrentInstallState != ERROR_SUCCESS)
|
|
||||||
rc = package->CurrentInstallState;
|
|
||||||
|
|
||||||
if (rc == ERROR_FUNCTION_NOT_CALLED)
|
if (rc == ERROR_FUNCTION_NOT_CALLED)
|
||||||
rc = ERROR_SUCCESS;
|
rc = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ struct msi_dialog_tag
|
||||||
LPWSTR control_cancel;
|
LPWSTR control_cancel;
|
||||||
event_handler pending_event;
|
event_handler pending_event;
|
||||||
LPWSTR pending_argument;
|
LPWSTR pending_argument;
|
||||||
|
INT retval;
|
||||||
WCHAR name[1];
|
WCHAR name[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4245,10 +4246,11 @@ struct control_event
|
||||||
static UINT dialog_event_handler( msi_dialog *, const WCHAR *, const WCHAR * );
|
static UINT dialog_event_handler( msi_dialog *, const WCHAR *, const WCHAR * );
|
||||||
|
|
||||||
/* create a dialog box and run it if it's modal */
|
/* 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;
|
msi_dialog *dialog;
|
||||||
UINT r;
|
UINT r;
|
||||||
|
INT retval;
|
||||||
|
|
||||||
/* create a new dialog */
|
/* create a new dialog */
|
||||||
dialog = dialog_create( package, name, parent, dialog_event_handler );
|
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 */
|
/* modeless dialogs return an error message */
|
||||||
r = dialog_run_message_loop( dialog );
|
r = dialog_run_message_loop( dialog );
|
||||||
if (r == ERROR_SUCCESS)
|
if (r == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
retval = dialog->retval;
|
||||||
msi_dialog_destroy( dialog );
|
msi_dialog_destroy( dialog );
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
package->dialog = dialog;
|
package->dialog = dialog;
|
||||||
|
return IDOK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else r = ERROR_FUNCTION_FAILED;
|
else return 0;
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end a modal dialog box */
|
/* 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};
|
static const WCHAR returnW[] = {'R','e','t','u','r','n',0};
|
||||||
|
|
||||||
if (!strcmpW( argument, exitW ))
|
if (!strcmpW( argument, exitW ))
|
||||||
dialog->package->CurrentInstallState = ERROR_INSTALL_USEREXIT;
|
dialog->retval = IDCANCEL;
|
||||||
else if (!strcmpW( argument, retryW ))
|
else if (!strcmpW( argument, retryW ))
|
||||||
dialog->package->CurrentInstallState = ERROR_INSTALL_SUSPEND;
|
dialog->retval = IDRETRY;
|
||||||
else if (!strcmpW( argument, ignoreW ))
|
else if (!strcmpW( argument, ignoreW ))
|
||||||
dialog->package->CurrentInstallState = ERROR_SUCCESS;
|
dialog->retval = IDOK;
|
||||||
else if (!strcmpW( argument, returnW ))
|
else if (!strcmpW( argument, returnW ))
|
||||||
dialog->package->CurrentInstallState = ERROR_SUCCESS;
|
dialog->retval = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ERR("Unknown argument string %s\n", debugstr_w(argument));
|
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 );
|
event_cleanup_subscriptions( dialog->package, dialog->name );
|
||||||
msi_dialog_end_dialog( dialog );
|
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 */
|
/* create a new child dialog of an existing modal dialog */
|
||||||
static UINT event_spawn_dialog( msi_dialog *dialog, const WCHAR *argument )
|
static UINT event_spawn_dialog( msi_dialog *dialog, const WCHAR *argument )
|
||||||
{
|
{
|
||||||
|
INT r;
|
||||||
/* don't destroy a modeless dialogs that might be our parent */
|
/* don't destroy a modeless dialogs that might be our parent */
|
||||||
event_do_dialog( dialog->package, argument, dialog, FALSE );
|
r = event_do_dialog( dialog->package, argument, dialog, FALSE );
|
||||||
if (dialog->package->CurrentInstallState != ERROR_SUCCESS)
|
if (r != 0)
|
||||||
|
{
|
||||||
|
dialog->retval = r;
|
||||||
msi_dialog_end_dialog( dialog );
|
msi_dialog_end_dialog( dialog );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
msi_dialog_update_all_controls(dialog);
|
msi_dialog_update_all_controls(dialog);
|
||||||
|
|
||||||
|
@ -4472,26 +4484,20 @@ INT ACTION_ShowDialog( MSIPACKAGE *package, const WCHAR *dialog )
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return ERROR_SUCCESS if dialog is process and ERROR_FUNCTION_FAILED
|
INT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog )
|
||||||
* if the given parameter is not a dialog box
|
|
||||||
*/
|
|
||||||
UINT ACTION_DialogBox( MSIPACKAGE *package, const WCHAR *dialog )
|
|
||||||
{
|
{
|
||||||
UINT r;
|
INT r;
|
||||||
|
|
||||||
if (package->next_dialog) ERR("Already got next dialog... ignoring it\n");
|
if (package->next_dialog) ERR("Already got next dialog... ignoring it\n");
|
||||||
package->next_dialog = NULL;
|
package->next_dialog = NULL;
|
||||||
|
|
||||||
/* Dialogs are chained by filling in the next_dialog member
|
/* Dialogs are chained through NewDialog, which sets the next_dialog member.
|
||||||
* of the package structure, then terminating the current dialog.
|
* We fall out of the loop if we reach a modeless dialog, which immediately
|
||||||
* The code below sees the next_dialog member set, and runs the
|
* returns IDOK, or an EndDialog event, which returns the value corresponding
|
||||||
* next dialog.
|
* to its argument.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
r = event_do_dialog( package, dialog, NULL, TRUE );
|
r = event_do_dialog( package, dialog, NULL, TRUE );
|
||||||
while (r == ERROR_SUCCESS && package->next_dialog)
|
while (package->next_dialog)
|
||||||
{
|
{
|
||||||
WCHAR *name = 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 );
|
r = event_do_dialog( package, name, NULL, TRUE );
|
||||||
msi_free( name );
|
msi_free( name );
|
||||||
}
|
}
|
||||||
if (r == ERROR_IO_PENDING) r = ERROR_SUCCESS;
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,7 +414,6 @@ typedef struct tagMSIPACKAGE
|
||||||
BOOL delete_on_close;
|
BOOL delete_on_close;
|
||||||
|
|
||||||
INSTALLUILEVEL ui_level;
|
INSTALLUILEVEL ui_level;
|
||||||
UINT CurrentInstallState;
|
|
||||||
msi_dialog *dialog;
|
msi_dialog *dialog;
|
||||||
LPWSTR next_dialog;
|
LPWSTR next_dialog;
|
||||||
float center_x;
|
float center_x;
|
||||||
|
@ -803,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 INT ACTION_ShowDialog( MSIPACKAGE*, 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 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;
|
||||||
extern UINT MSI_SetFeatureStates( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
|
extern UINT MSI_SetFeatureStates( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -1767,9 +1767,9 @@ static INT internal_ui_handler(MSIPACKAGE *package, INSTALLMESSAGE eMessageType,
|
||||||
case INSTALLMESSAGE_SHOWDIALOG:
|
case INSTALLMESSAGE_SHOWDIALOG:
|
||||||
{
|
{
|
||||||
LPWSTR dialog = msi_dup_record_field(record, 0);
|
LPWSTR dialog = msi_dup_record_field(record, 0);
|
||||||
UINT rc = ACTION_DialogBox(package, dialog);
|
INT rc = ACTION_DialogBox(package, dialog);
|
||||||
msi_free(dialog);
|
msi_free(dialog);
|
||||||
return (rc == ERROR_SUCCESS);
|
return rc;
|
||||||
}
|
}
|
||||||
case INSTALLMESSAGE_ACTIONSTART:
|
case INSTALLMESSAGE_ACTIONSTART:
|
||||||
{
|
{
|
||||||
|
|
|
@ -9806,14 +9806,12 @@ static void test_controlevent(void)
|
||||||
ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
|
ok_sequence(openpackage_sequence, "MsiOpenPackage()", FALSE);
|
||||||
|
|
||||||
r = MsiDoActionA(hpkg, "spawn");
|
r = MsiDoActionA(hpkg, "spawn");
|
||||||
todo_wine
|
|
||||||
ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
|
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");
|
r = MsiDoActionA(hpkg, "spawn2");
|
||||||
todo_wine
|
|
||||||
ok(r == ERROR_INSTALL_USEREXIT, "expected ERROR_INSTALL_USEREXIT, got %u\n", r);
|
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);
|
MsiCloseHandle(hpkg);
|
||||||
ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
|
ok_sequence(closehandle_sequence, "MsiCloseHandle()", FALSE);
|
||||||
|
|
Loading…
Reference in New Issue