Module: wine Branch: master Commit: 8ecd34b97132bde3638c56f7e71dd0213af0159d URL: http://source.winehq.org/git/wine.git/?a=commit;h=8ecd34b97132bde3638c56f7e7...
Author: Mike McCormack mike@codeweavers.com Date: Fri Oct 20 01:53:51 2006 +0900
msi: Allow rows in the _Columns table to be unordered.
---
dlls/msi/table.c | 74 ++++++++++++++++++++++++++++++++++++------------------ 1 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 15f4da2..8d416f2 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -34,6 +34,7 @@ #include "objidl.h" #include "winnls.h" #include "msipriv.h" #include "query.h" +#include "assert.h"
#include "wine/debug.h" #include "wine/unicode.h" @@ -81,7 +82,7 @@ #define MAX_STREAM_NAME 0x1f
static UINT table_get_column_info( MSIDATABASE *db, LPCWSTR name, MSICOLUMNINFO **pcols, UINT *pcount ); -static UINT get_tablecolumns( MSIDATABASE *db, +static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz); static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count );
@@ -926,12 +927,14 @@ static LPWSTR msi_makestring( MSIDATABAS return strdupW(msi_string_lookup_id( db->strings, stringid )); }
-static UINT get_tablecolumns( MSIDATABASE *db, +static UINT get_tablecolumns( MSIDATABASE *db, LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz) { UINT r, i, n=0, table_id, count, maxcount = *sz; MSITABLE *table = NULL;
+ TRACE("%s\n", debugstr_w(szTableName)); + /* first check if there is a default table with that name */ r = get_defaulttablecolumns( szTableName, colinfo, sz ); if( ( r == ERROR_SUCCESS ) && *sz ) @@ -954,6 +957,8 @@ static UINT get_tablecolumns( MSIDATABAS
TRACE("Table id is %d, row count is %d\n", table_id, table->row_count);
+ /* if maxcount is non-zero, assume it's exactly right for this table */ + memset( colinfo, 0, maxcount*sizeof(*colinfo) ); count = table->row_count; for( i=0; i<count; i++ ) { @@ -962,32 +967,53 @@ static UINT get_tablecolumns( MSIDATABAS if( colinfo ) { UINT id = table->data[ i ] [ 2 ]; - colinfo[n].tablename = msi_makestring( db, table_id ); - colinfo[n].number = table->data[ i ][ 1 ] - (1<<15); - colinfo[n].colname = msi_makestring( db, id ); - colinfo[n].type = table->data[ i ] [ 3 ] ^ 0x8000; - colinfo[n].hash_table = NULL; - /* this assumes that columns are in order in the table */ - if( n ) - colinfo[n].offset = colinfo[n-1].offset - + bytes_per_column( &colinfo[n-1] ); - else - colinfo[n].offset = 0; - TRACE("table %s column %d is [%s] (%d) with type %08x " - "offset %d at row %d\n", debugstr_w(szTableName), - colinfo[n].number, debugstr_w(colinfo[n].colname), - id, colinfo[n].type, colinfo[n].offset, i); - if( n != (colinfo[n].number-1) ) + UINT col = table->data[ i ][ 1 ] - (1<<15); + + /* check the column number is in range */ + if (col<1 || col>maxcount) { - ERR("oops. data in the _Columns table isn't in the right " - "order for table %s\n", debugstr_w(szTableName)); - msi_free_colinfo(colinfo, n+1 ); - return ERROR_FUNCTION_FAILED; + ERR("column %d out of range\n", col); + continue; } + + /* check if this column was already set */ + if (colinfo[ col - 1 ].number) + { + ERR("duplicate column %d\n", col); + continue; + } + + colinfo[ col - 1 ].tablename = msi_makestring( db, table_id ); + colinfo[ col - 1 ].number = col; + colinfo[ col - 1 ].colname = msi_makestring( db, id ); + colinfo[ col - 1 ].type = table->data[ i ] [ 3 ] - (1<<15); + colinfo[ col - 1 ].offset = 0; + colinfo[ col - 1 ].hash_table = NULL; } n++; - if( colinfo && ( n >= maxcount ) ) - break; + } + + TRACE("%s has %d columns\n", debugstr_w(szTableName), n); + + if (maxcount && n != maxcount) + { + ERR("missing column in table %s\n", debugstr_w(szTableName)); + msi_free_colinfo(colinfo, maxcount ); + return ERROR_FUNCTION_FAILED; + } + + /* calculate the offsets */ + for( i=0; maxcount && (i<maxcount); i++ ) + { + assert( (i+1) == colinfo[ i ].number ); + if (i) + colinfo[i].offset = colinfo[ i - 1 ].offset + + bytes_per_column( &colinfo[ i - 1 ] ); + else + colinfo[i].offset = 0; + TRACE("column %d is [%s] with type %08x ofs %d\n", + colinfo[i].number, debugstr_w(colinfo[i].colname), + colinfo[i].type, colinfo[i].offset); } *sz = n;