Commit c6bfbde8 authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Implement handling for the ErrorDialog and use it to change media.

parent b851d465
......@@ -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;
}
......@@ -425,6 +425,29 @@ static UINT msi_extract_remote_cabinet( MSIPACKAGE *package, struct media_info *
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( MSIPACKAGE *package, struct media_info *mi,
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( MSIPACKAGE *package, struct media_info *mi,
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, mi->count, volume,
prompt);
done:
msiobj_release(&row->hdr);
return rc;
......
......@@ -680,6 +680,7 @@ extern UINT msi_dialog_reset( msi_dialog *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 * );
......
......@@ -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
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment