msi [2/3]: Run SetProperty events before all other events no matter what the order is [try2]

James Hawkins truiken at gmail.com
Tue Oct 17 04:48:36 CDT 2006


Hi,

Modified thanks to Mike's comments.

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

 dlls/msi/dialog.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 66 insertions(+), 1 deletions(-)

-- 
James Hawkins
-------------- next part --------------
diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index f40ed76..36625f4 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -2886,6 +2886,31 @@ static UINT msi_dialog_control_event( MS
     return ERROR_SUCCESS;
 }
 
+struct rec_list
+{
+    struct list entry;
+    MSIRECORD *rec;
+};
+
+static UINT add_recs_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 UINT msi_dialog_button_handler( msi_dialog *dialog,
                                        msi_control *control, WPARAM param )
 {
@@ -2899,11 +2924,15 @@ static UINT msi_dialog_button_handler( m
       '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 +2941,44 @@ static UINT msi_dialog_button_handler( m
         return 0;
     }
 
-    r = MSI_IterateRecords( view, 0, msi_dialog_control_event, dialog );
+    r = MSI_IterateRecords( view, 0, add_recs_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 );
+        list_remove( &rec_entry->entry );
+        msiobj_release( &rec_entry->rec->hdr );
+
+        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 );
+        list_remove( &rec_entry->entry );
+        msiobj_release( &rec_entry->rec->hdr );
+
+        if ( r != ERROR_SUCCESS )
+            goto done;
+    }
+
+done:
+    LIST_FOR_EACH_ENTRY_SAFE( rec_entry, next, &events, struct rec_list, entry )
+    {
+        list_remove( &rec_entry->entry );
+        msi_free( rec_entry );
+    }
 
     return r;
 }
-- 
1.3.0


More information about the wine-patches mailing list