msi: Implement handling for the ErrorDialog and use it to change
media
James Hawkins
truiken at gmail.com
Thu Oct 26 04:29:01 CDT 2006
Hi,
This fixes bug 3236. http://bugs.winehq.org/show_bug.cgi?id=3236
Changelog:
* Implement handling for the ErrorDialog and use it to change media.
dlls/msi/dialog.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/files.c | 26 ++++++++++++
dlls/msi/msipriv.h | 1
3 files changed, 139 insertions(+), 0 deletions(-)
--
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index 422f0c5..e1e7ac7 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -3449,3 +3449,115 @@ 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 )
+{
+ static const WCHAR update[] =
+ {'U','P','D','A','T','E',' ','`','C','o','n','t','r','o','l','`',' ',
+ 'S','E','T',' ','`','E','r','r','o','r','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};
+ MSIRECORD * row;
+
+ 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 );
+ LPWSTR title;
+ DWORD size;
+
+ size = lstrlenW( title_fmt ) + lstrlenW( product_name ) - 1;
+ title = msi_alloc( size * sizeof(WCHAR) );
+ if ( !title )
+ {
+ msi_free( product_name );
+ return ERROR_OUTOFMEMORY;
+ }
+
+ sprintfW( title, title_fmt, product_name );
+ res = MessageBoxW( NULL, error, title, MB_OKCANCEL | MB_ICONWARNING );
+
+ msi_free( product_name );
+ msi_free( title );
+
+ if ( res != IDOK )
+ return ERROR_FUNCTION_FAILED;
+
+ return ERROR_SUCCESS;
+ }
+
+ 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 99cc6b5..bfea3ea 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -425,6 +425,25 @@ 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 error_prop[] = {'E','r','r','o','r','D','i','a','l','o','g',0};
+
+ 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 )
{
@@ -523,6 +542,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,
@@ -565,6 +590,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 5acdd25..97b9d18 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 * );
--
1.4.2.4
More information about the wine-patches
mailing list