ReactOS 0.4.16-dev-106-g10b08aa
string.c File Reference
#include <stdarg.h>
#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
#include "objidl.h"
#include "msipriv.h"
#include "winnls.h"
#include "query.h"
Include dependency graph for string.c:

Go to the source code of this file.

Classes

struct  msistring
 
struct  string_table
 

Macros

#define COBJMACROS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msidb)
 
static BOOL validate_codepage (UINT codepage)
 
static string_tableinit_stringtable (int entries, UINT codepage)
 
VOID msi_destroy_stringtable (string_table *st)
 
static int st_find_free_entry (string_table *st)
 
static int cmp_string (const WCHAR *str1, int len1, const WCHAR *str2, int len2)
 
static int find_insert_index (const string_table *st, UINT string_id)
 
static void insert_string_sorted (string_table *st, UINT string_id)
 
static void set_st_entry (string_table *st, UINT n, WCHAR *str, int len, USHORT refcount, BOOL persistent)
 
static UINT string2id (const string_table *st, const char *buffer, UINT *id)
 
static int add_string (string_table *st, UINT n, const char *data, UINT len, USHORT refcount, BOOL persistent)
 
int msi_add_string (string_table *st, const WCHAR *data, int len, BOOL persistent)
 
const WCHARmsi_string_lookup (const string_table *st, UINT id, int *len)
 
static UINT id2string (const string_table *st, UINT id, char *buffer, UINT *sz)
 
UINT msi_string2id (const string_table *st, const WCHAR *str, int len, UINT *id)
 
static void string_totalsize (const string_table *st, UINT *datasize, UINT *poolsize)
 
HRESULT msi_init_string_table (IStorage *stg)
 
string_tablemsi_load_string_table (IStorage *stg, UINT *bytes_per_strref)
 
UINT msi_save_string_table (const string_table *st, IStorage *storage, UINT *bytes_per_strref)
 
UINT msi_get_string_table_codepage (const string_table *st)
 
UINT msi_set_string_table_codepage (string_table *st, UINT codepage)
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 23 of file string.c.

Function Documentation

◆ add_string()

static int add_string ( string_table st,
UINT  n,
const char data,
UINT  len,
USHORT  refcount,
BOOL  persistent 
)
static

Definition at line 257 of file string.c.

258{
259 LPWSTR str;
260 int sz;
261
262 if( !data || !len )
263 return 0;
264 if( n > 0 )
265 {
266 if( st->strings[n].persistent_refcount ||
267 st->strings[n].nonpersistent_refcount )
268 return -1;
269 }
270 else
271 {
272 if (string2id( st, data, &n ) == ERROR_SUCCESS)
273 {
274 if (persistent)
275 st->strings[n].persistent_refcount += refcount;
276 else
277 st->strings[n].nonpersistent_refcount += refcount;
278 return n;
279 }
280 n = st_find_free_entry( st );
281 if( n == -1 )
282 return -1;
283 }
284
285 if( n < 1 )
286 {
287 ERR("invalid index adding %s (%d)\n", debugstr_a( data ), n );
288 return -1;
289 }
290
291 /* allocate a new string */
292 sz = MultiByteToWideChar( st->codepage, 0, data, len, NULL, 0 );
293 str = malloc( (sz + 1) * sizeof(WCHAR) );
294 if( !str )
295 return -1;
296 MultiByteToWideChar( st->codepage, 0, data, len, str, sz );
297 str[sz] = 0;
298
299 set_st_entry( st, n, str, sz, refcount, persistent );
300 return n;
301}
#define ERR(fmt,...)
Definition: precomp.h:57
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define MultiByteToWideChar
Definition: compat.h:110
static int st_find_free_entry(string_table *st)
Definition: string.c:122
static void set_st_entry(string_table *st, UINT n, WCHAR *str, int len, USHORT refcount, BOOL persistent)
Definition: string.c:208
static UINT string2id(const string_table *st, const char *buffer, UINT *id)
Definition: string.c:231
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_a
Definition: kernel32.h:31
const WCHAR * str
UINT codepage
Definition: string.c:55
struct msistring * strings
Definition: string.c:57
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by msi_load_string_table().

◆ cmp_string()

static int cmp_string ( const WCHAR str1,
int  len1,
const WCHAR str2,
int  len2 
)
inlinestatic

Definition at line 163 of file string.c.

