msi: Fix writing of long strings to the database.
This commit is contained in:
parent
b9d6ec3b87
commit
5f832b2731
|
@ -328,7 +328,7 @@ extern string_table *msi_init_stringtable( int entries, UINT codepage );
|
||||||
extern VOID msi_destroy_stringtable( string_table *st );
|
extern VOID msi_destroy_stringtable( string_table *st );
|
||||||
extern UINT msi_string_count( 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_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 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 const WCHAR *msi_string_lookup_id( string_table *st, UINT id );
|
||||||
extern UINT msi_string_get_codepage( string_table *st );
|
extern UINT msi_string_get_codepage( string_table *st );
|
||||||
|
|
|
@ -435,13 +435,17 @@ UINT msi_id_refcount( string_table *st, UINT i )
|
||||||
return st->strings[i].refcount;
|
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 )
|
if( st->strings[0].str || st->strings[0].refcount )
|
||||||
ERR("oops. element 0 has a string\n");
|
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++ )
|
for( i=1; i<st->maxcount; i++ )
|
||||||
{
|
{
|
||||||
if( st->strings[i].str )
|
if( st->strings[i].str )
|
||||||
|
@ -451,12 +455,18 @@ UINT msi_string_totalsize( string_table *st, UINT *total )
|
||||||
st->strings[i].str, -1, NULL, 0, NULL, NULL);
|
st->strings[i].str, -1, NULL, 0, NULL, NULL);
|
||||||
if( len )
|
if( len )
|
||||||
len--;
|
len--;
|
||||||
size += len;
|
(*datasize) += len;
|
||||||
*total = (i+1);
|
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 );
|
TRACE("data %u pool %u codepage %x\n", *datasize, *poolsize, st->codepage );
|
||||||
return size;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT msi_string_get_codepage( string_table *st )
|
UINT msi_string_get_codepage( string_table *st )
|
||||||
|
|
|
@ -765,7 +765,7 @@ end:
|
||||||
|
|
||||||
static UINT save_string_table( MSIDATABASE *db )
|
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;
|
UINT ret = ERROR_FUNCTION_FAILED;
|
||||||
static const WCHAR szStringData[] = {
|
static const WCHAR szStringData[] = {
|
||||||
'_','S','t','r','i','n','g','D','a','t','a',0 };
|
'_','S','t','r','i','n','g','D','a','t','a',0 };
|
||||||
|
@ -777,8 +777,9 @@ static UINT save_string_table( MSIDATABASE *db )
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
/* construct the new table in memory first */
|
/* construct the new table in memory first */
|
||||||
datasize = msi_string_totalsize( db->strings, &count );
|
count = msi_string_totalsize( db->strings, &datasize, &poolsize );
|
||||||
poolsize = (count + 1)*2*sizeof(USHORT);
|
|
||||||
|
TRACE("%u %u %u\n", count, datasize, poolsize );
|
||||||
|
|
||||||
pool = msi_alloc( poolsize );
|
pool = msi_alloc( poolsize );
|
||||||
if( ! pool )
|
if( ! pool )
|
||||||
|
@ -797,6 +798,7 @@ static UINT save_string_table( MSIDATABASE *db )
|
||||||
codepage = msi_string_get_codepage( db->strings );
|
codepage = msi_string_get_codepage( db->strings );
|
||||||
pool[0]=codepage&0xffff;
|
pool[0]=codepage&0xffff;
|
||||||
pool[1]=(codepage>>16);
|
pool[1]=(codepage>>16);
|
||||||
|
n = 1;
|
||||||
for( i=1; i<count; i++ )
|
for( i=1; i<count; i++ )
|
||||||
{
|
{
|
||||||
sz = datasize - used;
|
sz = datasize - used;
|
||||||
|
@ -808,9 +810,20 @@ static UINT save_string_table( MSIDATABASE *db )
|
||||||
}
|
}
|
||||||
if( sz && (sz < (datasize - used ) ) )
|
if( sz && (sz < (datasize - used ) ) )
|
||||||
sz--;
|
sz--;
|
||||||
TRACE("adding %u bytes %s\n", sz, debugstr_a(data+used) );
|
|
||||||
pool[ i*2 ] = sz;
|
pool[ n*2 + 1 ] = msi_id_refcount( db->strings, i );
|
||||||
pool[ i*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;
|
used += sz;
|
||||||
if( used > datasize )
|
if( used > datasize )
|
||||||
{
|
{
|
||||||
|
|
|
@ -940,9 +940,7 @@ static void test_longstrings(void)
|
||||||
|
|
||||||
r = MsiRecordGetString(hrec, 2, NULL, &len);
|
r = MsiRecordGetString(hrec, 2, NULL, &len);
|
||||||
ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
|
ok(r == ERROR_SUCCESS, "MsiViewFetch failed\n");
|
||||||
todo_wine {
|
|
||||||
ok(len == STRING_LENGTH, "string length wrong\n");
|
ok(len == STRING_LENGTH, "string length wrong\n");
|
||||||
}
|
|
||||||
|
|
||||||
MsiCloseHandle(hrec);
|
MsiCloseHandle(hrec);
|
||||||
MsiCloseHandle(hdb);
|
MsiCloseHandle(hdb);
|
||||||
|
|
Loading…
Reference in New Issue