James Hawkins : msi: Perform button control events in greatest to least order.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Oct 9 14:04:57 CDT 2006


Module: wine
Branch: master
Commit: f721a24a13bf250f0794b7249ffa863619b0b450
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f721a24a13bf250f0794b7249ffa863619b0b450

Author: James Hawkins <truiken at gmail.com>
Date:   Fri Oct  6 18:09:43 2006 -0700

msi: Perform button control events in greatest to least order.

---

 dlls/msi/dialog.c   |    2 +
 dlls/msi/msipriv.h  |    1 +
 dlls/msi/msiquery.c |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 1 deletions(-)

diff --git a/dlls/msi/dialog.c b/dlls/msi/dialog.c
index 11890ac..6c6aa0e 100644
--- a/dlls/msi/dialog.c
+++ b/dlls/msi/dialog.c
@@ -2914,7 +2914,7 @@ static UINT msi_dialog_button_handler( m
         return 0;
     }
 
-    r = MSI_IterateRecords( view, 0, msi_dialog_control_event, dialog );
+    r = MSI_ReverseIterateRecords( view, 0, msi_dialog_control_event, dialog );
     msiobj_release( &view->hdr );
 
     return r;
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index cc3b88b..8b9eabb 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -386,6 +386,7 @@ extern UINT MSI_OpenDatabaseW( LPCWSTR, 
 extern UINT MSI_DatabaseOpenViewW(MSIDATABASE *, LPCWSTR, MSIQUERY ** );
 extern UINT MSI_OpenQuery( MSIDATABASE *, MSIQUERY **, LPCWSTR, ... );
 typedef UINT (*record_func)( MSIRECORD *, LPVOID );
+extern UINT MSI_ReverseIterateRecords( MSIQUERY *, DWORD *, record_func, LPVOID );
 extern UINT MSI_IterateRecords( MSIQUERY *, DWORD *, record_func, LPVOID );
 extern MSIRECORD *MSI_QueryGetRecord( MSIDATABASE *db, LPCWSTR query, ... );
 extern UINT MSI_DatabaseImport( MSIDATABASE *, LPCWSTR, LPCWSTR );
diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c
index 7816e13..ff8aa42 100644
--- a/dlls/msi/msiquery.c
+++ b/dlls/msi/msiquery.c
@@ -27,6 +27,7 @@ #include "winbase.h"
 #include "winerror.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
+#include "wine/list.h"
 #include "msi.h"
 #include "msiquery.h"
 #include "objbase.h"
@@ -164,6 +165,82 @@ UINT MSI_OpenQuery( MSIDATABASE *db, MSI
     return r;
 }
 
+struct rec_list
+{
+    struct list entry;
+    MSIRECORD *rec;
+};
+
+UINT MSI_ReverseIterateRecords( MSIQUERY *view, DWORD *count,
+                                record_func func, LPVOID param )
+{
+    MSIRECORD *rec = NULL;
+    struct rec_list *add_rec; 
+    struct list records;
+    UINT r, n = 0, max = 0;
+
+    r = MSI_ViewExecute( view, NULL );
+    if( r != ERROR_SUCCESS )
+        return r;
+
+    list_init( &records );
+
+    if( count )
+        max = *count;
+
+    /* reverse the query */
+    for( n = 0; (max == 0) || (n < max); n++ )
+    {
+        r = MSI_ViewFetch( view, &rec );
+        if( r != ERROR_SUCCESS )
+        {
+            if ( r == ERROR_NO_MORE_ITEMS )
+                break;
+            else
+                goto done;
+        }
+
+        add_rec = msi_alloc( sizeof( *add_rec ) );
+        if (!add_rec)
+            goto done;
+
+        add_rec->rec = rec;
+        list_add_head( &records, &add_rec->entry );
+    }
+
+    /* iterate over the reversed records */
+    n = 0;
+    LIST_FOR_EACH_ENTRY( add_rec, &records, struct rec_list, entry )
+    {
+        if (func)
+            r = func( add_rec->rec, param );
+
+        msiobj_release( &add_rec->rec->hdr );
+        if ( r != ERROR_SUCCESS )
+            goto done;
+
+        n++;
+    }
+
+done:
+    MSI_ViewClose( view );
+
+    while ( !list_empty( &records ) )
+    {
+        add_rec = LIST_ENTRY( list_head( &records ), struct rec_list, entry );
+        list_remove( &add_rec->entry );
+        msi_free( add_rec );
+    }
+
+    if( count )
+        *count = n;
+
+    if( r == ERROR_NO_MORE_ITEMS )
+        r = ERROR_SUCCESS;
+
+    return r;
+}
+
 UINT MSI_IterateRecords( MSIQUERY *view, DWORD *count,
                          record_func func, LPVOID param )
 {




More information about the wine-cvs mailing list