164{
165 if (len1 < len2) return -1;
166 else if (len1 > len2) return 1;
167 while (len1)
168 {
169 if (*str1 == *str2) { str1++; str2++; }
170 else return *str1 - *str2;
171 len1--;
172 }
173 return 0;
174}

Referenced by find_insert_index(), and msi_string2id().

◆ find_insert_index()

static int find_insert_index ( const string_table st,
UINT  string_id 
)
static

Definition at line 176 of file string.c.

177{
178 int i, c, low = 0, high = st->sortcount - 1;
179
180 while (low <= high)
181 {
182 i = (low + high) / 2;
183 c = cmp_string( st->strings[string_id].data, st->strings[string_id].len,
184 st->strings[st->sorted[i]].data, st->strings[st->sorted[i]].len );
185 if (c < 0)
186 high = i - 1;
187 else if (c > 0)
188 low = i + 1;
189 else
190 return -1; /* already exists */
191 }
192 return high + 1;
193}
static int cmp_string(const WCHAR *str1, int len1, const WCHAR *str2, int len2)
Definition: string.c:163
const GLubyte * c
Definition: glext.h:8905
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define c
Definition: ke_i.h:80
UINT * sorted
Definition: string.c:58
UINT sortcount
Definition: string.c:56

Referenced by insert_string_sorted().

◆ id2string()

static UINT id2string ( const string_table st,
UINT  id,
char buffer,
UINT sz 
)
static

Definition at line 372 of file string.c.

373{
374 int len, lenW;
375 const WCHAR *str;
376
377 TRACE("Finding string %d of %d\n", id, st->maxcount);
378
379 str = msi_string_lookup( st, id, &lenW );
380 if( !str )
382
383 len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL );
384 if( *sz < len )
385 {
386 *sz = len;
387 return ERROR_MORE_DATA;
388 }
389 *sz = WideCharToMultiByte( st->codepage, 0, str, lenW, buffer, *sz, NULL, NULL );
390 return ERROR_SUCCESS;
391}
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define WideCharToMultiByte
Definition: compat.h:111
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len)
Definition: string.c:343
GLuint buffer
Definition: glext.h:5915
#define TRACE(s)
Definition: solgame.cpp:4
UINT maxcount
Definition: string.c:53
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985

Referenced by msi_save_string_table().

◆ init_stringtable()

static string_table * init_stringtable ( int  entries,
UINT  codepage 
)
static

Definition at line 71 of file string.c.

72{
73 string_table *st;
74
76 return NULL;
77
78 st = malloc( sizeof(string_table) );
79 if( !st )
80 return NULL;
81 if( entries < 1 )
82 entries = 1;
83
84 st->strings = calloc( entries, sizeof(struct msistring) );
85 if( !st->strings )
86 {
87 free( st );
88 return NULL;
89 }
90
91 st->sorted = malloc( sizeof(UINT) * entries );
92 if( !st->sorted )
93 {
94 free( st->strings );
95 free( st );
96 return NULL;
97 }
98
99 st->maxcount = entries;
100 st->freeslot = 1;
101 st->codepage = codepage;
102 st->sortcount = 0;
103
104 return st;
105}
#define free
Definition: debug_ros.c:5
static BOOL validate_codepage(UINT codepage)
Definition: string.c:61
unsigned int UINT
Definition: ndis.h:50
#define calloc
Definition: rosglue.h:14
UINT freeslot
Definition: string.c:54
int codepage
Definition: win_iconv.c:156

Referenced by msi_load_string_table().

◆ insert_string_sorted()

static void insert_string_sorted ( string_table st,
UINT  string_id 
)
static

Definition at line 195 of file string.c.

196{
197 int i;
198
199 i = find_insert_index( st, string_id );
200 if (i == -1)
201 return;
202
203 memmove( &st->sorted[i] + 1, &st->sorted[i], (st->sortcount - i) * sizeof(UINT) );
204 st->sorted[i] = string_id;
205 st->sortcount++;
206}
static int find_insert_index(const string_table *st, UINT string_id)
Definition: string.c:176
#define memmove(s1, s2, n)
Definition: mkisofs.h:881

Referenced by set_st_entry().

◆ msi_add_string()

int msi_add_string ( string_table st,
const WCHAR data,
int  len,
BOOL  persistent 
)

Definition at line 303 of file string.c.

