Mike McCormack : msi: Allow rows in the _Columns table to be
unordered.
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Oct 19 07:19:18 CDT 2006
Module: wine
Branch: master
Commit: 8ecd34b97132bde3638c56f7e71dd0213af0159d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8ecd34b97132bde3638c56f7e71dd0213af0159d
Author: Mike McCormack <mike at 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;
More information about the wine-cvs
mailing list