ReactOS 0.4.15-dev-7924-g5949c20
string.c
Go to the documentation of this file.
1/*
2 * String Table Functions
3 *
4 * Copyright 2002-2004, Mike McCormack for CodeWeavers
5 * Copyright 2007 Robert Shearman for CodeWeavers
6 * Copyright 2010 Hans Leidekker for CodeWeavers
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#define COBJMACROS
24
25#include <stdarg.h>
26#include <assert.h>
27
28#include "windef.h"
29#include "winbase.h"
30#include "winerror.h"
31#include "wine/debug.h"
32#include "msi.h"
33#include "msiquery.h"
34#include "objbase.h"
35#include "objidl.h"
36#include "msipriv.h"
37#include "winnls.h"
38
39#include "query.h"
40
42
44{
48 int len;
49};
50
52{
53 UINT maxcount; /* the number of strings */
57 struct msistring *strings; /* an array of strings */
58 UINT *sorted; /* index */
59};
60
62{
64 {
65 WARN("invalid codepage %u\n", codepage);
66 return FALSE;
67 }
68 return TRUE;
69}
70
72{
73 string_table *st;
74
76 return NULL;
77
78 st = msi_alloc( sizeof (string_table) );
79 if( !st )
80 return NULL;
81 if( entries < 1 )
82 entries = 1;
83
84 st->strings = msi_alloc_zero( sizeof(struct msistring) * entries );
85 if( !st->strings )
86 {
87 msi_free( st );
88 return NULL;
89 }
90
91 st->sorted = msi_alloc( sizeof (UINT) * entries );
92 if( !st->sorted )
93 {
94 msi_free( st->strings );
95 msi_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}
106
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 msi_free( st->strings[i].data );
116 }
117 msi_free( st->strings );
118 msi_free( st->sorted );
119 msi_free( st );
120}
121
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 = msi_realloc( st->strings, sz * sizeof(*p) ))) return -1;
144 memset( p + st->maxcount, 0, (sz - st->maxcount) * sizeof(*p) );
145
146 if (!(s = msi_realloc( st->sorted, sz * sizeof(*s) )))
147 {
148 msi_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}
162
163static inline int cmp_string( const WCHAR *str1, int len1, const WCHAR *str2, int len2 )
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}
175
176static int find_insert_index( const string_table *st, UINT string_id )
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}
194
195static void insert_string_sorted( string_table *st, UINT string_id )
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}
207
208static void set_st_entry( string_table *st, UINT n, WCHAR *str, int len, USHORT refcount,
209 BOOL persistent )
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}
230
231static UINT string2id( const string_table *st, const char *buffer, UINT *id )
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 = msi_alloc( 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 msi_free( str );
254 return r;
255}
256
257static int add_string( string_table *st, UINT n, const char *data, UINT len, USHORT refcount, BOOL persistent )
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 = msi_alloc( (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}
302
303int msi_add_string( string_table *st, const WCHAR *data, int len, BOOL persistent )
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 = msi_alloc( (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}
341
342/* find the string identified by an id - return null if there's none */
343const WCHAR *msi_string_lookup( const string_table *st, UINT id, int *len )
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}
360
361/*
362 * id2string
363 *
364 * [in] st - pointer to the string table
365 * [in] id - id of the string to retrieve
366 * [out] buffer - destination of the UTF8 string
367 * [in/out] sz - number of bytes available in the buffer on input
368 * number of bytes used on output
369 *
370 * Returned string is not nul terminated.
371 */
372static UINT id2string( const string_table *st, UINT id, char *buffer, UINT *sz )
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}
392
393/*
394 * msi_string2id
395 *
396 * [in] st - pointer to the string table
397 * [in] str - string to find in the string table
398 * [out] id - id of the string, if found
399 */
400UINT msi_string2id( const string_table *st, const WCHAR *str, int len, UINT *id )
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}
423
424static void string_totalsize( const string_table *st, UINT *datasize, UINT *poolsize )
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}
459
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}
477
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 msi_free( pool );
559 msi_free( data );
560
561 return st;
562}
563
564UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *bytes_per_strref )
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 = msi_alloc( poolsize );
579 if( ! pool )
580 {
581 WARN("Failed to alloc pool %d bytes\n", poolsize );
582 goto err;
583 }
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 msi_free( data );
666 msi_free( pool );
667
668 return ret;
669}
670
672{
673 return st->codepage;
674}
675
677{
679 {
680 st->codepage = codepage;
681 return ERROR_SUCCESS;
682 }
684}
static int used
Definition: adh-main.c:39
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
static SIZE_T datasize
Definition: asm.c:30
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
UINT msi_string2id(const string_table *st, const WCHAR *str, int len, UINT *id)
Definition: string.c:400
static UINT id2string(const string_table *st, UINT id, char *buffer, UINT *sz)
Definition: string.c:372
UINT msi_get_string_table_codepage(const string_table *st)
Definition: string.c:671
static int cmp_string(const WCHAR *str1, int len1, const WCHAR *str2, int len2)
Definition: string.c:163
static BOOL validate_codepage(UINT codepage)
Definition: string.c:61
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
static int st_find_free_entry(string_table *st)
Definition: string.c:122
static void string_totalsize(const string_table *st, UINT *datasize, UINT *poolsize)
Definition: string.c:424
HRESULT msi_init_string_table(IStorage *stg)
Definition: string.c:460
static void insert_string_sorted(string_table *st, UINT string_id)
Definition: string.c:195
string_table * msi_load_string_table(IStorage *stg, UINT *bytes_per_strref)
Definition: string.c:478
const WCHAR * msi_string_lookup(const string_table *st, UINT id, int *len)
Definition: string.c:343
VOID msi_destroy_stringtable(string_table *st)
Definition: string.c:107
UINT msi_save_string_table(const string_table *st, IStorage *storage, UINT *bytes_per_strref)
Definition: string.c:564
UINT msi_set_string_table_codepage(string_table *st, UINT codepage)
Definition: string.c:676
static int find_insert_index(const string_table *st, UINT string_id)
Definition: string.c:176
static void set_st_entry(string_table *st, UINT n, WCHAR *str, int len, USHORT refcount, BOOL persistent)
Definition: string.c:208
int msi_add_string(string_table *st, const WCHAR *data, int len, BOOL persistent)
Definition: string.c:303
static UINT string2id(const string_table *st, const char *buffer, UINT *id)
Definition: string.c:231
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLintptr offset
Definition: glext.h:5920
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 S_OK
Definition: intsafe.h:52
#define c
Definition: ke_i.h:80
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
Definition: navigate.c:960
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
static void msi_free(void *mem)
Definition: msipriv.h:1159
#define LONG_STR_BYTES
Definition: msipriv.h:57
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
UINT write_stream_data(IStorage *stg, LPCWSTR stname, LPCVOID data, UINT sz, BOOL bTable) DECLSPEC_HIDDEN
Definition: table.c:296
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define err(...)
const WCHAR * str
#define memset(x, y, z)
Definition: compat.h:39
int zero
Definition: sehframes.cpp:29
#define TRACE(s)
Definition: solgame.cpp:4
WCHAR * data
Definition: string.c:47
USHORT nonpersistent_refcount
Definition: string.c:46
int len
Definition: string.c:48
USHORT persistent_refcount
Definition: string.c:45
UINT codepage
Definition: string.c:55
UINT * sorted
Definition: string.c:58
UINT freeslot
Definition: string.c:54
struct msistring * strings
Definition: string.c:57
UINT sortcount
Definition: string.c:56
UINT maxcount
Definition: string.c:53
int ret
int codepage
Definition: win_iconv.c:156
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193