304{
305 UINT n;
306 LPWSTR str;
307
308 if( !data )
309 return 0;
310
311 if (len < 0) len = lstrlenW( data );
312
313 if( !data[0] && !len )
314 return 0;
315
316 if (msi_string2id( st, data, len, &n) == ERROR_SUCCESS )
317 {
318 if (persistent)
319 st->strings[n].persistent_refcount++;
320 else
321 st->strings[n].nonpersistent_refcount++;
322 return n;
323 }
324
325 n = st_find_free_entry( st );
326 if( n == -1 )
327 return -1;
328
329 /* allocate a new string */
330 TRACE( "%s, n = %d len = %d\n", debugstr_wn(data, len), n, len );
331
332 str = malloc( (len + 1) * sizeof(WCHAR) );
333 if( !str )
334 return -1;
335 memcpy( str, data, len*sizeof(WCHAR) );
336 str[len] = 0;
337
338 set_st_entry( st, n, str, len, 1, persistent );
339 return n;
340}
#define lstrlenW
Definition: compat.h:750
UINT msi_string2id(const string_table *st, const WCHAR *str, int len, UINT *id)
Definition: string.c:400
#define debugstr_wn
Definition: kernel32.h:33
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878

Referenced by add_storages_to_table(), append_stream(), msi_create_table(), STORAGES_set_row(), STREAMS_set_row(), TABLE_add_column(), TABLE_set_row(), and TABLE_set_string().

◆ msi_destroy_stringtable()

VOID msi_destroy_stringtable ( string_table st)

Definition at line 107 of file string.c.

108{
109 UINT i;
110
111 for( i=0; i<st->maxcount; i++ )
112 {
113 if( st->strings[i].persistent_refcount ||
114 st->strings[i].nonpersistent_refcount )
115 free( st->strings[i].data );
116 }
117 free( st->strings );
118 free( st->sorted );
119 free( st );
120}

Referenced by MSI_CloseDatabase(), and msi_table_apply_transform().

◆ msi_get_string_table_codepage()

UINT msi_get_string_table_codepage ( const string_table st)

Definition at line 671 of file string.c.

672{
673 return st->codepage;
674}

Referenced by ACTION_ExecuteAction(), MSI_DatabaseExport(), and MSI_OpenPackageW().

◆ msi_init_string_table()

HRESULT msi_init_string_table ( IStorage stg)

Definition at line 460 of file string.c.

461{
462 USHORT zero[2] = { 0, 0 };
463 UINT ret;
464
465 /* create the StringPool stream... add the zero string to it*/
466 ret = write_stream_data(stg, L"_StringPool", zero, sizeof zero, TRUE);
467 if (ret != ERROR_SUCCESS)
468 return E_FAIL;
469
470 /* create the StringData stream... make it zero length */
471 ret = write_stream_data(stg, L"_StringData", NULL, 0, TRUE);
472 if (ret != ERROR_SUCCESS)
473 return E_FAIL;
474
475 return S_OK;
476}
#define E_FAIL
Definition: ddrawi.h:102
#define TRUE
Definition: types.h:120
#define S_OK
Definition: intsafe.h:52
UINT write_stream_data(IStorage *stg, LPCWSTR stname, LPCVOID data, UINT sz, BOOL bTable)
Definition: table.c:298
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
int zero
Definition: sehframes.cpp:29
int ret

Referenced by db_initialize().

◆ msi_load_string_table()

string_table * msi_load_string_table ( IStorage stg,
UINT bytes_per_strref 
)

Definition at line 478 of file string.c.

