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