Module: wine Branch: master Commit: c6bfbde849b5ddf2217f30bbac31bc7e43043278 URL: http://source.winehq.org/git/wine.git/?a=commit;h=c6bfbde849b5ddf2217f30bbac...
Author: James Hawkins truiken@gmail.com Date: Thu Oct 26 17:13:52 2006 -0700
msi: Implement handling for the ErrorDialog and use it to change media.
---
dlls/msi/dialog.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/msi/files.c | 30 +++++++++++++ dlls/msi/msipriv.h | 1 + dlls/msi/tests/install.c | 2 + 4 files changed, 136 insertions(+), 0 deletions(-)
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c index 403e65f..407cb29 100644 --- a/dlls/msi/dialog.c +++ b/dlls/msi/dialog.c @@ -3448,3 +3448,106 @@ void msi_dialog_unregister_class( void ) UnregisterClassW( szMsiHiddenWindow, NULL ); uiThreadId = 0; } + +static UINT error_dialog_handler(MSIPACKAGE *package, LPCWSTR event, + LPCWSTR argument, msi_dialog* dialog) +{ + static const WCHAR end_dialog[] = {'E','n','d','D','i','a','l','o','g',0}; + static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0}; + static const WCHAR error_cancel[] = {'E','r','r','o','r','C','a','n','c','e','l',0}; + static const WCHAR error_no[] = {'E','r','r','o','r','N','o',0}; + static const WCHAR result_prop[] = { + 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0 + }; + + if ( lstrcmpW( event, end_dialog ) ) + return ERROR_SUCCESS; + + if ( !lstrcmpW( argument, error_abort ) || !lstrcmpW( argument, error_cancel ) || + !lstrcmpW( argument, error_no ) ) + { + MSI_SetPropertyW( package, result_prop, error_abort ); + } + + ControlEvent_CleanupSubscriptions(package); + msi_dialog_end_dialog( dialog ); + + return ERROR_SUCCESS; +} + +static UINT msi_error_dialog_set_error( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error ) +{ + MSIRECORD * row; + + static const WCHAR update[] = + {'U','P','D','A','T','E',' ','`','C','o','n','t','r','o','l','`',' ', + 'S','E','T',' ','`','T','e','x','t','`',' ','=',' ',''','%','s',''',' ', + 'W','H','E','R','E', ' ','`','D','i','a','l','o','g','_','`',' ','=',' ',''','%','s',''',' ', + 'A','N','D',' ','`','C','o','n','t','r','o','l','`',' ','=',' ', + ''','E','r','r','o','r','T','e','x','t',''',0}; + + row = MSI_QueryGetRecord( package->db, update, error, error_dialog ); + if (!row) + return ERROR_FUNCTION_FAILED; + + msiobj_release(&row->hdr); + return ERROR_SUCCESS; +} + +UINT msi_spawn_error_dialog( MSIPACKAGE *package, LPWSTR error_dialog, LPWSTR error ) +{ + msi_dialog *dialog; + WCHAR result[MAX_PATH]; + UINT r = ERROR_SUCCESS; + DWORD size = MAX_PATH; + int res; + + static const WCHAR pn_prop[] = {'P','r','o','d','u','c','t','N','a','m','e',0}; + static const WCHAR title_fmt[] = {'%','s',' ','W','a','r','n','i','n','g',0}; + static const WCHAR error_abort[] = {'E','r','r','o','r','A','b','o','r','t',0}; + static const WCHAR result_prop[] = { + 'M','S','I','E','r','r','o','r','D','i','a','l','o','g','R','e','s','u','l','t',0 + }; + + if ( !error_dialog ) + { + LPWSTR product_name = msi_dup_property( package, pn_prop ); + WCHAR title[MAX_PATH]; + + sprintfW( title, title_fmt, product_name ); + res = MessageBoxW( NULL, error, title, MB_OKCANCEL | MB_ICONWARNING ); + + msi_free( product_name ); + + if ( res == IDOK ) + return ERROR_SUCCESS; + else + return ERROR_FUNCTION_FAILED; + } + + r = msi_error_dialog_set_error( package, error_dialog, error ); + if ( r != ERROR_SUCCESS ) + return r; + + dialog = msi_dialog_create( package, error_dialog, package->dialog, + error_dialog_handler ); + if ( !dialog ) + return ERROR_FUNCTION_FAILED; + + dialog->finished = FALSE; + r = msi_dialog_run_message_loop( dialog ); + if ( r != ERROR_SUCCESS ) + goto done; + + r = MSI_GetPropertyW( package, result_prop, result, &size ); + if ( r != ERROR_SUCCESS) + r = ERROR_SUCCESS; + + if ( !lstrcmpW( result, error_abort ) ) + r = ERROR_FUNCTION_FAILED; + +done: + msi_dialog_destroy( dialog ); + + return r; +} diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 6c5b288..7eec8a2 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -425,6 +425,29 @@ static UINT msi_extract_remote_cabinet( return !extract_cabinet_file(package, mi->source, mi->last_path); }
+static UINT msi_change_media( MSIPACKAGE *package, struct media_info *mi, LPCWSTR prompt ) +{ + LPWSTR error, error_dialog; + UINT r = ERROR_SUCCESS; + + static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0}; + static const WCHAR error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0}; + + if ( msi_get_property_int(package, szUILevel, 0) == INSTALLUILEVEL_NONE ) + return ERROR_SUCCESS; + + error = generate_error_string( package, 1302, 1, prompt ); + error_dialog = msi_dup_property( package, error_prop ); + + while ( r == ERROR_SUCCESS && GetFileAttributesW( mi->source ) == INVALID_FILE_ATTRIBUTES ) + r = msi_spawn_error_dialog( package, error_dialog, error ); + + msi_free( error ); + msi_free( error_dialog ); + + return r; +} + static UINT ready_media_for_file( MSIPACKAGE *package, struct media_info *mi, MSIFILE *file ) { @@ -528,6 +551,12 @@ static UINT ready_media_for_file( MSIPAC strcpyW(mi->last_path,mi->source); strcatW(mi->source,cab);
+ if (GetFileAttributesW(mi->source) == INVALID_FILE_ATTRIBUTES) + rc = msi_change_media(package, mi, prompt); + + if ( rc != ERROR_SUCCESS ) + goto done; + MsiSourceListSetInfoW(package->ProductCode, NULL, MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT|MSISOURCETYPE_MEDIA, @@ -570,6 +599,7 @@ static UINT ready_media_for_file( MSIPAC MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume, prompt);
+done: msiobj_release(&row->hdr);
return rc; diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 4745b9e..45bdeac 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -680,6 +680,7 @@ extern UINT msi_dialog_reset( msi_dialog extern UINT msi_dialog_directorylist_up( msi_dialog *dialog ); extern msi_dialog *msi_dialog_get_parent( msi_dialog *dialog ); extern LPWSTR msi_dialog_get_name( msi_dialog *dialog ); +extern UINT msi_spawn_error_dialog( MSIPACKAGE*, LPWSTR, LPWSTR );
/* preview */ extern MSIPREVIEW *MSI_EnableUIPreview( MSIDATABASE * ); diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c index aed5a78..760e81e 100644 --- a/dlls/msi/tests/install.c +++ b/dlls/msi/tests/install.c @@ -803,6 +803,8 @@ static void test_continuouscabs(void) create_cc_test_files(); create_database(msifile, cc_tables, sizeof(cc_tables) / sizeof(msi_table));
+ MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); + r = MsiInstallProductA(msifile, NULL); todo_wine {