479{
480 string_table *st = NULL;
481 CHAR *data = NULL;
482 USHORT *pool = NULL;
483 UINT r, datasize = 0, poolsize = 0, codepage;
484 DWORD i, count, offset, len, n, refs;
485
486 r = read_stream_data( stg, L"_StringPool", TRUE, (BYTE **)&pool, &poolsize );
487 if( r != ERROR_SUCCESS)
488 goto end;
489 r = read_stream_data( stg, L"_StringData", TRUE, (BYTE **)&data, &datasize );
490 if( r != ERROR_SUCCESS)
491 goto end;
492
493 if ( (poolsize > 4) && (pool[1] & 0x8000) )
494 *bytes_per_strref = LONG_STR_BYTES;
495 else
496 *bytes_per_strref = sizeof(USHORT);
497
498 count = poolsize/4;
499 if( poolsize > 4 )
500 codepage = pool[0] | ( (pool[1] & ~0x8000) << 16 );
501 else
504 if (!st)
505 goto end;
506
507 offset = 0;
508 n = 1;
509 i = 1;
510 while( i<count )
511 {
512 /* the string reference count is always the second word */
513 refs = pool[i*2+1];
514
515 /* empty entries have two zeros, still have a string id */
516 if (pool[i*2] == 0 && refs == 0)
517 {
518 i++;
519 n++;
520 continue;
521 }
522
523 /*
524 * If a string is over 64k, the previous string entry is made null
525 * and its the high word of the length is inserted in the null string's
526 * reference count field.
527 */
528 if( pool[i*2] == 0)
529 {
530 len = (pool[i*2+3] << 16) + pool[i*2+2];
531 i += 2;
532 }
533 else
534 {
535 len = pool[i*2];
536 i += 1;
537 }
538
539 if ( (offset + len) > datasize )
540 {
541 ERR("string table corrupt?\n");
542 break;
543 }
544
545 r = add_string( st, n, data+offset, len, refs, TRUE );
546 if( r != n )
547 ERR( "Failed to add string %lu\n", n );
548 n++;
549 offset += len;
550 }
551
552 if ( datasize != offset )
553 ERR( "string table load failed! (%u != %lu), please report\n", datasize, offset );
554
555 TRACE( "loaded %lu strings\n", count );
556
557end:
558 free( pool );
559 free( data );
560
561 return st;
562}
static SIZE_T datasize
Definition: asm.c:30
#define CP_ACP
Definition: compat.h:109
static int add_string(string_table *st, UINT n, const char *data, UINT len, USHORT refcount, BOOL persistent)
Definition: string.c:257
static string_table * init_stringtable(int entries, UINT codepage)
Definition: string.c:71
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLintptr offset
Definition: glext.h:5920
static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
Definition: navigate.c:960
#define LONG_STR_BYTES
Definition: msipriv.h:57
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193

Referenced by MSI_OpenDatabaseW(), and msi_table_apply_transform().

◆ msi_save_string_table()

UINT msi_save_string_table ( const string_table st,
IStorage storage,
UINT bytes_per_strref 
)

Definition at line 564 of file string.c.

565{
566 UINT i, datasize = 0, poolsize = 0, sz, used, r, codepage, n;
568 CHAR *data = NULL;
569 USHORT *pool = NULL;
570
571 TRACE("\n");
572
573 /* construct the new table in memory first */
574 string_totalsize( st, &datasize, &poolsize );
575
576 TRACE("%u %u %u\n", st->maxcount, datasize, poolsize );
577
578 pool = malloc( poolsize );
579 if( ! pool )
580 {
581 WARN("Failed to alloc pool %d bytes\n", poolsize );
582 goto err;
583 }
584 data = malloc( datasize );
585 if( ! data )
586 {
587 WARN("Failed to alloc data %d bytes\n", datasize );
588 goto err;
589 }
590
591 used = 0;
592 codepage = st->codepage;
593 pool[0] = codepage & 0xffff;
594 pool[1] = codepage >> 16;
595 if (st->maxcount > 0xffff)
596 {
597 pool[1] |= 0x8000;
598 *bytes_per_strref = LONG_STR_BYTES;
599 }
600 else
601 *bytes_per_strref = sizeof(USHORT);
602
603 n = 1;
604 for( i=1; i<st->maxcount; i++ )
605 {
606 if( !st->strings[i].persistent_refcount )
607 {
608 pool[ n*2 ] = 0;
609 pool[ n*2 + 1] = 0;
610 n++;
611 continue;
612 }
613
614 sz = datasize - used;
615 r = id2string( st, i, data+used, &sz );
616 if( r != ERROR_SUCCESS )
617 {
618 ERR("failed to fetch string\n");
619 sz = 0;
620 }
621
622 if (sz)
623 pool[ n*2 + 1 ] = st->strings[i].persistent_refcount;
624 else
625 pool[ n*2 + 1 ] = 0;
626 if (sz < 0x10000)
627 {
628 pool[ n*2 ] = sz;
629 n++;
630 }
631 else
632 {
633 pool[ n*2 ] = 0;
634 pool[ n*2 + 2 ] = sz&0xffff;
635 pool[ n*2 + 3 ] = (sz>>16);
636 n += 2;
637 }
638 used += sz;
639 if( used > datasize )
640 {
641 ERR("oops overran %d >= %d\n", used, datasize);
642 goto err;
643 }
644 }
645
646 if( used != datasize )
647 {
648 ERR("oops used %d != datasize %d\n", used, datasize);
649 goto err;
650 }
651
652 /* write the streams */
653 r = write_stream_data( storage, L"_StringData", data, datasize, TRUE );
654 TRACE("Wrote StringData r=%08x\n", r);
655 if( r )
656 goto err;
657 r = write_stream_data( storage, L"_StringPool", pool, poolsize, TRUE );
658 TRACE("Wrote StringPool r=%08x\n", r);
659 if( r )
660 goto err;
661
663
664err:
665 free( data );
666 free( pool );
667
668 return ret;
669}
static int used
Definition: adh-main.c:39
#define WARN(fmt,...)
Definition: precomp.h:61
static UINT id2string(const string_table *st, UINT id, char *buffer, UINT *sz)
Definition: string.c:372
static void string_totalsize(const string_table *st, UINT *datasize, UINT *poolsize)
Definition: string.c:424
#define err(...)

