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