Commit 8321276c authored by James Hawkins's avatar James Hawkins Committed by Alexandre Julliard

msi: Run SetProperty events before all other events no matter what the order is.

parent f9bfbe2e
......@@ -2886,6 +2886,38 @@ static UINT msi_dialog_control_event( MSIRECORD *rec, LPVOID param )
return ERROR_SUCCESS;
}
struct rec_list
{
struct list entry;
MSIRECORD *rec;
};
static UINT add_rec_to_list( MSIRECORD *rec, LPVOID param )
{
struct rec_list *add_rec;
struct list *records = (struct list *)param;
msiobj_addref( &rec->hdr );
add_rec = msi_alloc( sizeof( *add_rec ) );
if (!add_rec)
{
msiobj_release( &rec->hdr );
return ERROR_OUTOFMEMORY;
}
add_rec->rec = rec;
list_add_tail( records, &add_rec->entry );
return ERROR_SUCCESS;
}
static inline void remove_rec_from_list( struct rec_list *rec_entry )
{
msiobj_release( &rec_entry->rec->hdr );
list_remove( &rec_entry->entry );
msi_free( rec_entry );
}
static UINT msi_dialog_button_handler( msi_dialog *dialog,
msi_control *control, WPARAM param )
{
......@@ -2899,11 +2931,15 @@ static UINT msi_dialog_button_handler( msi_dialog *dialog,
'O','R','D','E','R',' ','B','Y',' ','`','O','r','d','e','r','i','n','g','`',0
};
MSIQUERY *view = NULL;
struct rec_list *rec_entry, *next;
struct list events;
UINT r;
if( HIWORD(param) != BN_CLICKED )
return ERROR_SUCCESS;
list_init( &events );
r = MSI_OpenQuery( dialog->package->db, &view, query,
dialog->name, control->name );
if( r != ERROR_SUCCESS )
......@@ -2912,8 +2948,41 @@ static UINT msi_dialog_button_handler( msi_dialog *dialog,
return 0;
}
r = MSI_IterateRecords( view, 0, msi_dialog_control_event, dialog );
r = MSI_IterateRecords( view, 0, add_rec_to_list, &events );
msiobj_release( &view->hdr );
if (r != ERROR_SUCCESS)
goto done;
/* handle all SetProperty events first */
LIST_FOR_EACH_ENTRY_SAFE( rec_entry, next, &events, struct rec_list, entry )
{
LPCWSTR event = MSI_RecordGetString( rec_entry->rec, 3 );
if ( event[0] != '[' )
continue;
r = msi_dialog_control_event( rec_entry->rec, dialog );
remove_rec_from_list( rec_entry );
if ( r != ERROR_SUCCESS )
goto done;
}
/* handle all other events */
LIST_FOR_EACH_ENTRY_SAFE( rec_entry, next, &events, struct rec_list, entry )
{
r = msi_dialog_control_event( rec_entry->rec, dialog );
remove_rec_from_list( rec_entry );
if ( r != ERROR_SUCCESS )
goto done;
}
done:
LIST_FOR_EACH_ENTRY_SAFE( rec_entry, next, &events, struct rec_list, entry )
{
remove_rec_from_list( rec_entry );
}
return r;
}
......
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