Referenced by MSI_CommitTables().

◆ msi_set_string_table_codepage()

UINT msi_set_string_table_codepage ( string_table st,
UINT  codepage 
)

Definition at line 676 of file string.c.

677{
679 {
680 st->codepage = codepage;
681 return ERROR_SUCCESS;
682 }
684}

Referenced by MSI_DatabaseImport().

◆ msi_string2id()

UINT msi_string2id ( const string_table st,
const WCHAR str,
int  len,
UINT id 
)

Definition at line 400 of file string.c.

401{
402 int i, c, low = 0, high = st->sortcount - 1;
403
404 if (len < 0) len = lstrlenW( str );
405
406 while (low <= high)
407 {
408 i = (low + high) / 2;
409 c = cmp_string( str, len, st->strings[st->sorted[i]].data, st->strings[st->sorted[i]].len );
410
411 if (c < 0)
412 high = i - 1;
413 else if (c > 0)
414 low = i + 1;
415 else
416 {
417 *id = st->sorted[i];
418 return ERROR_SUCCESS;
419 }
420 }
422}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101

Referenced by find_stream(), get_table_value_from_record(), get_tablecolumns(), join_find_row(), msi_add_string(), record_to_row(), storages_find_row(), streams_find_row(), string2id(), TABLE_add_column(), TABLE_Exists(), TABLE_set_string(), and TransformView_Create().

◆ msi_string_lookup()

const WCHAR * msi_string_lookup ( const string_table st,
UINT  id,
int len 
)

Definition at line 343 of file string.c.

344{
345 if( id == 0 )
346 {
347 if (len) *len = 0;
348 return L"";
349 }
350 if( id >= st->maxcount )
351 return NULL;
352
353 if( id && !st->strings[id].persistent_refcount && !st->strings[id].nonpersistent_refcount)
354 return NULL;
355
356 if (len) *len = st->strings[id].len;
357
358 return st->strings[id].data;
359}
GLuint id
Definition: glext.h:5910

Referenced by dump_table(), get_stream_name(), get_tablecolumns(), get_transform_record(), id2string(), msi_commit_streams(), msi_create_table(), msi_view_refresh_row(), STORAGES_set_stream(), STREAMS_delete_row(), STRING_evaluate(), TABLE_add_column(), TransformView_Create(), and TransformView_drop_table().

◆ set_st_entry()

static void set_st_entry ( string_table st,
UINT  n,
WCHAR str,
int  len,
USHORT  refcount,
BOOL  persistent 
)
static

Definition at line 208 of file string.c.

210{
211 if (persistent)
212 {
213 st->strings[n].persistent_refcount = refcount;
214 st->strings[n].nonpersistent_refcount = 0;
215 }
216 else
217 {
218 st->strings[n].persistent_refcount = 0;
219 st->strings[n].nonpersistent_refcount = refcount;
220 }
221
222 st->strings[n].data = str;
223 st->strings[n].len = len;
224
225 insert_string_sorted( st, n );
226
227 if( n < st->maxcount )
228 st->freeslot = n + 1;
229}
static void insert_string_sorted(string_table *st, UINT string_id)
Definition: string.c:195

Referenced by add_string(), and msi_add_string().

