msi: Perform button control events in greatest to least order [tr2]
James Hawkins
truiken at gmail.com
Fri Oct 6 20:09:43 CDT 2006
Hi,
This version pulls the records out into a linked list, and then
executes the function on the reversed records. Fixes bug 6379.
http://bugs.winehq.org/show_bug.cgi?id=6379
Changelog:
* 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(-)
--
James Hawkins
-------------- next part --------------
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..83e51df 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 )
{
--
1.4.2.1
More information about the wine-patches
mailing list