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