diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c index 85c9f51a3f7..eb659047148 100644 --- a/dlls/msi/insert.c +++ b/dlls/msi/insert.c @@ -66,7 +66,6 @@ static MSIRECORD *INSERT_merge_record( UINT fields, column_info *vl, MSIRECORD * { 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( UINT fields, column_info *vl, MSIRECORD * 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 991c11cb1fa..191c7709c62 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -371,6 +371,7 @@ extern UINT MSI_RecordSetStreamW( MSIRECORD *, unsigned int, LPCWSTR ); 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 6c9a56713c9..8bc3871d3d8 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, int *out ) 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 abb2dbdb33b..d47792b225f 100644 --- a/dlls/msi/select.c +++ b/dlls/msi/select.c @@ -102,13 +102,34 @@ static UINT SELECT_set_int( struct tagMSIVIEW *view, UINT row, UINT col, UINT va 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; - return sv->table->ops->insert_row( sv->table, record ); + /* 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 ); + + for (i=0; inum_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 )