Mike McCormack : msi: Create a function to copy record fields, use it to order INSERT fields correctly.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Sep 7 05:07:08 CDT 2006


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

Author: Mike McCormack <mike at codeweavers.com>
Date:   Thu Aug 31 17:05:45 2006 +0900

msi: Create a function to copy record fields, use it to order INSERT fields correctly.

---

 dlls/msi/insert.c  |    6 +-----
 dlls/msi/msipriv.h |    1 +
 dlls/msi/record.c  |   48 +++++++++++++++++++++++++++++++++++++++++++++++-
 dlls/msi/select.c  |   27 ++++++++++++++++++++++++---
 4 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c
index 85c9f51..eb65904 100644
--- a/dlls/msi/insert.c
+++ b/dlls/msi/insert.c
@@ -66,7 +66,6 @@ static MSIRECORD *INSERT_merge_record( U
 {
     MSIRECORD *merged;
     DWORD wildcard_count = 1, i;
-    const WCHAR *str;
 
     merged = MSI_CreateRecord( fields );
     for( i=1; i <= fields; i++ )
@@ -88,10 +87,7 @@ static MSIRECORD *INSERT_merge_record( U
         case EXPR_WILDCARD:
             if( !rec )
                 goto err;
-            if( MSI_RecordIsNull( rec, wildcard_count ) )
-                goto err;
-            str = MSI_RecordGetString( rec, wildcard_count );
-            MSI_RecordSetStringW( merged, i, str );
+            MSI_RecordCopyField( rec, wildcard_count, merged, i );
             wildcard_count++;
             break;
         default:
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 991c11c..191c770 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -371,6 +371,7 @@ extern UINT MSI_RecordSetStreamW( MSIREC
 extern UINT MSI_RecordSetStreamA( MSIRECORD *, unsigned int, LPCSTR );
 extern UINT MSI_RecordDataSize( MSIRECORD *, unsigned int );
 extern UINT MSI_RecordStreamToFile( MSIRECORD *, unsigned int, LPCWSTR );
+extern UINT MSI_RecordCopyField( MSIRECORD *, unsigned int, MSIRECORD *, unsigned int );
 
 /* stream internals */
 extern UINT get_raw_stream( MSIHANDLE hdb, LPCWSTR stname, IStream **stm );
diff --git a/dlls/msi/record.c b/dlls/msi/record.c
index 6c9a567..8bc3871 100644
--- a/dlls/msi/record.c
+++ b/dlls/msi/record.c
@@ -43,7 +43,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb);
 
 #define MSIFIELD_NULL   0
 #define MSIFIELD_INT    1
-#define MSIFIELD_STR    2
 #define MSIFIELD_WSTR   3
 #define MSIFIELD_STREAM 4
 
@@ -154,6 +153,53 @@ static BOOL string2intW( LPCWSTR str, in
     return TRUE;
 }
 
+UINT MSI_RecordCopyField( MSIRECORD *in_rec, unsigned int in_n,
+                          MSIRECORD *out_rec, unsigned int out_n )
+{
+    UINT r = ERROR_SUCCESS;
+
+    msiobj_lock( &in_rec->hdr );
+
+    if ( in_n > in_rec->count || out_n > out_rec->count )
+        r = ERROR_FUNCTION_FAILED;
+    else if ( in_rec != out_rec || in_n != out_n )
+    {
+        LPWSTR str;
+        MSIFIELD *in, *out;
+
+        in = &in_rec->fields[in_n];
+        out = &out_rec->fields[out_n];
+
+        switch ( in->type )
+        {
+        case MSIFIELD_NULL:
+            break;
+        case MSIFIELD_INT:
+            out->u.iVal = in->u.iVal;
+            break;
+        case MSIFIELD_WSTR:
+            str = strdupW( in->u.szwVal );
+            if ( !str )
+                r = ERROR_OUTOFMEMORY;
+            else
+                out->u.szwVal = str;
+            break;
+        case MSIFIELD_STREAM:
+            IStream_AddRef( in->u.stream );
+            out->u.stream = in->u.stream;
+            break;
+        default:
+            ERR("invalid field type %d\n", in->type);
+        }
+        if (r == ERROR_SUCCESS)
+            out->type = in->type;
+    }
+
+    msiobj_unlock( &in_rec->hdr );
+
+    return r;
+}
+
 int MSI_RecordGetInteger( MSIRECORD *rec, unsigned int iField)
 {
     int ret = 0;
diff --git a/dlls/msi/select.c b/dlls/msi/select.c
index abb2dbd..d47792b 100644
--- a/dlls/msi/select.c
+++ b/dlls/msi/select.c
@@ -102,13 +102,34 @@ static UINT SELECT_set_int( struct tagMS
 static UINT SELECT_insert_row( struct tagMSIVIEW *view, MSIRECORD *record )
 {
     MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
+    UINT i, table_cols, r;
+    MSIRECORD *outrec;
 
     TRACE("%p %p\n", sv, record );
 
-    if( !sv->table )
-         return ERROR_FUNCTION_FAILED;
+    if ( !sv->table )
+        return ERROR_FUNCTION_FAILED;
+
+    /* rearrange the record to suit the table */
+    r = sv->table->ops->get_dimensions( sv->table, NULL, &table_cols );
+    if (r != ERROR_SUCCESS)
+        return r;
+
+    outrec = MSI_CreateRecord( table_cols + 1 );
 
-    return sv->table->ops->insert_row( sv->table, record );
+    for (i=0; i<sv->num_cols; i++)
+    {
+        r = MSI_RecordCopyField( record, i+1, outrec, sv->cols[i] );
+        if (r != ERROR_SUCCESS)
+            goto fail;
+    }
+
+    r = sv->table->ops->insert_row( sv->table, outrec );
+
+fail:
+    msiobj_release( &outrec->hdr );
+
+    return r;
 }
 
 static UINT SELECT_execute( struct tagMSIVIEW *view, MSIRECORD *record )




More information about the wine-cvs mailing list