Release 1.5.29.
[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     ok( r == ERROR_SUCCESS, "set string failed\n");
1027     sz = sizeof buffer;
1028     r = MsiFormatRecord(0, hrec, buffer, &sz);
1029     ok( sz == 2, "size wrong\n");
1030     ok( 0 == strcmp(buffer,"[]"), "wrong output\n");
1031     ok( r == ERROR_SUCCESS, "format failed\n");
1032
1033     /* MsiFormatRecord doesn't seem to handle a negative too well */
1034     r = MsiRecordSetString(hrec, 0, "[-1]");
1035     ok( r == ERROR_SUCCESS, "set string failed\n");
1036     sz = sizeof buffer;
1037     r = MsiFormatRecord(0, hrec, buffer, &sz);
1038     ok( sz == 4, "size wrong\n");
1039     ok( 0 == strcmp(buffer,"[-1]"), "wrong output\n");
1040     ok( r == ERROR_SUCCESS, "format failed\n");
1041
1042     r = MsiRecordSetString(hrec, 0, "{[]}");
1043     ok( r == ERROR_SUCCESS, "set string failed\n");
1044     sz = sizeof buffer;
1045     r = MsiFormatRecord(0, hrec, buffer, &sz);
1046     ok( sz == 4, "size wrong\n");
1047     ok( 0 == strcmp(buffer,"{[]}"), "wrong output\n");
1048     ok( r == ERROR_SUCCESS, "format failed\n");
1049
1050     r = MsiRecordSetString(hrec, 0, "[0]");
1051     ok( r == ERROR_SUCCESS, "set string failed\n");
1052     sz = sizeof buffer;
1053     r = MsiFormatRecord(0, hrec, buffer, &sz);
1054     ok( sz == 3, "size wrong\n");
1055     ok( 0 == strcmp(buffer,"[0]"), "wrong output\n");
1056     ok( r == ERROR_SUCCESS, "format failed\n");
1057
1058     r = MsiRecordSetString(hrec, 0, "[100]");
1059     ok( r == ERROR_SUCCESS, "set string failed\n");
1060     sz = sizeof buffer;
1061     r = MsiFormatRecord(0, hrec, buffer, &sz);
1062     ok( sz == 0, "size wrong\n");
1063     ok( 0 == strcmp(buffer,""), "wrong output\n");
1064     ok( r == ERROR_SUCCESS, "format failed\n");
1065
1066     r = MsiRecordSetString(hrec, 0, "{[1] [2]}");
1067     ok( r == ERROR_SUCCESS, "set string failed\n");
1068     r = MsiRecordSetString(hrec, 1, "boo");
1069     ok( r == ERROR_SUCCESS, "set string failed\n");
1070     r = MsiRecordSetString(hrec, 2, "hoo");
1071     ok( r == ERROR_SUCCESS, "set string failed\n");
1072     sz = sizeof buffer;
1073     r = MsiFormatRecord(0, hrec, buffer, &sz);
1074     ok( sz == 7, "size wrong\n");
1075     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
1076     ok( r == ERROR_SUCCESS, "format failed\n");
1077
1078     r = MsiRecordSetString(hrec, 0, "{}");
1079     ok( r == ERROR_SUCCESS, "set string failed\n");
1080     sz = sizeof buffer;
1081     r = MsiFormatRecord(0, hrec, buffer, &sz);
1082     ok( sz == 0, "size wrong\n");
1083     ok( 0 == strcmp(buffer,""), "wrong output\n");
1084     ok( r == ERROR_SUCCESS, "format failed\n");
1085
1086     r = MsiRecordSetString(hrec, 0, "{foo}");
1087     ok( r == ERROR_SUCCESS, "set string failed\n");
1088     sz = sizeof buffer;
1089     r = MsiFormatRecord(0, hrec, buffer, &sz);
1090     ok( sz == 5, "size wrong\n");
1091     ok( 0 == strcmp(buffer,"{foo}"), "wrong output\n");
1092     ok( r == ERROR_SUCCESS, "format failed\n");
1093
1094     r = MsiRecordSetString(hrec, 0, "{boo [1]}");
1095     ok( r == ERROR_SUCCESS, "set string failed\n");
1096     r = MsiRecordSetString(hrec, 1, "hoo");
1097     ok( r == ERROR_SUCCESS, "set string failed\n");
1098     sz = sizeof buffer;
1099     r = MsiFormatRecord(0, hrec, buffer, &sz);
1100     ok( sz == 7, "size wrong\n");
1101     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
1102     ok( r == ERROR_SUCCESS, "format failed\n");
1103
1104     r = MsiRecordSetString(hrec, 0, "{{[1]}}");
1105     ok( r == ERROR_SUCCESS, "set string failed\n");
1106     r = MsiRecordSetString(hrec, 1, "hoo");
1107     ok( r == ERROR_SUCCESS, "set string failed\n");
1108     sz = sizeof buffer;
1109     r = MsiFormatRecord(0, hrec, buffer, &sz);
1110     ok( sz == 0, "size wrong\n");
1111     ok( 0 == strcmp(buffer,""), "wrong output\n");
1112     ok( r == ERROR_SUCCESS, "format failed\n");
1113
1114     r = MsiRecordSetString(hrec, 0, "{ {[1]}}");
1115     ok( r == ERROR_SUCCESS, "set string failed\n");
1116     r = MsiRecordSetString(hrec, 1, "hoo");
1117     ok( r == ERROR_SUCCESS, "set string failed\n");
1118     sz = sizeof buffer;
1119     r = MsiFormatRecord(0, hrec, buffer, &sz);
1120     todo_wine
1121     {
1122         ok( 0 == strcmp(buffer," {hoo}"), "wrong output\n");
1123         ok( sz == 6, "size wrong\n");
1124     }
1125     ok( r == ERROR_SUCCESS, "format failed\n");
1126
1127     r = MsiRecordSetString(hrec, 0, "{{[1]} }");
1128     ok( r == ERROR_SUCCESS, "set string failed\n");
1129     r = MsiRecordSetString(hrec, 1, "hoo");
1130     ok( r == ERROR_SUCCESS, "set string failed\n");
1131     sz = sizeof buffer;
1132     r = MsiFormatRecord(0, hrec, buffer, &sz);
1133     ok( sz == 8, "size wrong\n");
1134     ok( 0 == strcmp(buffer,"{{hoo} }"), "wrong output\n");
1135     ok( r == ERROR_SUCCESS, "format failed\n");
1136
1137     r = MsiRecordSetString(hrec, 0, "{{ [1]}}");
1138     ok( r == ERROR_SUCCESS, "set string failed\n");
1139     r = MsiRecordSetString(hrec, 1, "hoo");
1140     ok( r == ERROR_SUCCESS, "set string failed\n");
1141     sz = sizeof buffer;
1142     r = MsiFormatRecord(0, hrec, buffer, &sz);
1143     ok( sz == 0, "size wrong\n");
1144     ok( 0 == strcmp(buffer,""), "wrong output\n");
1145     ok( r == ERROR_SUCCESS, "format failed\n");
1146
1147     r = MsiRecordSetString(hrec, 0, "{{[1] }}");
1148     ok( r == ERROR_SUCCESS, "set string failed\n");
1149     r = MsiRecordSetString(hrec, 1, "hoo");
1150     ok( r == ERROR_SUCCESS, "set string failed\n");
1151     sz = sizeof buffer;
1152     r = MsiFormatRecord(0, hrec, buffer, &sz);
1153     ok( sz == 0, "size wrong\n");
1154     ok( 0 == strcmp(buffer,""), "wrong output\n");
1155     ok( r == ERROR_SUCCESS, "format failed\n");
1156
1157     r = MsiRecordSetString(hrec, 0, "{{a}{b}{c }{ d}{any text}}");
1158     ok( r == ERROR_SUCCESS, "set string failed\n");
1159     sz = sizeof buffer;
1160     r = MsiFormatRecord(0, hrec, buffer, &sz);
1161     ok( sz == 0, "size wrong\n");
1162     ok( 0 == strcmp(buffer,""), "wrong output\n");
1163     ok( r == ERROR_SUCCESS, "format failed\n");
1164
1165     r = MsiRecordSetString(hrec, 0, "{{a} }");
1166     ok( r == ERROR_SUCCESS, "set string failed\n");
1167     sz = sizeof buffer;
1168     r = MsiFormatRecord(0, hrec, buffer, &sz);
1169     ok( sz == 6, "size wrong\n");
1170     ok( 0 == strcmp(buffer,"{{a} }"), "wrong output\n");
1171     ok( r == ERROR_SUCCESS, "format failed\n");
1172
1173     r = MsiRecordSetString(hrec, 0, "{{a} {b}}");
1174     ok( r == ERROR_SUCCESS, "set string failed\n");
1175     sz = sizeof buffer;
1176     r = MsiFormatRecord(0, hrec, buffer, &sz);
1177     ok( sz == 0, "size wrong\n");
1178     ok( 0 == strcmp(buffer,""), "wrong output\n");
1179     ok( r == ERROR_SUCCESS, "format failed\n");
1180
1181     r = MsiRecordSetString(hrec, 0, "{{a} b}}");
1182     ok( r == ERROR_SUCCESS, "set string failed\n");
1183     sz = sizeof buffer;
1184     r = MsiFormatRecord(0, hrec, buffer, &sz);
1185     todo_wine ok( sz == 0, "size wrong\n");
1186     todo_wine ok( 0 == strcmp(buffer,""), "wrong output\n");
1187     ok( r == ERROR_SUCCESS, "format failed\n");
1188
1189     r = MsiRecordSetString(hrec, 0, "{{a b}}");
1190     ok( r == ERROR_SUCCESS, "set string failed\n");
1191     sz = sizeof buffer;
1192     r = MsiFormatRecord(0, hrec, buffer, &sz);
1193     ok( sz == 0, "size wrong\n");
1194     ok( 0 == strcmp(buffer,""), "wrong output\n");
1195     ok( r == ERROR_SUCCESS, "format failed\n");
1196
1197     r = MsiRecordSetString(hrec, 0, "{ }");
1198     ok( r == ERROR_SUCCESS, "set string failed\n");
1199     sz = sizeof buffer;
1200     r = MsiFormatRecord(0, hrec, buffer, &sz);
1201     ok( sz == 3, "size wrong\n");
1202     ok( 0 == strcmp(buffer,"{ }"), "wrong output\n");
1203     ok( r == ERROR_SUCCESS, "format failed\n");
1204
1205     r = MsiRecordSetString(hrec, 0, " {{a}}}");
1206     ok( r == ERROR_SUCCESS, "set string failed\n");
1207     sz = sizeof buffer;
1208     r = MsiFormatRecord(0, hrec, buffer, &sz);
1209     ok( sz == 2, "size wrong\n");
1210     ok( 0 == strcmp(buffer," }"), "wrong output\n");
1211     ok( r == ERROR_SUCCESS, "format failed\n");
1212
1213     r = MsiRecordSetString(hrec, 0, "{{ almost {{ any }} text }}");
1214     ok( r == ERROR_SUCCESS, "set string failed\n");
1215     sz = sizeof buffer;
1216     r = MsiFormatRecord(0, hrec, buffer, &sz);
1217     todo_wine ok( sz == 8, "size wrong\n");
1218     todo_wine ok( 0 == strcmp(buffer," text }}"), "wrong output\n");
1219     ok( r == ERROR_SUCCESS, "format failed\n");
1220
1221     r = MsiRecordSetString(hrec, 0, "{{ } { hidden ][ [ }}");
1222     ok( r == ERROR_SUCCESS, "set string failed\n");
1223     sz = sizeof buffer;
1224     r = MsiFormatRecord(0, hrec, buffer, &sz);
1225     todo_wine ok( sz == 0, "size wrong\n");
1226     todo_wine ok( 0 == strcmp(buffer,""), "wrong output\n");
1227     ok( r == ERROR_SUCCESS, "format failed\n");
1228
1229     r = MsiRecordSetString(hrec, 0, "[ 1]");
1230     ok( r == ERROR_SUCCESS, "set string failed\n");
1231     r = MsiRecordSetString(hrec, 1, "hoo");
1232     ok( r == ERROR_SUCCESS, "set string failed\n");
1233     sz = sizeof buffer;
1234     r = MsiFormatRecord(0, hrec, buffer, &sz);
1235     ok( sz == 4, "size wrong\n");
1236     ok( 0 == strcmp(buffer,"[ 1]"), "wrong output\n");
1237     ok( r == ERROR_SUCCESS, "format failed\n");
1238
1239     r = MsiRecordSetString(hrec, 0, "[01]");
1240     ok( r == ERROR_SUCCESS, "set string failed\n");
1241     r = MsiRecordSetString(hrec, 1, "hoo");
1242     ok( r == ERROR_SUCCESS, "set string failed\n");
1243     sz = sizeof buffer;
1244     r = MsiFormatRecord(0, hrec, buffer, &sz);
1245     ok( sz == 3, "size wrong\n");
1246     ok( 0 == strcmp(buffer,"hoo"), "wrong output\n");
1247     ok( r == ERROR_SUCCESS, "format failed\n");
1248
1249     r = MsiRecordSetString(hrec, 0, "{{test}} [01");
1250     ok( r == ERROR_SUCCESS, "set string failed\n");
1251     r = MsiRecordSetString(hrec, 1, "hoo");
1252     ok( r == ERROR_SUCCESS, "set string failed\n");
1253     sz = sizeof buffer;
1254     r = MsiFormatRecord(0, hrec, buffer, &sz);
1255     todo_wine ok( sz == 4, "size wrong\n");
1256     todo_wine ok( 0 == strcmp(buffer," [01"), "wrong output\n");
1257     ok( r == ERROR_SUCCESS, "format failed\n");
1258
1259     r = MsiRecordSetString(hrec, 0, "[\\[]");
1260     ok( r == ERROR_SUCCESS, "set string failed\n");
1261     r = MsiRecordSetString(hrec, 1, "hoo");
1262     ok( r == ERROR_SUCCESS, "set string failed\n");
1263     sz = sizeof buffer;
1264     r = MsiFormatRecord(0, hrec, buffer, &sz);
1265     ok( sz == 4, "size wrong\n");
1266     ok( 0 == strcmp(buffer,"[\\[]"), "wrong output\n");
1267     ok( r == ERROR_SUCCESS, "format failed\n");
1268
1269     r = MsiRecordSetString(hrec, 0, "[\\[]");
1270     ok( r == ERROR_SUCCESS, "set string failed\n");
1271     r = MsiRecordSetString(hrec, 1, "hoo");
1272     ok( r == ERROR_SUCCESS, "set string failed\n");
1273     sz = sizeof(buffer);
1274     r = MsiFormatRecord(0, hrec, buffer, &sz);
1275     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1276     ok(sz == 4, "Expected 4, got %d\n", sz);
1277     ok(!lstrcmpA(buffer, "[\\[]"), "Expected \"[\\[]\", got \"%s\"\n", buffer);
1278
1279     r = MsiRecordSetString(hrec, 0, "[foo]");
1280     ok( r == ERROR_SUCCESS, "set string failed\n");
1281     r = MsiRecordSetString(hrec, 1, "hoo");
1282     ok( r == ERROR_SUCCESS, "set string failed\n");
1283     sz = sizeof buffer;
1284     r = MsiFormatRecord(0, hrec, buffer, &sz);
1285     ok( sz == 5, "size wrong\n");
1286     ok( 0 == strcmp(buffer,"[foo]"), "wrong output\n");
1287     ok( r == ERROR_SUCCESS, "format failed\n");
1288
1289     r = MsiRecordSetString(hrec, 0, "[01.]");
1290     ok( r == ERROR_SUCCESS, "set string failed\n");
1291     r = MsiRecordSetString(hrec, 1, "hoo");
1292     ok( r == ERROR_SUCCESS, "set string failed\n");
1293     sz = sizeof buffer;
1294     r = MsiFormatRecord(0, hrec, buffer, &sz);
1295     ok( sz == 5, "size wrong\n");
1296     ok( 0 == strcmp(buffer,"[01.]"), "wrong output\n");
1297     ok( r == ERROR_SUCCESS, "format failed\n");
1298
1299     SetEnvironmentVariable("FOO", "BAR");
1300     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1301     ok( r == ERROR_SUCCESS, "set string failed\n");
1302     sz = sizeof buffer;
1303     r = MsiFormatRecord(0, hrec, buffer, &sz);
1304     ok( sz == 6, "size wrong\n");
1305     ok( 0 == strcmp(buffer,"[%FOO]"), "wrong output\n");
1306     ok( r == ERROR_SUCCESS, "format failed\n");
1307
1308     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1309     ok( r == ERROR_SUCCESS, "set string failed\n");
1310     r = MsiRecordSetString(hrec, 1, "hoo");
1311     ok( r == ERROR_SUCCESS, "set string failed\n");
1312     sz = sizeof buffer;
1313     r = MsiFormatRecord(0, hrec, buffer, &sz);
1314     ok( sz == 6, "size wrong\n");
1315     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output\n");
1316     ok( r == ERROR_SUCCESS, "format failed\n");
1317
1318     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1319     ok( r == ERROR_SUCCESS, "set string failed\n");
1320     r = MsiRecordSetString(hrec, 1, "hoo");
1321     ok( r == ERROR_SUCCESS, "set string failed\n");
1322     sz = sizeof buffer;
1323     r = MsiFormatRecord(0, hrec, buffer, &sz);
1324     ok( sz == 8, "size wrong\n");
1325     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1326     ok( r == ERROR_SUCCESS, "format failed\n");
1327
1328     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1329     ok( r == ERROR_SUCCESS, "set string failed\n");
1330     r = MsiRecordSetString(hrec, 1, "hoo");
1331     ok( r == ERROR_SUCCESS, "set string failed\n");
1332     sz = sizeof buffer;
1333     r = MsiFormatRecord(0, hrec, buffer, &sz);
1334     ok( sz == 8, "size wrong\n");
1335     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1336     ok( r == ERROR_SUCCESS, "format failed\n");
1337
1338     r = MsiRecordSetString(hrec, 0, "{{ {{[1]}");
1339     ok( r == ERROR_SUCCESS, "set string failed\n");
1340     r = MsiRecordSetString(hrec, 1, "hoo");
1341     ok( r == ERROR_SUCCESS, "set string failed\n");
1342     sz = sizeof buffer;
1343     r = MsiFormatRecord(0, hrec, buffer, &sz);
1344     ok( sz == 9, "size wrong\n");
1345     ok( 0 == strcmp(buffer,"{{ {{hoo}"), "wrong output\n");
1346     ok( r == ERROR_SUCCESS, "format failed\n");
1347
1348     r = MsiRecordSetString(hrec, 0, "[1]}");
1349     ok( r == ERROR_SUCCESS, "set string failed\n");
1350     r = MsiRecordSetString(hrec, 1, "hoo");
1351     ok( r == ERROR_SUCCESS, "set string failed\n");
1352     sz = sizeof buffer;
1353     r = MsiFormatRecord(0, hrec, buffer, &sz);
1354     ok( sz == 4, "size wrong\n");
1355     ok( 0 == strcmp(buffer,"hoo}"), "wrong output\n");
1356     ok( r == ERROR_SUCCESS, "format failed\n");
1357
1358     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1359     ok( r == ERROR_SUCCESS, "set string failed\n");
1360     sz = sizeof buffer;
1361     r = MsiFormatRecord(0, hrec, buffer, &sz);
1362     ok( sz == 7, "size wrong\n");
1363     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1364     ok( r == ERROR_SUCCESS, "format failed\n");
1365
1366     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1367     ok( r == ERROR_SUCCESS, "set string failed\n");
1368     sz = sizeof buffer;
1369     r = MsiFormatRecord(0, hrec, buffer, &sz);
1370     ok( sz == 7, "size wrong\n");
1371     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1372     ok( r == ERROR_SUCCESS, "format failed\n");
1373
1374     r = MsiRecordSetString(hrec, 0, "0{1{2{3{4[1]5}6}7}8}9");
1375     ok( r == ERROR_SUCCESS, "set string failed\n");
1376     r = MsiRecordSetString(hrec, 1, "hoo");
1377     ok( r == ERROR_SUCCESS, "set string failed\n");
1378     sz = sizeof buffer;
1379     r = MsiFormatRecord(0, hrec, buffer, &sz);
1380     todo_wine
1381     {
1382         ok( sz == 19, "size wrong\n");
1383         ok( 0 == strcmp(buffer,"01{2{3{4hoo56}7}8}9"), "wrong output\n");
1384     }
1385     ok( r == ERROR_SUCCESS, "format failed\n");
1386
1387     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1388     ok( r == ERROR_SUCCESS, "set string failed\n");
1389     r = MsiRecordSetString(hrec, 1, "hoo");
1390     ok( r == ERROR_SUCCESS, "set string failed\n");
1391     sz = sizeof buffer;
1392     r = MsiFormatRecord(0, hrec, buffer, &sz);
1393     todo_wine
1394     {
1395         ok( sz == 9, "size wrong\n");
1396         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1397     }
1398     ok( r == ERROR_SUCCESS, "format failed\n");
1399
1400     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1401     ok( r == ERROR_SUCCESS, "set string failed\n");
1402     r = MsiRecordSetString(hrec, 1, "hoo");
1403     ok( r == ERROR_SUCCESS, "set string failed\n");
1404     sz = sizeof buffer;
1405     r = MsiFormatRecord(0, hrec, buffer, &sz);
1406     todo_wine
1407     {
1408         ok( sz == 9, "size wrong\n");
1409         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1410     }
1411     ok( r == ERROR_SUCCESS, "format failed\n");
1412
1413     r = MsiRecordSetString(hrec, 0, "{[1.} [1]");
1414     ok( r == ERROR_SUCCESS, "set string failed\n");
1415     r = MsiRecordSetString(hrec, 1, "hoo");
1416     ok( r == ERROR_SUCCESS, "set string failed\n");
1417     sz = sizeof buffer;
1418     r = MsiFormatRecord(0, hrec, buffer, &sz);
1419     ok( sz == 9, "size wrong\n");
1420     todo_wine
1421     {
1422         ok( 0 == strcmp(buffer,"{[1.} hoo"), "wrong output\n");
1423     }
1424     ok( r == ERROR_SUCCESS, "format failed\n");
1425
1426     r = MsiRecordSetString(hrec, 0, "{[{[1]}]}");
1427     ok( r == ERROR_SUCCESS, "set string failed\n");
1428     r = MsiRecordSetString(hrec, 1, "2");
1429     ok( r == ERROR_SUCCESS, "set string failed\n");
1430     r = MsiRecordSetString(hrec, 2, "foo");
1431     ok( r == ERROR_SUCCESS, "set string failed\n");
1432     sz = sizeof buffer;
1433     r = MsiFormatRecord(0, hrec, buffer, &sz);
1434     todo_wine
1435     {
1436         ok( sz == 9, "size wrong\n");
1437         ok( 0 == strcmp(buffer,"{[{[1]}]}"), "wrong output\n");
1438     }
1439     ok( r == ERROR_SUCCESS, "format failed\n");
1440
1441     r = MsiRecordSetString(hrec, 0, "{[1][}");
1442     ok( r == ERROR_SUCCESS, "set string failed\n");
1443     r = MsiRecordSetString(hrec, 1, "2");
1444     ok( r == ERROR_SUCCESS, "set string failed\n");
1445     r = MsiRecordSetString(hrec, 2, "foo");
1446     ok( r == ERROR_SUCCESS, "set string failed\n");
1447     sz = sizeof buffer;
1448     r = MsiFormatRecord(0, hrec, buffer, &sz);
1449     todo_wine
1450     {
1451         ok( sz == 2, "size wrong\n");
1452         ok( 0 == strcmp(buffer,"2["), "wrong output\n");
1453     }
1454     ok( r == ERROR_SUCCESS, "format failed\n");
1455
1456     r = MsiRecordSetString(hrec, 0, "[1]");
1457     ok( r == ERROR_SUCCESS, "set string failed\n");
1458     r = MsiRecordSetString(hrec, 1, "[2]");
1459     ok( r == ERROR_SUCCESS, "set string failed\n");
1460     r = MsiRecordSetString(hrec, 2, "foo");
1461     ok( r == ERROR_SUCCESS, "set string failed\n");
1462     sz = sizeof buffer;
1463     r = MsiFormatRecord(0, hrec, buffer, &sz);
1464     ok( sz == 3, "size wrong\n");
1465     ok( 0 == strcmp(buffer,"[2]"), "wrong output\n");
1466     ok( r == ERROR_SUCCESS, "format failed\n");
1467
1468     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1469     ok( r == ERROR_SUCCESS, "set string failed\n");
1470     r = MsiRecordSetString(hrec, 1, "hoo");
1471     ok( r == ERROR_SUCCESS, "set string failed\n");
1472     sz = sizeof buffer;
1473     r = MsiFormatRecord(0, hrec, buffer, &sz);
1474     ok( r == ERROR_SUCCESS, "format failed\n");
1475     ok( sz == 3, "size wrong\n");
1476     todo_wine
1477     {
1478         ok( 0 == strcmp(buffer,"[1]"), "wrong output: %s\n", buffer);
1479     }
1480
1481     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1482     ok( r == ERROR_SUCCESS, "set string failed\n");
1483     r = MsiRecordSetString(hrec, 0, "[1{{boo}}]");
1484     ok( r == ERROR_SUCCESS, "set string failed\n");
1485     r = MsiRecordSetString(hrec, 1, "hoo");
1486     ok( r == ERROR_SUCCESS, "set string failed\n");
1487     sz = sizeof buffer;
1488     r = MsiFormatRecord(0, hrec, buffer, &sz);
1489     ok( sz == 3, "size wrong\n");
1490     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1491     ok( r == ERROR_SUCCESS, "format failed\n");
1492
1493     r = MsiRecordSetString(hrec, 0, "{[1]{{boo} }}");
1494     ok( r == ERROR_SUCCESS, "set string failed\n");
1495     r = MsiRecordSetString(hrec, 1, "hoo");
1496     ok( r == ERROR_SUCCESS, "set string failed\n");
1497     sz = sizeof buffer;
1498     r = MsiFormatRecord(0, hrec, buffer, &sz);
1499     todo_wine
1500     {
1501         ok( sz == 11, "size wrong\n");
1502         ok( 0 == strcmp(buffer,"hoo{{boo }}"), "wrong output\n");
1503     }
1504     ok( r == ERROR_SUCCESS, "format failed\n");
1505
1506     r = MsiRecordSetString(hrec, 0, "{[1{{boo}}]}");
1507     ok( r == ERROR_SUCCESS, "set string failed\n");
1508     r = MsiRecordSetString(hrec, 1, "hoo");
1509     ok( r == ERROR_SUCCESS, "set string failed\n");
1510     sz = sizeof buffer;
1511     r = MsiFormatRecord(0, hrec, buffer, &sz);
1512     todo_wine
1513     {
1514         ok( sz == 12, "size wrong: got %u, expected 12\n", sz);
1515         ok( 0 == strcmp(buffer,"{[1{{boo}}]}"), "wrong output: got %s, expected [1]\n", buffer);
1516     }
1517     ok( r == ERROR_SUCCESS, "format failed\n");
1518
1519     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1520     ok( r == ERROR_SUCCESS, "set string failed\n");
1521     r = MsiRecordSetString(hrec, 1, "hoo");
1522     ok( r == ERROR_SUCCESS, "set string failed\n");
1523     sz = sizeof buffer;
1524     r = MsiFormatRecord(0, hrec, buffer, &sz);
1525     ok( sz == 6, "size wrong: got %u, expected 3\n", sz);
1526     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output: got %s, expected [1]\n", buffer);
1527     ok( r == ERROR_SUCCESS, "format failed\n");
1528
1529     r = MsiRecordSetString(hrec, 0, "{[1{{bo}o}}]}");
1530     ok( r == ERROR_SUCCESS, "set string failed\n");
1531     r = MsiRecordSetString(hrec, 1, "hoo");
1532     ok( r == ERROR_SUCCESS, "set string failed\n");
1533     sz = sizeof buffer;
1534     r = MsiFormatRecord(0, hrec, buffer, &sz);
1535     ok( sz == 13, "size wrong\n");
1536     ok( 0 == strcmp(buffer,"{[1{{bo}o}}]}"), "wrong output %s\n",buffer);
1537     ok( r == ERROR_SUCCESS, "format failed\n");
1538
1539     r = MsiRecordSetString(hrec, 0, "{[1{{b{o}o}}]}");
1540     ok( r == ERROR_SUCCESS, "set string failed\n");
1541     sz = sizeof buffer;
1542     r = MsiFormatRecord(0, hrec, buffer, &sz);
1543     todo_wine
1544     {
1545         ok( sz == 14, "size wrong\n");
1546         ok( 0 == strcmp(buffer,"{[1{{b{o}o}}]}"), "wrong output %s\n",buffer);
1547     }
1548     ok( r == ERROR_SUCCESS, "format failed\n");
1549
1550     r = MsiRecordSetString(hrec, 0, "{ {[1]}");
1551     ok( r == ERROR_SUCCESS, "set string failed\n");
1552     r = MsiRecordSetString(hrec, 1, "hoo");
1553     ok( r == ERROR_SUCCESS, "set string failed\n");
1554     sz = sizeof buffer;
1555     r = MsiFormatRecord(0, hrec, buffer, &sz);
1556     todo_wine
1557     {
1558         ok( sz == 5, "size wrong\n");
1559         ok( 0 == strcmp(buffer," {hoo"), "wrong output %s\n",buffer);
1560     }
1561     ok( r == ERROR_SUCCESS, "format failed\n");
1562
1563     /* {} inside a substitution does strange things... */
1564     r = MsiRecordSetString(hrec, 0, "[[1]{}]");
1565     ok( r == ERROR_SUCCESS, "set string failed\n");
1566     r = MsiRecordSetString(hrec, 1, "2");
1567     ok( r == ERROR_SUCCESS, "set string failed\n");
1568     sz = sizeof buffer;
1569     r = MsiFormatRecord(0, hrec, buffer, &sz);
1570     todo_wine
1571     {
1572         ok( sz == 5, "size wrong\n");
1573         ok( 0 == strcmp(buffer,"[[1]]"), "wrong output %s\n",buffer);
1574     }
1575     ok( r == ERROR_SUCCESS, "format failed\n");
1576
1577     r = MsiRecordSetString(hrec, 0, "[[1]{}[1]]");
1578     ok( r == ERROR_SUCCESS, "set string failed\n");
1579     r = MsiRecordSetString(hrec, 1, "2");
1580     ok( r == ERROR_SUCCESS, "set string failed\n");
1581     sz = sizeof buffer;
1582     r = MsiFormatRecord(0, hrec, buffer, &sz);
1583     todo_wine
1584     {
1585         ok( sz == 6, "size wrong\n");
1586         ok( 0 == strcmp(buffer,"[[1]2]"), "wrong output %s\n",buffer);
1587     }
1588     ok( r == ERROR_SUCCESS, "format failed\n");
1589
1590     r = MsiRecordSetString(hrec, 0, "[a[1]b[1]c{}d[1]e]");
1591     ok( r == ERROR_SUCCESS, "set string failed\n");
1592     r = MsiRecordSetString(hrec, 1, "2");
1593     ok( r == ERROR_SUCCESS, "set string failed\n");
1594     sz = sizeof buffer;
1595     r = MsiFormatRecord(0, hrec, buffer, &sz);
1596     todo_wine
1597     {
1598         ok( sz == 14, "size wrong\n");
1599         ok( 0 == strcmp(buffer,"[a[1]b[1]cd2e]"), "wrong output %s\n",buffer);
1600     }
1601     ok( r == ERROR_SUCCESS, "format failed\n");
1602
1603     r = MsiRecordSetString(hrec, 0, "[a[1]b");
1604     ok( r == ERROR_SUCCESS, "set string failed\n");
1605     r = MsiRecordSetString(hrec, 1, "2");
1606     ok( r == ERROR_SUCCESS, "set string failed\n");
1607     sz = sizeof buffer;
1608     r = MsiFormatRecord(0, hrec, buffer, &sz);
1609     ok( sz == 6, "size wrong\n");
1610     ok( 0 == strcmp(buffer,"[a[1]b"), "wrong output %s\n",buffer);
1611     ok( r == ERROR_SUCCESS, "format failed\n");
1612
1613     r = MsiRecordSetString(hrec, 0, "a[1]b]");
1614     ok( r == ERROR_SUCCESS, "set string failed\n");
1615     r = MsiRecordSetString(hrec, 1, "2");
1616     ok( r == ERROR_SUCCESS, "set string failed\n");
1617     sz = sizeof buffer;
1618     r = MsiFormatRecord(0, hrec, buffer, &sz);
1619     ok( sz == 4, "size wrong\n");
1620     ok( 0 == strcmp(buffer,"a2b]"), "wrong output %s\n",buffer);
1621     ok( r == ERROR_SUCCESS, "format failed\n");
1622
1623     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1624     ok( r == ERROR_SUCCESS, "set string failed\n");
1625     r = MsiRecordSetString(hrec, 1, "2");
1626     ok( r == ERROR_SUCCESS, "set string failed\n");
1627     sz = sizeof buffer;
1628     r = MsiFormatRecord(0, hrec, buffer, &sz);
1629     ok( sz == 4, "size wrong\n");
1630     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1631     ok( r == ERROR_SUCCESS, "format failed\n");
1632
1633     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1634     ok( r == ERROR_SUCCESS, "set string failed\n");
1635     r = MsiRecordSetString(hrec, 1, "2");
1636     ok( r == ERROR_SUCCESS, "set string failed\n");
1637     sz = sizeof buffer;
1638     r = MsiFormatRecord(0, hrec, buffer, &sz);
1639     ok( sz == 4, "size wrong\n");
1640     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1641     ok( r == ERROR_SUCCESS, "format failed\n");
1642
1643     r = MsiRecordSetString(hrec, 0, "\\[1]");
1644     ok( r == ERROR_SUCCESS, "set string failed\n");
1645     r = MsiRecordSetString(hrec, 1, "2");
1646     ok( r == ERROR_SUCCESS, "set string failed\n");
1647     sz = sizeof buffer;
1648     r = MsiFormatRecord(0, hrec, buffer, &sz);
1649     ok( sz == 2, "size wrong\n");
1650     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1651     ok( r == ERROR_SUCCESS, "format failed\n");
1652
1653     r = MsiRecordSetString(hrec, 0, "\\{[1]}");
1654     ok( r == ERROR_SUCCESS, "set string failed\n");
1655     r = MsiRecordSetString(hrec, 1, "2");
1656     ok( r == ERROR_SUCCESS, "set string failed\n");
1657     sz = sizeof buffer;
1658     r = MsiFormatRecord(0, hrec, buffer, &sz);
1659     ok( sz == 2, "size wrong\n");
1660     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1661     ok( r == ERROR_SUCCESS, "format failed\n");
1662
1663     r = MsiRecordSetString(hrec, 0, "a{b[1]c}d");
1664     ok( r == ERROR_SUCCESS, "set string failed\n");
1665     r = MsiRecordSetString(hrec, 1, NULL);
1666     ok( r == ERROR_SUCCESS, "set string failed\n");
1667     sz = sizeof buffer;
1668     r = MsiFormatRecord(0, hrec, buffer, &sz);
1669     ok( sz == 2, "size wrong\n");
1670     ok( 0 == strcmp(buffer,"ad"), "wrong output %s\n",buffer);
1671     ok( r == ERROR_SUCCESS, "format failed\n");
1672
1673     r = MsiRecordSetString(hrec, 0, "{a[0]b}");
1674     ok( r == ERROR_SUCCESS, "set string failed\n");
1675     r = MsiRecordSetString(hrec, 1, "foo");
1676     ok( r == ERROR_SUCCESS, "set string failed\n");
1677     sz = sizeof buffer;
1678     r = MsiFormatRecord(0, hrec, buffer, &sz);
1679     ok( sz == 9, "size wrong\n");
1680     ok( 0 == strcmp(buffer,"a{a[0]b}b"), "wrong output %s\n",buffer);
1681     ok( r == ERROR_SUCCESS, "format failed\n");
1682
1683     r = MsiRecordSetString(hrec, 0, "[foo]");
1684     ok( r == ERROR_SUCCESS, "set string failed\n");
1685     sz = sizeof buffer;
1686     r = MsiFormatRecord(0, hrec, buffer, &sz);
1687     ok( sz == 5, "size wrong\n");
1688     ok( 0 == strcmp(buffer,"[foo]"), "wrong output %s\n",buffer);
1689     ok( r == ERROR_SUCCESS, "format failed\n");
1690
1691     r = MsiRecordSetString(hrec, 0, "{[1][-1][1]}");
1692     ok( r == ERROR_SUCCESS, "set string failed\n");
1693     r = MsiRecordSetString(hrec, 1, "foo");
1694     ok( r == ERROR_SUCCESS, "set string failed\n");
1695     sz = sizeof buffer;
1696     r = MsiFormatRecord(0, hrec, buffer, &sz);
1697     todo_wine
1698     {
1699         ok( sz == 12, "size wrong\n");
1700         ok( 0 == strcmp(buffer,"{foo[-1]foo}"), "wrong output %s\n",buffer);
1701     }
1702     ok( r == ERROR_SUCCESS, "format failed\n");
1703
1704     /* nested braces */
1705     sz = sizeof buffer;
1706     r = MsiRecordSetString(hrec, 0, "{abcd}");
1707     ok( r == ERROR_SUCCESS, "set string failed\n");
1708     r = MsiFormatRecord(0, hrec, buffer, &sz);
1709     ok( r == ERROR_SUCCESS, "format failed\n");
1710     ok( sz == 6, "size wrong(%i)\n",sz);
1711     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
1712
1713     sz = sizeof buffer;
1714     r = MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
1715     ok( r == ERROR_SUCCESS, "set string failed\n");
1716     r = MsiFormatRecord(0, hrec, buffer, &sz);
1717     ok( r == ERROR_SUCCESS, "format failed\n");
1718     ok( sz == 23, "size wrong(%i)\n",sz);
1719     ok( 0 == strcmp(buffer,"{a[one]bc[two]de[one]f}"), "wrong output (%s)\n",buffer);
1720
1721     sz = sizeof buffer;
1722     r = MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
1723     ok( r == ERROR_SUCCESS, "set string failed\n");
1724     r = MsiFormatRecord(0, hrec, buffer, &sz);
1725     ok( r == ERROR_SUCCESS, "format failed\n");
1726     ok( sz == 23, "size wrong(%i)\n",sz);
1727     ok( 0 == strcmp(buffer,"{a[one]bc[bad]de[two]f}"), "wrong output (%s)\n",buffer);
1728
1729     sz = sizeof buffer;
1730     r = MsiRecordSetString(hrec, 0, "{[bad]}");
1731     ok( r == ERROR_SUCCESS, "set string failed\n");
1732     r = MsiFormatRecord(0, hrec, buffer, &sz);
1733     ok( r == ERROR_SUCCESS, "format failed\n");
1734     ok( sz == 7, "size wrong(%i)\n",sz);
1735     ok( 0 == strcmp(buffer,"{[bad]}"), "wrong output (%s)\n",buffer);
1736
1737     sz = sizeof buffer;
1738     r = MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
1739     ok( r == ERROR_SUCCESS, "set string failed\n");
1740     r = MsiFormatRecord(0, hrec, buffer, &sz);
1741     ok( r == ERROR_SUCCESS, "format failed\n");
1742     ok( sz == 14, "size wrong(%i)\n",sz);
1743     ok( 0 == strcmp(buffer,"{abc{d[one]ef}"), "wrong output (%s)\n",buffer);
1744
1745     sz = sizeof buffer;
1746     r = MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
1747     ok( r == ERROR_SUCCESS, "set string failed\n");
1748     r = MsiFormatRecord(0, hrec, buffer, &sz);
1749     ok( r == ERROR_SUCCESS, "format failed\n");
1750     ok( sz == 15, "size wrong(%i)\n",sz);
1751     ok( 0 == strcmp(buffer,"{abc{d[one]ef}}"), "wrong output (%s)\n",buffer);
1752
1753     sz = sizeof buffer;
1754     r = MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
1755     ok( r == ERROR_SUCCESS, "set string failed\n");
1756     r = MsiFormatRecord(0, hrec, buffer, &sz);
1757     ok( r == ERROR_SUCCESS, "format failed\n");
1758     ok( sz == 5, "size wrong(%i)\n",sz);
1759     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
1760
1761     sz = sizeof buffer;
1762     r = MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
1763     ok( r == ERROR_SUCCESS, "set string failed\n");
1764     r = MsiFormatRecord(0, hrec, buffer, &sz);
1765     ok( r == ERROR_SUCCESS, "format failed\n");
1766     ok( sz == 0, "size wrong(%i)\n",sz);
1767     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1768
1769     sz = sizeof buffer;
1770     r = MsiRecordSetString(hrec, 0, "{{def}hi{jk}}");
1771     ok( r == ERROR_SUCCESS, "set string failed\n");
1772     r = MsiFormatRecord(0, hrec, buffer, &sz);
1773     ok( r == ERROR_SUCCESS, "format failed\n");
1774     ok( sz == 0, "size wrong(%i)\n",sz);
1775     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1776
1777     sz = sizeof buffer;
1778     r = MsiRecordSetString(hrec, 0, "{{{def}}hi{jk}}");
1779     ok( r == ERROR_SUCCESS, "set string failed\n");
1780     r = MsiFormatRecord(0, hrec, buffer, &sz);
1781     ok( r == ERROR_SUCCESS, "format failed\n");
1782     todo_wine
1783     {
1784         ok( sz == 7, "size wrong(%i)\n",sz);
1785         ok( 0 == strcmp(buffer,"hi{jk}}"), "wrong output (%s)\n",buffer);
1786     }
1787
1788     sz = sizeof buffer;
1789     r = MsiRecordSetString(hrec, 0, "{{def}hi{{jk}}}");
1790     ok( r == ERROR_SUCCESS, "set string failed\n");
1791     r = MsiFormatRecord(0, hrec, buffer, &sz);
1792     ok( r == ERROR_SUCCESS, "format failed\n");
1793     todo_wine
1794     {
1795         ok( sz == 1, "size wrong(%i)\n",sz);
1796         ok( 0 == strcmp(buffer,"}"), "wrong output (%s)\n",buffer);
1797     }
1798
1799     sz = sizeof buffer;
1800     r = MsiRecordSetString(hrec, 0, "{{def}{jk}}");
1801     ok( r == ERROR_SUCCESS, "set string failed\n");
1802     r = MsiFormatRecord(0, hrec, buffer, &sz);
1803     ok( r == ERROR_SUCCESS, "format failed\n");
1804     ok( sz == 0, "size wrong(%i)\n",sz);
1805     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1806
1807     sz = sizeof buffer;
1808     r = MsiRecordSetString(hrec, 0, "{{def}}");
1809     ok( r == ERROR_SUCCESS, "set string failed\n");
1810     r = MsiFormatRecord(0, hrec, buffer, &sz);
1811     ok( r == ERROR_SUCCESS, "format failed\n");
1812     ok( sz == 0, "size wrong(%i)\n",sz);
1813     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1814
1815     sz = sizeof buffer;
1816     r = MsiRecordSetString(hrec, 0, "{a{b}c}");
1817     ok( r == ERROR_SUCCESS, "set string failed\n");
1818     r = MsiFormatRecord(0, hrec, buffer, &sz);
1819     ok( r == ERROR_SUCCESS, "format failed\n");
1820     ok( sz == 7, "size wrong(%i)\n",sz);
1821     ok( 0 == strcmp(buffer,"{a{b}c}"), "wrong output (%s)\n",buffer);
1822
1823     sz = sizeof buffer;
1824     r = MsiRecordSetString(hrec, 0, "{a{b}}");
1825     ok( r == ERROR_SUCCESS, "set string failed\n");
1826     r = MsiFormatRecord(0, hrec, buffer, &sz);
1827     ok( r == ERROR_SUCCESS, "format failed\n");
1828     ok( sz == 6, "size wrong(%i)\n",sz);
1829     ok( 0 == strcmp(buffer,"{a{b}}"), "wrong output (%s)\n",buffer);
1830
1831     sz = sizeof buffer;
1832     r = MsiRecordSetString(hrec, 0, "{{b}c}");
1833     ok( r == ERROR_SUCCESS, "set string failed\n");
1834     r = MsiFormatRecord(0, hrec, buffer, &sz);
1835     ok( r == ERROR_SUCCESS, "format failed\n");
1836     ok( sz == 6, "size wrong(%i)\n",sz);
1837     ok( 0 == strcmp(buffer,"{{b}c}"), "wrong output (%s)\n",buffer);
1838
1839     sz = sizeof buffer;
1840     r = MsiRecordSetString(hrec, 0, "{{{{}}}}");
1841     ok( r == ERROR_SUCCESS, "set string failed\n");
1842     r = MsiFormatRecord(0, hrec, buffer, &sz);
1843     ok( r == ERROR_SUCCESS, "format failed\n");
1844     todo_wine
1845     {
1846         ok( sz == 2, "size wrong(%i)\n",sz);
1847         ok( 0 == strcmp(buffer,"}}"), "wrong output (%s)\n",buffer);
1848     }
1849
1850     sz = sizeof buffer;
1851     MsiRecordSetInteger(hrec, 1, 100);
1852     MsiRecordSetInteger(hrec, 2, -100);
1853     r = MsiRecordSetString(hrec, 0, "[1] [2]");
1854     ok( r == ERROR_SUCCESS, "set string failed\n");
1855     r = MsiFormatRecord(0, hrec, buffer, &sz);
1856     ok( r == ERROR_SUCCESS, "format failed\n");
1857     ok( sz == 8, "size wrong(%i)\n",sz);
1858     ok( 0 == strcmp(buffer,"100 -100"), "wrong output (%s)\n",buffer);
1859
1860     sz = sizeof(buffer);
1861     r = MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
1862     ok( r == ERROR_SUCCESS, "set string failed\n");
1863     r = MsiRecordSetString(hrec, 1, "one");
1864     ok( r == ERROR_SUCCESS, "set string failed\n");
1865     r = MsiFormatRecord(0, hrec, buffer, &sz);
1866     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1867     ok(sz == 33, "Expected 33, got %d\n",sz);
1868     ok(!lstrcmpA(buffer, "one {[noprop] [twoprop]} {abcdef}"),
1869        "Expected \"one {[noprop] [twoprop]} {abcdef}\", got \"%s\"\n", buffer);
1870
1871     sz = sizeof(buffer);
1872     r = MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
1873     ok( r == ERROR_SUCCESS, "set string failed\n");
1874     r = MsiRecordSetString(hrec, 1, "one");
1875     ok( r == ERROR_SUCCESS, "set string failed\n");
1876     r = MsiFormatRecord(0, hrec, buffer, &sz);
1877     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1878     ok(sz == 29, "Expected 29, got %d\n",sz);
1879     ok(!lstrcmpA(buffer, "one {[noprop] [one]} {abcdef}"),
1880        "Expected \"one {[noprop] [one]} {abcdef}\", got \"%s\"\n", buffer);
1881
1882     sz = sizeof(buffer);
1883     r = MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
1884     ok( r == ERROR_SUCCESS, "set string failed\n");
1885     r = MsiRecordSetString(hrec, 1, "one");
1886     ok( r == ERROR_SUCCESS, "set string failed\n");
1887     r = MsiFormatRecord(0, hrec, buffer, &sz);
1888     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1889     ok(sz == 20, "Expected 20, got %d\n",sz);
1890     ok(!lstrcmpA(buffer, "one {[one]} {abcdef}"),
1891        "Expected \"one {[one]} {abcdef}\", got \"%s\"\n", buffer);
1892
1893     MsiCloseHandle( hrec );
1894 }
1895
1896 static void test_formatrecord_package(void)
1897 {
1898     char buffer[100];
1899     MSIHANDLE hrec;
1900     MSIHANDLE package;
1901     UINT r;
1902     DWORD sz=100;
1903
1904     r = helper_createpackage( msifile, &package );
1905     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1906     {
1907         skip("Not enough rights to perform tests\n");
1908         return;
1909     }
1910     ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r );
1911
1912     hrec = MsiCreateRecord(12);
1913     ok( hrec, "failed to create record\n");
1914
1915     r = MsiFormatRecord(package, 0, NULL, NULL );
1916     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
1917
1918     r = MsiFormatRecord(package, hrec, NULL, NULL );
1919     ok( r == ERROR_SUCCESS, "format failed\n");
1920
1921     r = MsiRecordSetString(hrec,0,NULL);
1922     ok( r == ERROR_SUCCESS, "set string failed\n");
1923     r = MsiRecordSetString(hrec,1,NULL);
1924     ok( r == ERROR_SUCCESS, "set string failed\n");
1925     r = MsiRecordSetString(hrec,2,NULL);
1926     ok( r == ERROR_SUCCESS, "set string failed\n");
1927     r = MsiRecordSetString(hrec,3,NULL);
1928     ok( r == ERROR_SUCCESS, "set string failed\n");
1929     r = MsiRecordSetString(hrec,4,NULL);
1930     ok( r == ERROR_SUCCESS, "set string failed\n");
1931     r = MsiRecordSetString(hrec,5,NULL);
1932     ok( r == ERROR_SUCCESS, "set string failed\n");
1933     r = MsiRecordSetString(hrec,6,NULL);
1934     ok( r == ERROR_SUCCESS, "set string failed\n");
1935     r = MsiRecordSetString(hrec,7,NULL);
1936     ok( r == ERROR_SUCCESS, "set string failed\n");
1937     r = MsiRecordSetString(hrec,8,NULL);
1938     ok( r == ERROR_SUCCESS, "set string failed\n");
1939     r = MsiRecordSetString(hrec,9,NULL);
1940     ok( r == ERROR_SUCCESS, "set string failed\n");
1941     r = MsiRecordSetString(hrec,10,NULL);
1942     ok( r == ERROR_SUCCESS, "set string failed\n");
1943     r = MsiRecordSetString(hrec,11,NULL);
1944     ok( r == ERROR_SUCCESS, "set string failed\n");
1945     r = MsiRecordSetString(hrec,12,NULL);
1946     ok( r == ERROR_SUCCESS, "set string failed\n");
1947
1948     sz = sizeof buffer;
1949     r = MsiFormatRecord(package, hrec, buffer, &sz);
1950     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1951     ok( sz == 51, "size wrong (%i)\n",sz);
1952     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
1953
1954     r = MsiSetProperty(package, "prop", "val");
1955     ok( r == ERROR_SUCCESS, "failed to set propertY: %d\n", r);
1956
1957     r = MsiRecordSetString(hrec, 0, NULL);
1958     ok( r == ERROR_SUCCESS, "set string failed\n");
1959     r = MsiRecordSetString(hrec, 1, "[2]");
1960     ok( r == ERROR_SUCCESS, "set string failed\n");
1961     r = MsiRecordSetString(hrec, 2, "stuff");
1962     ok( r == ERROR_SUCCESS, "set string failed\n");
1963     r = MsiRecordSetString(hrec, 3, "prop");
1964     ok( r == ERROR_SUCCESS, "set string failed\n");
1965     r = MsiRecordSetString(hrec, 4, "[prop]");
1966     ok( r == ERROR_SUCCESS, "set string failed\n");
1967     r = MsiRecordSetString(hrec, 5, "[noprop]");
1968     ok( r == ERROR_SUCCESS, "set string failed\n");
1969     sz = sizeof buffer;
1970     r = MsiFormatRecord(package, hrec, buffer, &sz);
1971     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1972     todo_wine
1973     {
1974         ok( sz == 66, "size wrong (%i)\n",sz);
1975         ok( !lstrcmpA(buffer,
1976             "1: [2] 2: stuff 3: prop 4: val 5:  6:  7:  8:  9:  10:  11:  12:  "),
1977             "wrong output(%s)\n",buffer);
1978     }
1979
1980     /* now put play games with escaping */
1981     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
1982     ok( r == ERROR_SUCCESS, "set string failed\n");
1983     r = MsiRecordSetString(hrec, 1, "boo");
1984     ok( r == ERROR_SUCCESS, "set string failed\n");
1985     r = MsiRecordSetString(hrec, 2, "hoo");
1986     ok( r == ERROR_SUCCESS, "set string failed\n");
1987     sz = sizeof buffer;
1988     r = MsiFormatRecord(package, hrec, buffer, &sz);
1989     ok( r == ERROR_SUCCESS, "format failed\n");
1990     ok( sz == 9, "size wrong(%i)\n",sz);
1991     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
1992
1993     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
1994     ok( r == ERROR_SUCCESS, "set string failed\n");
1995     r = MsiRecordSetString(hrec, 1, "boo");
1996     ok( r == ERROR_SUCCESS, "set string failed\n");
1997     r = MsiRecordSetString(hrec, 2, "hoo");
1998     ok( r == ERROR_SUCCESS, "set string failed\n");
1999     sz = sizeof buffer;
2000     r = MsiFormatRecord(package, hrec, buffer, &sz);
2001     ok( r == ERROR_SUCCESS, "format failed\n");
2002     ok( sz == 9, "size wrong(%i)\n",sz);
2003     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
2004
2005     MsiRecordSetString(hrec, 0, "[\\x]");
2006     sz = sizeof buffer;
2007     r = MsiFormatRecord(package, hrec, buffer, &sz);
2008     ok( r == ERROR_SUCCESS, "format failed\n");
2009     ok( sz == 1, "size wrong: %d\n", sz);
2010     ok( 0 == strcmp(buffer,"x"), "wrong output: %s\n", buffer);
2011
2012     MsiRecordSetString(hrec, 0, "{\\x}");
2013     sz = sizeof buffer;
2014     r = MsiFormatRecord(package, hrec, buffer, &sz);
2015     ok( r == ERROR_SUCCESS, "format failed\n");
2016     ok( sz == 4, "size wrong: %d\n", sz);
2017     ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer);
2018
2019     MsiRecordSetString(hrec, 0, "[abc\\x]");
2020     sz = sizeof buffer;
2021     r = MsiFormatRecord(package, hrec, buffer, &sz);
2022     ok( r == ERROR_SUCCESS, "format failed\n");
2023     ok( sz == 0, "size wrong: %d\n", sz);
2024     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
2025
2026     MsiRecordSetString(hrec, 0, "[abc\\xdef]");
2027     sz = sizeof buffer;
2028     r = MsiFormatRecord(package, hrec, buffer, &sz);
2029     ok( r == ERROR_SUCCESS, "format failed\n");
2030     ok( sz == 0, "size wrong: %d\n", sz);
2031     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
2032
2033     MsiRecordSetString(hrec, 0, "\\x");
2034     sz = sizeof(buffer);
2035     r = MsiFormatRecord(package, hrec, buffer, &sz);
2036     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2037     ok(sz == 2, "Expected 2, got %d\n", sz);
2038     ok(!lstrcmpA(buffer, "\\x"), "Expected \"\\x\", got \"%s\"\n", buffer);
2039
2040     MsiRecordSetString(hrec, 0, "[\\[");
2041     sz = sizeof(buffer);
2042     r = MsiFormatRecord(package, hrec, buffer, &sz);
2043     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2044     ok(sz == 3, "Expected 3, got %d\n", sz);
2045     ok(!lstrcmpA(buffer, "[\\["), "Expected \"[\\[\", got \"%s\"\n", buffer);
2046
2047     MsiRecordSetString(hrec, 0, "[\\[]");
2048     sz = sizeof(buffer);
2049     r = MsiFormatRecord(package, hrec, buffer, &sz);
2050     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2051     ok(sz == 1, "Expected 1, got %d\n", sz);
2052     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
2053
2054     MsiRecordSetString(hrec, 0, "[[]");
2055     sz = sizeof(buffer);
2056     r = MsiFormatRecord(package, hrec, buffer, &sz);
2057     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2058     ok(sz == 3, "Expected 3, got %d\n", sz);
2059     ok(!lstrcmpA(buffer, "[[]"), "Expected \"[]\", got \"%s\"\n", buffer);
2060
2061     MsiRecordSetString(hrec, 0, "[\\[]]");
2062     sz = sizeof(buffer);
2063     r = MsiFormatRecord(package, hrec, buffer, &sz);
2064     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2065     ok(sz == 2, "Expected 2, got %d\n", sz);
2066     ok(!lstrcmpA(buffer, "[]"), "Expected \"[]\", got \"%s\"\n", buffer);
2067
2068     MsiRecordSetString(hrec, 0, "[\\[a]");
2069     sz = sizeof(buffer);
2070     r = MsiFormatRecord(package, hrec, buffer, &sz);
2071     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2072     ok(sz == 1, "Expected 1, got %d\n", sz);
2073     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
2074
2075     MsiRecordSetString(hrec, 0, "[\\a[]");
2076     sz = sizeof(buffer);
2077     r = MsiFormatRecord(package, hrec, buffer, &sz);
2078     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2079     todo_wine
2080     {
2081         ok(sz == 1, "Expected 1, got %d\n", sz);
2082         ok(!lstrcmpA(buffer, "a"), "Expected \"a\", got \"%s\"\n", buffer);
2083     }
2084
2085     MsiRecordSetString(hrec, 0, "[prop]");
2086     sz = sizeof(buffer);
2087     r = MsiFormatRecord(package, hrec, buffer, &sz);
2088     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2089     ok(sz == 3, "Expected 3, got %d\n", sz);
2090     ok(!lstrcmpA(buffer, "val"), "Expected \"val\", got \"%s\"\n", buffer);
2091
2092     MsiRecordSetString(hrec, 0, "[prop] [pro\\pblah] [prop]");
2093     sz = sizeof(buffer);
2094     r = MsiFormatRecord(package, hrec, buffer, &sz);
2095     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2096     ok(sz == 8, "Expected 8, got %d\n", sz);
2097     ok(!lstrcmpA(buffer, "val  val"), "Expected \"val  val\", got \"%s\"\n", buffer);
2098
2099     MsiSetPropertyA(package, "b", "ball");
2100     MsiRecordSetString(hrec, 0, "[\\b]");
2101     sz = sizeof(buffer);
2102     r = MsiFormatRecord(package, hrec, buffer, &sz);
2103     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2104     ok(sz == 1, "Expected 1, got %d\n", sz);
2105     ok(!lstrcmpA(buffer, "b"), "Expected \"b\", got \"%s\"\n", buffer);
2106
2107     MsiRecordSetString(hrec, 0, "[\\c]");
2108     sz = sizeof(buffer);
2109     r = MsiFormatRecord(package, hrec, buffer, &sz);
2110     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2111     ok(sz == 1, "Expected 1, got %d\n", sz);
2112     ok(!lstrcmpA(buffer, "c"), "Expected \"c\", got \"%s\"\n", buffer);
2113
2114     MsiRecordSetString(hrec, 0, "[\\[]prop]");
2115     sz = sizeof(buffer);
2116     r = MsiFormatRecord(package, hrec, buffer, &sz);
2117     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2118     ok(sz == 6, "Expected 6, got %d\n", sz);
2119     ok(!lstrcmpA(buffer, "[prop]"), "Expected \"[prop]\", got \"%s\"\n", buffer);
2120
2121     MsiRecordSetString(hrec, 0, "[\\a]prop]");
2122     sz = sizeof(buffer);
2123     r = MsiFormatRecord(package, hrec, buffer, &sz);
2124     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2125     ok(sz == 6, "Expected 6, got %d\n", sz);
2126     ok(!lstrcmpA(buffer, "aprop]"), "Expected \"aprop]\", got \"%s\"\n", buffer);
2127
2128     MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]");
2129     sz = sizeof buffer;
2130     r = MsiFormatRecord(package, hrec, buffer, &sz);
2131     ok( r == ERROR_SUCCESS, "format failed\n");
2132     ok( sz == 14, "size wrong: %d\n", sz);
2133     ok( 0 == strcmp(buffer,"[Bracket Text]"), "wrong output: %s\n", buffer);
2134
2135     /* null characters */
2136     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
2137     ok( r == ERROR_SUCCESS, "set string failed\n");
2138     r = MsiRecordSetString(hrec, 1, "boo");
2139     ok( r == ERROR_SUCCESS, "set string failed\n");
2140     r = MsiRecordSetString(hrec, 2, "hoo");
2141     ok( r == ERROR_SUCCESS, "set string failed\n");
2142     sz = sizeof buffer;
2143     r = MsiFormatRecord(package, hrec, buffer, &sz);
2144     ok( r == ERROR_SUCCESS, "format failed\n");
2145     ok( sz == 9, "size wrong: %d\n", sz);
2146     ok( 0 == strcmp(buffer,"boo "), "wrong output: %s\n", buffer);
2147     ok(!lstrcmpA(&buffer[5], " hoo"),
2148        "Expected \" hoo\", got \"%s\"\n", &buffer[5]);
2149
2150     r = MsiRecordSetString(hrec, 0, "[1] [~abc] [2]");
2151     ok( r == ERROR_SUCCESS, "set string failed\n");
2152     r = MsiRecordSetString(hrec, 1, "boo");
2153     ok( r == ERROR_SUCCESS, "set string failed\n");
2154     r = MsiRecordSetString(hrec, 2, "hoo");
2155     ok( r == ERROR_SUCCESS, "set string failed\n");
2156     sz = sizeof(buffer);
2157     r = MsiFormatRecord(package, hrec, buffer, &sz);
2158     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2159     ok(sz == 8, "Expected 8, got %d\n", sz);
2160     ok(!lstrcmpA(buffer, "boo  hoo"), "Expected \"boo  hoo\", got \"%s\"\n", buffer);
2161
2162     /* properties */
2163     r = MsiSetProperty(package,"dummy","Bork");
2164     ok( r == ERROR_SUCCESS, "set property failed\n");
2165     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
2166     ok( r == ERROR_SUCCESS, "set string failed\n");
2167     r = MsiRecordSetString(hrec, 1, "boo");
2168     ok( r == ERROR_SUCCESS, "set string failed\n");
2169     r = MsiRecordSetString(hrec, 2, "hoo");
2170     ok( r == ERROR_SUCCESS, "set string failed\n");
2171     sz = sizeof buffer;
2172     r = MsiFormatRecord(package, hrec, buffer, &sz);
2173     ok( r == ERROR_SUCCESS, "format failed\n");
2174     ok( sz == 12, "size wrong\n");
2175     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
2176
2177     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
2178     ok( r == ERROR_SUCCESS, "set string failed\n");
2179     r = MsiRecordSetString(hrec, 1, "boo");
2180     ok( r == ERROR_SUCCESS, "set string failed\n");
2181     r = MsiRecordSetString(hrec, 2, "hoo");
2182     ok( r == ERROR_SUCCESS, "set string failed\n");
2183     sz = sizeof buffer;
2184     r = MsiFormatRecord(package, hrec, buffer, &sz);
2185     ok( r == ERROR_SUCCESS, "format failed\n");
2186     ok( sz == 8, "size wrong\n");
2187     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
2188
2189     /* nesting tests */
2190     r = MsiSetProperty(package,"dummya","foo");
2191     ok( r == ERROR_SUCCESS, "set string failed\n");
2192     r = MsiSetProperty(package,"dummyb","baa");
2193     ok( r == ERROR_SUCCESS, "set string failed\n");
2194     r = MsiSetProperty(package,"adummyc","whoa");
2195     ok( r == ERROR_SUCCESS, "set property failed\n");
2196     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
2197     ok( r == ERROR_SUCCESS, "set string failed\n");
2198     r = MsiRecordSetString(hrec, 1, "a");
2199     ok( r == ERROR_SUCCESS, "set string failed\n");
2200     r = MsiRecordSetString(hrec, 2, "b");
2201     ok( r == ERROR_SUCCESS, "set string failed\n");
2202     r = MsiRecordSetString(hrec, 3, "c");
2203     ok( r == ERROR_SUCCESS, "set string failed\n");
2204     sz = sizeof buffer;
2205     r = MsiFormatRecord(package, hrec, buffer, &sz);
2206     ok( r == ERROR_SUCCESS, "format failed\n");
2207     ok( sz == 12, "size wrong(%i)\n",sz);
2208     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
2209
2210     r = MsiSetProperty(package,"dummya","1");
2211     ok( r == ERROR_SUCCESS, "set property failed\n");
2212     r = MsiSetProperty(package,"dummyb","[2]");
2213     ok( r == ERROR_SUCCESS, "set property failed\n");
2214     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
2215     ok( r == ERROR_SUCCESS, "set string failed\n");
2216     r = MsiRecordSetString(hrec, 1, "aaa");
2217     ok( r == ERROR_SUCCESS, "set string failed\n");
2218     r = MsiRecordSetString(hrec, 2, "bbb");
2219     ok( r == ERROR_SUCCESS, "set string failed\n");
2220     r = MsiRecordSetString(hrec, 3, "ccc");
2221     ok( r == ERROR_SUCCESS, "set string failed\n");
2222     sz = sizeof buffer;
2223     r = MsiFormatRecord(package, hrec, buffer, &sz);
2224     ok( r == ERROR_SUCCESS, "format failed\n");
2225     todo_wine
2226     {
2227         ok( sz == 9, "size wrong(%i)\n",sz);
2228         ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
2229     }
2230
2231     r = MsiSetProperty(package,"dummya","1");
2232     ok( r == ERROR_SUCCESS, "set property failed\n");
2233     r = MsiSetProperty(package,"dummyb","a");
2234     ok( r == ERROR_SUCCESS, "set property failed\n");
2235     r = MsiSetProperty(package,"dummyc","\\blath");
2236     ok( r == ERROR_SUCCESS, "set property failed\n");
2237     r = MsiSetProperty(package,"dummyd","[\\blath]");
2238     ok( r == ERROR_SUCCESS, "set property failed\n");
2239     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
2240     ok( r == ERROR_SUCCESS, "set string failed\n");
2241     r = MsiRecordSetString(hrec, 1, "aaa");
2242     ok( r == ERROR_SUCCESS, "set string failed\n");
2243     r = MsiRecordSetString(hrec, 2, "bbb");
2244     ok( r == ERROR_SUCCESS, "set string failed\n");
2245     r = MsiRecordSetString(hrec, 3, "ccc");
2246     ok( r == ERROR_SUCCESS, "set string failed\n");
2247     sz = sizeof buffer;
2248     r = MsiFormatRecord(package, hrec, buffer, &sz);
2249     ok( r == ERROR_SUCCESS, "format failed\n");
2250     ok( sz == 10, "size wrong(%i)\n",sz);
2251     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
2252
2253     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
2254     ok( r == ERROR_SUCCESS, "set string failed\n");
2255     r = MsiRecordSetString(hrec, 1, "boo");
2256     ok( r == ERROR_SUCCESS, "set string failed\n");
2257     r = MsiRecordSetString(hrec, 2, "hoo");
2258     ok( r == ERROR_SUCCESS, "set string failed\n");
2259     r = MsiRecordSetString(hrec, 3, "yeah");
2260     ok( r == ERROR_SUCCESS, "set string failed\n");
2261     sz = sizeof buffer;
2262     r = MsiFormatRecord(package, hrec, buffer, &sz);
2263     ok( r == ERROR_SUCCESS, "format failed\n");
2264     todo_wine
2265     {
2266         ok( sz == 11, "size wrong(%i)\n",sz);
2267         ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
2268     }
2269
2270     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
2271     ok( r == ERROR_SUCCESS, "set string failed\n");
2272     r = MsiRecordSetString(hrec, 1, "boo");
2273     ok( r == ERROR_SUCCESS, "set string failed\n");
2274     r = MsiRecordSetString(hrec, 2, "hoo");
2275     ok( r == ERROR_SUCCESS, "set string failed\n");
2276     r = MsiRecordSetString(hrec, 3, "\\help");
2277     ok( r == ERROR_SUCCESS, "set string failed\n");
2278     sz = sizeof buffer;
2279     r = MsiFormatRecord(package, hrec, buffer, &sz);
2280     ok( r == ERROR_SUCCESS, "format failed\n");
2281     ok( sz == 9, "size wrong(%i)\n",sz);
2282     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
2283
2284     /* nested properties */
2285     MsiSetProperty(package, "PropA", "surprise");
2286     MsiSetProperty(package, "PropB", "[PropA]");
2287     MsiSetProperty(package, "PropC", "[PropB]");
2288     sz = sizeof buffer;
2289     MsiRecordSetString(hrec, 0, "[PropC]");
2290     r = MsiFormatRecord(package, hrec, buffer, &sz);
2291     ok( r == ERROR_SUCCESS, "format failed\n");
2292     ok( sz == 7, "size wrong(%i)\n",sz);
2293     ok( 0 == strcmp(buffer,"[PropB]"), "wrong output (%s)\n",buffer);
2294
2295     MsiSetProperty(package, "PropA", "surprise");
2296     MsiSetProperty(package, "PropB", "PropA");
2297     MsiSetProperty(package, "PropC", "PropB");
2298     sz = sizeof buffer;
2299     MsiRecordSetString(hrec, 0, "[PropC]");
2300     r = MsiFormatRecord(package, hrec, buffer, &sz);
2301     ok( r == ERROR_SUCCESS, "format failed\n");
2302     ok( sz == 5, "size wrong(%i)\n",sz);
2303     ok( 0 == strcmp(buffer,"PropB"), "wrong output (%s)\n",buffer);
2304
2305     MsiSetProperty(package, "PropA", "surprise");
2306     MsiSetProperty(package, "PropB", "[PropA]");
2307     MsiSetProperty(package, "PropC", "[PropB]");
2308     sz = sizeof buffer;
2309     MsiRecordSetString(hrec, 0, "[[PropC]]");
2310     r = MsiFormatRecord(package, hrec, buffer, &sz);
2311     ok( r == ERROR_SUCCESS, "format failed\n");
2312     ok( sz == 0, "size wrong(%i)\n",sz);
2313     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2314
2315     MsiSetProperty(package, "PropA", "surprise");
2316     MsiSetProperty(package, "PropB", "[PropA]");
2317     MsiSetProperty(package, "PropC", "PropB");
2318     sz = sizeof buffer;
2319     MsiRecordSetString(hrec, 0, "[[PropC]]");
2320     r = MsiFormatRecord(package, hrec, buffer, &sz);
2321     ok( r == ERROR_SUCCESS, "format failed\n");
2322     ok( sz == 7, "size wrong(%i)\n",sz);
2323     ok( 0 == strcmp(buffer,"[PropA]"), "wrong output (%s)\n",buffer);
2324
2325     MsiSetProperty(package, "PropA", "surprise");
2326     MsiSetProperty(package, "PropB", "PropA");
2327     MsiSetProperty(package, "PropC", "PropB");
2328     sz = sizeof buffer;
2329     MsiRecordSetString(hrec, 0, "[[PropC]]");
2330     r = MsiFormatRecord(package, hrec, buffer, &sz);
2331     ok( r == ERROR_SUCCESS, "format failed\n");
2332     ok( sz == 5, "size wrong(%i)\n",sz);
2333     ok( 0 == strcmp(buffer,"PropA"), "wrong output (%s)\n",buffer);
2334
2335     MsiSetProperty(package, "PropA", "surprise");
2336     MsiSetProperty(package, "PropB", "PropA");
2337     MsiSetProperty(package, "PropC", "PropB");
2338     sz = sizeof buffer;
2339     MsiRecordSetString(hrec, 0, "[[[PropC]]]");
2340     r = MsiFormatRecord(package, hrec, buffer, &sz);
2341     ok( r == ERROR_SUCCESS, "format failed\n");
2342     ok( sz == 8, "size wrong(%i)\n",sz);
2343     ok( 0 == strcmp(buffer,"surprise"), "wrong output (%s)\n",buffer);
2344
2345     /* properties inside braces */
2346     sz = sizeof buffer;
2347     MsiRecordSetString(hrec, 0, "{abcd}");
2348     r = MsiFormatRecord(package, hrec, buffer, &sz);
2349     ok( r == ERROR_SUCCESS, "format failed\n");
2350     ok( sz == 6, "size wrong(%i)\n",sz);
2351     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
2352
2353     MsiSetProperty(package, "one", "mercury");
2354     MsiSetProperty(package, "two", "venus");
2355     sz = sizeof buffer;
2356     MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
2357     r = MsiFormatRecord(package, hrec, buffer, &sz);
2358     ok( r == ERROR_SUCCESS, "format failed: %d\n", r);
2359     ok( sz == 25, "size wrong(%i)\n",sz);
2360     ok( 0 == strcmp(buffer,"amercurybcvenusdemercuryf"), "wrong output (%s)\n",buffer);
2361
2362     MsiSetProperty(package, "one", "mercury");
2363     MsiSetProperty(package, "two", "venus");
2364     MsiSetProperty(package, "bad", "");
2365     sz = sizeof buffer;
2366     MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
2367     r = MsiFormatRecord(package, hrec, buffer, &sz);
2368     ok( r == ERROR_SUCCESS, "format failed\n");
2369     ok( sz == 0, "size wrong(%i)\n",sz);
2370     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2371
2372     MsiSetProperty(package, "bad", "");
2373     sz = sizeof buffer;
2374     MsiRecordSetString(hrec, 0, "{[bad]}");
2375     r = MsiFormatRecord(package, hrec, buffer, &sz);
2376     ok( r == ERROR_SUCCESS, "format failed\n");
2377     ok( sz == 0, "size wrong(%i)\n",sz);
2378     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2379
2380     MsiSetProperty(package, "one", "mercury");
2381     sz = sizeof buffer;
2382     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
2383     r = MsiFormatRecord(package, hrec, buffer, &sz);
2384     ok( r == ERROR_SUCCESS, "format failed\n");
2385     todo_wine
2386     {
2387         ok( sz == 14, "size wrong(%i)\n",sz);
2388         ok( 0 == strcmp(buffer,"abc{dmercuryef"), "wrong output (%s)\n",buffer);
2389     }
2390
2391     MsiSetProperty(package, "one", "mercury");
2392     sz = sizeof buffer;
2393     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
2394     r = MsiFormatRecord(package, hrec, buffer, &sz);
2395     ok( r == ERROR_SUCCESS, "format failed\n");
2396     todo_wine
2397     {
2398         ok( sz == 15, "size wrong(%i)\n",sz);
2399         ok( 0 == strcmp(buffer,"abc{dmercuryef}"), "wrong output (%s)\n",buffer);
2400     }
2401
2402     MsiSetProperty(package, "one", "mercury");
2403     sz = sizeof buffer;
2404     MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
2405     r = MsiFormatRecord(package, hrec, buffer, &sz);
2406     ok( r == ERROR_SUCCESS, "format failed\n");
2407     ok( sz == 5, "size wrong(%i)\n",sz);
2408     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
2409
2410     MsiSetProperty(package, "one", "mercury");
2411
2412     sz = sizeof buffer;
2413     MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
2414     r = MsiFormatRecord(package, hrec, buffer, &sz);
2415     ok( r == ERROR_SUCCESS, "format failed\n");
2416     ok( sz == 0, "size wrong(%i)\n",sz);
2417     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2418
2419     sz = sizeof(buffer);
2420     MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
2421     MsiRecordSetString(hrec, 1, "one");
2422     r = MsiFormatRecord(package, hrec, buffer, &sz);
2423     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2424     ok(sz == 13, "Expected 13, got %d\n",sz);
2425     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2426        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2427
2428     sz = sizeof(buffer);
2429     MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
2430     MsiRecordSetString(hrec, 1, "one");
2431     r = MsiFormatRecord(package, hrec, buffer, &sz);
2432     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2433     ok(sz == 13, "Expected 13, got %d\n",sz);
2434     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2435        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2436
2437     sz = sizeof(buffer);
2438     MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
2439     MsiRecordSetString(hrec, 1, "one");
2440     r = MsiFormatRecord(package, hrec, buffer, &sz);
2441     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2442     ok(sz == 20, "Expected 20, got %d\n",sz);
2443     ok(!lstrcmpA(buffer, "one mercury {abcdef}"),
2444        "Expected \"one mercury {abcdef}\", got \"%s\"\n", buffer);
2445
2446     MsiCloseHandle(hrec);
2447
2448     r = MsiCloseHandle(package);
2449     ok(r==ERROR_SUCCESS, "Unable to close package\n");
2450
2451     DeleteFile( msifile );
2452 }
2453
2454 static void test_formatrecord_tables(void)
2455 {
2456     MSIHANDLE hdb, hrec, hpkg = 0;
2457     CHAR buf[MAX_PATH];
2458     CHAR curr_dir[MAX_PATH];
2459     CHAR expected[MAX_PATH];
2460     CHAR root[MAX_PATH];
2461     DWORD size;
2462     UINT r;
2463
2464     GetCurrentDirectory( MAX_PATH, curr_dir );
2465
2466     hdb = create_package_db();
2467     ok ( hdb, "failed to create package database\n");
2468
2469     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2470     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2471
2472     r = add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2473                              "'I am a really long directory'" );
2474     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2475
2476     r = create_feature_table( hdb );
2477     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r);
2478
2479     r = add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2480     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2481
2482     r = create_component_table( hdb );
2483     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r);
2484
2485     r = add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2486     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2487
2488     r = add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2489     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2490
2491     r = add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2492     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2493
2494     r = create_feature_components_table( hdb );
2495     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r);
2496
2497     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2498     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2499
2500     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2501     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2502
2503     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2504     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2505
2506     r = create_file_table( hdb );
2507     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r);
2508
2509     r = add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2510     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2511
2512     r = add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2513     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2514
2515     r = add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2516     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2517
2518     r = create_custom_action_table( hdb );
2519     ok( r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
2520
2521     r = add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2522     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2523
2524     r = add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2525     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2526
2527     r = add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2528     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2529
2530     r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2531     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2532
2533     r = add_custom_action_entry( hdb, "'EmbedNull', 51, 'prop', '[~]np'" );
2534     ok( r == ERROR_SUCCESS, "cannot add custom action: %d\n", r);
2535
2536     r = package_from_db( hdb, &hpkg );
2537     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2538     {
2539         skip("Not enough rights to perform tests\n");
2540         MsiCloseHandle( hdb );
2541         DeleteFile( msifile );
2542         return;
2543     }
2544     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2545
2546     MsiCloseHandle( hdb );
2547
2548     r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2549     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2550
2551     hrec = MsiCreateRecord( 1 );
2552
2553     /* property doesn't exist */
2554     size = MAX_PATH;
2555     /*MsiRecordSetString( hrec, 0, "[1]" ); */
2556     MsiRecordSetString( hrec, 1, "[idontexist]" );
2557     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2558     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2559     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2560
2561     /* property exists */
2562     size = MAX_PATH;
2563     MsiRecordSetString( hrec, 1, "[imaprop]" );
2564     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2565     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2566     ok( !lstrcmp( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2567
2568     /* environment variable doesn't exist */
2569     size = MAX_PATH;
2570     MsiRecordSetString( hrec, 1, "[%idontexist]" );
2571     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2572     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2573     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2574
2575     /* environment variable exists */
2576     size = MAX_PATH;
2577     SetEnvironmentVariable( "crazyvar", "crazyval" );
2578     MsiRecordSetString( hrec, 1, "[%crazyvar]" );
2579     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2580     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2581     ok( !lstrcmp( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2582
2583     /* file key before CostInitialize */
2584     size = MAX_PATH;
2585     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2586     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2587     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2588     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2589
2590     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2591
2592     r = MsiDoAction(hpkg, "CostInitialize");
2593     ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2594
2595     r = MsiDoAction(hpkg, "FileCost");
2596     ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2597
2598     r = MsiDoAction(hpkg, "CostFinalize");
2599     ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2600
2601     size = MAX_PATH;
2602     MsiGetProperty( hpkg, "ROOTDRIVE", root, &size );
2603
2604     sprintf( expected, "1: %sfrontal.txt ", root);
2605
2606     /* frontal full file key */
2607     size = MAX_PATH;
2608     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2609     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2610     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2611     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2612
2613     /* frontal short file key */
2614     size = MAX_PATH;
2615     MsiRecordSetString( hrec, 1, "[!frontal_file]" );
2616     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2617     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2618     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2619
2620     sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2621
2622     /* temporal full file key */
2623     size = MAX_PATH;
2624     MsiRecordSetString( hrec, 1, "[#temporal_file]" );
2625     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2626     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2627     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2628
2629     /* temporal short file key */
2630     size = MAX_PATH;
2631     MsiRecordSetString( hrec, 1, "[!temporal_file]" );
2632     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2633     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2634     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2635
2636     /* custom action 51, files don't exist */
2637     r = MsiDoAction( hpkg, "MyCustom" );
2638     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2639
2640     sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2641
2642     size = MAX_PATH;
2643     r = MsiGetProperty( hpkg, "prop", buf, &size );
2644     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2645     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2646
2647     sprintf( buf, "%sI am a really long directory", root );
2648     CreateDirectory( buf, NULL );
2649
2650     lstrcat( buf, "\\temporal.txt" );
2651     create_test_file( buf );
2652
2653     /* custom action 51, files exist */
2654     r = MsiDoAction( hpkg, "MyCustom" );
2655     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2656
2657     size = MAX_PATH;
2658     r = MsiGetProperty( hpkg, "prop", buf, &size );
2659     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2660     todo_wine
2661     {
2662         ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2663     }
2664
2665     /* custom action 51, escaped text 1 */
2666     r = MsiDoAction( hpkg, "EscapeIt1" );
2667     ok( r == ERROR_SUCCESS, "EscapeIt1 failed: %d\n", r);
2668
2669     size = MAX_PATH;
2670     r = MsiGetProperty( hpkg, "prop", buf, &size );
2671     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2672     ok( !lstrcmp( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2673
2674     /* custom action 51, escaped text 2 */
2675     r = MsiDoAction( hpkg, "EscapeIt2" );
2676     ok( r == ERROR_SUCCESS, "EscapeIt2 failed: %d\n", r);
2677
2678     size = MAX_PATH;
2679     r = MsiGetProperty( hpkg, "prop", buf, &size );
2680     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2681     ok( !lstrcmp( buf, "x" ), "Expected 'x', got %s\n", buf);
2682
2683     /* custom action 51, escaped text 3 */
2684     r = MsiDoAction( hpkg, "EscapeIt3" );
2685     ok( r == ERROR_SUCCESS, "EscapeIt3 failed: %d\n", r);
2686
2687     size = MAX_PATH;
2688     r = MsiGetProperty( hpkg, "prop", buf, &size );
2689     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2690     ok( !lstrcmp( buf, "" ), "Expected '', got %s\n", buf);
2691
2692     /* custom action 51, embedded null */
2693     r = MsiDoAction( hpkg, "EmbedNull" );
2694     ok( r == ERROR_SUCCESS, "EmbedNull failed: %d\n", r);
2695
2696     size = MAX_PATH;
2697     memset( buf, 'a', sizeof(buf) );
2698     r = MsiGetProperty( hpkg, "prop", buf, &size );
2699     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2700     ok( !memcmp( buf, "\0np", sizeof("\0np") ), "wrong value\n");
2701     ok( size == sizeof("\0np") - 1, "got %u\n", size );
2702
2703     r = MsiSetProperty( hpkg, "prop", "[~]np" );
2704     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2705
2706     size = MAX_PATH;
2707     memset( buf, 'a', sizeof(buf) );
2708     r = MsiGetProperty( hpkg, "prop", buf, &size );
2709     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2710     ok( !lstrcmp( buf, "[~]np" ), "Expected '[~]np', got %s\n", buf);
2711
2712     sprintf( expected, "1: %sI am a really long directory\\ ", root);
2713
2714     /* component with INSTALLSTATE_LOCAL */
2715     size = MAX_PATH;
2716     MsiRecordSetString( hrec, 1, "[$temporal]" );
2717     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2718     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2719     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2720
2721     r = MsiSetComponentState( hpkg, "temporal", INSTALLSTATE_SOURCE );
2722     ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2723
2724     /* component with INSTALLSTATE_SOURCE */
2725     lstrcpy( expected, "1: " );
2726     lstrcat( expected, curr_dir );
2727     if (strlen(curr_dir) > 3)
2728         lstrcat( expected, "\\" );
2729     lstrcat( expected, " " );
2730     size = MAX_PATH;
2731     MsiRecordSetString( hrec, 1, "[$parietal]" );
2732     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2733     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2734     ok( !lstrcmp( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2735
2736     sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2737     DeleteFile( buf );
2738
2739     sprintf( buf, "%sI am a really long directory", root );
2740     RemoveDirectory( buf );
2741
2742     MsiCloseHandle( hrec );
2743     MsiCloseHandle( hpkg );
2744     DeleteFile( msifile );
2745 }
2746
2747 static void test_processmessage(void)
2748 {
2749     MSIHANDLE hrec, package;
2750     UINT r;
2751
2752     MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL);
2753
2754     r = helper_createpackage( msifile, &package );
2755     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2756     {
2757         skip("Not enough rights to perform tests\n");
2758         return;
2759     }
2760     ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r );
2761
2762     hrec = MsiCreateRecord(3);
2763     ok( hrec, "failed to create record\n");
2764
2765     r = MsiRecordSetString(hrec, 1, "");
2766     ok( r == ERROR_SUCCESS, "set string failed\n");
2767
2768     r = MsiProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, hrec);
2769     ok( r == IDOK, "expected IDOK, got %i\n", r);
2770
2771     MsiCloseHandle(hrec);
2772     MsiCloseHandle(package);
2773
2774     DeleteFile(msifile);
2775 }
2776
2777 START_TEST(format)
2778 {
2779     test_createpackage();
2780     test_formatrecord();
2781     test_formatrecord_package();
2782     test_formatrecord_tables();
2783     test_processmessage();
2784 }