ReactOS 0.4.15-dev-7788-g1ad9096
format.c
Go to the documentation of this file.
1/*
2 * Implementation of the Microsoft Installer (msi.dll)
3 *
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2005 Aric Stewart for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24
25#define COBJMACROS
26
27#include "windef.h"
28#include "winbase.h"
29#include "winerror.h"
30#include "wine/debug.h"
31#include "msi.h"
32#include "winnls.h"
33#include "objbase.h"
34#include "oleauto.h"
35
36#include "msipriv.h"
37#include "winemsi_s.h"
38#include "wine/exception.h"
39
41
42/* types arranged by precedence */
43#define FORMAT_NULL 0x0001
44#define FORMAT_LITERAL 0x0002
45#define FORMAT_NUMBER 0x0004
46#define FORMAT_LBRACK 0x0010
47#define FORMAT_LBRACE 0x0020
48#define FORMAT_RBRACK 0x0011
49#define FORMAT_RBRACE 0x0021
50#define FORMAT_ESCAPE 0x0040
51#define FORMAT_PROPNULL 0x0080
52#define FORMAT_ERROR 0x1000
53#define FORMAT_FAIL 0x2000
54
55#define left_type(x) (x & 0xF0)
56
57typedef struct _tagFORMAT
58{
62 int len;
63 int n;
66 int groups;
68
69typedef struct _tagFORMSTR
70{
71 struct list entry;
72 int n;
73 int len;
74 int type;
78
79typedef struct _tagSTACK
80{
81 struct list items;
83
84static STACK *create_stack(void)
85{
86 STACK *stack = msi_alloc(sizeof(STACK));
87 list_init(&stack->items);
88 return stack;
89}
90
91static void free_stack(STACK *stack)
92{
93 while (!list_empty(&stack->items))
94 {
96 list_remove(&str->entry);
98 }
99
101}
102
104{
105 list_add_head(&stack->items, &str->entry);
106}
107
109{
110 FORMSTR *ret;
111
112 if (list_empty(&stack->items))
113 return NULL;
114
116 list_remove(&ret->entry);
117 return ret;
118}
119
121{
122 FORMSTR *str;
123
125 {
126 if (str->type == type)
127 return str;
128 }
129
130 return NULL;
131}
132
134{
135 return LIST_ENTRY(list_head(&stack->items), FORMSTR, entry);
136}
137
139{
140 return &format->deformatted[str->n];
141}
142
144{
145 WCHAR *val;
146
147 if (!str->len) return NULL;
148 if ((val = msi_alloc( (str->len + 1) * sizeof(WCHAR) )))
149 {
150 memcpy( val, get_formstr_data(format, str), str->len * sizeof(WCHAR) );
151 val[str->len] = 0;
152 *ret_len = str->len;
153 }
154 return val;
155}
156
158{
159 WCHAR *val, *ret;
160 DWORD len;
161 int field;
162
163 if (!(val = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
165 field = wcstol( val, NULL, 10 );
166 msi_free( val );
167
168 if (MSI_RecordIsNull( format->record, field ) ||
169 MSI_RecordGetStringW( format->record, field, NULL, &len )) return NULL;
170
171 len++;
172 if (!(ret = msi_alloc( len * sizeof(WCHAR) ))) return NULL;
173 ret[0] = 0;
174 if (MSI_RecordGetStringW( format->record, field, ret, &len ))
175 {
176 msi_free( ret );
177 return NULL;
178 }
179 *ret_len = len;
180 return ret;
181}
182
184{
185 WCHAR *prop, *ret;
186 DWORD len = 0;
187 UINT r;
188
189 if (!(prop = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
190 lstrcpynW( prop, get_formstr_data(format, str), str->len + 1 );
191
192 r = msi_get_property( format->package->db, prop, NULL, &len );
193 if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
194 {
195 msi_free( prop );
196 return NULL;
197 }
198 len++;
199 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
200 msi_get_property( format->package->db, prop, ret, &len );
201 msi_free( prop );
202 *ret_len = len;
203 return ret;
204}
205
207{
208 WCHAR *key, *ret;
209 MSICOMPONENT *comp;
210
211 if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
213
214 if (!(comp = msi_get_loaded_component( format->package, key )))
215 {
216 msi_free( key );
217 return NULL;
218 }
219 if (comp->Action == INSTALLSTATE_SOURCE)
220 ret = msi_resolve_source_folder( format->package, comp->Directory, NULL );
221 else
222 ret = strdupW( msi_get_target_folder( format->package, comp->Directory ) );
223
224 if (ret) *ret_len = lstrlenW( ret );
225 else *ret_len = 0;
226 msi_free( key );
227 return ret;
228}
229
230static WCHAR *deformat_file( FORMAT *format, FORMSTR *str, BOOL shortname, int *ret_len )
231{
232 WCHAR *key, *ret = NULL;
233 const MSIFILE *file;
234 DWORD len = 0;
235
236 if (!(key = msi_alloc( (str->len + 1) * sizeof(WCHAR) ))) return NULL;
238
239 if (!(file = msi_get_loaded_file( format->package, key ))) goto done;
240 if (!shortname)
241 {
242 if ((ret = strdupW( file->TargetPath ))) len = lstrlenW( ret );
243 goto done;
244 }
245 if (!(len = GetShortPathNameW(file->TargetPath, NULL, 0)))
246 {
247 if ((ret = strdupW( file->TargetPath ))) len = lstrlenW( ret );
248 goto done;
249 }
250 len++;
251 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
252 len = GetShortPathNameW( file->TargetPath, ret, len );
253
254done:
255 msi_free( key );
256 *ret_len = len;
257 return ret;
258}
259
261{
262 WCHAR *key, *ret = NULL;
263 DWORD len;
264
265 if (!(key = msi_alloc((str->len + 1) * sizeof(WCHAR)))) return NULL;
267
268 if ((len = GetEnvironmentVariableW( key, NULL, 0 )))
269 {
270 len++;
271 if ((ret = msi_alloc( len * sizeof(WCHAR) )))
273 }
274 msi_free( key );
275 return ret;
276}
277
279 int *type, int *len )
280{
282 WCHAR *replaced = NULL;
283 char ch = data[0];
284
285 if (ch == '\\')
286 {
287 str->n++;
288 if (str->len == 1)
289 {
290 str->len = 0;
291 replaced = NULL;
292 }
293 else
294 {
295 str->len = 1;
296 replaced = dup_formstr( format, str, len );
297 }
298 }
299 else if (ch == '~')
300 {
301 if (str->len != 1)
302 replaced = NULL;
303 else if ((replaced = msi_alloc( sizeof(WCHAR) )))
304 {
305 *replaced = 0;
306 *len = 0;
307 }
308 }
309 else if (ch == '%' || ch == '#' || ch == '!' || ch == '$')
310 {
311 str->n++;
312 str->len--;
313
314 switch (ch)
315 {
316 case '%':
317 replaced = deformat_environment( format, str, len ); break;
318 case '#':
319 replaced = deformat_file( format, str, FALSE, len ); break;
320 case '!':
321 replaced = deformat_file( format, str, TRUE, len ); break;
322 case '$':
323 replaced = deformat_component( format, str, len ); break;
324 }
325
327 }
328 else
329 {
330 replaced = deformat_property( format, str, len );
332
333 if (replaced)
334 *propfound = TRUE;
335 else
336 format->propfailed = TRUE;
337 }
338
339 return replaced;
340}
341
343{
345 WCHAR *ret, *tmp, buf[26];
346 DWORD size = 1;
347
348 if (!(ret = msi_alloc( sizeof(*ret) ))) return NULL;
349 ret[0] = 0;
350
351 for (i = 1; i <= count; i++)
352 {
353 size += swprintf( buf, ARRAY_SIZE(buf), L"%d: [%d] ", i, i );
354 if (!(tmp = msi_realloc( ret, size * sizeof(*ret) )))
355 {
356 msi_free( ret );
357 return NULL;
358 }
359 ret = tmp;
360 lstrcatW( ret, buf );
361 }
362 return ret;
363}
364
366{
367 return ((x >= '0') && (x <= '9'));
368}
369
371{
372 LPWSTR ptr;
373
374 for (ptr = str; *ptr; ptr++)
375 if (!format_is_number(*ptr))
376 return FALSE;
377
378 return TRUE;
379}
380
382{
383 return (!format_is_number(x) && x != '\0' &&
384 x != '[' && x != ']' && x != '{' && x != '}');
385}
386
388{
389 return (format_is_alpha(x) || format_is_number(x));
390}
391
393{
394 int type, len = 1;
395 FORMSTR *str;
397 WCHAR ch;
398
399 *out = NULL;
400
401 if (!format->deformatted)
402 return FORMAT_NULL;
403
404 *out = msi_alloc_zero(sizeof(FORMSTR));
405 if (!*out)
406 return FORMAT_FAIL;
407
408 str = *out;
409 str->n = format->n;
410 str->len = 1;
412
413 ch = data[0];
414 switch (ch)
415 {
416 case '{': type = FORMAT_LBRACE; break;
417 case '}': type = FORMAT_RBRACE; break;
418 case '[': type = FORMAT_LBRACK; break;
419 case ']': type = FORMAT_RBRACK; break;
420 case '~': type = FORMAT_PROPNULL; break;
421 case '\0': type = FORMAT_NULL; break;
422
423 default:
424 type = 0;
425 }
426
427 if (type)
428 {
429 str->type = type;
430 format->n++;
431 return type;
432 }
433
434 if (ch == '\\')
435 {
436 while (data[len] && data[len] != ']')
437 len++;
438
440 }
441 else if (format_is_alpha(ch))
442 {
443 while (format_is_literal(data[len]))
444 len++;
445
447 }
448 else if (format_is_number(ch))
449 {
450 while (format_is_number(data[len]))
451 len++;
452
454
455 if (data[len] != ']')
456 {
457 while (format_is_literal(data[len]))
458 len++;
459
461 }
462 }
463 else
464 {
465 ERR("Got unknown character %c(%x)\n", ch, ch);
466 return FORMAT_ERROR;
467 }
468
469 format->n += len;
470 str->len = len;
471 str->type = type;
472
473 return type;
474}
475
476static FORMSTR *format_replace( FORMAT *format, BOOL propfound, BOOL nonprop,
477 int oldsize, int type, WCHAR *replace, int len )
478{
479 FORMSTR *ret;
480 LPWSTR str, ptr;
481 DWORD size = 0;
482 int n;
483
484 if (replace)
485 {
486 if (!len)
487 size = 1;
488 else
489 size = len;
490 }
491
492 size -= oldsize;
493 size = format->len + size + 1;
494
495 if (size <= 1)
496 {
497 msi_free(format->deformatted);
498 format->deformatted = NULL;
499 format->len = 0;
500 return NULL;
501 }
502
503 str = msi_alloc(size * sizeof(WCHAR));
504 if (!str)
505 return NULL;
506
507 str[0] = '\0';
508 memcpy(str, format->deformatted, format->n * sizeof(WCHAR));
509 n = format->n;
510
511 if (replace)
512 {
513 if (!len) str[n++] = 0;
514 else
515 {
516 memcpy( str + n, replace, len * sizeof(WCHAR) );
517 n += len;
518 str[n] = 0;
519 }
520 }
521
522 ptr = &format->deformatted[format->n + oldsize];
523 memcpy(&str[n], ptr, (lstrlenW(ptr) + 1) * sizeof(WCHAR));
524
525 msi_free(format->deformatted);
526 format->deformatted = str;
527 format->len = size - 1;
528
529 /* don't reformat the NULL */
530 if (replace && !len)
531 format->n++;
532
533 if (!replace)
534 return NULL;
535
536 ret = msi_alloc_zero(sizeof(FORMSTR));
537 if (!ret)
538 return NULL;
539
540 ret->len = len;
541 ret->type = type;
542 ret->n = format->n;
543 ret->propfound = propfound;
544 ret->nonprop = nonprop;
545
546 return ret;
547}
548
550 BOOL *propfound, BOOL *nonprop,
551 int *oldsize, int *type, int *len )
552{
553 WCHAR *replaced;
555 int n;
556
557 *nonprop = FALSE;
558 *propfound = FALSE;
559
561 n = node->n;
562 *oldsize = node->len;
563 msi_free(node);
564
565 while ((node = stack_pop(values)))
566 {
567 *oldsize += node->len;
568
569 if (node->nonprop)
570 *nonprop = TRUE;
571
572 if (node->propfound)
573 *propfound = TRUE;
574
575 msi_free(node);
576 }
577
578 content = msi_alloc_zero(sizeof(FORMSTR));
579 content->n = n;
580 content->len = *oldsize;
581 content->type = FORMAT_LITERAL;
582
583 if (!format->groupfailed && (*oldsize == 2 ||
584 (format->propfailed && !*nonprop)))
585 {
587 return NULL;
588 }
589 else if (format->deformatted[content->n + 1] == '{' &&
590 format->deformatted[content->n + content->len - 2] == '}')
591 {
592 format->groupfailed = FALSE;
593 content->len = 0;
594 }
595 else if (*propfound && !*nonprop &&
596 !format->groupfailed && format->groups == 0)
597 {
598 content->n++;
599 content->len -= 2;
600 }
601 else
602 {
603 if (format->groups != 0)
604 format->groupfailed = TRUE;
605
606 *nonprop = TRUE;
607 }
608
609 replaced = dup_formstr( format, content, len );
610 *type = content->type;
612
613 if (format->groups == 0)
614 format->propfailed = FALSE;
615
616 return replaced;
617}
618
620 BOOL *propfound, BOOL *nonprop,
621 int *oldsize, int *type, int *len )
622{
623 WCHAR *replaced;
625 int n;
626
627 *propfound = FALSE;
628 *nonprop = FALSE;
629
631 n = node->n;
632 *oldsize = node->len;
634 msi_free(node);
635
636 while ((node = stack_pop(values)))
637 {
638 *oldsize += node->len;
639
640 if (*type != FORMAT_ESCAPE &&
641 stack_peek(values) && node->type != *type)
643
644 msi_free(node);
645 }
646
647 content = msi_alloc_zero(sizeof(FORMSTR));
648 content->n = n + 1;
649 content->len = *oldsize - 2;
650 content->type = *type;
651
652 if (*type == FORMAT_NUMBER && format->record)
653 {
654 replaced = deformat_index( format, content, len );
655 if (replaced)
656 *propfound = TRUE;
657 else
658 format->propfailed = TRUE;
659
660 if (replaced)
661 *type = format_str_is_number(replaced) ?
663 }
664 else if (format->package)
665 {
666 replaced = deformat_literal( format, content, propfound, type, len );
667 }
668 else
669 {
670 *nonprop = TRUE;
671 content->n--;
672 content->len += 2;
673 replaced = dup_formstr( format, content, len );
674 }
676 return replaced;
677}
678
680{
681 WCHAR *replaced = NULL;
682 FORMSTR *beg, *top, *node;
683 BOOL propfound = FALSE, nonprop = FALSE, group = FALSE;
684 int type, n, len = 0, oldsize = 0;
685
687 type = node->type;
688 n = node->n;
689
690 if (type == FORMAT_LBRACK)
691 replaced = replace_stack_prop( format, values, &propfound,
692 &nonprop, &oldsize, &type, &len );
693 else if (type == FORMAT_LBRACE)
694 {
695 replaced = replace_stack_group( format, values, &propfound,
696 &nonprop, &oldsize, &type, &len );
697 group = TRUE;
698 }
699
700 format->n = n;
701 beg = format_replace( format, propfound, nonprop, oldsize, type, replaced, len );
702 msi_free(replaced);
703 if (!beg)
704 return ERROR_SUCCESS;
705
706 format->n = beg->n + beg->len;
707
709 if (top)
710 {
711 type = top->type;
712
713 if ((type == FORMAT_LITERAL || type == FORMAT_NUMBER) &&
714 type == beg->type)
715 {
716 top->len += beg->len;
717
718 if (group)
719 top->nonprop = FALSE;
720
721 if (type == FORMAT_LITERAL)
722 top->nonprop = beg->nonprop;
723
724 if (beg->propfound)
725 top->propfound = TRUE;
726
727 msi_free(beg);
728 return ERROR_SUCCESS;
729 }
730 }
731
732 stack_push(stack, beg);
733 return ERROR_SUCCESS;
734}
735
737{
738 int count = 0;
739
740 while (*data)
741 {
742 if (*data == '[' && *(data - 1) != '\\')
743 count++;
744 else if (*data == ']')
745 count--;
746
747 data++;
748 }
749
750 if (count > 0)
751 return FALSE;
752
753 return TRUE;
754}
755
757 WCHAR** data, DWORD *len,
759{
761 FORMSTR *str = NULL;
762 STACK *stack, *temp;
763 FORMSTR *node;
764 int type;
765
766 if (!ptr)
767 {
768 *data = NULL;
769 *len = 0;
770 return ERROR_SUCCESS;
771 }
772
773 *data = strdupW(ptr);
774 *len = lstrlenW(ptr);
775
776 ZeroMemory(&format, sizeof(FORMAT));
777 format.package = package;
778 format.record = record;
779 format.deformatted = *data;
780 format.len = *len;
781
782 if (!verify_format(*data))
783 return ERROR_SUCCESS;
784
786 temp = create_stack();
787
788 while ((type = format_lex(&format, &str)) != FORMAT_NULL)
789 {
790 if (type == FORMAT_LBRACK || type == FORMAT_LBRACE ||
793 {
794 if (type == FORMAT_LBRACE)
795 {
796 format.propfailed = FALSE;
797 format.groups++;
798 }
799 else if (type == FORMAT_ESCAPE &&
801 {
802 format.n -= str->len - 1;
803 str->len = 1;
804 }
805
807 }
808 else if (type == FORMAT_RBRACK || type == FORMAT_RBRACE)
809 {
810 if (type == FORMAT_RBRACE)
811 format.groups--;
812
814
816 {
817 do
818 {
821 } while (node->type != left_type(type));
822
824 }
825 }
826 }
827
828 *data = format.deformatted;
829 *len = format.len;
830
831 msi_free(str);
834
835 return ERROR_SUCCESS;
836}
837
839 LPDWORD size )
840{
841 WCHAR *format, *deformated = NULL;
843 DWORD len;
844 MSIRECORD *record_deformated;
845 int field_count, i;
846
847 TRACE("%p %p %p %p\n", package, record, buffer, size);
849
850 if (!(format = msi_dup_record_field( record, 0 )))
852
853 field_count = MSI_RecordGetFieldCount(record);
854 record_deformated = MSI_CloneRecord(record);
855 if (!record_deformated)
856 {
858 goto end;
859 }
860 MSI_RecordSetStringW(record_deformated, 0, format);
861 for (i = 1; i <= field_count; i++)
862 {
864 {
865 deformat_string_internal(package, MSI_RecordGetString(record, i), &deformated, &len, NULL);
866 MSI_RecordSetStringW(record_deformated, i, deformated);
867 msi_free(deformated);
868 }
869 }
870
871 deformat_string_internal(package, format, &deformated, &len, record_deformated);
872 if (buffer)
873 {
874 if (*size>len)
875 {
876 memcpy(buffer,deformated,len*sizeof(WCHAR));
877 rc = ERROR_SUCCESS;
878 buffer[len] = 0;
879 }
880 else
881 {
882 if (*size > 0)
883 {
884 memcpy(buffer,deformated,(*size)*sizeof(WCHAR));
885 buffer[(*size)-1] = 0;
886 }
887 rc = ERROR_MORE_DATA;
888 }
889 }
890 else rc = ERROR_SUCCESS;
891
892 *size = len;
893 msiobj_release(&record_deformated->hdr);
894end:
895 msi_free( format );
896 msi_free( deformated );
897 return rc;
898}
899
900UINT WINAPI MsiFormatRecordW( MSIHANDLE hInstall, MSIHANDLE hRecord, WCHAR *szResult, DWORD *sz )
901{
903 MSIPACKAGE *package;
905
906 TRACE( "%lu, %lu, %p, %p\n", hInstall, hRecord, szResult, sz );
907
909 if (!record)
911
912 package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
913 if (!package)
914 {
915 LPWSTR value = NULL;
916 MSIHANDLE remote;
917
918 if ((remote = msi_get_remote(hInstall)))
919 {
920 __TRY
921 {
922 r = remote_FormatRecord(remote, (struct wire_record *)&record->count, &value);
923 }
925 {
927 }
929
930 if (!r)
931 r = msi_strncpyW(value, -1, szResult, sz);
932
934 msiobj_release(&record->hdr);
935 return r;
936 }
937 }
938
939 if (!sz)
940 {
941 msiobj_release( &record->hdr );
942 if (szResult)
944 else
945 return ERROR_SUCCESS;
946 }
947
948 r = MSI_FormatRecordW( package, record, szResult, sz );
949 msiobj_release( &record->hdr );
950 if (package)
951 msiobj_release( &package->hdr );
952 return r;
953}
954
956{
957 MSIPACKAGE *package;
958 MSIRECORD *rec;
960 DWORD len;
961 UINT r;
962
963 TRACE( "%lu, %lu, %p, %p\n", hinst, hrec, buf, sz );
964
966 if (!rec)
968
969 package = msihandle2msiinfo(hinst, MSIHANDLETYPE_PACKAGE);
970 if (!package)
971 {
972 LPWSTR value = NULL;
973 MSIHANDLE remote;
974
975 if ((remote = msi_get_remote(hinst)))
976 {
977 __TRY
978 {
979 r = remote_FormatRecord(remote, (struct wire_record *)&rec->count, &value);
980 }
982 {
984 }
986
987 if (!r)
988 r = msi_strncpyWtoA(value, -1, buf, sz, TRUE);
989
991 msiobj_release(&rec->hdr);
992 return r;
993 }
994 }
995
996 r = MSI_FormatRecordW(package, rec, NULL, &len);
997 if (r != ERROR_SUCCESS)
998 return r;
999
1000 value = msi_alloc(++len * sizeof(WCHAR));
1001 if (!value)
1002 goto done;
1003
1004 r = MSI_FormatRecordW(package, rec, value, &len);
1005 if (!r)
1006 r = msi_strncpyWtoA(value, len, buf, sz, FALSE);
1007
1008 msi_free(value);
1009done:
1010 msiobj_release(&rec->hdr);
1011 if (package) msiobj_release(&package->hdr);
1012 return r;
1013}
1014
1015/* wrapper to resist a need for a full rewrite right now */
1017{
1018 DWORD len;
1019 MSIRECORD *rec;
1020
1021 *data = NULL;
1022 if (!fmt) return 0;
1023 if (!(rec = MSI_CreateRecord( 1 ))) return 0;
1024
1025 MSI_RecordSetStringW( rec, 0, fmt );
1026 MSI_FormatRecordW( package, rec, NULL, &len );
1027 if (!(*data = msi_alloc( ++len * sizeof(WCHAR) )))
1028 {
1029 msiobj_release( &rec->hdr );
1030 return 0;
1031 }
1032 MSI_FormatRecordW( package, rec, *data, &len );
1033 msiobj_release( &rec->hdr );
1034 return len;
1035}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define ARRAY_SIZE(A)
Definition: main.h:33
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
Definition: _stack.h:55
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#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
content
Definition: atl_ax.c:994
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define __TRY
Definition: compat.h:80
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define __ENDTRY
Definition: compat.h:82
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
MSICOMPONENT * msi_get_loaded_component(MSIPACKAGE *package, const WCHAR *Component)
Definition: action.c:552
MSIFILE * msi_get_loaded_file(MSIPACKAGE *package, const WCHAR *key)
Definition: action.c:574
LONG WINAPI rpc_filter(EXCEPTION_POINTERS *eptr)
Definition: custom.c:85
static BOOL format_is_number(WCHAR x)
Definition: format.c:365
#define FORMAT_LITERAL
Definition: format.c:44
static WCHAR * replace_stack_prop(FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
Definition: format.c:619
static WCHAR * deformat_literal(FORMAT *format, FORMSTR *str, BOOL *propfound, int *type, int *len)
Definition: format.c:278
static BOOL format_str_is_number(LPWSTR str)
Definition: format.c:370
DWORD deformat_string(MSIPACKAGE *package, const WCHAR *fmt, WCHAR **data)
Definition: format.c:1016
static BOOL format_is_literal(WCHAR x)
Definition: format.c:387
struct _tagSTACK STACK
#define FORMAT_NULL
Definition: format.c:43
static FORMSTR * stack_find(STACK *stack, int type)
Definition: format.c:120
static WCHAR * deformat_property(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:183
UINT WINAPI MsiFormatRecordA(MSIHANDLE hinst, MSIHANDLE hrec, char *buf, DWORD *sz)
Definition: format.c:955
struct _tagFORMAT FORMAT
static STACK * create_stack(void)
Definition: format.c:84
static BOOL verify_format(LPWSTR data)
Definition: format.c:736
static WCHAR * deformat_index(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:157
#define FORMAT_PROPNULL
Definition: format.c:51
static WCHAR * deformat_environment(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:260
static LPCWSTR get_formstr_data(FORMAT *format, FORMSTR *str)
Definition: format.c:138
static WCHAR * deformat_component(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:206
static WCHAR * dup_formstr(FORMAT *format, FORMSTR *str, int *ret_len)
Definition: format.c:143
struct _tagFORMSTR FORMSTR
#define FORMAT_LBRACK
Definition: format.c:46
static FORMSTR * stack_peek(STACK *stack)
Definition: format.c:133
UINT WINAPI MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, WCHAR *szResult, DWORD *sz)
Definition: format.c:900
#define FORMAT_LBRACE
Definition: format.c:47
#define left_type(x)
Definition: format.c:55
static DWORD deformat_string_internal(MSIPACKAGE *package, LPCWSTR ptr, WCHAR **data, DWORD *len, MSIRECORD *record)
Definition: format.c:756
static void free_stack(STACK *stack)
Definition: format.c:91
static BOOL format_is_alpha(WCHAR x)
Definition: format.c:381
static FORMSTR * stack_pop(STACK *stack)
Definition: format.c:108
static FORMSTR * format_replace(FORMAT *format, BOOL propfound, BOOL nonprop, int oldsize, int type, WCHAR *replace, int len)
Definition: format.c:476
UINT MSI_FormatRecordW(MSIPACKAGE *package, MSIRECORD *record, LPWSTR buffer, LPDWORD size)
Definition: format.c:838
static WCHAR * build_default_format(const MSIRECORD *record)
Definition: format.c:342
static void stack_push(STACK *stack, FORMSTR *str)
Definition: format.c:103
static WCHAR * deformat_file(FORMAT *format, FORMSTR *str, BOOL shortname, int *ret_len)
Definition: format.c:230
#define FORMAT_ESCAPE
Definition: format.c:50
#define FORMAT_NUMBER
Definition: format.c:45
static WCHAR * replace_stack_group(FORMAT *format, STACK *values, BOOL *propfound, BOOL *nonprop, int *oldsize, int *type, int *len)
Definition: format.c:549
#define FORMAT_ERROR
Definition: format.c:52
#define FORMAT_RBRACE
Definition: format.c:49
static UINT replace_stack(FORMAT *format, STACK *stack, STACK *values)
Definition: format.c:679
#define FORMAT_RBRACK
Definition: format.c:48
static int format_lex(FORMAT *format, FORMSTR **out)
Definition: format.c:392
#define FORMAT_FAIL
Definition: format.c:53
MSIHANDLE msi_get_remote(MSIHANDLE handle)
Definition: handle.c:183
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
void * msihandle2msiinfo(MSIHANDLE handle, UINT type)
Definition: handle.c:158
UINT msi_strncpyW(const WCHAR *str, int len, WCHAR *buf, DWORD *sz)
Definition: install.c:213
WCHAR * msi_resolve_source_folder(MSIPACKAGE *package, const WCHAR *name, MSIFOLDER **folder)
Definition: install.c:364
UINT msi_strncpyWtoA(const WCHAR *str, int lenW, char *buf, DWORD *sz, BOOL remote)
Definition: install.c:190
const WCHAR * msi_get_target_folder(MSIPACKAGE *package, const WCHAR *name)
Definition: install.c:232
#define swprintf
Definition: precomp.h:40
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
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
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLuint buffer
Definition: glext.h:5915
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLboolean GLuint group
Definition: glext.h:11120
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
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
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
uint32_t entry
Definition: isohybrid.c:63
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static PVOID ptr
Definition: dispmode.c:27
static HINSTANCE hinst
Definition: edit.c:551
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
@ INSTALLSTATE_SOURCE
Definition: msi.h:47
static void * msi_realloc(void *mem, size_t len) __WINE_ALLOC_SIZE(2)
Definition: msipriv.h:1154
WCHAR * msi_dup_record_field(MSIRECORD *row, INT index) DECLSPEC_HIDDEN
Definition: record.c:1002
static void * msi_alloc_zero(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1148
UINT MSI_RecordGetStringW(MSIRECORD *, UINT, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
#define MSIHANDLETYPE_RECORD
Definition: msipriv.h:725
static void msi_free(void *mem)
Definition: msipriv.h:1159
UINT msi_get_property(MSIDATABASE *, LPCWSTR, LPWSTR, LPDWORD) DECLSPEC_HIDDEN
Definition: package.c:2250
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
UINT MSI_RecordGetFieldCount(const MSIRECORD *rec) DECLSPEC_HIDDEN
Definition: record.c:108
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
MSIRECORD * MSI_CloneRecord(MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:921
void dump_record(MSIRECORD *) DECLSPEC_HIDDEN
Definition: record.c:1028
BOOL MSI_RecordIsNull(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:321
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
#define __EXCEPT(func)
Definition: exception.h:84
static FILE * out
Definition: regtests2xml.c:44
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:47
const WCHAR * str
static calc_node_t temp
Definition: rpn_ieee.c:38
#define midl_user_free
Definition: rpc.h:45
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define GetExceptionCode()
Definition: seh.h:27
#define TRACE(s)
Definition: solgame.cpp:4
BOOL propfailed
Definition: format.c:64
int len
Definition: format.c:62
MSIPACKAGE * package
Definition: format.c:59
LPWSTR deformatted
Definition: format.c:61
MSIRECORD * record
Definition: format.c:60
int groups
Definition: format.c:66
int n
Definition: format.c:63
BOOL groupfailed
Definition: format.c:65
struct list entry
Definition: format.c:71
int n
Definition: format.c:72
BOOL nonprop
Definition: format.c:76
int type
Definition: format.c:74
BOOL propfound
Definition: format.c:75
int len
Definition: format.c:73
struct list items
Definition: format.c:81
Definition: parser.c:44
Definition: fci.c:127
Definition: dsound.c:943
Definition: copy.c:22
Definition: list.h:15
INSTALLSTATE Action
Definition: msipriv.h:533
LPWSTR Directory
Definition: msipriv.h:527
MSIOBJECTHDR hdr
Definition: msipriv.h:393
MSIOBJECTHDR hdr
Definition: msipriv.h:151
UINT count
Definition: msipriv.h:152
#define LIST_ENTRY(type)
Definition: queue.h:175
uint32_t * LPDWORD
Definition: typedefs.h:59
Definition: dlist.c:348
Definition: pdh_main.c:94
int ret
#define ZeroMemory
Definition: winbase.h:1712
#define WINAPI
Definition: msvc.h:6
unsigned long MSIHANDLE
Definition: winemsi.idl:27
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185