Module: wine Branch: master Commit: 2e3289ca6c76627073f8960057a599452654c646 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2e3289ca6c76627073f8960057...
Author: Rob Shearman rob@codeweavers.com Date: Mon Apr 23 08:17:00 2007 +0100
msi: Add support for non-persistent strings.
Store the loaded refcount in the string table.
---
dlls/msi/msipriv.h | 12 +++++++-- dlls/msi/string.c | 63 ++++++++++++++++++++++++++++++++++++--------------- dlls/msi/table.c | 9 +++++-- 3 files changed, 59 insertions(+), 25 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index b160443..b8a4bef 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -542,8 +542,14 @@ extern HRESULT init_string_table( IStorage *stg );
/* string table functions */ -extern BOOL msi_addstring( string_table *st, UINT string_no, const CHAR *data, int len, UINT refcount ); -extern BOOL msi_addstringW( string_table *st, UINT string_no, const WCHAR *data, int len, UINT refcount ); +enum StringPersistence +{ + StringPersistent = 0, + StringNonPersistent = 1 +}; + +extern BOOL msi_addstring( string_table *st, UINT string_no, const CHAR *data, int len, UINT refcount, enum StringPersistence persistence ); +extern BOOL msi_addstringW( string_table *st, UINT string_no, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ); extern UINT msi_id2stringW( string_table *st, UINT string_no, LPWSTR buffer, UINT *sz ); extern UINT msi_id2stringA( string_table *st, UINT string_no, LPSTR buffer, UINT *sz );
@@ -552,7 +558,7 @@ extern UINT msi_string2idA( string_table *st, LPCSTR str, UINT *id ); extern string_table *msi_init_stringtable( int entries, UINT codepage ); 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_id_persistent_refcount( string_table *st, UINT i ); 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 ); diff --git a/dlls/msi/string.c b/dlls/msi/string.c index 7a80663..16ed478 100644 --- a/dlls/msi/string.c +++ b/dlls/msi/string.c @@ -42,7 +42,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb); typedef struct _msistring { int hash_next; - UINT refcount; + UINT persistent_refcount; + UINT nonpersistent_refcount; LPWSTR str; } msistring;
@@ -103,7 +104,8 @@ VOID msi_destroy_stringtable( string_table *st )
for( i=0; i<st->maxcount; i++ ) { - if( st->strings[i].refcount ) + if( st->strings[i].persistent_refcount || + st->strings[i].nonpersistent_refcount ) msi_free( st->strings[i].str ); } msi_free( st->strings ); @@ -120,11 +122,13 @@ static int st_find_free_entry( string_table *st ) if( st->freeslot ) { for( i = st->freeslot; i < st->maxcount; i++ ) - if( !st->strings[i].refcount ) + if( !st->strings[i].persistent_refcount && + !st->strings[i].nonpersistent_refcount ) return i; } for( i = 1; i < st->maxcount; i++ ) - if( !st->strings[i].refcount ) + if( !st->strings[i].persistent_refcount && + !st->strings[i].nonpersistent_refcount ) return i;
/* dynamically resize */ @@ -135,16 +139,27 @@ static int st_find_free_entry( string_table *st ) st->strings = p; st->freeslot = st->maxcount; st->maxcount = sz; - if( st->strings[st->freeslot].refcount ) + if( st->strings[st->freeslot].persistent_refcount || + st->strings[st->freeslot].nonpersistent_refcount ) ERR("oops. expected freeslot to be free...\n"); return st->freeslot; }
-static void set_st_entry( string_table *st, UINT n, LPWSTR str ) +static void set_st_entry( string_table *st, UINT n, LPWSTR str, UINT refcount, enum StringPersistence persistence ) { UINT hash = msistring_makehash( str );
- st->strings[n].refcount = 1; + if (persistence == StringPersistent) + { + st->strings[n].persistent_refcount = refcount; + st->strings[n].nonpersistent_refcount = 0; + } + else + { + st->strings[n].persistent_refcount = 0; + st->strings[n].nonpersistent_refcount = refcount; + } + st->strings[n].str = str;
st->strings[n].hash_next = st->hash[hash]; @@ -154,7 +169,7 @@ static void set_st_entry( string_table *st, UINT n, LPWSTR str ) st->freeslot = n + 1; }
-int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount ) +int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT refcount, enum StringPersistence persistence ) { LPWSTR str; int sz; @@ -165,14 +180,18 @@ int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT ref return 0; if( n > 0 ) { - if( st->strings[n].refcount ) + if( st->strings[n].persistent_refcount || + st->strings[n].nonpersistent_refcount ) return -1; } else { if( ERROR_SUCCESS == msi_string2idA( st, data, &n ) ) { - st->strings[n].refcount++; + if (persistence == StringPersistent) + st->strings[n].persistent_refcount += refcount; + else + st->strings[n].nonpersistent_refcount += refcount; return n; } n = st_find_free_entry( st ); @@ -196,12 +215,12 @@ int msi_addstring( string_table *st, UINT n, const CHAR *data, int len, UINT ref MultiByteToWideChar( st->codepage, 0, data, len, str, sz ); str[sz] = 0;
- set_st_entry( st, n, str ); + set_st_entry( st, n, str, refcount, persistence );
return n; }
-int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount ) +int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT refcount, enum StringPersistence persistence ) { LPWSTR str;
@@ -213,14 +232,18 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT r return 0; if( n > 0 ) { - if( st->strings[n].refcount ) + if( st->strings[n].persistent_refcount || + st->strings[n].nonpersistent_refcount ) return -1; } else { if( ERROR_SUCCESS == msi_string2idW( st, data, &n ) ) { - st->strings[n].refcount++; + if (persistence == StringPersistent) + st->strings[n].persistent_refcount += refcount; + else + st->strings[n].nonpersistent_refcount += refcount; return n; } n = st_find_free_entry( st ); @@ -246,7 +269,7 @@ int msi_addstringW( string_table *st, UINT n, const WCHAR *data, int len, UINT r memcpy( str, data, len*sizeof(WCHAR) ); str[len] = 0;
- set_st_entry( st, n, str ); + set_st_entry( st, n, str, refcount, persistence );
return n; } @@ -261,7 +284,7 @@ const WCHAR *msi_string_lookup_id( string_table *st, UINT id ) if( id >= st->maxcount ) return NULL;
- if( id && !st->strings[id].refcount ) + if( id && !st->strings[id].persistent_refcount && !st->strings[id].nonpersistent_refcount) return NULL;
return st->strings[id].str; @@ -428,18 +451,18 @@ UINT msi_string_count( string_table *st ) return st->maxcount; }
-UINT msi_id_refcount( string_table *st, UINT i ) +UINT msi_id_persistent_refcount( string_table *st, UINT i ) { if( i >= st->maxcount ) return 0; - return st->strings[i].refcount; + return st->strings[i].persistent_refcount; }
UINT msi_string_totalsize( string_table *st, UINT *datasize, UINT *poolsize ) { UINT i, len, max, holesize;
- if( st->strings[0].str || st->strings[0].refcount ) + if( st->strings[0].str || st->strings[0].persistent_refcount || st->strings[0].nonpersistent_refcount) ERR("oops. element 0 has a string\n");
*poolsize = 4; @@ -448,6 +471,8 @@ UINT msi_string_totalsize( string_table *st, UINT *datasize, UINT *poolsize ) holesize = 0; for( i=1; i<st->maxcount; i++ ) { + if( !st->strings[i].persistent_refcount ) + continue; if( st->strings[i].str ) { TRACE("[%u] = %s\n", i, debugstr_w(st->strings[i].str)); diff --git a/dlls/msi/table.c b/dlls/msi/table.c index ce5df79..f256726 100644 --- a/dlls/msi/table.c +++ b/dlls/msi/table.c @@ -743,7 +743,7 @@ string_table *load_string_table( IStorage *stg ) break; }
- r = msi_addstring( st, n, data+offset, len, refs ); + r = msi_addstring( st, n, data+offset, len, refs, StringPersistent ); if( r != n ) ERR("Failed to add string %d\n", n ); n++; @@ -796,6 +796,9 @@ static UINT save_string_table( MSIDATABASE *db ) n = 1; for( i=1; i<count; i++ ) { + UINT refcount = msi_id_persistent_refcount( db->strings, i ); + if( !refcount ) + continue; sz = datasize - used; r = msi_id2stringA( db->strings, i, data+used, &sz ); if( r != ERROR_SUCCESS ) @@ -807,7 +810,7 @@ static UINT save_string_table( MSIDATABASE *db ) sz--;
if (sz) - pool[ n*2 + 1 ] = msi_id_refcount( db->strings, i ); + pool[ n*2 + 1 ] = refcount; else pool[ n*2 + 1 ] = 0; if (sz < 0x10000) @@ -1258,7 +1261,7 @@ static UINT TABLE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI else if ( tv->columns[i].type & MSITYPE_STRING ) { LPCWSTR sval = MSI_RecordGetString( rec, i + 1 ); - val = msi_addstringW( tv->db->strings, 0, sval, -1, 1 ); + val = msi_addstringW( tv->db->strings, 0, sval, -1, 1, StringPersistent ); } else if ( 2 == bytes_per_column( &tv->columns[ i ] ) ) {