◆ st_find_free_entry()

static int st_find_free_entry ( string_table st)
static

Definition at line 122 of file string.c.

123{
124 UINT i, sz, *s;
125 struct msistring *p;
126
127 TRACE("%p\n", st);
128
129 if( st->freeslot )
130 {
131 for( i = st->freeslot; i < st->maxcount; i++ )
132 if( !st->strings[i].persistent_refcount &&
133 !st->strings[i].nonpersistent_refcount )
134 return i;
135 }
136 for( i = 1; i < st->maxcount; i++ )
137 if( !st->strings[i].persistent_refcount &&
138 !st->strings[i].nonpersistent_refcount )
139 return i;
140
141 /* dynamically resize */
142 sz = st->maxcount + 1 + st->maxcount / 2;
143 if (!(p = realloc( st->strings, sz * sizeof(*p) ))) return -1;
144 memset( p + st->maxcount, 0, (sz - st->maxcount) * sizeof(*p) );
145
146 if (!(s = realloc( st->sorted, sz * sizeof(*s) )))
147 {
148 free( p );
149 return -1;
150 }
151
152 st->strings = p;
153 st->sorted = s;
154
155 st->freeslot = st->maxcount;
156 st->maxcount = sz;
157 if( st->strings[st->freeslot].persistent_refcount ||
158 st->strings[st->freeslot].nonpersistent_refcount )
159 ERR("oops. expected freeslot to be free...\n");
160 return st->freeslot;
161}
#define realloc
Definition: debug_ros.c:6
GLdouble s
Definition: gl.h:2039
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39

Referenced by add_string(), and msi_add_string().

◆ string2id()

static UINT string2id ( const string_table st,
const char buffer,
UINT id 
)
static

Definition at line 231 of file string.c.

232{
233 int sz;
235 LPWSTR str;
236
237 TRACE("Finding string %s in string table\n", debugstr_a(buffer) );
238
239 if( buffer[0] == 0 )
240 {
241 *id = 0;
242 return ERROR_SUCCESS;
243 }
244
245 if (!(sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 )))
246 return r;
247 str = malloc( sz * sizeof(WCHAR) );
248 if( !str )
250 MultiByteToWideChar( st->codepage, 0, buffer, -1, str, sz );
251
252 r = msi_string2id( st, str, sz - 1, id );
253 free( str );
254 return r;
255}
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7

Referenced by add_string().

◆ string_totalsize()

static void string_totalsize ( const string_table st,
UINT datasize,
UINT poolsize 
)
static

Definition at line 424 of file string.c.

425{
426 UINT i, len, holesize;
427
428 if( st->strings[0].data || st->strings[0].persistent_refcount || st->strings[0].nonpersistent_refcount)
429 ERR("oops. element 0 has a string\n");
430
431 *poolsize = 4;
432 *datasize = 0;
433 holesize = 0;
434 for( i=1; i<st->maxcount; i++ )
435 {
436 if( !st->strings[i].persistent_refcount )
437 {
438 TRACE("[%u] nonpersistent = %s\n", i, debugstr_wn(st->strings[i].data, st->strings[i].len));
439 (*poolsize) += 4;
440 }
441 else if( st->strings[i].data )
442 {
443 TRACE("[%u] = %s\n", i, debugstr_wn(st->strings[i].data, st->strings[i].len));
444 len = WideCharToMultiByte( st->codepage, 0, st->strings[i].data, st->strings[i].len + 1,
445 NULL, 0, NULL, NULL);
446 if( len )
447 len--;
448 (*datasize) += len;
449 if (len>0xffff)
450 (*poolsize) += 4;
451 (*poolsize) += holesize + 4;
452 holesize = 0;
453 }
454 else
455 holesize += 4;
456 }
457 TRACE("data %u pool %u codepage %x\n", *datasize, *poolsize, st->codepage );
458}

Referenced by msi_save_string_table().

◆ validate_codepage()

static BOOL validate_codepage ( UINT  codepage)
static

Definition at line 61 of file string.c.

62{
64 {
65 WARN("invalid codepage %u\n", codepage);
66 return FALSE;
67 }
68 return TRUE;
69}
#define FALSE
Definition: types.h:117
BOOL WINAPI IsValidCodePage(UINT codepage)
Definition: locale.c:2078

Referenced by init_stringtable(), and msi_set_string_table_codepage().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msidb  )