msi: Register more patch details.
[wine] / dlls / msi / tests / format.c
1 /*
2  * Copyright (C) 2005 Mike McCormack for CodeWeavers
3  * Copyright (C) 2005 Aric Stewart for CodeWeavers
4  *
5  * A test program for MSI record formatting
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 <stdio.h>
23 #include <windows.h>
24 #include <shlwapi.h>
25 #include <msi.h>
26 #include <msiquery.h>
27
28 #include "wine/test.h"
29
30 static const char msifile[] = "winetest-format.msi";
31
32 static UINT run_query( MSIHANDLE hdb, const char *query )
33 {
34     MSIHANDLE hview = 0;
35     UINT r;
36
37     r = MsiDatabaseOpenView(hdb, query, &hview);
38     if( r != ERROR_SUCCESS )
39         return r;
40
41     r = MsiViewExecute(hview, 0);
42     if( r == ERROR_SUCCESS )
43         r = MsiViewClose(hview);
44     MsiCloseHandle(hview);
45     return r;
46 }
47
48 static UINT create_feature_table( MSIHANDLE hdb )
49 {
50     return run_query( hdb,
51             "CREATE TABLE `Feature` ( "
52             "`Feature` CHAR(38) NOT NULL, "
53             "`Feature_Parent` CHAR(38), "
54             "`Title` CHAR(64), "
55             "`Description` CHAR(255), "
56             "`Display` SHORT NOT NULL, "
57             "`Level` SHORT NOT NULL, "
58             "`Directory_` CHAR(72), "
59             "`Attributes` SHORT NOT NULL "
60             "PRIMARY KEY `Feature`)" );
61 }
62
63 static UINT create_component_table( MSIHANDLE hdb )
64 {
65     return run_query( hdb,
66             "CREATE TABLE `Component` ( "
67             "`Component` CHAR(72) NOT NULL, "
68             "`ComponentId` CHAR(38), "
69             "`Directory_` CHAR(72) NOT NULL, "
70             "`Attributes` SHORT NOT NULL, "
71             "`Condition` CHAR(255), "
72             "`KeyPath` CHAR(72) "
73             "PRIMARY KEY `Component`)" );
74 }
75
76 static UINT create_feature_components_table( MSIHANDLE hdb )
77 {
78     return run_query( hdb,
79             "CREATE TABLE `FeatureComponents` ( "
80             "`Feature_` CHAR(38) NOT NULL, "
81             "`Component_` CHAR(72) NOT NULL "
82             "PRIMARY KEY `Feature_`, `Component_` )" );
83 }
84
85 static UINT create_file_table( MSIHANDLE hdb )
86 {
87     return run_query( hdb,
88             "CREATE TABLE `File` ("
89             "`File` CHAR(72) NOT NULL, "
90             "`Component_` CHAR(72) NOT NULL, "
91             "`FileName` CHAR(255) NOT NULL, "
92             "`FileSize` LONG NOT NULL, "
93             "`Version` CHAR(72), "
94             "`Language` CHAR(20), "
95             "`Attributes` SHORT, "
96             "`Sequence` SHORT NOT NULL "
97             "PRIMARY KEY `File`)" );
98 }
99
100 static UINT create_custom_action_table( MSIHANDLE hdb )
101 {
102     return run_query( hdb,
103             "CREATE TABLE `CustomAction` ("
104             "`Action` CHAR(72) NOT NULL, "
105             "`Type` SHORT NOT NULL, "
106             "`Source` CHAR(75), "
107             "`Target` CHAR(255) "
108             "PRIMARY KEY `Action`)" );
109 }
110
111 #define make_add_entry(type, qtext) \
112     static UINT add##_##type##_##entry( MSIHANDLE hdb, const char *values ) \
113     { \
114         char insert[] = qtext; \
115         char *query; \
116         UINT sz, r; \
117         sz = strlen(values) + sizeof insert; \
118         query = HeapAlloc(GetProcessHeap(),0,sz); \
119         sprintf(query,insert,values); \
120         r = run_query( hdb, query ); \
121         HeapFree(GetProcessHeap(), 0, query); \
122         return r; \
123     }
124
125 make_add_entry(feature,
126                "INSERT INTO `Feature` "
127                "(`Feature`, `Feature_Parent`, `Title`, `Description`, "
128                "`Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )")
129
130 make_add_entry(component,
131                "INSERT INTO `Component`  "
132                "(`Component`, `ComponentId`, `Directory_`, "
133                "`Attributes`, `Condition`, `KeyPath`) VALUES( %s )")
134
135 make_add_entry(feature_components,
136                "INSERT INTO `FeatureComponents` "
137                "(`Feature_`, `Component_`) VALUES( %s )")
138
139 make_add_entry(file,
140                "INSERT INTO `File` "
141                "(`File`, `Component_`, `FileName`, `FileSize`, "
142                "`Version`, `Language`, `Attributes`, `Sequence`) VALUES( %s )")
143
144 make_add_entry(directory,
145                "INSERT INTO `Directory` "
146                "(`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )")
147
148 make_add_entry(custom_action,
149                "INSERT INTO `CustomAction`  "
150                "(`Action`, `Type`, `Source`, `Target`) VALUES( %s )")
151
152 static UINT set_summary_info(MSIHANDLE hdb)
153 {
154     UINT res;
155     MSIHANDLE suminfo;
156
157     /* build summary info */
158     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
159     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
160
161     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
162                         "Installation Database");
163     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
164
165     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
166                         "Installation Database");
167     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
168
169     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
170                         "Wine Hackers");
171     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
172
173     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
174                     ";1033");
175     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
176
177     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
178                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
179     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
180
181     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
182     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
183
184     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
185     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
186
187     res = MsiSummaryInfoPersist(suminfo);
188     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
189
190     res = MsiCloseHandle( suminfo);
191     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
192
193     return res;
194 }
195
196 static MSIHANDLE create_package_db(void)
197 {
198     MSIHANDLE hdb = 0;
199     UINT res;
200
201     DeleteFile(msifile);
202
203     /* create an empty database */
204     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
205     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
206     if( res != ERROR_SUCCESS )
207         return hdb;
208
209     res = MsiDatabaseCommit( hdb );
210     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
211
212     res = set_summary_info(hdb);
213
214     res = run_query( hdb,
215             "CREATE TABLE `Directory` ( "
216             "`Directory` CHAR(255) NOT NULL, "
217             "`Directory_Parent` CHAR(255), "
218             "`DefaultDir` CHAR(255) NOT NULL "
219             "PRIMARY KEY `Directory`)" );
220     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
221
222     return hdb;
223 }
224
225 static MSIHANDLE package_from_db(MSIHANDLE hdb)
226 {
227     UINT res;
228     CHAR szPackage[10];
229     MSIHANDLE hPackage;
230
231     sprintf(szPackage,"#%i",hdb);
232     res = MsiOpenPackage(szPackage,&hPackage);
233     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
234
235     res = MsiCloseHandle(hdb);
236     ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
237
238     return hPackage;
239 }
240
241 static void create_test_file(const CHAR *name)
242 {
243     HANDLE file;
244     DWORD written;
245
246     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
247     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
248     WriteFile(file, name, strlen(name), &written, NULL);
249     WriteFile(file, "\n", strlen("\n"), &written, NULL);
250     CloseHandle(file);
251 }
252
253 static MSIHANDLE helper_createpackage( const char *szName )
254 {
255     MSIHANDLE hdb = 0;
256     UINT res;
257     CHAR szPackage[10];
258     MSIHANDLE hPackage;
259     MSIHANDLE suminfo;
260
261     DeleteFile(szName);
262
263     /* create an empty database */
264     res = MsiOpenDatabase(szName, MSIDBOPEN_CREATE, &hdb );
265     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
266
267     res = MsiDatabaseCommit( hdb );
268     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
269
270     /* build summary info */
271     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
272     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
273
274     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
275                         "Installation Database");
276     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
277
278     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
279                         "Installation Database");
280     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
281
282     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
283                         "Wine Hackers");
284     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
285
286     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
287                     ";1033");
288     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
289
290     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
291                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
292     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
293
294     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
295     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
296
297     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
298     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
299
300     res = MsiSummaryInfoPersist(suminfo);
301     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
302
303     res = MsiCloseHandle( suminfo);
304     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
305
306     sprintf(szPackage,"#%i",hdb);
307     res = MsiOpenPackage(szPackage,&hPackage);
308     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
309
310     res = MsiCloseHandle( hdb );
311     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
312
313     return hPackage;
314 }
315
316 static void test_createpackage(void)
317 {
318     MSIHANDLE hPackage = 0;
319     UINT res;
320
321     hPackage = helper_createpackage( msifile );
322     ok ( hPackage != 0, " Failed to create package\n");
323
324     res = MsiCloseHandle( hPackage);
325     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
326
327     DeleteFile( msifile );
328 }
329
330 static void test_formatrecord(void)
331 {
332     char buffer[100];
333     MSIHANDLE hrec;
334     UINT r;
335     DWORD sz;
336
337     r = MsiFormatRecord(0, 0, NULL, NULL );
338     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
339
340     hrec = MsiCreateRecord(0);
341     ok( hrec, "failed to create record\n");
342
343     /* format an empty record on a record with no parameters */
344     sz = sizeof(buffer);
345     r = MsiFormatRecordA(0, hrec, buffer, &sz );
346     ok( r == ERROR_SUCCESS, "format failed\n");
347     ok( sz == 0, "size wrong\n");
348
349     MsiCloseHandle( hrec );
350
351     hrec = MsiCreateRecord(4);
352     ok( hrec, "failed to create record\n");
353
354     /* format an empty record */
355     r = MsiFormatRecord(0, hrec, NULL, NULL );
356     ok( r == ERROR_SUCCESS, "format failed\n");
357     buffer[0] = 'x';
358     buffer[1] = 0;
359     sz=0;
360     r = MsiFormatRecord(0, hrec, buffer+1, &sz);
361     ok( r == ERROR_MORE_DATA && buffer[0] == 'x', "format failed measuring with buffer\n");
362     ok( sz == 16, "size wrong\n");
363     sz=100;
364     r = MsiFormatRecord(0, hrec, buffer, &sz);
365     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
366     ok( sz == 16, "size wrong\n");
367     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  "), "wrong output\n");
368
369     r = MsiCloseHandle(hrec);
370     ok(r==ERROR_SUCCESS, "Unable to close record\n");
371
372     hrec = MsiCreateRecord(6);
373     ok( hrec, "failed to create record\n");
374
375     sz = 100;
376     buffer[0] = 'x';
377     buffer[1] = 0;
378     r = MsiFormatRecord(0, hrec, buffer, &sz);
379     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
380     ok( sz == 24, "size wrong\n");
381     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  "), "wrong output\n");
382
383
384     /* format a format string with everything else empty */
385     r = MsiRecordSetString(hrec, 0, "%1");
386     ok( r == ERROR_SUCCESS, "set string failed\n");
387     r = MsiFormatRecord(0, hrec, NULL, NULL );
388     ok( r == ERROR_SUCCESS, "format failed\n");
389     r = MsiFormatRecord(0, hrec, buffer, NULL);
390     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
391
392     sz = 123;
393     r = MsiFormatRecord(0, hrec, NULL, &sz);
394     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
395     ok( sz == 2, "size wrong (%i)\n",sz);
396     sz = sizeof buffer;
397     buffer[0] = 'x';
398     buffer[1] = 0;
399     r = MsiFormatRecord(0, hrec, buffer, &sz);
400     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
401     ok( sz == 2, "size wrong\n");
402     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
403
404     /* make the buffer too small */
405     sz = 0;
406     buffer[0] = 'x';
407     buffer[1] = 0;
408     r = MsiFormatRecord(0, hrec, buffer, &sz);
409     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
410     ok( sz == 2, "size wrong\n");
411     ok( 0 == strcmp(buffer,"x"), "wrong output\n");
412
413     /* make the buffer a little bit bigger */
414     sz = 1;
415     buffer[0] = 'x';
416     buffer[1] = 0;
417     r = MsiFormatRecord(0, hrec, buffer, &sz);
418     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
419     ok( sz == 2, "size wrong\n");
420     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
421
422     /* and again */
423     sz = 2;
424     buffer[0] = 'x';
425     buffer[1] = 0;
426     r = MsiFormatRecord(0, hrec, buffer, &sz);
427     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
428     ok( sz == 2, "size wrong\n");
429     ok( 0 == strcmp(buffer,"%"), "wrong output\n");
430
431     /* and again */
432     sz = 3;
433     buffer[0] = 'x';
434     buffer[1] = 0;
435     r = MsiFormatRecord(0, hrec, buffer, &sz);
436     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
437     ok( sz == 2, "size wrong\n");
438     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
439
440     /* now try a real format string */
441     r = MsiRecordSetString(hrec, 0, "[1]");
442     ok( r == ERROR_SUCCESS, "set string failed\n");
443     sz = sizeof buffer;
444     r = MsiFormatRecord(0, hrec, buffer, &sz);
445     ok( r == ERROR_SUCCESS, "format failed\n");
446     ok( sz == 0, "size wrong\n");
447     ok( 0 == strcmp(buffer,""), "wrong output\n");
448
449     /* now put something in the first field */
450     r = MsiRecordSetString(hrec, 1, "boo hoo");
451     ok( r == ERROR_SUCCESS, "set string failed\n");
452     sz = sizeof buffer;
453     r = MsiFormatRecord(0, hrec, buffer, &sz);
454     ok( r == ERROR_SUCCESS, "format failed\n");
455     ok( sz == 7, "size wrong\n");
456     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
457
458     /* now put something in the first field */
459     r = MsiRecordSetString(hrec, 0, "[1] [2]");
460     r = MsiRecordSetString(hrec, 1, "boo");
461     r = MsiRecordSetString(hrec, 2, "hoo");
462     ok( r == ERROR_SUCCESS, "set string failed\n");
463     sz = sizeof buffer;
464     r = MsiFormatRecord(0, hrec, buffer, &sz);
465     ok( r == ERROR_SUCCESS, "format failed\n");
466     ok( sz == 7, "size wrong\n");
467     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
468
469     /* empty string */
470     r = MsiRecordSetString(hrec, 0, "");
471     sz = sizeof buffer;
472     r = MsiFormatRecord(0, hrec, buffer, &sz);
473     ok( r == ERROR_SUCCESS, "format failed\n");
474     ok( sz == 30, "size wrong %i\n",sz);
475     ok( 0 == strcmp(buffer,"1: boo 2: hoo 3:  4:  5:  6:  "), 
476                     "wrong output(%s)\n",buffer);
477
478     /* play games with recursive lookups */
479     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
480     r = MsiRecordSetString(hrec, 1, "2");
481     r = MsiRecordSetString(hrec, 2, "hey");
482     ok( r == ERROR_SUCCESS, "set string failed\n");
483     sz = sizeof buffer;
484     r = MsiFormatRecord(0, hrec, buffer, &sz);
485     ok( r == ERROR_SUCCESS, "format failed\n");
486     ok( sz == 7, "size wrong,(%i)\n",sz);
487     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
488
489     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
490     r = MsiRecordSetString(hrec, 1, "[2]");
491     r = MsiRecordSetString(hrec, 2, "hey");
492     ok( r == ERROR_SUCCESS, "set string failed\n");
493     sz = sizeof buffer;
494     r = MsiFormatRecord(0, hrec, buffer, &sz);
495     ok( r == ERROR_SUCCESS, "format failed\n");
496     ok( sz == 9, "size wrong,(%i)\n",sz);
497     ok( 0 == strcmp(buffer,"[[2]] hey"), "wrong output (%s)\n",buffer);
498
499     r = MsiRecordSetString(hrec, 0, "[[[3]]] [2]");
500     r = MsiRecordSetString(hrec, 1, "2");
501     r = MsiRecordSetString(hrec, 2, "hey");
502     r = MsiRecordSetString(hrec, 3, "1");
503     ok( r == ERROR_SUCCESS, "set string failed\n");
504     sz = sizeof buffer;
505     r = MsiFormatRecord(0, hrec, buffer, &sz);
506     ok( r == ERROR_SUCCESS, "format failed\n");
507     ok( sz == 7, "size wrong,(%i)\n",sz);
508     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
509
510     r = MsiCloseHandle(hrec);
511     ok(r==ERROR_SUCCESS, "Unable to close record\n");
512     hrec = MsiCreateRecord(12);
513     ok( hrec, "failed to create record\n");
514
515     r = MsiRecordSetString(hrec, 0, "[[3][1]] [2]");
516     r = MsiRecordSetString(hrec, 1, "2");
517     r = MsiRecordSetString(hrec, 2, "hey");
518     r = MsiRecordSetString(hrec, 3, "1");
519     r = MsiRecordSetString(hrec, 12, "big");
520     ok( r == ERROR_SUCCESS, "set string failed\n");
521     sz = sizeof buffer;
522     r = MsiFormatRecord(0, hrec, buffer, &sz);
523     ok( r == ERROR_SUCCESS, "format failed\n");
524     ok( sz == 7, "size wrong,(%i)\n",sz);
525     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
526
527     r = MsiRecordSetString(hrec, 0, "[[3][4][1]] [2]");
528     r = MsiRecordSetString(hrec, 1, "2");
529     r = MsiRecordSetString(hrec, 2, "hey");
530     r = MsiRecordSetString(hrec, 3, "1");
531     r = MsiRecordSetString(hrec, 4, NULL);
532     r = MsiRecordSetString(hrec, 12, "big");
533     ok( r == ERROR_SUCCESS, "set string failed\n");
534     sz = sizeof buffer;
535     r = MsiFormatRecord(0, hrec, buffer, &sz);
536     ok( r == ERROR_SUCCESS, "format failed\n");
537     ok( sz == 7, "size wrong,(%i)\n",sz);
538     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
539
540     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]");
541     r = MsiRecordSetString(hrec, 1, "2");
542     r = MsiRecordSetString(hrec, 2, "hey");
543     r = MsiRecordSetString(hrec, 3, "1");
544     r = MsiRecordSetString(hrec, 4, NULL);
545     r = MsiRecordSetString(hrec, 12, "big");
546     ok( r == ERROR_SUCCESS, "set string failed\n");
547     sz = sizeof buffer;
548     r = MsiFormatRecord(0, hrec, buffer, &sz);
549     ok( r == ERROR_SUCCESS, "format failed\n");
550     ok( sz == 10, "size wrong,(%i)\n",sz);
551     ok( 0 == strcmp(buffer,"[1[]2] hey"), "wrong output (%s)\n",buffer);
552
553     /* incorrect  formats */
554     r = MsiRecordSetString(hrec, 0, "[[[3][[4]][1]] [2]");
555     r = MsiRecordSetString(hrec, 1, "2");
556     r = MsiRecordSetString(hrec, 2, "hey");
557     r = MsiRecordSetString(hrec, 3, "1");
558     r = MsiRecordSetString(hrec, 4, NULL);
559     r = MsiRecordSetString(hrec, 12, "big");
560     ok( r == ERROR_SUCCESS, "set string failed\n");
561     sz = sizeof buffer;
562     r = MsiFormatRecord(0, hrec, buffer, &sz);
563     ok( r == ERROR_SUCCESS, "format failed\n");
564     ok( sz == 18, "size wrong,(%i)\n",sz);
565     ok( 0 == strcmp(buffer,"[[[3][[4]][1]] [2]"), "wrong output (%s)\n",buffer);
566
567     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]]");
568     r = MsiRecordSetString(hrec, 1, "2");
569     r = MsiRecordSetString(hrec, 2, "hey");
570     r = MsiRecordSetString(hrec, 3, "1");
571     r = MsiRecordSetString(hrec, 4, NULL);
572     r = MsiRecordSetString(hrec, 12, "big");
573     ok( r == ERROR_SUCCESS, "set string failed\n");
574     sz = sizeof buffer;
575     r = MsiFormatRecord(0, hrec, buffer, &sz);
576     ok( r == ERROR_SUCCESS, "format failed\n");
577     ok( sz == 11, "size wrong,(%i)\n",sz);
578     ok( 0 == strcmp(buffer,"[1[]2] hey]"), "wrong output (%s)\n",buffer);
579
580
581     /* play games with {} */
582
583     r = MsiRecordSetString(hrec, 0, "{[3][1]} [2]");
584     r = MsiRecordSetString(hrec, 1, "2");
585     r = MsiRecordSetString(hrec, 2, "hey");
586     r = MsiRecordSetString(hrec, 3, "1");
587     r = MsiRecordSetString(hrec, 4, NULL);
588     r = MsiRecordSetString(hrec, 12, "big");
589     ok( r == ERROR_SUCCESS, "set string failed\n");
590     sz = sizeof buffer;
591     r = MsiFormatRecord(0, hrec, buffer, &sz);
592     ok( r == ERROR_SUCCESS, "format failed\n");
593     ok( sz == 6, "size wrong,(%i)\n",sz);
594     ok( 0 == strcmp(buffer,"12 hey"), "wrong output (%s)\n",buffer);
595
596     r = MsiRecordSetString(hrec, 0, "[{[3][1]}] [2]");
597     r = MsiRecordSetString(hrec, 1, "2");
598     r = MsiRecordSetString(hrec, 2, "hey");
599     r = MsiRecordSetString(hrec, 3, "1");
600     r = MsiRecordSetString(hrec, 4, NULL);
601     r = MsiRecordSetString(hrec, 12, "big");
602     ok( r == ERROR_SUCCESS, "set string failed\n");
603     sz = sizeof buffer;
604     r = MsiFormatRecord(0, hrec, buffer, &sz);
605     ok( r == ERROR_SUCCESS, "format failed\n");
606     ok( sz == 8, "size wrong,(%i)\n",sz);
607     ok( 0 == strcmp(buffer,"[12] hey"), "wrong output (%s)\n",buffer);
608
609
610     r = MsiRecordSetString(hrec, 0, "{test} [2]");
611     r = MsiRecordSetString(hrec, 1, "2");
612     r = MsiRecordSetString(hrec, 2, "hey");
613     r = MsiRecordSetString(hrec, 3, "1");
614     r = MsiRecordSetString(hrec, 4, NULL);
615     r = MsiRecordSetString(hrec, 12, "big");
616     ok( r == ERROR_SUCCESS, "set string failed\n");
617     sz = sizeof buffer;
618     r = MsiFormatRecord(0, hrec, buffer, &sz);
619     ok( r == ERROR_SUCCESS, "format failed\n");
620     ok( sz == 10, "size wrong,(%i)\n",sz);
621     ok( 0 == strcmp(buffer,"{test} hey"), "wrong output (%s)\n",buffer);
622
623     r = MsiRecordSetString(hrec, 0, "{[test]} [2]");
624     r = MsiRecordSetString(hrec, 1, "2");
625     r = MsiRecordSetString(hrec, 2, "hey");
626     r = MsiRecordSetString(hrec, 3, "1");
627     r = MsiRecordSetString(hrec, 4, NULL);
628     r = MsiRecordSetString(hrec, 12, "big");
629     ok( r == ERROR_SUCCESS, "set string failed\n");
630     sz = sizeof buffer;
631     r = MsiFormatRecord(0, hrec, buffer, &sz);
632     ok( r == ERROR_SUCCESS, "format failed\n");
633     ok( sz == 12, "size wrong,(%i)\n",sz);
634     ok( 0 == strcmp(buffer,"{[test]} hey"), "wrong output (%s)\n",buffer);
635
636     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4]} [2]");
637     r = MsiRecordSetString(hrec, 1, "2");
638     r = MsiRecordSetString(hrec, 2, "hey");
639     r = MsiRecordSetString(hrec, 3, "1");
640     r = MsiRecordSetString(hrec, 4, NULL);
641     r = MsiRecordSetString(hrec, 12, "big");
642     ok( r == ERROR_SUCCESS, "set string failed\n");
643     sz = sizeof buffer;
644     r = MsiFormatRecord(0, hrec, buffer, &sz);
645     ok( r == ERROR_SUCCESS, "format failed\n");
646     ok( sz == 4, "size wrong,(%i)\n",sz);
647     ok( 0 == strcmp(buffer," hey"), "wrong output (%s)\n",buffer);
648
649     r = MsiRecordSetString(hrec, 0, "{[1][2][3][dummy]} [2]");
650     r = MsiRecordSetString(hrec, 1, "2");
651     r = MsiRecordSetString(hrec, 2, "hey");
652     r = MsiRecordSetString(hrec, 3, "1");
653     r = MsiRecordSetString(hrec, 4, NULL);
654     r = MsiRecordSetString(hrec, 12, "big");
655     ok( r == ERROR_SUCCESS, "set string failed\n");
656     sz = sizeof buffer;
657     r = MsiFormatRecord(0, hrec, buffer, &sz);
658     ok( r == ERROR_SUCCESS, "format failed\n");
659     ok( sz == 18, "size wrong,(%i)\n",sz);
660     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
661
662     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4][dummy]} [2]");
663     r = MsiRecordSetString(hrec, 1, "2");
664     r = MsiRecordSetString(hrec, 2, "hey");
665     r = MsiRecordSetString(hrec, 3, "1");
666     r = MsiRecordSetString(hrec, 4, NULL);
667     r = MsiRecordSetString(hrec, 12, "big");
668     ok( r == ERROR_SUCCESS, "set string failed\n");
669     sz = sizeof buffer;
670     r = MsiFormatRecord(0, hrec, buffer, &sz);
671     ok( r == ERROR_SUCCESS, "format failed\n");
672     ok( sz == 18, "size wrong,(%i)\n",sz);
673     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
674
675     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3][4][dummy]}");
676     r = MsiRecordSetString(hrec, 1, "2");
677     r = MsiRecordSetString(hrec, 2, "hey");
678     r = MsiRecordSetString(hrec, 3, "1");
679     r = MsiRecordSetString(hrec, 4, NULL);
680     r = MsiRecordSetString(hrec, 12, "big");
681     ok( r == ERROR_SUCCESS, "set string failed\n");
682     sz = sizeof buffer;
683     r = MsiFormatRecord(0, hrec, buffer, &sz);
684     ok( r == ERROR_SUCCESS, "format failed\n");
685     ok( sz == 16, "size wrong,(%i)\n",sz);
686     ok( 0 == strcmp(buffer,"{{2hey}1[dummy]}"), "wrong output (%s)\n",buffer);
687
688     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]{[4][dummy]}}");
689     r = MsiRecordSetString(hrec, 1, "2");
690     r = MsiRecordSetString(hrec, 2, "hey");
691     r = MsiRecordSetString(hrec, 3, "1");
692     r = MsiRecordSetString(hrec, 4, NULL);
693     r = MsiRecordSetString(hrec, 12, "big");
694     ok( r == ERROR_SUCCESS, "set string failed\n");
695     sz = sizeof buffer;
696     r = MsiFormatRecord(0, hrec, buffer, &sz);
697     ok( r == ERROR_SUCCESS, "format failed\n");
698     ok( sz == 0, "size wrong,(%i)\n",sz);
699     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
700
701     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]} {[1][2]}");
702     r = MsiRecordSetString(hrec, 1, "1");
703     r = MsiRecordSetString(hrec, 2, "2");
704     r = MsiRecordSetString(hrec, 3, "3");
705     r = MsiRecordSetString(hrec, 4, NULL);
706     r = MsiRecordSetString(hrec, 12, "big");
707     ok( r == ERROR_SUCCESS, "set string failed\n");
708     sz = sizeof buffer;
709     r = MsiFormatRecord(0, hrec, buffer, &sz);
710     ok( r == ERROR_SUCCESS, "format failed\n");
711     ok( sz == 12, "size wrong,(%i)\n",sz);
712     ok( 0 == strcmp(buffer,"{{12}3} {12}"), "wrong output (%s)\n",buffer);
713
714     r = MsiRecordSetString(hrec, 0, "{[1][2]} {{[1][2]}[3]} {[1][2]}");
715     r = MsiRecordSetString(hrec, 1, "1");
716     r = MsiRecordSetString(hrec, 2, "2");
717     r = MsiRecordSetString(hrec, 3, "3");
718     r = MsiRecordSetString(hrec, 4, NULL);
719     r = MsiRecordSetString(hrec, 12, "big");
720     ok( r == ERROR_SUCCESS, "set string failed\n");
721     sz = sizeof buffer;
722     r = MsiFormatRecord(0, hrec, buffer, &sz);
723     ok( r == ERROR_SUCCESS, "format failed\n");
724     ok( sz == 15, "size wrong,(%i)\n",sz);
725     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
726
727     r = MsiRecordSetString(hrec, 0, "{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
728     r = MsiRecordSetString(hrec, 1, "1");
729     r = MsiRecordSetString(hrec, 2, "2");
730     r = MsiRecordSetString(hrec, 3, "3");
731     r = MsiRecordSetString(hrec, 4, NULL);
732     r = MsiRecordSetString(hrec, 12, "big");
733     ok( r == ERROR_SUCCESS, "set string failed\n");
734     sz = sizeof buffer;
735     r = MsiFormatRecord(0, hrec, buffer, &sz);
736     ok( r == ERROR_SUCCESS, "format failed\n");
737     ok( sz == 15, "size wrong,(%i)\n",sz);
738     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
739
740     r = MsiRecordSetString(hrec, 0, "{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
741     r = MsiRecordSetString(hrec, 1, "1");
742     r = MsiRecordSetString(hrec, 2, "2");
743     r = MsiRecordSetString(hrec, 3, "3");
744     r = MsiRecordSetString(hrec, 4, NULL);
745     r = MsiRecordSetString(hrec, 12, "big");
746     ok( r == ERROR_SUCCESS, "set string failed\n");
747     sz = sizeof buffer;
748     r = MsiFormatRecord(0, hrec, buffer, &sz);
749     ok( r == ERROR_SUCCESS, "format failed\n");
750     ok( sz == 22, "size wrong,(%i)\n",sz);
751     ok( 0 == strcmp(buffer,"{blah} 12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
752
753     r = MsiRecordSetString(hrec, 0, "{{[1]}[2]} {[4]}{[1][2]}");
754     r = MsiRecordSetString(hrec, 1, "1");
755     r = MsiRecordSetString(hrec, 2, "2");
756     r = MsiRecordSetString(hrec, 3, "3");
757     r = MsiRecordSetString(hrec, 4, NULL);
758     r = MsiRecordSetString(hrec, 12, "big");
759     ok( r == ERROR_SUCCESS, "set string failed\n");
760     sz = sizeof buffer;
761     r = MsiFormatRecord(0, hrec, buffer, &sz);
762     ok( r == ERROR_SUCCESS, "format failed\n");
763     ok( sz == 13, "size wrong,(%i)\n",sz);
764     ok( 0 == strcmp(buffer,"{{1}2} {}{12}"), "wrong output (%s)\n",buffer);
765
766     r = MsiRecordSetString(hrec, 0, "{{[1]}} {[4]}{[1][2]}");
767     r = MsiRecordSetString(hrec, 1, "1");
768     r = MsiRecordSetString(hrec, 2, "2");
769     r = MsiRecordSetString(hrec, 3, "3");
770     r = MsiRecordSetString(hrec, 4, NULL);
771     r = MsiRecordSetString(hrec, 12, "big");
772     ok( r == ERROR_SUCCESS, "set string failed\n");
773     sz = sizeof buffer;
774     r = MsiFormatRecord(0, hrec, buffer, &sz);
775     ok( r == ERROR_SUCCESS, "format failed\n");
776     ok( sz == 3, "size wrong,(%i)\n",sz);
777     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
778
779     r = MsiRecordSetString(hrec, 0, "{{{[1]}} {[4]}{[1][2]}");
780     r = MsiRecordSetString(hrec, 1, "1");
781     r = MsiRecordSetString(hrec, 2, "2");
782     r = MsiRecordSetString(hrec, 3, "3");
783     r = MsiRecordSetString(hrec, 4, NULL);
784     r = MsiRecordSetString(hrec, 12, "big");
785     ok( r == ERROR_SUCCESS, "set string failed\n");
786     sz = sizeof buffer;
787     r = MsiFormatRecord(0, hrec, buffer, &sz);
788     ok( r == ERROR_SUCCESS, "format failed\n");
789     todo_wine{
790     ok( sz == 3, "size wrong,(%i)\n",sz);
791     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
792     }
793     
794     /* now put play games with escaping */
795     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
796     r = MsiRecordSetString(hrec, 1, "boo");
797     r = MsiRecordSetString(hrec, 2, "hoo");
798     ok( r == ERROR_SUCCESS, "set string failed\n");
799     sz = sizeof buffer;
800     r = MsiFormatRecord(0, hrec, buffer, &sz);
801     ok( r == ERROR_SUCCESS, "format failed\n");
802     ok( sz == 16, "size wrong\n");
803     ok( 0 == strcmp(buffer,"boo hoo [\\3asdf]"), "wrong output\n");
804
805     /* now put play games with escaping */
806     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
807     r = MsiRecordSetString(hrec, 1, "boo");
808     r = MsiRecordSetString(hrec, 2, "hoo");
809     ok( r == ERROR_SUCCESS, "set string failed\n");
810     sz = sizeof buffer;
811     r = MsiFormatRecord(0, hrec, buffer, &sz);
812     ok( r == ERROR_SUCCESS, "format failed\n");
813     ok( sz == 12, "size wrong\n");
814     ok( 0 == strcmp(buffer,"boo hoo [\\x]"), "wrong output\n");
815
816     MsiRecordSetString(hrec, 0, "[\\x]");
817     sz = sizeof buffer;
818     r = MsiFormatRecord(0, hrec, buffer, &sz);
819     ok( r == ERROR_SUCCESS, "format failed\n");
820     ok( sz == 4, "size wrong: %d\n", sz);
821     ok( 0 == strcmp(buffer,"[\\x]"), "wrong output: %s\n", buffer);
822
823     MsiRecordSetString(hrec, 0, "{\\x}");
824     sz = sizeof buffer;
825     r = MsiFormatRecord(0, hrec, buffer, &sz);
826     ok( r == ERROR_SUCCESS, "format failed\n");
827     ok( sz == 4, "size wrong: %d\n", sz);
828     ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer);
829
830     MsiRecordSetString(hrec, 0, "[abc\\x]");
831     sz = sizeof buffer;
832     r = MsiFormatRecord(0, hrec, buffer, &sz);
833     ok( r == ERROR_SUCCESS, "format failed\n");
834     ok( sz == 7, "size wrong: %d\n", sz);
835     ok( 0 == strcmp(buffer,"[abc\\x]"), "wrong output: %s\n", buffer);
836
837     MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]");
838     sz = sizeof buffer;
839     r = MsiFormatRecord(0, hrec, buffer, &sz);
840     ok( r == ERROR_SUCCESS, "format failed\n");
841     ok( sz == 20, "size wrong: %d\n", sz);
842     ok( 0 == strcmp(buffer,"[\\[]Bracket Text[\\]]"), "wrong output: %s\n", buffer);
843
844     /* now try other formats without a package */
845     r = MsiRecordSetString(hrec, 0, "[1] [2] [property]");
846     r = MsiRecordSetString(hrec, 1, "boo");
847     r = MsiRecordSetString(hrec, 2, "hoo");
848     ok( r == ERROR_SUCCESS, "set string failed\n");
849     sz = sizeof buffer;
850     r = MsiFormatRecord(0, hrec, buffer, &sz);
851     ok( r == ERROR_SUCCESS, "format failed\n");
852     ok( sz == 18, "size wrong\n");
853     ok( 0 == strcmp(buffer,"boo hoo [property]"), "wrong output\n");
854
855     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
856     r = MsiRecordSetString(hrec, 1, "boo");
857     r = MsiRecordSetString(hrec, 2, "hoo");
858     ok( r == ERROR_SUCCESS, "set string failed\n");
859     sz = sizeof buffer;
860     r = MsiFormatRecord(0, hrec, buffer, &sz);
861     ok( r == ERROR_SUCCESS, "format failed\n");
862     ok( sz == 11, "size wrong\n");
863     ok( 0 == strcmp(buffer,"boo [~] hoo"), "wrong output (%s)\n",buffer);
864
865     r = MsiRecordSetString(hrec, 0, "[1]");
866     r = MsiRecordSetInteger(hrec, 1, 123456);
867     ok( r == ERROR_SUCCESS, "set integer failed\n");
868     sz = sizeof buffer;
869     r = MsiFormatRecord(0, hrec, buffer, &sz);
870     ok( r == ERROR_SUCCESS, "format failed\n");
871     ok( sz == 6, "size wrong\n");
872     ok( 0 == strcmp(buffer,"123456"), "wrong output (%s)\n",buffer);
873
874     r = MsiRecordSetString(hrec, 0, "[~]");
875     sz = sizeof buffer;
876     r = MsiFormatRecord(0, hrec, buffer, &sz);
877     ok( sz == 3, "size wrong\n");
878     ok( 0 == strcmp(buffer,"[~]"), "wrong output\n");
879     ok( r == ERROR_SUCCESS, "format failed\n");
880
881     r = MsiRecordSetString(hrec, 0, "[]");
882     sz = sizeof buffer;
883     r = MsiFormatRecord(0, hrec, buffer, &sz);
884     ok( sz == 2, "size wrong\n");
885     ok( 0 == strcmp(buffer,"[]"), "wrong output\n");
886     ok( r == ERROR_SUCCESS, "format failed\n");
887
888     /* MsiFormatRecord doesn't seem to handle a negative too well */
889     r = MsiRecordSetString(hrec, 0, "[-1]");
890     sz = sizeof buffer;
891     r = MsiFormatRecord(0, hrec, buffer, &sz);
892     ok( sz == 4, "size wrong\n");
893     ok( 0 == strcmp(buffer,"[-1]"), "wrong output\n");
894     ok( r == ERROR_SUCCESS, "format failed\n");
895
896     r = MsiRecordSetString(hrec, 0, "{[]}");
897     sz = sizeof buffer;
898     r = MsiFormatRecord(0, hrec, buffer, &sz);
899     ok( sz == 4, "size wrong\n");
900     ok( 0 == strcmp(buffer,"{[]}"), "wrong output\n");
901     ok( r == ERROR_SUCCESS, "format failed\n");
902
903     r = MsiRecordSetString(hrec, 0, "[0]");
904     sz = sizeof buffer;
905     r = MsiFormatRecord(0, hrec, buffer, &sz);
906     ok( sz == 3, "size wrong\n");
907     ok( 0 == strcmp(buffer,"[0]"), "wrong output\n");
908     ok( r == ERROR_SUCCESS, "format failed\n");
909
910     r = MsiRecordSetString(hrec, 0, "[100]");
911     sz = sizeof buffer;
912     r = MsiFormatRecord(0, hrec, buffer, &sz);
913     ok( sz == 0, "size wrong\n");
914     ok( 0 == strcmp(buffer,""), "wrong output\n");
915     ok( r == ERROR_SUCCESS, "format failed\n");
916
917     r = MsiRecordSetString(hrec, 0, "{[1] [2]}");
918     r = MsiRecordSetString(hrec, 1, "boo");
919     r = MsiRecordSetString(hrec, 2, "hoo");
920     sz = sizeof buffer;
921     r = MsiFormatRecord(0, hrec, buffer, &sz);
922     ok( sz == 7, "size wrong\n");
923     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
924     ok( r == ERROR_SUCCESS, "format failed\n");
925
926     r = MsiRecordSetString(hrec, 0, "{}");
927     sz = sizeof buffer;
928     r = MsiFormatRecord(0, hrec, buffer, &sz);
929     ok( sz == 0, "size wrong\n");
930     ok( 0 == strcmp(buffer,""), "wrong output\n");
931     ok( r == ERROR_SUCCESS, "format failed\n");
932
933     r = MsiRecordSetString(hrec, 0, "{foo}");
934     sz = sizeof buffer;
935     r = MsiFormatRecord(0, hrec, buffer, &sz);
936     ok( sz == 5, "size wrong\n");
937     ok( 0 == strcmp(buffer,"{foo}"), "wrong output\n");
938     ok( r == ERROR_SUCCESS, "format failed\n");
939
940     r = MsiRecordSetString(hrec, 0, "{boo [1]}");
941     r = MsiRecordSetString(hrec, 1, "hoo");
942     sz = sizeof buffer;
943     r = MsiFormatRecord(0, hrec, buffer, &sz);
944     ok( sz == 7, "size wrong\n");
945     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
946     ok( r == ERROR_SUCCESS, "format failed\n");
947
948     r = MsiRecordSetString(hrec, 0, "{{[1]}}");
949     r = MsiRecordSetString(hrec, 1, "hoo");
950     sz = sizeof buffer;
951     r = MsiFormatRecord(0, hrec, buffer, &sz);
952     ok( sz == 0, "size wrong\n");
953     ok( 0 == strcmp(buffer,""), "wrong output\n");
954     ok( r == ERROR_SUCCESS, "format failed\n");
955
956     r = MsiRecordSetString(hrec, 0, "{ {[1]}}");
957     r = MsiRecordSetString(hrec, 1, "hoo");
958     sz = sizeof buffer;
959     r = MsiFormatRecord(0, hrec, buffer, &sz);
960     todo_wine
961     {
962         ok( 0 == strcmp(buffer," {hoo}"), "wrong output\n");
963         ok( sz == 6, "size wrong\n");
964     }
965     ok( r == ERROR_SUCCESS, "format failed\n");
966
967     r = MsiRecordSetString(hrec, 0, "{{[1]} }");
968     r = MsiRecordSetString(hrec, 1, "hoo");
969     sz = sizeof buffer;
970     r = MsiFormatRecord(0, hrec, buffer, &sz);
971     ok( sz == 8, "size wrong\n");
972     ok( 0 == strcmp(buffer,"{{hoo} }"), "wrong output\n");
973     ok( r == ERROR_SUCCESS, "format failed\n");
974
975     r = MsiRecordSetString(hrec, 0, "{{ [1]}}");
976     r = MsiRecordSetString(hrec, 1, "hoo");
977     sz = sizeof buffer;
978     r = MsiFormatRecord(0, hrec, buffer, &sz);
979     ok( sz == 0, "size wrong\n");
980     ok( 0 == strcmp(buffer,""), "wrong output\n");
981     ok( r == ERROR_SUCCESS, "format failed\n");
982
983     r = MsiRecordSetString(hrec, 0, "{{[1] }}");
984     r = MsiRecordSetString(hrec, 1, "hoo");
985     sz = sizeof buffer;
986     r = MsiFormatRecord(0, hrec, buffer, &sz);
987     ok( sz == 0, "size wrong\n");
988     ok( 0 == strcmp(buffer,""), "wrong output\n");
989     ok( r == ERROR_SUCCESS, "format failed\n");
990
991     r = MsiRecordSetString(hrec, 0, "{{a}{b}{c }{ d}{any text}}");
992     sz = sizeof buffer;
993     r = MsiFormatRecord(0, hrec, buffer, &sz);
994     ok( sz == 0, "size wrong\n");
995     ok( 0 == strcmp(buffer,""), "wrong output\n");
996     ok( r == ERROR_SUCCESS, "format failed\n");
997
998     r = MsiRecordSetString(hrec, 0, "{{a} }");
999     sz = sizeof buffer;
1000     r = MsiFormatRecord(0, hrec, buffer, &sz);
1001     ok( sz == 6, "size wrong\n");
1002     ok( 0 == strcmp(buffer,"{{a} }"), "wrong output\n");
1003     ok( r == ERROR_SUCCESS, "format failed\n");
1004
1005     r = MsiRecordSetString(hrec, 0, "{{a} {b}}");
1006     sz = sizeof buffer;
1007     r = MsiFormatRecord(0, hrec, buffer, &sz);
1008     ok( sz == 0, "size wrong\n");
1009     ok( 0 == strcmp(buffer,""), "wrong output\n");
1010     ok( r == ERROR_SUCCESS, "format failed\n");
1011
1012     todo_wine {
1013     r = MsiRecordSetString(hrec, 0, "{{a} b}}");
1014     sz = sizeof buffer;
1015     r = MsiFormatRecord(0, hrec, buffer, &sz);
1016     ok( sz == 0, "size wrong\n");
1017     ok( 0 == strcmp(buffer,""), "wrong output\n");
1018     }
1019     ok( r == ERROR_SUCCESS, "format failed\n");
1020
1021     r = MsiRecordSetString(hrec, 0, "{{a b}}");
1022     sz = sizeof buffer;
1023     r = MsiFormatRecord(0, hrec, buffer, &sz);
1024     ok( sz == 0, "size wrong\n");
1025     ok( 0 == strcmp(buffer,""), "wrong output\n");
1026     ok( r == ERROR_SUCCESS, "format failed\n");
1027
1028     r = MsiRecordSetString(hrec, 0, "{ }");
1029     sz = sizeof buffer;
1030     r = MsiFormatRecord(0, hrec, buffer, &sz);
1031     ok( sz == 3, "size wrong\n");
1032     ok( 0 == strcmp(buffer,"{ }"), "wrong output\n");
1033     ok( r == ERROR_SUCCESS, "format failed\n");
1034
1035     r = MsiRecordSetString(hrec, 0, " {{a}}}");
1036     sz = sizeof buffer;
1037     r = MsiFormatRecord(0, hrec, buffer, &sz);
1038     ok( sz == 2, "size wrong\n");
1039     ok( 0 == strcmp(buffer," }"), "wrong output\n");
1040     ok( r == ERROR_SUCCESS, "format failed\n");
1041
1042     todo_wine {
1043     r = MsiRecordSetString(hrec, 0, "{{ almost {{ any }} text }}");
1044     sz = sizeof buffer;
1045     r = MsiFormatRecord(0, hrec, buffer, &sz);
1046     ok( sz == 8, "size wrong\n");
1047     ok( 0 == strcmp(buffer," text }}"), "wrong output\n");
1048     }
1049     ok( r == ERROR_SUCCESS, "format failed\n");
1050
1051     todo_wine {
1052     r = MsiRecordSetString(hrec, 0, "{{ } { hidden ][ [ }}");
1053     sz = sizeof buffer;
1054     r = MsiFormatRecord(0, hrec, buffer, &sz);
1055     ok( sz == 0, "size wrong\n");
1056     ok( 0 == strcmp(buffer,""), "wrong output\n");
1057     }
1058     ok( r == ERROR_SUCCESS, "format failed\n");
1059
1060     r = MsiRecordSetString(hrec, 0, "[ 1]");
1061     r = MsiRecordSetString(hrec, 1, "hoo");
1062     sz = sizeof buffer;
1063     r = MsiFormatRecord(0, hrec, buffer, &sz);
1064     ok( sz == 4, "size wrong\n");
1065     ok( 0 == strcmp(buffer,"[ 1]"), "wrong output\n");
1066     ok( r == ERROR_SUCCESS, "format failed\n");
1067
1068     r = MsiRecordSetString(hrec, 0, "[01]");
1069     r = MsiRecordSetString(hrec, 1, "hoo");
1070     sz = sizeof buffer;
1071     r = MsiFormatRecord(0, hrec, buffer, &sz);
1072     ok( sz == 3, "size wrong\n");
1073     ok( 0 == strcmp(buffer,"hoo"), "wrong output\n");
1074     ok( r == ERROR_SUCCESS, "format failed\n");
1075
1076     todo_wine {
1077     r = MsiRecordSetString(hrec, 0, "{{test}} [01");
1078     r = MsiRecordSetString(hrec, 1, "hoo");
1079     sz = sizeof buffer;
1080     r = MsiFormatRecord(0, hrec, buffer, &sz);
1081     ok( sz == 4, "size wrong\n");
1082     ok( 0 == strcmp(buffer," [01"), "wrong output\n");
1083     }
1084     ok( r == ERROR_SUCCESS, "format failed\n");
1085
1086     r = MsiRecordSetString(hrec, 0, "[\\[]");
1087     r = MsiRecordSetString(hrec, 1, "hoo");
1088     sz = sizeof buffer;
1089     r = MsiFormatRecord(0, hrec, buffer, &sz);
1090     ok( sz == 4, "size wrong\n");
1091     ok( 0 == strcmp(buffer,"[\\[]"), "wrong output\n");
1092     ok( r == ERROR_SUCCESS, "format failed\n");
1093
1094     MsiRecordSetString(hrec, 0, "[\\[]");
1095     MsiRecordSetString(hrec, 1, "hoo");
1096     sz = sizeof(buffer);
1097     r = MsiFormatRecord(0, hrec, buffer, &sz);
1098     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1099     ok(sz == 4, "Expected 4, got %d\n", sz);
1100     ok(!lstrcmpA(buffer, "[\\[]"), "Expected \"[\\[]\", got \"%s\"\n", buffer);
1101
1102     r = MsiRecordSetString(hrec, 0, "[foo]");
1103     r = MsiRecordSetString(hrec, 1, "hoo");
1104     sz = sizeof buffer;
1105     r = MsiFormatRecord(0, hrec, buffer, &sz);
1106     ok( sz == 5, "size wrong\n");
1107     ok( 0 == strcmp(buffer,"[foo]"), "wrong output\n");
1108     ok( r == ERROR_SUCCESS, "format failed\n");
1109
1110     r = MsiRecordSetString(hrec, 0, "[01.]");
1111     r = MsiRecordSetString(hrec, 1, "hoo");
1112     sz = sizeof buffer;
1113     r = MsiFormatRecord(0, hrec, buffer, &sz);
1114     ok( sz == 5, "size wrong\n");
1115     ok( 0 == strcmp(buffer,"[01.]"), "wrong output\n");
1116     ok( r == ERROR_SUCCESS, "format failed\n");
1117
1118     SetEnvironmentVariable("FOO", "BAR");
1119     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1120     sz = sizeof buffer;
1121     r = MsiFormatRecord(0, hrec, buffer, &sz);
1122     ok( sz == 6, "size wrong\n");
1123     ok( 0 == strcmp(buffer,"[%FOO]"), "wrong output\n");
1124     ok( r == ERROR_SUCCESS, "format failed\n");
1125
1126     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1127     r = MsiRecordSetString(hrec, 1, "hoo");
1128     sz = sizeof buffer;
1129     r = MsiFormatRecord(0, hrec, buffer, &sz);
1130     ok( sz == 6, "size wrong\n");
1131     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output\n");
1132     ok( r == ERROR_SUCCESS, "format failed\n");
1133
1134     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1135     r = MsiRecordSetString(hrec, 1, "hoo");
1136     sz = sizeof buffer;
1137     r = MsiFormatRecord(0, hrec, buffer, &sz);
1138     ok( sz == 8, "size wrong\n");
1139     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1140     ok( r == ERROR_SUCCESS, "format failed\n");
1141
1142     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1143     r = MsiRecordSetString(hrec, 1, "hoo");
1144     sz = sizeof buffer;
1145     r = MsiFormatRecord(0, hrec, buffer, &sz);
1146     ok( sz == 8, "size wrong\n");
1147     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1148     ok( r == ERROR_SUCCESS, "format failed\n");
1149
1150     r = MsiRecordSetString(hrec, 0, "{{ {{[1]}");
1151     r = MsiRecordSetString(hrec, 1, "hoo");
1152     sz = sizeof buffer;
1153     r = MsiFormatRecord(0, hrec, buffer, &sz);
1154     ok( sz == 9, "size wrong\n");
1155     ok( 0 == strcmp(buffer,"{{ {{hoo}"), "wrong output\n");
1156     ok( r == ERROR_SUCCESS, "format failed\n");
1157
1158     r = MsiRecordSetString(hrec, 0, "[1]}");
1159     r = MsiRecordSetString(hrec, 1, "hoo");
1160     sz = sizeof buffer;
1161     r = MsiFormatRecord(0, hrec, buffer, &sz);
1162     ok( sz == 4, "size wrong\n");
1163     ok( 0 == strcmp(buffer,"hoo}"), "wrong output\n");
1164     ok( r == ERROR_SUCCESS, "format failed\n");
1165
1166     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1167     sz = sizeof buffer;
1168     r = MsiFormatRecord(0, hrec, buffer, &sz);
1169     ok( sz == 7, "size wrong\n");
1170     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1171     ok( r == ERROR_SUCCESS, "format failed\n");
1172
1173     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1174     sz = sizeof buffer;
1175     r = MsiFormatRecord(0, hrec, buffer, &sz);
1176     ok( sz == 7, "size wrong\n");
1177     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1178     ok( r == ERROR_SUCCESS, "format failed\n");
1179
1180     r = MsiRecordSetString(hrec, 0, "0{1{2{3{4[1]5}6}7}8}9");
1181     r = MsiRecordSetString(hrec, 1, "hoo");
1182     sz = sizeof buffer;
1183     r = MsiFormatRecord(0, hrec, buffer, &sz);
1184     todo_wine
1185     {
1186         ok( sz == 19, "size wrong\n");
1187         ok( 0 == strcmp(buffer,"01{2{3{4hoo56}7}8}9"), "wrong output\n");
1188     }
1189     ok( r == ERROR_SUCCESS, "format failed\n");
1190
1191     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1192     r = MsiRecordSetString(hrec, 1, "hoo");
1193     sz = sizeof buffer;
1194     r = MsiFormatRecord(0, hrec, buffer, &sz);
1195     todo_wine
1196     {
1197         ok( sz == 9, "size wrong\n");
1198         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1199     }
1200     ok( r == ERROR_SUCCESS, "format failed\n");
1201
1202     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1203     r = MsiRecordSetString(hrec, 1, "hoo");
1204     sz = sizeof buffer;
1205     r = MsiFormatRecord(0, hrec, buffer, &sz);
1206     todo_wine
1207     {
1208         ok( sz == 9, "size wrong\n");
1209         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1210     }
1211     ok( r == ERROR_SUCCESS, "format failed\n");
1212
1213     r = MsiRecordSetString(hrec, 0, "{[1.} [1]");
1214     r = MsiRecordSetString(hrec, 1, "hoo");
1215     sz = sizeof buffer;
1216     r = MsiFormatRecord(0, hrec, buffer, &sz);
1217     ok( sz == 9, "size wrong\n");
1218     todo_wine
1219     {
1220         ok( 0 == strcmp(buffer,"{[1.} hoo"), "wrong output\n");
1221     }
1222     ok( r == ERROR_SUCCESS, "format failed\n");
1223
1224     r = MsiRecordSetString(hrec, 0, "{[{[1]}]}");
1225     r = MsiRecordSetString(hrec, 1, "2");
1226     r = MsiRecordSetString(hrec, 2, "foo");
1227     sz = sizeof buffer;
1228     r = MsiFormatRecord(0, hrec, buffer, &sz);
1229     todo_wine
1230     {
1231         ok( sz == 9, "size wrong\n");
1232         ok( 0 == strcmp(buffer,"{[{[1]}]}"), "wrong output\n");
1233     }
1234     ok( r == ERROR_SUCCESS, "format failed\n");
1235
1236     r = MsiRecordSetString(hrec, 0, "{[1][}");
1237     r = MsiRecordSetString(hrec, 1, "2");
1238     r = MsiRecordSetString(hrec, 2, "foo");
1239     sz = sizeof buffer;
1240     r = MsiFormatRecord(0, hrec, buffer, &sz);
1241     todo_wine
1242     {
1243         ok( sz == 2, "size wrong\n");
1244         ok( 0 == strcmp(buffer,"2["), "wrong output\n");
1245     }
1246     ok( r == ERROR_SUCCESS, "format failed\n");
1247
1248     r = MsiRecordSetString(hrec, 0, "[1]");
1249     r = MsiRecordSetString(hrec, 1, "[2]");
1250     r = MsiRecordSetString(hrec, 2, "foo");
1251     sz = sizeof buffer;
1252     r = MsiFormatRecord(0, hrec, buffer, &sz);
1253     ok( sz == 3, "size wrong\n");
1254     ok( 0 == strcmp(buffer,"[2]"), "wrong output\n");
1255     ok( r == ERROR_SUCCESS, "format failed\n");
1256
1257     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1258     r = MsiRecordSetString(hrec, 1, "hoo");
1259     sz = sizeof buffer;
1260     r = MsiFormatRecord(0, hrec, buffer, &sz);
1261     ok( r == ERROR_SUCCESS, "format failed\n");
1262     ok( sz == 3, "size wrong\n");
1263     todo_wine
1264     {
1265         ok( 0 == strcmp(buffer,"[1]"), "wrong output: %s\n", buffer);
1266     }
1267
1268     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1269     r = MsiRecordSetString(hrec, 0, "[1{{boo}}]");
1270     r = MsiRecordSetString(hrec, 1, "hoo");
1271     sz = sizeof buffer;
1272     r = MsiFormatRecord(0, hrec, buffer, &sz);
1273     ok( sz == 3, "size wrong\n");
1274     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1275     ok( r == ERROR_SUCCESS, "format failed\n");
1276
1277     r = MsiRecordSetString(hrec, 0, "{[1]{{boo} }}");
1278     r = MsiRecordSetString(hrec, 1, "hoo");
1279     sz = sizeof buffer;
1280     r = MsiFormatRecord(0, hrec, buffer, &sz);
1281     todo_wine
1282     {
1283         ok( sz == 11, "size wrong\n");
1284         ok( 0 == strcmp(buffer,"hoo{{boo }}"), "wrong output\n");
1285     }
1286     ok( r == ERROR_SUCCESS, "format failed\n");
1287
1288     r = MsiRecordSetString(hrec, 0, "{[1{{boo}}]}");
1289     r = MsiRecordSetString(hrec, 1, "hoo");
1290     sz = sizeof buffer;
1291     r = MsiFormatRecord(0, hrec, buffer, &sz);
1292     todo_wine
1293     {
1294         ok( sz == 12, "size wrong: got %u, expected 12\n", sz);
1295         ok( 0 == strcmp(buffer,"{[1{{boo}}]}"), "wrong output: got %s, expected [1]\n", buffer);
1296     }
1297     ok( r == ERROR_SUCCESS, "format failed\n");
1298
1299     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1300     r = MsiRecordSetString(hrec, 1, "hoo");
1301     sz = sizeof buffer;
1302     r = MsiFormatRecord(0, hrec, buffer, &sz);
1303     ok( sz == 6, "size wrong: got %u, expected 3\n", sz);
1304     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output: got %s, expected [1]\n", buffer);
1305     ok( r == ERROR_SUCCESS, "format failed\n");
1306
1307     r = MsiRecordSetString(hrec, 0, "{[1{{bo}o}}]}");
1308     r = MsiRecordSetString(hrec, 1, "hoo");
1309     sz = sizeof buffer;
1310     r = MsiFormatRecord(0, hrec, buffer, &sz);
1311     ok( sz == 13, "size wrong\n");
1312     ok( 0 == strcmp(buffer,"{[1{{bo}o}}]}"), "wrong output %s\n",buffer);
1313     ok( r == ERROR_SUCCESS, "format failed\n");
1314
1315     r = MsiRecordSetString(hrec, 0, "{[1{{b{o}o}}]}");
1316     sz = sizeof buffer;
1317     r = MsiFormatRecord(0, hrec, buffer, &sz);
1318     todo_wine
1319     {
1320         ok( sz == 14, "size wrong\n");
1321         ok( 0 == strcmp(buffer,"{[1{{b{o}o}}]}"), "wrong output %s\n",buffer);
1322     }
1323     ok( r == ERROR_SUCCESS, "format failed\n");
1324
1325     r = MsiRecordSetString(hrec, 0, "{ {[1]}");
1326     r = MsiRecordSetString(hrec, 1, "hoo");
1327     sz = sizeof buffer;
1328     r = MsiFormatRecord(0, hrec, buffer, &sz);
1329     todo_wine
1330     {
1331         ok( sz == 5, "size wrong\n");
1332         ok( 0 == strcmp(buffer," {hoo"), "wrong output %s\n",buffer);
1333     }
1334     ok( r == ERROR_SUCCESS, "format failed\n");
1335
1336     /* {} inside a substitution does strange things... */
1337     r = MsiRecordSetString(hrec, 0, "[[1]{}]");
1338     r = MsiRecordSetString(hrec, 1, "2");
1339     sz = sizeof buffer;
1340     r = MsiFormatRecord(0, hrec, buffer, &sz);
1341     todo_wine
1342     {
1343         ok( sz == 5, "size wrong\n");
1344         ok( 0 == strcmp(buffer,"[[1]]"), "wrong output %s\n",buffer);
1345     }
1346     ok( r == ERROR_SUCCESS, "format failed\n");
1347
1348     r = MsiRecordSetString(hrec, 0, "[[1]{}[1]]");
1349     r = MsiRecordSetString(hrec, 1, "2");
1350     sz = sizeof buffer;
1351     r = MsiFormatRecord(0, hrec, buffer, &sz);
1352     todo_wine
1353     {
1354         ok( sz == 6, "size wrong\n");
1355         ok( 0 == strcmp(buffer,"[[1]2]"), "wrong output %s\n",buffer);
1356     }
1357     ok( r == ERROR_SUCCESS, "format failed\n");
1358
1359     r = MsiRecordSetString(hrec, 0, "[a[1]b[1]c{}d[1]e]");
1360     r = MsiRecordSetString(hrec, 1, "2");
1361     sz = sizeof buffer;
1362     r = MsiFormatRecord(0, hrec, buffer, &sz);
1363     todo_wine
1364     {
1365         ok( sz == 14, "size wrong\n");
1366         ok( 0 == strcmp(buffer,"[a[1]b[1]cd2e]"), "wrong output %s\n",buffer);
1367     }
1368     ok( r == ERROR_SUCCESS, "format failed\n");
1369
1370     r = MsiRecordSetString(hrec, 0, "[a[1]b");
1371     r = MsiRecordSetString(hrec, 1, "2");
1372     sz = sizeof buffer;
1373     r = MsiFormatRecord(0, hrec, buffer, &sz);
1374     ok( sz == 6, "size wrong\n");
1375     ok( 0 == strcmp(buffer,"[a[1]b"), "wrong output %s\n",buffer);
1376     ok( r == ERROR_SUCCESS, "format failed\n");
1377
1378     r = MsiRecordSetString(hrec, 0, "a[1]b]");
1379     r = MsiRecordSetString(hrec, 1, "2");
1380     sz = sizeof buffer;
1381     r = MsiFormatRecord(0, hrec, buffer, &sz);
1382     ok( sz == 4, "size wrong\n");
1383     ok( 0 == strcmp(buffer,"a2b]"), "wrong output %s\n",buffer);
1384     ok( r == ERROR_SUCCESS, "format failed\n");
1385
1386     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1387     r = MsiRecordSetString(hrec, 1, "2");
1388     sz = sizeof buffer;
1389     r = MsiFormatRecord(0, hrec, buffer, &sz);
1390     ok( sz == 4, "size wrong\n");
1391     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1392     ok( r == ERROR_SUCCESS, "format failed\n");
1393
1394     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1395     r = MsiRecordSetString(hrec, 1, "2");
1396     sz = sizeof buffer;
1397     r = MsiFormatRecord(0, hrec, buffer, &sz);
1398     ok( sz == 4, "size wrong\n");
1399     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1400     ok( r == ERROR_SUCCESS, "format failed\n");
1401
1402     r = MsiRecordSetString(hrec, 0, "\\[1]");
1403     r = MsiRecordSetString(hrec, 1, "2");
1404     sz = sizeof buffer;
1405     r = MsiFormatRecord(0, hrec, buffer, &sz);
1406     ok( sz == 2, "size wrong\n");
1407     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1408     ok( r == ERROR_SUCCESS, "format failed\n");
1409
1410     r = MsiRecordSetString(hrec, 0, "\\{[1]}");
1411     r = MsiRecordSetString(hrec, 1, "2");
1412     sz = sizeof buffer;
1413     r = MsiFormatRecord(0, hrec, buffer, &sz);
1414     ok( sz == 2, "size wrong\n");
1415     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1416     ok( r == ERROR_SUCCESS, "format failed\n");
1417
1418     r = MsiRecordSetString(hrec, 0, "a{b[1]c}d");
1419     r = MsiRecordSetString(hrec, 1, NULL);
1420     sz = sizeof buffer;
1421     r = MsiFormatRecord(0, hrec, buffer, &sz);
1422     ok( sz == 2, "size wrong\n");
1423     ok( 0 == strcmp(buffer,"ad"), "wrong output %s\n",buffer);
1424     ok( r == ERROR_SUCCESS, "format failed\n");
1425
1426     r = MsiRecordSetString(hrec, 0, "{a[0]b}");
1427     r = MsiRecordSetString(hrec, 1, "foo");
1428     sz = sizeof buffer;
1429     r = MsiFormatRecord(0, hrec, buffer, &sz);
1430     ok( sz == 9, "size wrong\n");
1431     ok( 0 == strcmp(buffer,"a{a[0]b}b"), "wrong output %s\n",buffer);
1432     ok( r == ERROR_SUCCESS, "format failed\n");
1433
1434     r = MsiRecordSetString(hrec, 0, "[foo]");
1435     sz = sizeof buffer;
1436     r = MsiFormatRecord(0, hrec, buffer, &sz);
1437     ok( sz == 5, "size wrong\n");
1438     ok( 0 == strcmp(buffer,"[foo]"), "wrong output %s\n",buffer);
1439     ok( r == ERROR_SUCCESS, "format failed\n");
1440
1441     r = MsiRecordSetString(hrec, 0, "{[1][-1][1]}");
1442     r = MsiRecordSetString(hrec, 1, "foo");
1443     sz = sizeof buffer;
1444     r = MsiFormatRecord(0, hrec, buffer, &sz);
1445     todo_wine
1446     {
1447         ok( sz == 12, "size wrong\n");
1448         ok( 0 == strcmp(buffer,"{foo[-1]foo}"), "wrong output %s\n",buffer);
1449     }
1450     ok( r == ERROR_SUCCESS, "format failed\n");
1451
1452     /* nested braces */
1453     sz = sizeof buffer;
1454     MsiRecordSetString(hrec, 0, "{abcd}");
1455     r = MsiFormatRecord(0, hrec, buffer, &sz);
1456     ok( r == ERROR_SUCCESS, "format failed\n");
1457     ok( sz == 6, "size wrong(%i)\n",sz);
1458     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
1459
1460     sz = sizeof buffer;
1461     MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
1462     r = MsiFormatRecord(0, hrec, buffer, &sz);
1463     ok( r == ERROR_SUCCESS, "format failed\n");
1464     ok( sz == 23, "size wrong(%i)\n",sz);
1465     ok( 0 == strcmp(buffer,"{a[one]bc[two]de[one]f}"), "wrong output (%s)\n",buffer);
1466
1467     sz = sizeof buffer;
1468     MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
1469     r = MsiFormatRecord(0, hrec, buffer, &sz);
1470     ok( r == ERROR_SUCCESS, "format failed\n");
1471     ok( sz == 23, "size wrong(%i)\n",sz);
1472     ok( 0 == strcmp(buffer,"{a[one]bc[bad]de[two]f}"), "wrong output (%s)\n",buffer);
1473
1474     sz = sizeof buffer;
1475     MsiRecordSetString(hrec, 0, "{[bad]}");
1476     r = MsiFormatRecord(0, hrec, buffer, &sz);
1477     ok( r == ERROR_SUCCESS, "format failed\n");
1478     ok( sz == 7, "size wrong(%i)\n",sz);
1479     ok( 0 == strcmp(buffer,"{[bad]}"), "wrong output (%s)\n",buffer);
1480
1481     sz = sizeof buffer;
1482     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
1483     r = MsiFormatRecord(0, hrec, buffer, &sz);
1484     ok( r == ERROR_SUCCESS, "format failed\n");
1485     ok( sz == 14, "size wrong(%i)\n",sz);
1486     ok( 0 == strcmp(buffer,"{abc{d[one]ef}"), "wrong output (%s)\n",buffer);
1487
1488     sz = sizeof buffer;
1489     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
1490     r = MsiFormatRecord(0, hrec, buffer, &sz);
1491     ok( r == ERROR_SUCCESS, "format failed\n");
1492     ok( sz == 15, "size wrong(%i)\n",sz);
1493     ok( 0 == strcmp(buffer,"{abc{d[one]ef}}"), "wrong output (%s)\n",buffer);
1494
1495     sz = sizeof buffer;
1496     MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
1497     r = MsiFormatRecord(0, hrec, buffer, &sz);
1498     ok( r == ERROR_SUCCESS, "format failed\n");
1499     ok( sz == 5, "size wrong(%i)\n",sz);
1500     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
1501
1502     sz = sizeof buffer;
1503     MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
1504     r = MsiFormatRecord(0, hrec, buffer, &sz);
1505     ok( r == ERROR_SUCCESS, "format failed\n");
1506     ok( sz == 0, "size wrong(%i)\n",sz);
1507     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1508
1509     sz = sizeof buffer;
1510     MsiRecordSetString(hrec, 0, "{{def}hi{jk}}");
1511     r = MsiFormatRecord(0, hrec, buffer, &sz);
1512     ok( r == ERROR_SUCCESS, "format failed\n");
1513     ok( sz == 0, "size wrong(%i)\n",sz);
1514     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1515
1516     sz = sizeof buffer;
1517     MsiRecordSetString(hrec, 0, "{{{def}}hi{jk}}");
1518     r = MsiFormatRecord(0, hrec, buffer, &sz);
1519     ok( r == ERROR_SUCCESS, "format failed\n");
1520     todo_wine
1521     {
1522         ok( sz == 7, "size wrong(%i)\n",sz);
1523         ok( 0 == strcmp(buffer,"hi{jk}}"), "wrong output (%s)\n",buffer);
1524     }
1525
1526     sz = sizeof buffer;
1527     MsiRecordSetString(hrec, 0, "{{def}hi{{jk}}}");
1528     r = MsiFormatRecord(0, hrec, buffer, &sz);
1529     ok( r == ERROR_SUCCESS, "format failed\n");
1530     todo_wine
1531     {
1532         ok( sz == 1, "size wrong(%i)\n",sz);
1533         ok( 0 == strcmp(buffer,"}"), "wrong output (%s)\n",buffer);
1534     }
1535
1536     sz = sizeof buffer;
1537     MsiRecordSetString(hrec, 0, "{{def}{jk}}");
1538     r = MsiFormatRecord(0, hrec, buffer, &sz);
1539     ok( r == ERROR_SUCCESS, "format failed\n");
1540     ok( sz == 0, "size wrong(%i)\n",sz);
1541     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1542
1543     sz = sizeof buffer;
1544     MsiRecordSetString(hrec, 0, "{{def}}");
1545     r = MsiFormatRecord(0, hrec, buffer, &sz);
1546     ok( r == ERROR_SUCCESS, "format failed\n");
1547     ok( sz == 0, "size wrong(%i)\n",sz);
1548     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1549
1550     sz = sizeof buffer;
1551     MsiRecordSetString(hrec, 0, "{a{b}c}");
1552     r = MsiFormatRecord(0, hrec, buffer, &sz);
1553     ok( r == ERROR_SUCCESS, "format failed\n");
1554     ok( sz == 7, "size wrong(%i)\n",sz);
1555     ok( 0 == strcmp(buffer,"{a{b}c}"), "wrong output (%s)\n",buffer);
1556
1557     sz = sizeof buffer;
1558     MsiRecordSetString(hrec, 0, "{a{b}}");
1559     r = MsiFormatRecord(0, hrec, buffer, &sz);
1560     ok( r == ERROR_SUCCESS, "format failed\n");
1561     ok( sz == 6, "size wrong(%i)\n",sz);
1562     ok( 0 == strcmp(buffer,"{a{b}}"), "wrong output (%s)\n",buffer);
1563
1564     sz = sizeof buffer;
1565     MsiRecordSetString(hrec, 0, "{{b}c}");
1566     r = MsiFormatRecord(0, hrec, buffer, &sz);
1567     ok( r == ERROR_SUCCESS, "format failed\n");
1568     ok( sz == 6, "size wrong(%i)\n",sz);
1569     ok( 0 == strcmp(buffer,"{{b}c}"), "wrong output (%s)\n",buffer);
1570
1571     sz = sizeof buffer;
1572     MsiRecordSetString(hrec, 0, "{{{{}}}}");
1573     r = MsiFormatRecord(0, hrec, buffer, &sz);
1574     ok( r == ERROR_SUCCESS, "format failed\n");
1575     todo_wine
1576     {
1577         ok( sz == 2, "size wrong(%i)\n",sz);
1578         ok( 0 == strcmp(buffer,"}}"), "wrong output (%s)\n",buffer);
1579     }
1580
1581     sz = sizeof buffer;
1582     MsiRecordSetInteger(hrec, 1, 100);
1583     MsiRecordSetInteger(hrec, 2, -100);
1584     MsiRecordSetString(hrec, 0, "[1] [2]");
1585     r = MsiFormatRecord(0, hrec, buffer, &sz);
1586     ok( r == ERROR_SUCCESS, "format failed\n");
1587     ok( sz == 8, "size wrong(%i)\n",sz);
1588     ok( 0 == strcmp(buffer,"100 -100"), "wrong output (%s)\n",buffer);
1589
1590     sz = sizeof(buffer);
1591     MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
1592     MsiRecordSetString(hrec, 1, "one");
1593     r = MsiFormatRecord(0, hrec, buffer, &sz);
1594     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1595     ok(sz == 33, "Expected 33, got %d\n",sz);
1596     ok(!lstrcmpA(buffer, "one {[noprop] [twoprop]} {abcdef}"),
1597        "Expected \"one {[noprop] [twoprop]} {abcdef}\", got \"%s\"\n", buffer);
1598
1599     sz = sizeof(buffer);
1600     MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
1601     MsiRecordSetString(hrec, 1, "one");
1602     r = MsiFormatRecord(0, hrec, buffer, &sz);
1603     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1604     ok(sz == 29, "Expected 29, got %d\n",sz);
1605     ok(!lstrcmpA(buffer, "one {[noprop] [one]} {abcdef}"),
1606        "Expected \"one {[noprop] [one]} {abcdef}\", got \"%s\"\n", buffer);
1607
1608     sz = sizeof(buffer);
1609     MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
1610     MsiRecordSetString(hrec, 1, "one");
1611     r = MsiFormatRecord(0, hrec, buffer, &sz);
1612     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1613     ok(sz == 20, "Expected 20, got %d\n",sz);
1614     ok(!lstrcmpA(buffer, "one {[one]} {abcdef}"),
1615        "Expected \"one {[one]} {abcdef}\", got \"%s\"\n", buffer);
1616
1617     MsiCloseHandle( hrec );
1618 }
1619
1620 static void test_formatrecord_package(void)
1621 {
1622     char buffer[100];
1623     MSIHANDLE hrec;
1624     MSIHANDLE package;
1625     UINT r;
1626     DWORD sz=100;
1627
1628     package = helper_createpackage( msifile );
1629     ok(package!=0, "Unable to create package\n");
1630
1631     hrec = MsiCreateRecord(12);
1632     ok( hrec, "failed to create record\n");
1633
1634     r = MsiFormatRecord(package, 0, NULL, NULL );
1635     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
1636
1637     r = MsiFormatRecord(package, hrec, NULL, NULL );
1638     ok( r == ERROR_SUCCESS, "format failed\n");
1639
1640     r = MsiRecordSetString(hrec,0,NULL);
1641     r = MsiRecordSetString(hrec,1,NULL);
1642     r = MsiRecordSetString(hrec,2,NULL);
1643     r = MsiRecordSetString(hrec,3,NULL);
1644     r = MsiRecordSetString(hrec,4,NULL);
1645     r = MsiRecordSetString(hrec,5,NULL);
1646     r = MsiRecordSetString(hrec,6,NULL);
1647     r = MsiRecordSetString(hrec,7,NULL);
1648     r = MsiRecordSetString(hrec,8,NULL);
1649     r = MsiRecordSetString(hrec,9,NULL);
1650     r = MsiRecordSetString(hrec,10,NULL);
1651     r = MsiRecordSetString(hrec,11,NULL);
1652     r = MsiRecordSetString(hrec,12,NULL);
1653     ok( r == ERROR_SUCCESS, "set string failed\n");
1654
1655     sz = sizeof buffer;
1656     r = MsiFormatRecord(package, hrec, buffer, &sz);
1657     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1658     ok( sz == 51, "size wrong (%i)\n",sz);
1659     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
1660
1661     r = MsiSetProperty(package, "prop", "val");
1662     ok( r == ERROR_SUCCESS, "failed to set propertY: %d\n", r);
1663
1664     r = MsiRecordSetString(hrec, 0, NULL);
1665     r = MsiRecordSetString(hrec, 1, "[2]");
1666     r = MsiRecordSetString(hrec, 2, "stuff");
1667     r = MsiRecordSetString(hrec, 3, "prop");
1668     r = MsiRecordSetString(hrec, 4, "[prop]");
1669     r = MsiRecordSetString(hrec, 5, "[noprop]");
1670     sz = sizeof buffer;
1671     r = MsiFormatRecord(package, hrec, buffer, &sz);
1672     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1673     todo_wine
1674     {
1675         ok( sz == 66, "size wrong (%i)\n",sz);
1676         ok( !lstrcmpA(buffer,
1677             "1: [2] 2: stuff 3: prop 4: val 5:  6:  7:  8:  9:  10:  11:  12:  "),
1678             "wrong output(%s)\n",buffer);
1679     }
1680
1681     /* now put play games with escaping */
1682     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
1683     r = MsiRecordSetString(hrec, 1, "boo");
1684     r = MsiRecordSetString(hrec, 2, "hoo");
1685     ok( r == ERROR_SUCCESS, "set string failed\n");
1686     sz = sizeof buffer;
1687     r = MsiFormatRecord(package, hrec, buffer, &sz);
1688     ok( r == ERROR_SUCCESS, "format failed\n");
1689     ok( sz == 9, "size wrong(%i)\n",sz);
1690     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
1691
1692     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
1693     r = MsiRecordSetString(hrec, 1, "boo");
1694     r = MsiRecordSetString(hrec, 2, "hoo");
1695     ok( r == ERROR_SUCCESS, "set string failed\n");
1696     sz = sizeof buffer;
1697     r = MsiFormatRecord(package, hrec, buffer, &sz);
1698     ok( r == ERROR_SUCCESS, "format failed\n");
1699     ok( sz == 9, "size wrong(%i)\n",sz);
1700     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
1701
1702     MsiRecordSetString(hrec, 0, "[\\x]");
1703     sz = sizeof buffer;
1704     r = MsiFormatRecord(package, hrec, buffer, &sz);
1705     ok( r == ERROR_SUCCESS, "format failed\n");
1706     ok( sz == 1, "size wrong: %d\n", sz);
1707     ok( 0 == strcmp(buffer,"x"), "wrong output: %s\n", buffer);
1708
1709     MsiRecordSetString(hrec, 0, "{\\x}");
1710     sz = sizeof buffer;
1711     r = MsiFormatRecord(package, hrec, buffer, &sz);
1712     ok( r == ERROR_SUCCESS, "format failed\n");
1713     ok( sz == 4, "size wrong: %d\n", sz);
1714     ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer);
1715
1716     MsiRecordSetString(hrec, 0, "[abc\\x]");
1717     sz = sizeof buffer;
1718     r = MsiFormatRecord(package, hrec, buffer, &sz);
1719     ok( r == ERROR_SUCCESS, "format failed\n");
1720     ok( sz == 0, "size wrong: %d\n", sz);
1721     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
1722
1723     MsiRecordSetString(hrec, 0, "[abc\\xdef]");
1724     sz = sizeof buffer;
1725     r = MsiFormatRecord(package, hrec, buffer, &sz);
1726     ok( r == ERROR_SUCCESS, "format failed\n");
1727     ok( sz == 0, "size wrong: %d\n", sz);
1728     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
1729
1730     MsiRecordSetString(hrec, 0, "\\x");
1731     sz = sizeof(buffer);
1732     r = MsiFormatRecord(package, hrec, buffer, &sz);
1733     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1734     ok(sz == 2, "Expected 2, got %d\n", sz);
1735     ok(!lstrcmpA(buffer, "\\x"), "Expected \"\\x\", got \"%s\"\n", buffer);
1736
1737     MsiRecordSetString(hrec, 0, "[\\[");
1738     sz = sizeof(buffer);
1739     r = MsiFormatRecord(package, hrec, buffer, &sz);
1740     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1741     ok(sz == 3, "Expected 3, got %d\n", sz);
1742     ok(!lstrcmpA(buffer, "[\\["), "Expected \"[\\[\", got \"%s\"\n", buffer);
1743
1744     MsiRecordSetString(hrec, 0, "[\\[]");
1745     sz = sizeof(buffer);
1746     r = MsiFormatRecord(package, hrec, buffer, &sz);
1747     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1748     ok(sz == 1, "Expected 1, got %d\n", sz);
1749     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
1750
1751     MsiRecordSetString(hrec, 0, "[[]");
1752     sz = sizeof(buffer);
1753     r = MsiFormatRecord(package, hrec, buffer, &sz);
1754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1755     ok(sz == 3, "Expected 3, got %d\n", sz);
1756     ok(!lstrcmpA(buffer, "[[]"), "Expected \"[]\", got \"%s\"\n", buffer);
1757
1758     MsiRecordSetString(hrec, 0, "[\\[]]");
1759     sz = sizeof(buffer);
1760     r = MsiFormatRecord(package, hrec, buffer, &sz);
1761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1762     ok(sz == 2, "Expected 2, got %d\n", sz);
1763     ok(!lstrcmpA(buffer, "[]"), "Expected \"[]\", got \"%s\"\n", buffer);
1764
1765     MsiRecordSetString(hrec, 0, "[\\[a]");
1766     sz = sizeof(buffer);
1767     r = MsiFormatRecord(package, hrec, buffer, &sz);
1768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1769     ok(sz == 1, "Expected 1, got %d\n", sz);
1770     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
1771
1772     MsiRecordSetString(hrec, 0, "[\\a[]");
1773     sz = sizeof(buffer);
1774     r = MsiFormatRecord(package, hrec, buffer, &sz);
1775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1776     todo_wine
1777     {
1778         ok(sz == 1, "Expected 1, got %d\n", sz);
1779         ok(!lstrcmpA(buffer, "a"), "Expected \"a\", got \"%s\"\n", buffer);
1780     }
1781
1782     MsiRecordSetString(hrec, 0, "[prop]");
1783     sz = sizeof(buffer);
1784     r = MsiFormatRecord(package, hrec, buffer, &sz);
1785     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1786     ok(sz == 3, "Expected 3, got %d\n", sz);
1787     ok(!lstrcmpA(buffer, "val"), "Expected \"val\", got \"%s\"\n", buffer);
1788
1789     MsiRecordSetString(hrec, 0, "[prop] [pro\\pblah] [prop]");
1790     sz = sizeof(buffer);
1791     r = MsiFormatRecord(package, hrec, buffer, &sz);
1792     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1793     ok(sz == 8, "Expected 8, got %d\n", sz);
1794     ok(!lstrcmpA(buffer, "val  val"), "Expected \"val  val\", got \"%s\"\n", buffer);
1795
1796     MsiSetPropertyA(package, "b", "ball");
1797     MsiRecordSetString(hrec, 0, "[\\b]");
1798     sz = sizeof(buffer);
1799     r = MsiFormatRecord(package, hrec, buffer, &sz);
1800     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1801     ok(sz == 1, "Expected 1, got %d\n", sz);
1802     ok(!lstrcmpA(buffer, "b"), "Expected \"b\", got \"%s\"\n", buffer);
1803
1804     MsiRecordSetString(hrec, 0, "[\\c]");
1805     sz = sizeof(buffer);
1806     r = MsiFormatRecord(package, hrec, buffer, &sz);
1807     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1808     ok(sz == 1, "Expected 1, got %d\n", sz);
1809     ok(!lstrcmpA(buffer, "c"), "Expected \"c\", got \"%s\"\n", buffer);
1810
1811     MsiRecordSetString(hrec, 0, "[\\[]prop]");
1812     sz = sizeof(buffer);
1813     r = MsiFormatRecord(package, hrec, buffer, &sz);
1814     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1815     ok(sz == 6, "Expected 6, got %d\n", sz);
1816     ok(!lstrcmpA(buffer, "[prop]"), "Expected \"[prop]\", got \"%s\"\n", buffer);
1817
1818     MsiRecordSetString(hrec, 0, "[\\a]prop]");
1819     sz = sizeof(buffer);
1820     r = MsiFormatRecord(package, hrec, buffer, &sz);
1821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1822     ok(sz == 6, "Expected 6, got %d\n", sz);
1823     ok(!lstrcmpA(buffer, "aprop]"), "Expected \"aprop]\", got \"%s\"\n", buffer);
1824
1825     MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]");
1826     sz = sizeof buffer;
1827     r = MsiFormatRecord(package, hrec, buffer, &sz);
1828     ok( r == ERROR_SUCCESS, "format failed\n");
1829     ok( sz == 14, "size wrong: %d\n", sz);
1830     ok( 0 == strcmp(buffer,"[Bracket Text]"), "wrong output: %s\n", buffer);
1831
1832     /* null characters */
1833     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
1834     r = MsiRecordSetString(hrec, 1, "boo");
1835     r = MsiRecordSetString(hrec, 2, "hoo");
1836     ok( r == ERROR_SUCCESS, "set string failed\n");
1837     sz = sizeof buffer;
1838     r = MsiFormatRecord(package, hrec, buffer, &sz);
1839     ok( r == ERROR_SUCCESS, "format failed\n");
1840     ok( sz == 9, "size wrong: %d\n", sz);
1841     ok( 0 == strcmp(buffer,"boo "), "wrong output: %s\n", buffer);
1842     ok(!lstrcmpA(&buffer[5], " hoo"),
1843        "Expected \" hoo\", got \"%s\"\n", &buffer[5]);
1844
1845     MsiRecordSetString(hrec, 0, "[1] [~abc] [2]");
1846     MsiRecordSetString(hrec, 1, "boo");
1847     MsiRecordSetString(hrec, 2, "hoo");
1848     sz = sizeof(buffer);
1849     r = MsiFormatRecord(package, hrec, buffer, &sz);
1850     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1851     ok(sz == 8, "Expected 8, got %d\n", sz);
1852     ok(!lstrcmpA(buffer, "boo  hoo"), "Expected \"boo  hoo\", got \"%s\"\n", buffer);
1853
1854     /* properties */
1855     r = MsiSetProperty(package,"dummy","Bork");
1856     ok( r == ERROR_SUCCESS, "set property failed\n");
1857     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
1858     r = MsiRecordSetString(hrec, 1, "boo");
1859     r = MsiRecordSetString(hrec, 2, "hoo");
1860     ok( r == ERROR_SUCCESS, "set string failed\n");
1861     sz = sizeof buffer;
1862     r = MsiFormatRecord(package, hrec, buffer, &sz);
1863     ok( r == ERROR_SUCCESS, "format failed\n");
1864     ok( sz == 12, "size wrong\n");
1865     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
1866
1867     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
1868     r = MsiRecordSetString(hrec, 1, "boo");
1869     r = MsiRecordSetString(hrec, 2, "hoo");
1870     ok( r == ERROR_SUCCESS, "set string failed\n");
1871     sz = sizeof buffer;
1872     r = MsiFormatRecord(package, hrec, buffer, &sz);
1873     ok( r == ERROR_SUCCESS, "format failed\n");
1874     ok( sz == 8, "size wrong\n");
1875     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
1876
1877     /* nesting tests */
1878     r = MsiSetProperty(package,"dummya","foo");
1879     r = MsiSetProperty(package,"dummyb","baa");
1880     r = MsiSetProperty(package,"adummyc","whoa");
1881     ok( r == ERROR_SUCCESS, "set property failed\n");
1882     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
1883     r = MsiRecordSetString(hrec, 1, "a");
1884     r = MsiRecordSetString(hrec, 2, "b");
1885     r = MsiRecordSetString(hrec, 3, "c");
1886     ok( r == ERROR_SUCCESS, "set string failed\n");
1887     sz = sizeof buffer;
1888     r = MsiFormatRecord(package, hrec, buffer, &sz);
1889     ok( r == ERROR_SUCCESS, "format failed\n");
1890     ok( sz == 12, "size wrong(%i)\n",sz);
1891     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
1892
1893     r = MsiSetProperty(package,"dummya","1");
1894     r = MsiSetProperty(package,"dummyb","[2]");
1895     ok( r == ERROR_SUCCESS, "set property failed\n");
1896     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
1897     r = MsiRecordSetString(hrec, 1, "aaa");
1898     r = MsiRecordSetString(hrec, 2, "bbb");
1899     r = MsiRecordSetString(hrec, 3, "ccc");
1900     ok( r == ERROR_SUCCESS, "set string failed\n");
1901     sz = sizeof buffer;
1902     r = MsiFormatRecord(package, hrec, buffer, &sz);
1903     ok( r == ERROR_SUCCESS, "format failed\n");
1904     todo_wine
1905     {
1906         ok( sz == 9, "size wrong(%i)\n",sz);
1907         ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
1908     }
1909
1910     r = MsiSetProperty(package,"dummya","1");
1911     r = MsiSetProperty(package,"dummyb","a");
1912     r = MsiSetProperty(package,"dummyc","\\blath");
1913     r = MsiSetProperty(package,"dummyd","[\\blath]");
1914     ok( r == ERROR_SUCCESS, "set property failed\n");
1915     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
1916     r = MsiRecordSetString(hrec, 1, "aaa");
1917     r = MsiRecordSetString(hrec, 2, "bbb");
1918     r = MsiRecordSetString(hrec, 3, "ccc");
1919     ok( r == ERROR_SUCCESS, "set string failed\n");
1920     sz = sizeof buffer;
1921     r = MsiFormatRecord(package, hrec, buffer, &sz);
1922     ok( r == ERROR_SUCCESS, "format failed\n");
1923     ok( sz == 10, "size wrong(%i)\n",sz);
1924     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
1925
1926     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
1927     r = MsiRecordSetString(hrec, 1, "boo");
1928     r = MsiRecordSetString(hrec, 2, "hoo");
1929     r = MsiRecordSetString(hrec, 3, "yeah");
1930     ok( r == ERROR_SUCCESS, "set string failed\n");
1931     sz = sizeof buffer;
1932     r = MsiFormatRecord(package, hrec, buffer, &sz);
1933     ok( r == ERROR_SUCCESS, "format failed\n");
1934     todo_wine
1935     {
1936         ok( sz == 11, "size wrong(%i)\n",sz);
1937         ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
1938     }
1939
1940     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
1941     r = MsiRecordSetString(hrec, 1, "boo");
1942     r = MsiRecordSetString(hrec, 2, "hoo");
1943     r = MsiRecordSetString(hrec, 3, "\\help");
1944     ok( r == ERROR_SUCCESS, "set string failed\n");
1945     sz = sizeof buffer;
1946     r = MsiFormatRecord(package, hrec, buffer, &sz);
1947     ok( r == ERROR_SUCCESS, "format failed\n");
1948     ok( sz == 9, "size wrong(%i)\n",sz);
1949     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
1950
1951     /* nested properties */
1952     MsiSetProperty(package, "PropA", "surprise");
1953     MsiSetProperty(package, "PropB", "[PropA]");
1954     MsiSetProperty(package, "PropC", "[PropB]");
1955     sz = sizeof buffer;
1956     MsiRecordSetString(hrec, 0, "[PropC]");
1957     r = MsiFormatRecord(package, hrec, buffer, &sz);
1958     ok( r == ERROR_SUCCESS, "format failed\n");
1959     ok( sz == 7, "size wrong(%i)\n",sz);
1960     ok( 0 == strcmp(buffer,"[PropB]"), "wrong output (%s)\n",buffer);
1961
1962     MsiSetProperty(package, "PropA", "surprise");
1963     MsiSetProperty(package, "PropB", "PropA");
1964     MsiSetProperty(package, "PropC", "PropB");
1965     sz = sizeof buffer;
1966     MsiRecordSetString(hrec, 0, "[PropC]");
1967     r = MsiFormatRecord(package, hrec, buffer, &sz);
1968     ok( r == ERROR_SUCCESS, "format failed\n");
1969     ok( sz == 5, "size wrong(%i)\n",sz);
1970     ok( 0 == strcmp(buffer,"PropB"), "wrong output (%s)\n",buffer);
1971
1972     MsiSetProperty(package, "PropA", "surprise");
1973     MsiSetProperty(package, "PropB", "[PropA]");
1974     MsiSetProperty(package, "PropC", "[PropB]");
1975     sz = sizeof buffer;
1976     MsiRecordSetString(hrec, 0, "[[PropC]]");
1977     r = MsiFormatRecord(package, hrec, buffer, &sz);
1978     ok( r == ERROR_SUCCESS, "format failed\n");
1979     ok( sz == 0, "size wrong(%i)\n",sz);
1980     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1981
1982     MsiSetProperty(package, "PropA", "surprise");
1983     MsiSetProperty(package, "PropB", "[PropA]");
1984     MsiSetProperty(package, "PropC", "PropB");
1985     sz = sizeof buffer;
1986     MsiRecordSetString(hrec, 0, "[[PropC]]");
1987     r = MsiFormatRecord(package, hrec, buffer, &sz);
1988     ok( r == ERROR_SUCCESS, "format failed\n");
1989     ok( sz == 7, "size wrong(%i)\n",sz);
1990     ok( 0 == strcmp(buffer,"[PropA]"), "wrong output (%s)\n",buffer);
1991
1992     MsiSetProperty(package, "PropA", "surprise");
1993     MsiSetProperty(package, "PropB", "PropA");
1994     MsiSetProperty(package, "PropC", "PropB");
1995     sz = sizeof buffer;
1996     MsiRecordSetString(hrec, 0, "[[PropC]]");
1997     r = MsiFormatRecord(package, hrec, buffer, &sz);
1998     ok( r == ERROR_SUCCESS, "format failed\n");
1999     ok( sz == 5, "size wrong(%i)\n",sz);
2000     ok( 0 == strcmp(buffer,"PropA"), "wrong output (%s)\n",buffer);
2001
2002     MsiSetProperty(package, "PropA", "surprise");
2003     MsiSetProperty(package, "PropB", "PropA");
2004     MsiSetProperty(package, "PropC", "PropB");
2005     sz = sizeof buffer;
2006     MsiRecordSetString(hrec, 0, "[[[PropC]]]");
2007     r = MsiFormatRecord(package, hrec, buffer, &sz);
2008     ok( r == ERROR_SUCCESS, "format failed\n");
2009     ok( sz == 8, "size wrong(%i)\n",sz);
2010     ok( 0 == strcmp(buffer,"surprise"), "wrong output (%s)\n",buffer);
2011
2012     /* properties inside braces */
2013     sz = sizeof buffer;
2014     MsiRecordSetString(hrec, 0, "{abcd}");
2015     r = MsiFormatRecord(package, hrec, buffer, &sz);
2016     ok( r == ERROR_SUCCESS, "format failed\n");
2017     ok( sz == 6, "size wrong(%i)\n",sz);
2018     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
2019
2020     MsiSetProperty(package, "one", "mercury");
2021     MsiSetProperty(package, "two", "venus");
2022     sz = sizeof buffer;
2023     MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
2024     r = MsiFormatRecord(package, hrec, buffer, &sz);
2025     ok( r == ERROR_SUCCESS, "format failed: %d\n", r);
2026     ok( sz == 25, "size wrong(%i)\n",sz);
2027     ok( 0 == strcmp(buffer,"amercurybcvenusdemercuryf"), "wrong output (%s)\n",buffer);
2028
2029     MsiSetProperty(package, "one", "mercury");
2030     MsiSetProperty(package, "two", "venus");
2031     MsiSetProperty(package, "bad", "");
2032     sz = sizeof buffer;
2033     MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
2034     r = MsiFormatRecord(package, hrec, buffer, &sz);
2035     ok( r == ERROR_SUCCESS, "format failed\n");
2036     ok( sz == 0, "size wrong(%i)\n",sz);
2037     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2038
2039     MsiSetProperty(package, "bad", "");
2040     sz = sizeof buffer;
2041     MsiRecordSetString(hrec, 0, "{[bad]}");
2042     r = MsiFormatRecord(package, hrec, buffer, &sz);
2043     ok( r == ERROR_SUCCESS, "format failed\n");
2044     ok( sz == 0, "size wrong(%i)\n",sz);
2045     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2046
2047     MsiSetProperty(package, "one", "mercury");
2048     sz = sizeof buffer;
2049     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
2050     r = MsiFormatRecord(package, hrec, buffer, &sz);
2051     ok( r == ERROR_SUCCESS, "format failed\n");
2052     todo_wine
2053     {
2054         ok( sz == 14, "size wrong(%i)\n",sz);
2055         ok( 0 == strcmp(buffer,"abc{dmercuryef"), "wrong output (%s)\n",buffer);
2056     }
2057
2058     MsiSetProperty(package, "one", "mercury");
2059     sz = sizeof buffer;
2060     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
2061     r = MsiFormatRecord(package, hrec, buffer, &sz);
2062     ok( r == ERROR_SUCCESS, "format failed\n");
2063     todo_wine
2064     {
2065         ok( sz == 15, "size wrong(%i)\n",sz);
2066         ok( 0 == strcmp(buffer,"abc{dmercuryef}"), "wrong output (%s)\n",buffer);
2067     }
2068
2069     MsiSetProperty(package, "one", "mercury");
2070     sz = sizeof buffer;
2071     MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
2072     r = MsiFormatRecord(package, hrec, buffer, &sz);
2073     ok( r == ERROR_SUCCESS, "format failed\n");
2074     ok( sz == 5, "size wrong(%i)\n",sz);
2075     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
2076
2077     MsiSetProperty(package, "one", "mercury");
2078
2079     sz = sizeof buffer;
2080     MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
2081     r = MsiFormatRecord(package, hrec, buffer, &sz);
2082     ok( r == ERROR_SUCCESS, "format failed\n");
2083     ok( sz == 0, "size wrong(%i)\n",sz);
2084     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2085
2086     sz = sizeof(buffer);
2087     MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
2088     MsiRecordSetString(hrec, 1, "one");
2089     r = MsiFormatRecord(package, hrec, buffer, &sz);
2090     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2091     ok(sz == 13, "Expected 13, got %d\n",sz);
2092     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2093        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2094
2095     sz = sizeof(buffer);
2096     MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
2097     MsiRecordSetString(hrec, 1, "one");
2098     r = MsiFormatRecord(package, hrec, buffer, &sz);
2099     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2100     ok(sz == 13, "Expected 13, got %d\n",sz);
2101     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2102        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2103
2104     sz = sizeof(buffer);
2105     MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
2106     MsiRecordSetString(hrec, 1, "one");
2107     r = MsiFormatRecord(package, hrec, buffer, &sz);
2108     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2109     ok(sz == 20, "Expected 20, got %d\n",sz);
2110     ok(!lstrcmpA(buffer, "one mercury {abcdef}"),
2111        "Expected \"one mercury {abcdef}\", got \"%s\"\n", buffer);
2112
2113     MsiCloseHandle(hrec);
2114
2115     r = MsiCloseHandle(package);
2116     ok(r==ERROR_SUCCESS, "Unable to close package\n");
2117
2118     DeleteFile( msifile );
2119 }
2120
2121 static void test_formatrecord_tables(void)
2122 {
2123     MSIHANDLE hdb, hpkg, hrec;
2124     CHAR buf[MAX_PATH];
2125     CHAR curr_dir[MAX_PATH];
2126     CHAR expected[MAX_PATH];
2127     CHAR root[MAX_PATH];
2128     DWORD size;
2129     UINT r;
2130
2131     GetCurrentDirectory( MAX_PATH, curr_dir );
2132
2133     hdb = create_package_db();
2134     ok ( hdb, "failed to create package database\n");
2135
2136     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2137     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2138
2139     r = add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2140                              "'I am a really long directory'" );
2141     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2142
2143     r = create_feature_table( hdb );
2144     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r);
2145
2146     r = add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2147     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2148
2149     r = create_component_table( hdb );
2150     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r);
2151
2152     r = add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2153     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2154
2155     r = add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2156     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2157
2158     r = add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2159     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2160
2161     r = create_feature_components_table( hdb );
2162     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r);
2163
2164     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2165     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2166
2167     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2168     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2169
2170     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2171     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2172
2173     r = create_file_table( hdb );
2174     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r);
2175
2176     r = add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2177     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2178
2179     r = add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2180     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2181
2182     r = add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2183     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2184
2185     r = create_custom_action_table( hdb );
2186     ok( r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
2187
2188     r = add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2189     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2190
2191     r = add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2192     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2193
2194     r = add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2195     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2196
2197     r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2198     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2199
2200     hpkg = package_from_db( hdb );
2201     ok( hpkg, "failed to create package\n");
2202
2203     MsiCloseHandle( hdb );
2204
2205     r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2206     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2207
2208     hrec = MsiCreateRecord( 1 );
2209
2210     /* property doesn't exist */
2211     size = MAX_PATH;
2212     /*MsiRecordSetString( hrec, 0, "[1]" ); */
2213     MsiRecordSetString( hrec, 1, "[idontexist]" );
2214     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2215     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2216     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2217
2218     /* property exists */
2219     size = MAX_PATH;
2220     MsiRecordSetString( hrec, 1, "[imaprop]" );
2221     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2222     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2223     ok( !lstrcmp( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2224
2225     /* environment variable doesn't exist */
2226     size = MAX_PATH;
2227     MsiRecordSetString( hrec, 1, "[%idontexist]" );
2228     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2229     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2230     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2231
2232     /* environment variable exists */
2233     size = MAX_PATH;
2234     SetEnvironmentVariable( "crazyvar", "crazyval" );
2235     MsiRecordSetString( hrec, 1, "[%crazyvar]" );
2236     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2237     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2238     ok( !lstrcmp( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2239
2240     /* file key before CostInitialize */
2241     size = MAX_PATH;
2242     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2243     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2244     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2245     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2246
2247     r = MsiDoAction(hpkg, "CostInitialize");
2248     ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2249
2250     r = MsiDoAction(hpkg, "FileCost");
2251     ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2252
2253     r = MsiDoAction(hpkg, "CostFinalize");
2254     ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2255
2256     size = MAX_PATH;
2257     MsiGetProperty( hpkg, "ROOTDRIVE", root, &size );
2258
2259     sprintf( expected, "1: %sfrontal.txt ", root);
2260
2261     /* frontal full file key */
2262     size = MAX_PATH;
2263     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2264     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2265     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2266     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2267
2268     /* frontal short file key */
2269     size = MAX_PATH;
2270     MsiRecordSetString( hrec, 1, "[!frontal_file]" );
2271     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2272     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2273     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2274
2275     sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2276
2277     /* temporal full file key */
2278     size = MAX_PATH;
2279     MsiRecordSetString( hrec, 1, "[#temporal_file]" );
2280     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2281     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2282     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2283
2284     /* temporal short file key */
2285     size = MAX_PATH;
2286     MsiRecordSetString( hrec, 1, "[!temporal_file]" );
2287     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2288     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2289     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2290
2291     /* custom action 51, files don't exist */
2292     r = MsiDoAction( hpkg, "MyCustom" );
2293     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2294
2295     sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2296
2297     size = MAX_PATH;
2298     r = MsiGetProperty( hpkg, "prop", buf, &size );
2299     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2300     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2301
2302     sprintf( buf, "%sI am a really long directory", root );
2303     CreateDirectory( buf, NULL );
2304
2305     lstrcat( buf, "\\temporal.txt" );
2306     create_test_file( buf );
2307
2308     /* custom action 51, files exist */
2309     r = MsiDoAction( hpkg, "MyCustom" );
2310     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2311
2312     size = MAX_PATH;
2313     r = MsiGetProperty( hpkg, "prop", buf, &size );
2314     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2315     todo_wine
2316     {
2317         ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2318     }
2319
2320     /* custom action 51, escaped text 1 */
2321     r = MsiDoAction( hpkg, "EscapeIt1" );
2322     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2323
2324     size = MAX_PATH;
2325     r = MsiGetProperty( hpkg, "prop", buf, &size );
2326     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2327     ok( !lstrcmp( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2328
2329     /* custom action 51, escaped text 2 */
2330     r = MsiDoAction( hpkg, "EscapeIt2" );
2331     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2332
2333     size = MAX_PATH;
2334     r = MsiGetProperty( hpkg, "prop", buf, &size );
2335     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2336     ok( !lstrcmp( buf, "x" ), "Expected 'x', got %s\n", buf);
2337
2338     /* custom action 51, escaped text 3 */
2339     r = MsiDoAction( hpkg, "EscapeIt3" );
2340     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2341
2342     size = MAX_PATH;
2343     r = MsiGetProperty( hpkg, "prop", buf, &size );
2344     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2345     ok( !lstrcmp( buf, "" ), "Expected '', got %s\n", buf);
2346
2347     sprintf( expected, "1: %sI am a really long directory\\ ", root);
2348
2349     /* component with INSTALLSTATE_LOCAL */
2350     size = MAX_PATH;
2351     MsiRecordSetString( hrec, 1, "[$temporal]" );
2352     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2353     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2354     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2355
2356     r = MsiSetComponentState( hpkg, "temporal", INSTALLSTATE_SOURCE );
2357     ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2358
2359     /* component with INSTALLSTATE_SOURCE */
2360     lstrcpy( expected, "1: " );
2361     lstrcat( expected, curr_dir );
2362     if (strlen(curr_dir) > 3)
2363         lstrcat( expected, "\\" );
2364     lstrcat( expected, " " );
2365     size = MAX_PATH;
2366     MsiRecordSetString( hrec, 1, "[$parietal]" );
2367     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2368     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2369     ok( !lstrcmp( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2370
2371     sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2372     DeleteFile( buf );
2373
2374     sprintf( buf, "%sI am a really long directory", root );
2375     RemoveDirectory( buf );
2376
2377     MsiCloseHandle( hrec );
2378     MsiCloseHandle( hpkg );
2379     DeleteFile( msifile );
2380 }
2381
2382 static void test_processmessage(void)
2383 {
2384     MSIHANDLE hrec;
2385     MSIHANDLE package;
2386     int r;
2387
2388     package = helper_createpackage( msifile );
2389     ok(package!=0, "Unable to create package\n");
2390
2391     hrec = MsiCreateRecord(3);
2392     ok( hrec, "failed to create record\n");
2393
2394     r = MsiRecordSetString(hrec, 1, "");
2395     ok( r == ERROR_SUCCESS, "set string failed\n");
2396
2397     r = MsiProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, hrec);
2398     ok( r == IDOK, "expected IDOK, got %i\n", r);
2399
2400     MsiCloseHandle(hrec);
2401     MsiCloseHandle(package);
2402
2403     DeleteFile(msifile);
2404 }
2405
2406 START_TEST(format)
2407 {
2408     test_createpackage();
2409     test_formatrecord();
2410     test_formatrecord_package();
2411     test_formatrecord_tables();
2412     test_processmessage();
2413 }