Module: wine Branch: master Commit: 5f832b27310228f8db1bdafa7e01f99c6b4c60b0 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=5f832b27310228f8db1bdafa...
Author: Mike McCormack mike@codeweavers.com Date: Mon Aug 28 16:51:41 2006 +0900
msi: Fix writing of long strings to the database.
---
dlls/msi/msipriv.h | 2 +- dlls/msi/string.c | 24 +++++++++++++++++------- dlls/msi/table.c | 25 +++++++++++++++++++------ dlls/msi/tests/db.c | 2 -- 4 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index 1c5a894..abaa347 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -328,7 +328,7 @@ extern string_table *msi_init_stringtabl extern VOID msi_destroy_stringtable( string_table *st ); extern UINT msi_string_count( string_table *st ); extern UINT msi_id_refcount( string_table *st, UINT i ); -extern UINT msi_string_totalsize( string_table *st, UINT *last ); +extern UINT msi_string_totalsize( string_table *st, UINT *datasize, UINT *poolsize ); extern UINT msi_strcmp( string_table *st, UINT lval, UINT rval, UINT *res ); extern const WCHAR *msi_string_lookup_id( string_table *st, UINT id ); extern UINT msi_string_get_codepage( string_table *st ); diff --git a/dlls/msi/string.c b/dlls/msi/string.c index 3155c12..db10ae5 100644 --- a/dlls/msi/string.c +++ b/dlls/msi/string.c @@ -435,13 +435,17 @@ UINT msi_id_refcount( string_table *st, return st->strings[i].refcount; }
-UINT msi_string_totalsize( string_table *st, UINT *total ) +UINT msi_string_totalsize( string_table *st, UINT *datasize, UINT *poolsize ) { - UINT size = 0, i, len; + UINT i, len, max, holesize;
if( st->strings[0].str || st->strings[0].refcount ) ERR("oops. element 0 has a string\n"); - *total = 0; + + *poolsize = 4; + *datasize = 0; + max = 1; + holesize = 0; for( i=1; i<st->maxcount; i++ ) { if( st->strings[i].str ) @@ -451,12 +455,18 @@ UINT msi_string_totalsize( string_table st->strings[i].str, -1, NULL, 0, NULL, NULL); if( len ) len--; - size += len; - *total = (i+1); + (*datasize) += len; + if (len>0xffff) + (*poolsize) += 4; + max = i + 1; + (*poolsize) += holesize + 4; + holesize = 0; } + else + holesize += 4; } - TRACE("%u/%u strings %u bytes codepage %x\n", *total, st->maxcount, size, st->codepage ); - return size; + TRACE("data %u pool %u codepage %x\n", *datasize, *poolsize, st->codepage ); + return max; }
UINT msi_string_get_codepage( string_table *st ) diff --git a/dlls/msi/table.c b/dlls/msi/table.c index 57cd4df..fb468bc 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -765,7 +765,7 @@ end:
static UINT save_string_table( MSIDATABASE *db ) { - UINT i, count, datasize, poolsize, sz, used, r, codepage; + UINT i, count, datasize = 0, poolsize = 0, sz, used, r, codepage, n; UINT ret = ERROR_FUNCTION_FAILED; static const WCHAR szStringData[] = { '_','S','t','r','i','n','g','D','a','t','a',0 }; @@ -777,8 +777,9 @@ static UINT save_string_table( MSIDATABA TRACE("\n");
/* construct the new table in memory first */ - datasize = msi_string_totalsize( db->strings, &count ); - poolsize = (count + 1)*2*sizeof(USHORT); + count = msi_string_totalsize( db->strings, &datasize, &poolsize ); + + TRACE("%u %u %u\n", count, datasize, poolsize );
pool = msi_alloc( poolsize ); if( ! pool ) @@ -797,6 +798,7 @@ static UINT save_string_table( MSIDATABA codepage = msi_string_get_codepage( db->strings ); pool[0]=codepage&0xffff; pool[1]=(codepage>>16); + n = 1; for( i=1; i<count; i++ ) { sz = datasize - used; @@ -808,9 +810,20 @@ static UINT save_string_table( MSIDATABA } if( sz && (sz < (datasize - used ) ) ) sz--; - TRACE("adding %u bytes %s\n", sz, debugstr_a(data+used) ); - pool[ i*2 ] = sz; - pool[ i*2 + 1 ] = msi_id_refcount( db->strings, i ); + + pool[ n*2 + 1 ] = msi_id_refcount( db->strings, i ); + if (sz < 0x10000) + { + pool[ n*2 ] = sz; + n++; + } + else + { + pool[ n*2 ] = 0; + pool[ n*2 + 2 ] = sz&0xffff; + pool[ n*2 + 3 ] = (sz>>16); + n += 2; + } used += sz; if( used > datasize ) { diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c index 6da7666..781c6a5 100644 --- a/dlls/msi/tests/db.c +++ b/dlls/msi/tests/db.c @@ -940,9 +940,7 @@ static void test_longstrings(void)
r = MsiRecordGetString(hrec, 2, NULL, &len); ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n"); - todo_wine { ok(len == STRING_LENGTH, "string length wrong\n"); - }
MsiCloseHandle(hrec); MsiCloseHandle(hdb);