msi/tests: Move test coverage for standard actions to a separate module.
[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     r = MsiRecordSetString(hrec, 1, "boo");
477     r = MsiRecordSetString(hrec, 2, "hoo");
478     ok( r == ERROR_SUCCESS, "set string failed\n");
479     sz = sizeof buffer;
480     r = MsiFormatRecord(0, hrec, buffer, &sz);
481     ok( r == ERROR_SUCCESS, "format failed\n");
482     ok( sz == 7, "size wrong\n");
483     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
484
485     /* empty string */
486     r = MsiRecordSetString(hrec, 0, "");
487     sz = sizeof buffer;
488     r = MsiFormatRecord(0, hrec, buffer, &sz);
489     ok( r == ERROR_SUCCESS, "format failed\n");
490     ok( sz == 30, "size wrong %i\n",sz);
491     ok( 0 == strcmp(buffer,"1: boo 2: hoo 3:  4:  5:  6:  "), 
492                     "wrong output(%s)\n",buffer);
493
494     /* play games with recursive lookups */
495     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
496     r = MsiRecordSetString(hrec, 1, "2");
497     r = MsiRecordSetString(hrec, 2, "hey");
498     ok( r == ERROR_SUCCESS, "set string failed\n");
499     sz = sizeof buffer;
500     r = MsiFormatRecord(0, hrec, buffer, &sz);
501     ok( r == ERROR_SUCCESS, "format failed\n");
502     ok( sz == 7, "size wrong,(%i)\n",sz);
503     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
504
505     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
506     r = MsiRecordSetString(hrec, 1, "[2]");
507     r = MsiRecordSetString(hrec, 2, "hey");
508     ok( r == ERROR_SUCCESS, "set string failed\n");
509     sz = sizeof buffer;
510     r = MsiFormatRecord(0, hrec, buffer, &sz);
511     ok( r == ERROR_SUCCESS, "format failed\n");
512     ok( sz == 9, "size wrong,(%i)\n",sz);
513     ok( 0 == strcmp(buffer,"[[2]] hey"), "wrong output (%s)\n",buffer);
514
515     r = MsiRecordSetString(hrec, 0, "[[[3]]] [2]");
516     r = MsiRecordSetString(hrec, 1, "2");
517     r = MsiRecordSetString(hrec, 2, "hey");
518     r = MsiRecordSetString(hrec, 3, "1");
519     ok( r == ERROR_SUCCESS, "set string failed\n");
520     sz = sizeof buffer;
521     r = MsiFormatRecord(0, hrec, buffer, &sz);
522     ok( r == ERROR_SUCCESS, "format failed\n");
523     ok( sz == 7, "size wrong,(%i)\n",sz);
524     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
525
526     r = MsiCloseHandle(hrec);
527     ok(r==ERROR_SUCCESS, "Unable to close record\n");
528     hrec = MsiCreateRecord(12);
529     ok( hrec, "failed to create record\n");
530
531     r = MsiRecordSetString(hrec, 0, "[[3][1]] [2]");
532     r = MsiRecordSetString(hrec, 1, "2");
533     r = MsiRecordSetString(hrec, 2, "hey");
534     r = MsiRecordSetString(hrec, 3, "1");
535     r = MsiRecordSetString(hrec, 12, "big");
536     ok( r == ERROR_SUCCESS, "set string failed\n");
537     sz = sizeof buffer;
538     r = MsiFormatRecord(0, hrec, buffer, &sz);
539     ok( r == ERROR_SUCCESS, "format failed\n");
540     ok( sz == 7, "size wrong,(%i)\n",sz);
541     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
542
543     r = MsiRecordSetString(hrec, 0, "[[3][4][1]] [2]");
544     r = MsiRecordSetString(hrec, 1, "2");
545     r = MsiRecordSetString(hrec, 2, "hey");
546     r = MsiRecordSetString(hrec, 3, "1");
547     r = MsiRecordSetString(hrec, 4, NULL);
548     r = MsiRecordSetString(hrec, 12, "big");
549     ok( r == ERROR_SUCCESS, "set string failed\n");
550     sz = sizeof buffer;
551     r = MsiFormatRecord(0, hrec, buffer, &sz);
552     ok( r == ERROR_SUCCESS, "format failed\n");
553     ok( sz == 7, "size wrong,(%i)\n",sz);
554     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
555
556     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]");
557     r = MsiRecordSetString(hrec, 1, "2");
558     r = MsiRecordSetString(hrec, 2, "hey");
559     r = MsiRecordSetString(hrec, 3, "1");
560     r = MsiRecordSetString(hrec, 4, NULL);
561     r = MsiRecordSetString(hrec, 12, "big");
562     ok( r == ERROR_SUCCESS, "set string failed\n");
563     sz = sizeof buffer;
564     r = MsiFormatRecord(0, hrec, buffer, &sz);
565     ok( r == ERROR_SUCCESS, "format failed\n");
566     ok( sz == 10, "size wrong,(%i)\n",sz);
567     ok( 0 == strcmp(buffer,"[1[]2] hey"), "wrong output (%s)\n",buffer);
568
569     /* incorrect  formats */
570     r = MsiRecordSetString(hrec, 0, "[[[3][[4]][1]] [2]");
571     r = MsiRecordSetString(hrec, 1, "2");
572     r = MsiRecordSetString(hrec, 2, "hey");
573     r = MsiRecordSetString(hrec, 3, "1");
574     r = MsiRecordSetString(hrec, 4, NULL);
575     r = MsiRecordSetString(hrec, 12, "big");
576     ok( r == ERROR_SUCCESS, "set string failed\n");
577     sz = sizeof buffer;
578     r = MsiFormatRecord(0, hrec, buffer, &sz);
579     ok( r == ERROR_SUCCESS, "format failed\n");
580     ok( sz == 18, "size wrong,(%i)\n",sz);
581     ok( 0 == strcmp(buffer,"[[[3][[4]][1]] [2]"), "wrong output (%s)\n",buffer);
582
583     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]]");
584     r = MsiRecordSetString(hrec, 1, "2");
585     r = MsiRecordSetString(hrec, 2, "hey");
586     r = MsiRecordSetString(hrec, 3, "1");
587     r = MsiRecordSetString(hrec, 4, NULL);
588     r = MsiRecordSetString(hrec, 12, "big");
589     ok( r == ERROR_SUCCESS, "set string failed\n");
590     sz = sizeof buffer;
591     r = MsiFormatRecord(0, hrec, buffer, &sz);
592     ok( r == ERROR_SUCCESS, "format failed\n");
593     ok( sz == 11, "size wrong,(%i)\n",sz);
594     ok( 0 == strcmp(buffer,"[1[]2] hey]"), "wrong output (%s)\n",buffer);
595
596
597     /* play games with {} */
598
599     r = MsiRecordSetString(hrec, 0, "{[3][1]} [2]");
600     r = MsiRecordSetString(hrec, 1, "2");
601     r = MsiRecordSetString(hrec, 2, "hey");
602     r = MsiRecordSetString(hrec, 3, "1");
603     r = MsiRecordSetString(hrec, 4, NULL);
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 == 6, "size wrong,(%i)\n",sz);
610     ok( 0 == strcmp(buffer,"12 hey"), "wrong output (%s)\n",buffer);
611
612     r = MsiRecordSetString(hrec, 0, "[{[3][1]}] [2]");
613     r = MsiRecordSetString(hrec, 1, "2");
614     r = MsiRecordSetString(hrec, 2, "hey");
615     r = MsiRecordSetString(hrec, 3, "1");
616     r = MsiRecordSetString(hrec, 4, NULL);
617     r = MsiRecordSetString(hrec, 12, "big");
618     ok( r == ERROR_SUCCESS, "set string failed\n");
619     sz = sizeof buffer;
620     r = MsiFormatRecord(0, hrec, buffer, &sz);
621     ok( r == ERROR_SUCCESS, "format failed\n");
622     ok( sz == 8, "size wrong,(%i)\n",sz);
623     ok( 0 == strcmp(buffer,"[12] hey"), "wrong output (%s)\n",buffer);
624
625
626     r = MsiRecordSetString(hrec, 0, "{test} [2]");
627     r = MsiRecordSetString(hrec, 1, "2");
628     r = MsiRecordSetString(hrec, 2, "hey");
629     r = MsiRecordSetString(hrec, 3, "1");
630     r = MsiRecordSetString(hrec, 4, NULL);
631     r = MsiRecordSetString(hrec, 12, "big");
632     ok( r == ERROR_SUCCESS, "set string failed\n");
633     sz = sizeof buffer;
634     r = MsiFormatRecord(0, hrec, buffer, &sz);
635     ok( r == ERROR_SUCCESS, "format failed\n");
636     ok( sz == 10, "size wrong,(%i)\n",sz);
637     ok( 0 == strcmp(buffer,"{test} hey"), "wrong output (%s)\n",buffer);
638
639     r = MsiRecordSetString(hrec, 0, "{[test]} [2]");
640     r = MsiRecordSetString(hrec, 1, "2");
641     r = MsiRecordSetString(hrec, 2, "hey");
642     r = MsiRecordSetString(hrec, 3, "1");
643     r = MsiRecordSetString(hrec, 4, NULL);
644     r = MsiRecordSetString(hrec, 12, "big");
645     ok( r == ERROR_SUCCESS, "set string failed\n");
646     sz = sizeof buffer;
647     r = MsiFormatRecord(0, hrec, buffer, &sz);
648     ok( r == ERROR_SUCCESS, "format failed\n");
649     ok( sz == 12, "size wrong,(%i)\n",sz);
650     ok( 0 == strcmp(buffer,"{[test]} hey"), "wrong output (%s)\n",buffer);
651
652     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4]} [2]");
653     r = MsiRecordSetString(hrec, 1, "2");
654     r = MsiRecordSetString(hrec, 2, "hey");
655     r = MsiRecordSetString(hrec, 3, "1");
656     r = MsiRecordSetString(hrec, 4, NULL);
657     r = MsiRecordSetString(hrec, 12, "big");
658     ok( r == ERROR_SUCCESS, "set string failed\n");
659     sz = sizeof buffer;
660     r = MsiFormatRecord(0, hrec, buffer, &sz);
661     ok( r == ERROR_SUCCESS, "format failed\n");
662     ok( sz == 4, "size wrong,(%i)\n",sz);
663     ok( 0 == strcmp(buffer," hey"), "wrong output (%s)\n",buffer);
664
665     r = MsiRecordSetString(hrec, 0, "{[1][2][3][dummy]} [2]");
666     r = MsiRecordSetString(hrec, 1, "2");
667     r = MsiRecordSetString(hrec, 2, "hey");
668     r = MsiRecordSetString(hrec, 3, "1");
669     r = MsiRecordSetString(hrec, 4, NULL);
670     r = MsiRecordSetString(hrec, 12, "big");
671     ok( r == ERROR_SUCCESS, "set string failed\n");
672     sz = sizeof buffer;
673     r = MsiFormatRecord(0, hrec, buffer, &sz);
674     ok( r == ERROR_SUCCESS, "format failed\n");
675     ok( sz == 18, "size wrong,(%i)\n",sz);
676     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
677
678     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4][dummy]} [2]");
679     r = MsiRecordSetString(hrec, 1, "2");
680     r = MsiRecordSetString(hrec, 2, "hey");
681     r = MsiRecordSetString(hrec, 3, "1");
682     r = MsiRecordSetString(hrec, 4, NULL);
683     r = MsiRecordSetString(hrec, 12, "big");
684     ok( r == ERROR_SUCCESS, "set string failed\n");
685     sz = sizeof buffer;
686     r = MsiFormatRecord(0, hrec, buffer, &sz);
687     ok( r == ERROR_SUCCESS, "format failed\n");
688     ok( sz == 18, "size wrong,(%i)\n",sz);
689     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
690
691     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3][4][dummy]}");
692     r = MsiRecordSetString(hrec, 1, "2");
693     r = MsiRecordSetString(hrec, 2, "hey");
694     r = MsiRecordSetString(hrec, 3, "1");
695     r = MsiRecordSetString(hrec, 4, NULL);
696     r = MsiRecordSetString(hrec, 12, "big");
697     ok( r == ERROR_SUCCESS, "set string failed\n");
698     sz = sizeof buffer;
699     r = MsiFormatRecord(0, hrec, buffer, &sz);
700     ok( r == ERROR_SUCCESS, "format failed\n");
701     ok( sz == 16, "size wrong,(%i)\n",sz);
702     ok( 0 == strcmp(buffer,"{{2hey}1[dummy]}"), "wrong output (%s)\n",buffer);
703
704     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]{[4][dummy]}}");
705     r = MsiRecordSetString(hrec, 1, "2");
706     r = MsiRecordSetString(hrec, 2, "hey");
707     r = MsiRecordSetString(hrec, 3, "1");
708     r = MsiRecordSetString(hrec, 4, NULL);
709     r = MsiRecordSetString(hrec, 12, "big");
710     ok( r == ERROR_SUCCESS, "set string failed\n");
711     sz = sizeof buffer;
712     r = MsiFormatRecord(0, hrec, buffer, &sz);
713     ok( r == ERROR_SUCCESS, "format failed\n");
714     ok( sz == 0, "size wrong,(%i)\n",sz);
715     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
716
717     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]} {[1][2]}");
718     r = MsiRecordSetString(hrec, 1, "1");
719     r = MsiRecordSetString(hrec, 2, "2");
720     r = MsiRecordSetString(hrec, 3, "3");
721     r = MsiRecordSetString(hrec, 4, NULL);
722     r = MsiRecordSetString(hrec, 12, "big");
723     ok( r == ERROR_SUCCESS, "set string failed\n");
724     sz = sizeof buffer;
725     r = MsiFormatRecord(0, hrec, buffer, &sz);
726     ok( r == ERROR_SUCCESS, "format failed\n");
727     ok( sz == 12, "size wrong,(%i)\n",sz);
728     ok( 0 == strcmp(buffer,"{{12}3} {12}"), "wrong output (%s)\n",buffer);
729
730     r = MsiRecordSetString(hrec, 0, "{[1][2]} {{[1][2]}[3]} {[1][2]}");
731     r = MsiRecordSetString(hrec, 1, "1");
732     r = MsiRecordSetString(hrec, 2, "2");
733     r = MsiRecordSetString(hrec, 3, "3");
734     r = MsiRecordSetString(hrec, 4, NULL);
735     r = MsiRecordSetString(hrec, 12, "big");
736     ok( r == ERROR_SUCCESS, "set string failed\n");
737     sz = sizeof buffer;
738     r = MsiFormatRecord(0, hrec, buffer, &sz);
739     ok( r == ERROR_SUCCESS, "format failed\n");
740     ok( sz == 15, "size wrong,(%i)\n",sz);
741     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
742
743     r = MsiRecordSetString(hrec, 0, "{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
744     r = MsiRecordSetString(hrec, 1, "1");
745     r = MsiRecordSetString(hrec, 2, "2");
746     r = MsiRecordSetString(hrec, 3, "3");
747     r = MsiRecordSetString(hrec, 4, NULL);
748     r = MsiRecordSetString(hrec, 12, "big");
749     ok( r == ERROR_SUCCESS, "set string failed\n");
750     sz = sizeof buffer;
751     r = MsiFormatRecord(0, hrec, buffer, &sz);
752     ok( r == ERROR_SUCCESS, "format failed\n");
753     ok( sz == 15, "size wrong,(%i)\n",sz);
754     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
755
756     r = MsiRecordSetString(hrec, 0, "{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
757     r = MsiRecordSetString(hrec, 1, "1");
758     r = MsiRecordSetString(hrec, 2, "2");
759     r = MsiRecordSetString(hrec, 3, "3");
760     r = MsiRecordSetString(hrec, 4, NULL);
761     r = MsiRecordSetString(hrec, 12, "big");
762     ok( r == ERROR_SUCCESS, "set string failed\n");
763     sz = sizeof buffer;
764     r = MsiFormatRecord(0, hrec, buffer, &sz);
765     ok( r == ERROR_SUCCESS, "format failed\n");
766     ok( sz == 22, "size wrong,(%i)\n",sz);
767     ok( 0 == strcmp(buffer,"{blah} 12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
768
769     r = MsiRecordSetString(hrec, 0, "{{[1]}[2]} {[4]}{[1][2]}");
770     r = MsiRecordSetString(hrec, 1, "1");
771     r = MsiRecordSetString(hrec, 2, "2");
772     r = MsiRecordSetString(hrec, 3, "3");
773     r = MsiRecordSetString(hrec, 4, NULL);
774     r = MsiRecordSetString(hrec, 12, "big");
775     ok( r == ERROR_SUCCESS, "set string failed\n");
776     sz = sizeof buffer;
777     r = MsiFormatRecord(0, hrec, buffer, &sz);
778     ok( r == ERROR_SUCCESS, "format failed\n");
779     ok( sz == 13, "size wrong,(%i)\n",sz);
780     ok( 0 == strcmp(buffer,"{{1}2} {}{12}"), "wrong output (%s)\n",buffer);
781
782     r = MsiRecordSetString(hrec, 0, "{{[1]}} {[4]}{[1][2]}");
783     r = MsiRecordSetString(hrec, 1, "1");
784     r = MsiRecordSetString(hrec, 2, "2");
785     r = MsiRecordSetString(hrec, 3, "3");
786     r = MsiRecordSetString(hrec, 4, NULL);
787     r = MsiRecordSetString(hrec, 12, "big");
788     ok( r == ERROR_SUCCESS, "set string failed\n");
789     sz = sizeof buffer;
790     r = MsiFormatRecord(0, hrec, buffer, &sz);
791     ok( r == ERROR_SUCCESS, "format failed\n");
792     ok( sz == 3, "size wrong,(%i)\n",sz);
793     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
794
795     r = MsiRecordSetString(hrec, 0, "{{{[1]}} {[4]}{[1][2]}");
796     r = MsiRecordSetString(hrec, 1, "1");
797     r = MsiRecordSetString(hrec, 2, "2");
798     r = MsiRecordSetString(hrec, 3, "3");
799     r = MsiRecordSetString(hrec, 4, NULL);
800     r = MsiRecordSetString(hrec, 12, "big");
801     ok( r == ERROR_SUCCESS, "set string failed\n");
802     sz = sizeof buffer;
803     r = MsiFormatRecord(0, hrec, buffer, &sz);
804     ok( r == ERROR_SUCCESS, "format failed\n");
805     todo_wine{
806     ok( sz == 3, "size wrong,(%i)\n",sz);
807     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
808     }
809     
810     /* now put play games with escaping */
811     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
812     r = MsiRecordSetString(hrec, 1, "boo");
813     r = MsiRecordSetString(hrec, 2, "hoo");
814     ok( r == ERROR_SUCCESS, "set string failed\n");
815     sz = sizeof buffer;
816     r = MsiFormatRecord(0, hrec, buffer, &sz);
817     ok( r == ERROR_SUCCESS, "format failed\n");
818     ok( sz == 16, "size wrong\n");
819     ok( 0 == strcmp(buffer,"boo hoo [\\3asdf]"), "wrong output\n");
820
821     /* now put play games with escaping */
822     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
823     r = MsiRecordSetString(hrec, 1, "boo");
824     r = MsiRecordSetString(hrec, 2, "hoo");
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 == 12, "size wrong\n");
830     ok( 0 == strcmp(buffer,"boo hoo [\\x]"), "wrong output\n");
831
832     MsiRecordSetString(hrec, 0, "[\\x]");
833     sz = sizeof buffer;
834     r = MsiFormatRecord(0, hrec, buffer, &sz);
835     ok( r == ERROR_SUCCESS, "format failed\n");
836     ok( sz == 4, "size wrong: %d\n", sz);
837     ok( 0 == strcmp(buffer,"[\\x]"), "wrong output: %s\n", buffer);
838
839     MsiRecordSetString(hrec, 0, "{\\x}");
840     sz = sizeof buffer;
841     r = MsiFormatRecord(0, hrec, buffer, &sz);
842     ok( r == ERROR_SUCCESS, "format failed\n");
843     ok( sz == 4, "size wrong: %d\n", sz);
844     ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer);
845
846     MsiRecordSetString(hrec, 0, "[abc\\x]");
847     sz = sizeof buffer;
848     r = MsiFormatRecord(0, hrec, buffer, &sz);
849     ok( r == ERROR_SUCCESS, "format failed\n");
850     ok( sz == 7, "size wrong: %d\n", sz);
851     ok( 0 == strcmp(buffer,"[abc\\x]"), "wrong output: %s\n", buffer);
852
853     MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]");
854     sz = sizeof buffer;
855     r = MsiFormatRecord(0, hrec, buffer, &sz);
856     ok( r == ERROR_SUCCESS, "format failed\n");
857     ok( sz == 20, "size wrong: %d\n", sz);
858     ok( 0 == strcmp(buffer,"[\\[]Bracket Text[\\]]"), "wrong output: %s\n", buffer);
859
860     /* now try other formats without a package */
861     r = MsiRecordSetString(hrec, 0, "[1] [2] [property]");
862     r = MsiRecordSetString(hrec, 1, "boo");
863     r = MsiRecordSetString(hrec, 2, "hoo");
864     ok( r == ERROR_SUCCESS, "set string failed\n");
865     sz = sizeof buffer;
866     r = MsiFormatRecord(0, hrec, buffer, &sz);
867     ok( r == ERROR_SUCCESS, "format failed\n");
868     ok( sz == 18, "size wrong\n");
869     ok( 0 == strcmp(buffer,"boo hoo [property]"), "wrong output\n");
870
871     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
872     r = MsiRecordSetString(hrec, 1, "boo");
873     r = MsiRecordSetString(hrec, 2, "hoo");
874     ok( r == ERROR_SUCCESS, "set string failed\n");
875     sz = sizeof buffer;
876     r = MsiFormatRecord(0, hrec, buffer, &sz);
877     ok( r == ERROR_SUCCESS, "format failed\n");
878     ok( sz == 11, "size wrong\n");
879     ok( 0 == strcmp(buffer,"boo [~] hoo"), "wrong output (%s)\n",buffer);
880
881     r = MsiRecordSetString(hrec, 0, "[1]");
882     r = MsiRecordSetInteger(hrec, 1, 123456);
883     ok( r == ERROR_SUCCESS, "set integer failed\n");
884     sz = sizeof buffer;
885     r = MsiFormatRecord(0, hrec, buffer, &sz);
886     ok( r == ERROR_SUCCESS, "format failed\n");
887     ok( sz == 6, "size wrong\n");
888     ok( 0 == strcmp(buffer,"123456"), "wrong output (%s)\n",buffer);
889
890     r = MsiRecordSetString(hrec, 0, "[~]");
891     sz = sizeof buffer;
892     r = MsiFormatRecord(0, hrec, buffer, &sz);
893     ok( sz == 3, "size wrong\n");
894     ok( 0 == strcmp(buffer,"[~]"), "wrong output\n");
895     ok( r == ERROR_SUCCESS, "format failed\n");
896
897     r = MsiRecordSetString(hrec, 0, "[]");
898     sz = sizeof buffer;
899     r = MsiFormatRecord(0, hrec, buffer, &sz);
900     ok( sz == 2, "size wrong\n");
901     ok( 0 == strcmp(buffer,"[]"), "wrong output\n");
902     ok( r == ERROR_SUCCESS, "format failed\n");
903
904     /* MsiFormatRecord doesn't seem to handle a negative too well */
905     r = MsiRecordSetString(hrec, 0, "[-1]");
906     sz = sizeof buffer;
907     r = MsiFormatRecord(0, hrec, buffer, &sz);
908     ok( sz == 4, "size wrong\n");
909     ok( 0 == strcmp(buffer,"[-1]"), "wrong output\n");
910     ok( r == ERROR_SUCCESS, "format failed\n");
911
912     r = MsiRecordSetString(hrec, 0, "{[]}");
913     sz = sizeof buffer;
914     r = MsiFormatRecord(0, hrec, buffer, &sz);
915     ok( sz == 4, "size wrong\n");
916     ok( 0 == strcmp(buffer,"{[]}"), "wrong output\n");
917     ok( r == ERROR_SUCCESS, "format failed\n");
918
919     r = MsiRecordSetString(hrec, 0, "[0]");
920     sz = sizeof buffer;
921     r = MsiFormatRecord(0, hrec, buffer, &sz);
922     ok( sz == 3, "size wrong\n");
923     ok( 0 == strcmp(buffer,"[0]"), "wrong output\n");
924     ok( r == ERROR_SUCCESS, "format failed\n");
925
926     r = MsiRecordSetString(hrec, 0, "[100]");
927     sz = sizeof buffer;
928     r = MsiFormatRecord(0, hrec, buffer, &sz);
929     ok( sz == 0, "size wrong\n");
930     ok( 0 == strcmp(buffer,""), "wrong output\n");
931     ok( r == ERROR_SUCCESS, "format failed\n");
932
933     r = MsiRecordSetString(hrec, 0, "{[1] [2]}");
934     r = MsiRecordSetString(hrec, 1, "boo");
935     r = MsiRecordSetString(hrec, 2, "hoo");
936     sz = sizeof buffer;
937     r = MsiFormatRecord(0, hrec, buffer, &sz);
938     ok( sz == 7, "size wrong\n");
939     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
940     ok( r == ERROR_SUCCESS, "format failed\n");
941
942     r = MsiRecordSetString(hrec, 0, "{}");
943     sz = sizeof buffer;
944     r = MsiFormatRecord(0, hrec, buffer, &sz);
945     ok( sz == 0, "size wrong\n");
946     ok( 0 == strcmp(buffer,""), "wrong output\n");
947     ok( r == ERROR_SUCCESS, "format failed\n");
948
949     r = MsiRecordSetString(hrec, 0, "{foo}");
950     sz = sizeof buffer;
951     r = MsiFormatRecord(0, hrec, buffer, &sz);
952     ok( sz == 5, "size wrong\n");
953     ok( 0 == strcmp(buffer,"{foo}"), "wrong output\n");
954     ok( r == ERROR_SUCCESS, "format failed\n");
955
956     r = MsiRecordSetString(hrec, 0, "{boo [1]}");
957     r = MsiRecordSetString(hrec, 1, "hoo");
958     sz = sizeof buffer;
959     r = MsiFormatRecord(0, hrec, buffer, &sz);
960     ok( sz == 7, "size wrong\n");
961     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
962     ok( r == ERROR_SUCCESS, "format failed\n");
963
964     r = MsiRecordSetString(hrec, 0, "{{[1]}}");
965     r = MsiRecordSetString(hrec, 1, "hoo");
966     sz = sizeof buffer;
967     r = MsiFormatRecord(0, hrec, buffer, &sz);
968     ok( sz == 0, "size wrong\n");
969     ok( 0 == strcmp(buffer,""), "wrong output\n");
970     ok( r == ERROR_SUCCESS, "format failed\n");
971
972     r = MsiRecordSetString(hrec, 0, "{ {[1]}}");
973     r = MsiRecordSetString(hrec, 1, "hoo");
974     sz = sizeof buffer;
975     r = MsiFormatRecord(0, hrec, buffer, &sz);
976     todo_wine
977     {
978         ok( 0 == strcmp(buffer," {hoo}"), "wrong output\n");
979         ok( sz == 6, "size wrong\n");
980     }
981     ok( r == ERROR_SUCCESS, "format failed\n");
982
983     r = MsiRecordSetString(hrec, 0, "{{[1]} }");
984     r = MsiRecordSetString(hrec, 1, "hoo");
985     sz = sizeof buffer;
986     r = MsiFormatRecord(0, hrec, buffer, &sz);
987     ok( sz == 8, "size wrong\n");
988     ok( 0 == strcmp(buffer,"{{hoo} }"), "wrong output\n");
989     ok( r == ERROR_SUCCESS, "format failed\n");
990
991     r = MsiRecordSetString(hrec, 0, "{{ [1]}}");
992     r = MsiRecordSetString(hrec, 1, "hoo");
993     sz = sizeof buffer;
994     r = MsiFormatRecord(0, hrec, buffer, &sz);
995     ok( sz == 0, "size wrong\n");
996     ok( 0 == strcmp(buffer,""), "wrong output\n");
997     ok( r == ERROR_SUCCESS, "format failed\n");
998
999     r = MsiRecordSetString(hrec, 0, "{{[1] }}");
1000     r = MsiRecordSetString(hrec, 1, "hoo");
1001     sz = sizeof buffer;
1002     r = MsiFormatRecord(0, hrec, buffer, &sz);
1003     ok( sz == 0, "size wrong\n");
1004     ok( 0 == strcmp(buffer,""), "wrong output\n");
1005     ok( r == ERROR_SUCCESS, "format failed\n");
1006
1007     r = MsiRecordSetString(hrec, 0, "{{a}{b}{c }{ d}{any text}}");
1008     sz = sizeof buffer;
1009     r = MsiFormatRecord(0, hrec, buffer, &sz);
1010     ok( sz == 0, "size wrong\n");
1011     ok( 0 == strcmp(buffer,""), "wrong output\n");
1012     ok( r == ERROR_SUCCESS, "format failed\n");
1013
1014     r = MsiRecordSetString(hrec, 0, "{{a} }");
1015     sz = sizeof buffer;
1016     r = MsiFormatRecord(0, hrec, buffer, &sz);
1017     ok( sz == 6, "size wrong\n");
1018     ok( 0 == strcmp(buffer,"{{a} }"), "wrong output\n");
1019     ok( r == ERROR_SUCCESS, "format failed\n");
1020
1021     r = MsiRecordSetString(hrec, 0, "{{a} {b}}");
1022     sz = sizeof buffer;
1023     r = MsiFormatRecord(0, hrec, buffer, &sz);
1024     ok( sz == 0, "size wrong\n");
1025     ok( 0 == strcmp(buffer,""), "wrong output\n");
1026     ok( r == ERROR_SUCCESS, "format failed\n");
1027
1028     todo_wine {
1029     r = MsiRecordSetString(hrec, 0, "{{a} b}}");
1030     sz = sizeof buffer;
1031     r = MsiFormatRecord(0, hrec, buffer, &sz);
1032     ok( sz == 0, "size wrong\n");
1033     ok( 0 == strcmp(buffer,""), "wrong output\n");
1034     }
1035     ok( r == ERROR_SUCCESS, "format failed\n");
1036
1037     r = MsiRecordSetString(hrec, 0, "{{a b}}");
1038     sz = sizeof buffer;
1039     r = MsiFormatRecord(0, hrec, buffer, &sz);
1040     ok( sz == 0, "size wrong\n");
1041     ok( 0 == strcmp(buffer,""), "wrong output\n");
1042     ok( r == ERROR_SUCCESS, "format failed\n");
1043
1044     r = MsiRecordSetString(hrec, 0, "{ }");
1045     sz = sizeof buffer;
1046     r = MsiFormatRecord(0, hrec, buffer, &sz);
1047     ok( sz == 3, "size wrong\n");
1048     ok( 0 == strcmp(buffer,"{ }"), "wrong output\n");
1049     ok( r == ERROR_SUCCESS, "format failed\n");
1050
1051     r = MsiRecordSetString(hrec, 0, " {{a}}}");
1052     sz = sizeof buffer;
1053     r = MsiFormatRecord(0, hrec, buffer, &sz);
1054     ok( sz == 2, "size wrong\n");
1055     ok( 0 == strcmp(buffer," }"), "wrong output\n");
1056     ok( r == ERROR_SUCCESS, "format failed\n");
1057
1058     todo_wine {
1059     r = MsiRecordSetString(hrec, 0, "{{ almost {{ any }} text }}");
1060     sz = sizeof buffer;
1061     r = MsiFormatRecord(0, hrec, buffer, &sz);
1062     ok( sz == 8, "size wrong\n");
1063     ok( 0 == strcmp(buffer," text }}"), "wrong output\n");
1064     }
1065     ok( r == ERROR_SUCCESS, "format failed\n");
1066
1067     todo_wine {
1068     r = MsiRecordSetString(hrec, 0, "{{ } { hidden ][ [ }}");
1069     sz = sizeof buffer;
1070     r = MsiFormatRecord(0, hrec, buffer, &sz);
1071     ok( sz == 0, "size wrong\n");
1072     ok( 0 == strcmp(buffer,""), "wrong output\n");
1073     }
1074     ok( r == ERROR_SUCCESS, "format failed\n");
1075
1076     r = MsiRecordSetString(hrec, 0, "[ 1]");
1077     r = MsiRecordSetString(hrec, 1, "hoo");
1078     sz = sizeof buffer;
1079     r = MsiFormatRecord(0, hrec, buffer, &sz);
1080     ok( sz == 4, "size wrong\n");
1081     ok( 0 == strcmp(buffer,"[ 1]"), "wrong output\n");
1082     ok( r == ERROR_SUCCESS, "format failed\n");
1083
1084     r = MsiRecordSetString(hrec, 0, "[01]");
1085     r = MsiRecordSetString(hrec, 1, "hoo");
1086     sz = sizeof buffer;
1087     r = MsiFormatRecord(0, hrec, buffer, &sz);
1088     ok( sz == 3, "size wrong\n");
1089     ok( 0 == strcmp(buffer,"hoo"), "wrong output\n");
1090     ok( r == ERROR_SUCCESS, "format failed\n");
1091
1092     todo_wine {
1093     r = MsiRecordSetString(hrec, 0, "{{test}} [01");
1094     r = MsiRecordSetString(hrec, 1, "hoo");
1095     sz = sizeof buffer;
1096     r = MsiFormatRecord(0, hrec, buffer, &sz);
1097     ok( sz == 4, "size wrong\n");
1098     ok( 0 == strcmp(buffer," [01"), "wrong output\n");
1099     }
1100     ok( r == ERROR_SUCCESS, "format failed\n");
1101
1102     r = MsiRecordSetString(hrec, 0, "[\\[]");
1103     r = MsiRecordSetString(hrec, 1, "hoo");
1104     sz = sizeof buffer;
1105     r = MsiFormatRecord(0, hrec, buffer, &sz);
1106     ok( sz == 4, "size wrong\n");
1107     ok( 0 == strcmp(buffer,"[\\[]"), "wrong output\n");
1108     ok( r == ERROR_SUCCESS, "format failed\n");
1109
1110     MsiRecordSetString(hrec, 0, "[\\[]");
1111     MsiRecordSetString(hrec, 1, "hoo");
1112     sz = sizeof(buffer);
1113     r = MsiFormatRecord(0, hrec, buffer, &sz);
1114     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1115     ok(sz == 4, "Expected 4, got %d\n", sz);
1116     ok(!lstrcmpA(buffer, "[\\[]"), "Expected \"[\\[]\", got \"%s\"\n", buffer);
1117
1118     r = MsiRecordSetString(hrec, 0, "[foo]");
1119     r = MsiRecordSetString(hrec, 1, "hoo");
1120     sz = sizeof buffer;
1121     r = MsiFormatRecord(0, hrec, buffer, &sz);
1122     ok( sz == 5, "size wrong\n");
1123     ok( 0 == strcmp(buffer,"[foo]"), "wrong output\n");
1124     ok( r == ERROR_SUCCESS, "format failed\n");
1125
1126     r = MsiRecordSetString(hrec, 0, "[01.]");
1127     r = MsiRecordSetString(hrec, 1, "hoo");
1128     sz = sizeof buffer;
1129     r = MsiFormatRecord(0, hrec, buffer, &sz);
1130     ok( sz == 5, "size wrong\n");
1131     ok( 0 == strcmp(buffer,"[01.]"), "wrong output\n");
1132     ok( r == ERROR_SUCCESS, "format failed\n");
1133
1134     SetEnvironmentVariable("FOO", "BAR");
1135     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1136     sz = sizeof buffer;
1137     r = MsiFormatRecord(0, hrec, buffer, &sz);
1138     ok( sz == 6, "size wrong\n");
1139     ok( 0 == strcmp(buffer,"[%FOO]"), "wrong output\n");
1140     ok( r == ERROR_SUCCESS, "format failed\n");
1141
1142     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1143     r = MsiRecordSetString(hrec, 1, "hoo");
1144     sz = sizeof buffer;
1145     r = MsiFormatRecord(0, hrec, buffer, &sz);
1146     ok( sz == 6, "size wrong\n");
1147     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output\n");
1148     ok( r == ERROR_SUCCESS, "format failed\n");
1149
1150     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1151     r = MsiRecordSetString(hrec, 1, "hoo");
1152     sz = sizeof buffer;
1153     r = MsiFormatRecord(0, hrec, buffer, &sz);
1154     ok( sz == 8, "size wrong\n");
1155     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1156     ok( r == ERROR_SUCCESS, "format failed\n");
1157
1158     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
1159     r = MsiRecordSetString(hrec, 1, "hoo");
1160     sz = sizeof buffer;
1161     r = MsiFormatRecord(0, hrec, buffer, &sz);
1162     ok( sz == 8, "size wrong\n");
1163     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
1164     ok( r == ERROR_SUCCESS, "format failed\n");
1165
1166     r = MsiRecordSetString(hrec, 0, "{{ {{[1]}");
1167     r = MsiRecordSetString(hrec, 1, "hoo");
1168     sz = sizeof buffer;
1169     r = MsiFormatRecord(0, hrec, buffer, &sz);
1170     ok( sz == 9, "size wrong\n");
1171     ok( 0 == strcmp(buffer,"{{ {{hoo}"), "wrong output\n");
1172     ok( r == ERROR_SUCCESS, "format failed\n");
1173
1174     r = MsiRecordSetString(hrec, 0, "[1]}");
1175     r = MsiRecordSetString(hrec, 1, "hoo");
1176     sz = sizeof buffer;
1177     r = MsiFormatRecord(0, hrec, buffer, &sz);
1178     ok( sz == 4, "size wrong\n");
1179     ok( 0 == strcmp(buffer,"hoo}"), "wrong output\n");
1180     ok( r == ERROR_SUCCESS, "format failed\n");
1181
1182     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1183     sz = sizeof buffer;
1184     r = MsiFormatRecord(0, hrec, buffer, &sz);
1185     ok( sz == 7, "size wrong\n");
1186     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1187     ok( r == ERROR_SUCCESS, "format failed\n");
1188
1189     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
1190     sz = sizeof buffer;
1191     r = MsiFormatRecord(0, hrec, buffer, &sz);
1192     ok( sz == 7, "size wrong\n");
1193     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
1194     ok( r == ERROR_SUCCESS, "format failed\n");
1195
1196     r = MsiRecordSetString(hrec, 0, "0{1{2{3{4[1]5}6}7}8}9");
1197     r = MsiRecordSetString(hrec, 1, "hoo");
1198     sz = sizeof buffer;
1199     r = MsiFormatRecord(0, hrec, buffer, &sz);
1200     todo_wine
1201     {
1202         ok( sz == 19, "size wrong\n");
1203         ok( 0 == strcmp(buffer,"01{2{3{4hoo56}7}8}9"), "wrong output\n");
1204     }
1205     ok( r == ERROR_SUCCESS, "format failed\n");
1206
1207     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1208     r = MsiRecordSetString(hrec, 1, "hoo");
1209     sz = sizeof buffer;
1210     r = MsiFormatRecord(0, hrec, buffer, &sz);
1211     todo_wine
1212     {
1213         ok( sz == 9, "size wrong\n");
1214         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1215     }
1216     ok( r == ERROR_SUCCESS, "format failed\n");
1217
1218     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
1219     r = MsiRecordSetString(hrec, 1, "hoo");
1220     sz = sizeof buffer;
1221     r = MsiFormatRecord(0, hrec, buffer, &sz);
1222     todo_wine
1223     {
1224         ok( sz == 9, "size wrong\n");
1225         ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
1226     }
1227     ok( r == ERROR_SUCCESS, "format failed\n");
1228
1229     r = MsiRecordSetString(hrec, 0, "{[1.} [1]");
1230     r = MsiRecordSetString(hrec, 1, "hoo");
1231     sz = sizeof buffer;
1232     r = MsiFormatRecord(0, hrec, buffer, &sz);
1233     ok( sz == 9, "size wrong\n");
1234     todo_wine
1235     {
1236         ok( 0 == strcmp(buffer,"{[1.} hoo"), "wrong output\n");
1237     }
1238     ok( r == ERROR_SUCCESS, "format failed\n");
1239
1240     r = MsiRecordSetString(hrec, 0, "{[{[1]}]}");
1241     r = MsiRecordSetString(hrec, 1, "2");
1242     r = MsiRecordSetString(hrec, 2, "foo");
1243     sz = sizeof buffer;
1244     r = MsiFormatRecord(0, hrec, buffer, &sz);
1245     todo_wine
1246     {
1247         ok( sz == 9, "size wrong\n");
1248         ok( 0 == strcmp(buffer,"{[{[1]}]}"), "wrong output\n");
1249     }
1250     ok( r == ERROR_SUCCESS, "format failed\n");
1251
1252     r = MsiRecordSetString(hrec, 0, "{[1][}");
1253     r = MsiRecordSetString(hrec, 1, "2");
1254     r = MsiRecordSetString(hrec, 2, "foo");
1255     sz = sizeof buffer;
1256     r = MsiFormatRecord(0, hrec, buffer, &sz);
1257     todo_wine
1258     {
1259         ok( sz == 2, "size wrong\n");
1260         ok( 0 == strcmp(buffer,"2["), "wrong output\n");
1261     }
1262     ok( r == ERROR_SUCCESS, "format failed\n");
1263
1264     r = MsiRecordSetString(hrec, 0, "[1]");
1265     r = MsiRecordSetString(hrec, 1, "[2]");
1266     r = MsiRecordSetString(hrec, 2, "foo");
1267     sz = sizeof buffer;
1268     r = MsiFormatRecord(0, hrec, buffer, &sz);
1269     ok( sz == 3, "size wrong\n");
1270     ok( 0 == strcmp(buffer,"[2]"), "wrong output\n");
1271     ok( r == ERROR_SUCCESS, "format failed\n");
1272
1273     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1274     r = MsiRecordSetString(hrec, 1, "hoo");
1275     sz = sizeof buffer;
1276     r = MsiFormatRecord(0, hrec, buffer, &sz);
1277     ok( r == ERROR_SUCCESS, "format failed\n");
1278     ok( sz == 3, "size wrong\n");
1279     todo_wine
1280     {
1281         ok( 0 == strcmp(buffer,"[1]"), "wrong output: %s\n", buffer);
1282     }
1283
1284     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1285     r = MsiRecordSetString(hrec, 0, "[1{{boo}}]");
1286     r = MsiRecordSetString(hrec, 1, "hoo");
1287     sz = sizeof buffer;
1288     r = MsiFormatRecord(0, hrec, buffer, &sz);
1289     ok( sz == 3, "size wrong\n");
1290     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1291     ok( r == ERROR_SUCCESS, "format failed\n");
1292
1293     r = MsiRecordSetString(hrec, 0, "{[1]{{boo} }}");
1294     r = MsiRecordSetString(hrec, 1, "hoo");
1295     sz = sizeof buffer;
1296     r = MsiFormatRecord(0, hrec, buffer, &sz);
1297     todo_wine
1298     {
1299         ok( sz == 11, "size wrong\n");
1300         ok( 0 == strcmp(buffer,"hoo{{boo }}"), "wrong output\n");
1301     }
1302     ok( r == ERROR_SUCCESS, "format failed\n");
1303
1304     r = MsiRecordSetString(hrec, 0, "{[1{{boo}}]}");
1305     r = MsiRecordSetString(hrec, 1, "hoo");
1306     sz = sizeof buffer;
1307     r = MsiFormatRecord(0, hrec, buffer, &sz);
1308     todo_wine
1309     {
1310         ok( sz == 12, "size wrong: got %u, expected 12\n", sz);
1311         ok( 0 == strcmp(buffer,"{[1{{boo}}]}"), "wrong output: got %s, expected [1]\n", buffer);
1312     }
1313     ok( r == ERROR_SUCCESS, "format failed\n");
1314
1315     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1316     r = MsiRecordSetString(hrec, 1, "hoo");
1317     sz = sizeof buffer;
1318     r = MsiFormatRecord(0, hrec, buffer, &sz);
1319     ok( sz == 6, "size wrong: got %u, expected 3\n", sz);
1320     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output: got %s, expected [1]\n", buffer);
1321     ok( r == ERROR_SUCCESS, "format failed\n");
1322
1323     r = MsiRecordSetString(hrec, 0, "{[1{{bo}o}}]}");
1324     r = MsiRecordSetString(hrec, 1, "hoo");
1325     sz = sizeof buffer;
1326     r = MsiFormatRecord(0, hrec, buffer, &sz);
1327     ok( sz == 13, "size wrong\n");
1328     ok( 0 == strcmp(buffer,"{[1{{bo}o}}]}"), "wrong output %s\n",buffer);
1329     ok( r == ERROR_SUCCESS, "format failed\n");
1330
1331     r = MsiRecordSetString(hrec, 0, "{[1{{b{o}o}}]}");
1332     sz = sizeof buffer;
1333     r = MsiFormatRecord(0, hrec, buffer, &sz);
1334     todo_wine
1335     {
1336         ok( sz == 14, "size wrong\n");
1337         ok( 0 == strcmp(buffer,"{[1{{b{o}o}}]}"), "wrong output %s\n",buffer);
1338     }
1339     ok( r == ERROR_SUCCESS, "format failed\n");
1340
1341     r = MsiRecordSetString(hrec, 0, "{ {[1]}");
1342     r = MsiRecordSetString(hrec, 1, "hoo");
1343     sz = sizeof buffer;
1344     r = MsiFormatRecord(0, hrec, buffer, &sz);
1345     todo_wine
1346     {
1347         ok( sz == 5, "size wrong\n");
1348         ok( 0 == strcmp(buffer," {hoo"), "wrong output %s\n",buffer);
1349     }
1350     ok( r == ERROR_SUCCESS, "format failed\n");
1351
1352     /* {} inside a substitution does strange things... */
1353     r = MsiRecordSetString(hrec, 0, "[[1]{}]");
1354     r = MsiRecordSetString(hrec, 1, "2");
1355     sz = sizeof buffer;
1356     r = MsiFormatRecord(0, hrec, buffer, &sz);
1357     todo_wine
1358     {
1359         ok( sz == 5, "size wrong\n");
1360         ok( 0 == strcmp(buffer,"[[1]]"), "wrong output %s\n",buffer);
1361     }
1362     ok( r == ERROR_SUCCESS, "format failed\n");
1363
1364     r = MsiRecordSetString(hrec, 0, "[[1]{}[1]]");
1365     r = MsiRecordSetString(hrec, 1, "2");
1366     sz = sizeof buffer;
1367     r = MsiFormatRecord(0, hrec, buffer, &sz);
1368     todo_wine
1369     {
1370         ok( sz == 6, "size wrong\n");
1371         ok( 0 == strcmp(buffer,"[[1]2]"), "wrong output %s\n",buffer);
1372     }
1373     ok( r == ERROR_SUCCESS, "format failed\n");
1374
1375     r = MsiRecordSetString(hrec, 0, "[a[1]b[1]c{}d[1]e]");
1376     r = MsiRecordSetString(hrec, 1, "2");
1377     sz = sizeof buffer;
1378     r = MsiFormatRecord(0, hrec, buffer, &sz);
1379     todo_wine
1380     {
1381         ok( sz == 14, "size wrong\n");
1382         ok( 0 == strcmp(buffer,"[a[1]b[1]cd2e]"), "wrong output %s\n",buffer);
1383     }
1384     ok( r == ERROR_SUCCESS, "format failed\n");
1385
1386     r = MsiRecordSetString(hrec, 0, "[a[1]b");
1387     r = MsiRecordSetString(hrec, 1, "2");
1388     sz = sizeof buffer;
1389     r = MsiFormatRecord(0, hrec, buffer, &sz);
1390     ok( sz == 6, "size wrong\n");
1391     ok( 0 == strcmp(buffer,"[a[1]b"), "wrong output %s\n",buffer);
1392     ok( r == ERROR_SUCCESS, "format failed\n");
1393
1394     r = MsiRecordSetString(hrec, 0, "a[1]b]");
1395     r = MsiRecordSetString(hrec, 1, "2");
1396     sz = sizeof buffer;
1397     r = MsiFormatRecord(0, hrec, buffer, &sz);
1398     ok( sz == 4, "size wrong\n");
1399     ok( 0 == strcmp(buffer,"a2b]"), "wrong output %s\n",buffer);
1400     ok( r == ERROR_SUCCESS, "format failed\n");
1401
1402     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1403     r = MsiRecordSetString(hrec, 1, "2");
1404     sz = sizeof buffer;
1405     r = MsiFormatRecord(0, hrec, buffer, &sz);
1406     ok( sz == 4, "size wrong\n");
1407     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1408     ok( r == ERROR_SUCCESS, "format failed\n");
1409
1410     r = MsiRecordSetString(hrec, 0, "]a[1]b");
1411     r = MsiRecordSetString(hrec, 1, "2");
1412     sz = sizeof buffer;
1413     r = MsiFormatRecord(0, hrec, buffer, &sz);
1414     ok( sz == 4, "size wrong\n");
1415     ok( 0 == strcmp(buffer,"]a2b"), "wrong output %s\n",buffer);
1416     ok( r == ERROR_SUCCESS, "format failed\n");
1417
1418     r = MsiRecordSetString(hrec, 0, "\\[1]");
1419     r = MsiRecordSetString(hrec, 1, "2");
1420     sz = sizeof buffer;
1421     r = MsiFormatRecord(0, hrec, buffer, &sz);
1422     ok( sz == 2, "size wrong\n");
1423     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1424     ok( r == ERROR_SUCCESS, "format failed\n");
1425
1426     r = MsiRecordSetString(hrec, 0, "\\{[1]}");
1427     r = MsiRecordSetString(hrec, 1, "2");
1428     sz = sizeof buffer;
1429     r = MsiFormatRecord(0, hrec, buffer, &sz);
1430     ok( sz == 2, "size wrong\n");
1431     ok( 0 == strcmp(buffer,"\\2"), "wrong output %s\n",buffer);
1432     ok( r == ERROR_SUCCESS, "format failed\n");
1433
1434     r = MsiRecordSetString(hrec, 0, "a{b[1]c}d");
1435     r = MsiRecordSetString(hrec, 1, NULL);
1436     sz = sizeof buffer;
1437     r = MsiFormatRecord(0, hrec, buffer, &sz);
1438     ok( sz == 2, "size wrong\n");
1439     ok( 0 == strcmp(buffer,"ad"), "wrong output %s\n",buffer);
1440     ok( r == ERROR_SUCCESS, "format failed\n");
1441
1442     r = MsiRecordSetString(hrec, 0, "{a[0]b}");
1443     r = MsiRecordSetString(hrec, 1, "foo");
1444     sz = sizeof buffer;
1445     r = MsiFormatRecord(0, hrec, buffer, &sz);
1446     ok( sz == 9, "size wrong\n");
1447     ok( 0 == strcmp(buffer,"a{a[0]b}b"), "wrong output %s\n",buffer);
1448     ok( r == ERROR_SUCCESS, "format failed\n");
1449
1450     r = MsiRecordSetString(hrec, 0, "[foo]");
1451     sz = sizeof buffer;
1452     r = MsiFormatRecord(0, hrec, buffer, &sz);
1453     ok( sz == 5, "size wrong\n");
1454     ok( 0 == strcmp(buffer,"[foo]"), "wrong output %s\n",buffer);
1455     ok( r == ERROR_SUCCESS, "format failed\n");
1456
1457     r = MsiRecordSetString(hrec, 0, "{[1][-1][1]}");
1458     r = MsiRecordSetString(hrec, 1, "foo");
1459     sz = sizeof buffer;
1460     r = MsiFormatRecord(0, hrec, buffer, &sz);
1461     todo_wine
1462     {
1463         ok( sz == 12, "size wrong\n");
1464         ok( 0 == strcmp(buffer,"{foo[-1]foo}"), "wrong output %s\n",buffer);
1465     }
1466     ok( r == ERROR_SUCCESS, "format failed\n");
1467
1468     /* nested braces */
1469     sz = sizeof buffer;
1470     MsiRecordSetString(hrec, 0, "{abcd}");
1471     r = MsiFormatRecord(0, hrec, buffer, &sz);
1472     ok( r == ERROR_SUCCESS, "format failed\n");
1473     ok( sz == 6, "size wrong(%i)\n",sz);
1474     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
1475
1476     sz = sizeof buffer;
1477     MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
1478     r = MsiFormatRecord(0, hrec, buffer, &sz);
1479     ok( r == ERROR_SUCCESS, "format failed\n");
1480     ok( sz == 23, "size wrong(%i)\n",sz);
1481     ok( 0 == strcmp(buffer,"{a[one]bc[two]de[one]f}"), "wrong output (%s)\n",buffer);
1482
1483     sz = sizeof buffer;
1484     MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
1485     r = MsiFormatRecord(0, hrec, buffer, &sz);
1486     ok( r == ERROR_SUCCESS, "format failed\n");
1487     ok( sz == 23, "size wrong(%i)\n",sz);
1488     ok( 0 == strcmp(buffer,"{a[one]bc[bad]de[two]f}"), "wrong output (%s)\n",buffer);
1489
1490     sz = sizeof buffer;
1491     MsiRecordSetString(hrec, 0, "{[bad]}");
1492     r = MsiFormatRecord(0, hrec, buffer, &sz);
1493     ok( r == ERROR_SUCCESS, "format failed\n");
1494     ok( sz == 7, "size wrong(%i)\n",sz);
1495     ok( 0 == strcmp(buffer,"{[bad]}"), "wrong output (%s)\n",buffer);
1496
1497     sz = sizeof buffer;
1498     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
1499     r = MsiFormatRecord(0, hrec, buffer, &sz);
1500     ok( r == ERROR_SUCCESS, "format failed\n");
1501     ok( sz == 14, "size wrong(%i)\n",sz);
1502     ok( 0 == strcmp(buffer,"{abc{d[one]ef}"), "wrong output (%s)\n",buffer);
1503
1504     sz = sizeof buffer;
1505     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
1506     r = MsiFormatRecord(0, hrec, buffer, &sz);
1507     ok( r == ERROR_SUCCESS, "format failed\n");
1508     ok( sz == 15, "size wrong(%i)\n",sz);
1509     ok( 0 == strcmp(buffer,"{abc{d[one]ef}}"), "wrong output (%s)\n",buffer);
1510
1511     sz = sizeof buffer;
1512     MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
1513     r = MsiFormatRecord(0, hrec, buffer, &sz);
1514     ok( r == ERROR_SUCCESS, "format failed\n");
1515     ok( sz == 5, "size wrong(%i)\n",sz);
1516     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
1517
1518     sz = sizeof buffer;
1519     MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
1520     r = MsiFormatRecord(0, hrec, buffer, &sz);
1521     ok( r == ERROR_SUCCESS, "format failed\n");
1522     ok( sz == 0, "size wrong(%i)\n",sz);
1523     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1524
1525     sz = sizeof buffer;
1526     MsiRecordSetString(hrec, 0, "{{def}hi{jk}}");
1527     r = MsiFormatRecord(0, hrec, buffer, &sz);
1528     ok( r == ERROR_SUCCESS, "format failed\n");
1529     ok( sz == 0, "size wrong(%i)\n",sz);
1530     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1531
1532     sz = sizeof buffer;
1533     MsiRecordSetString(hrec, 0, "{{{def}}hi{jk}}");
1534     r = MsiFormatRecord(0, hrec, buffer, &sz);
1535     ok( r == ERROR_SUCCESS, "format failed\n");
1536     todo_wine
1537     {
1538         ok( sz == 7, "size wrong(%i)\n",sz);
1539         ok( 0 == strcmp(buffer,"hi{jk}}"), "wrong output (%s)\n",buffer);
1540     }
1541
1542     sz = sizeof buffer;
1543     MsiRecordSetString(hrec, 0, "{{def}hi{{jk}}}");
1544     r = MsiFormatRecord(0, hrec, buffer, &sz);
1545     ok( r == ERROR_SUCCESS, "format failed\n");
1546     todo_wine
1547     {
1548         ok( sz == 1, "size wrong(%i)\n",sz);
1549         ok( 0 == strcmp(buffer,"}"), "wrong output (%s)\n",buffer);
1550     }
1551
1552     sz = sizeof buffer;
1553     MsiRecordSetString(hrec, 0, "{{def}{jk}}");
1554     r = MsiFormatRecord(0, hrec, buffer, &sz);
1555     ok( r == ERROR_SUCCESS, "format failed\n");
1556     ok( sz == 0, "size wrong(%i)\n",sz);
1557     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1558
1559     sz = sizeof buffer;
1560     MsiRecordSetString(hrec, 0, "{{def}}");
1561     r = MsiFormatRecord(0, hrec, buffer, &sz);
1562     ok( r == ERROR_SUCCESS, "format failed\n");
1563     ok( sz == 0, "size wrong(%i)\n",sz);
1564     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
1565
1566     sz = sizeof buffer;
1567     MsiRecordSetString(hrec, 0, "{a{b}c}");
1568     r = MsiFormatRecord(0, hrec, buffer, &sz);
1569     ok( r == ERROR_SUCCESS, "format failed\n");
1570     ok( sz == 7, "size wrong(%i)\n",sz);
1571     ok( 0 == strcmp(buffer,"{a{b}c}"), "wrong output (%s)\n",buffer);
1572
1573     sz = sizeof buffer;
1574     MsiRecordSetString(hrec, 0, "{a{b}}");
1575     r = MsiFormatRecord(0, hrec, buffer, &sz);
1576     ok( r == ERROR_SUCCESS, "format failed\n");
1577     ok( sz == 6, "size wrong(%i)\n",sz);
1578     ok( 0 == strcmp(buffer,"{a{b}}"), "wrong output (%s)\n",buffer);
1579
1580     sz = sizeof buffer;
1581     MsiRecordSetString(hrec, 0, "{{b}c}");
1582     r = MsiFormatRecord(0, hrec, buffer, &sz);
1583     ok( r == ERROR_SUCCESS, "format failed\n");
1584     ok( sz == 6, "size wrong(%i)\n",sz);
1585     ok( 0 == strcmp(buffer,"{{b}c}"), "wrong output (%s)\n",buffer);
1586
1587     sz = sizeof buffer;
1588     MsiRecordSetString(hrec, 0, "{{{{}}}}");
1589     r = MsiFormatRecord(0, hrec, buffer, &sz);
1590     ok( r == ERROR_SUCCESS, "format failed\n");
1591     todo_wine
1592     {
1593         ok( sz == 2, "size wrong(%i)\n",sz);
1594         ok( 0 == strcmp(buffer,"}}"), "wrong output (%s)\n",buffer);
1595     }
1596
1597     sz = sizeof buffer;
1598     MsiRecordSetInteger(hrec, 1, 100);
1599     MsiRecordSetInteger(hrec, 2, -100);
1600     MsiRecordSetString(hrec, 0, "[1] [2]");
1601     r = MsiFormatRecord(0, hrec, buffer, &sz);
1602     ok( r == ERROR_SUCCESS, "format failed\n");
1603     ok( sz == 8, "size wrong(%i)\n",sz);
1604     ok( 0 == strcmp(buffer,"100 -100"), "wrong output (%s)\n",buffer);
1605
1606     sz = sizeof(buffer);
1607     MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
1608     MsiRecordSetString(hrec, 1, "one");
1609     r = MsiFormatRecord(0, hrec, buffer, &sz);
1610     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1611     ok(sz == 33, "Expected 33, got %d\n",sz);
1612     ok(!lstrcmpA(buffer, "one {[noprop] [twoprop]} {abcdef}"),
1613        "Expected \"one {[noprop] [twoprop]} {abcdef}\", got \"%s\"\n", buffer);
1614
1615     sz = sizeof(buffer);
1616     MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
1617     MsiRecordSetString(hrec, 1, "one");
1618     r = MsiFormatRecord(0, hrec, buffer, &sz);
1619     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1620     ok(sz == 29, "Expected 29, got %d\n",sz);
1621     ok(!lstrcmpA(buffer, "one {[noprop] [one]} {abcdef}"),
1622        "Expected \"one {[noprop] [one]} {abcdef}\", got \"%s\"\n", buffer);
1623
1624     sz = sizeof(buffer);
1625     MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
1626     MsiRecordSetString(hrec, 1, "one");
1627     r = MsiFormatRecord(0, hrec, buffer, &sz);
1628     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1629     ok(sz == 20, "Expected 20, got %d\n",sz);
1630     ok(!lstrcmpA(buffer, "one {[one]} {abcdef}"),
1631        "Expected \"one {[one]} {abcdef}\", got \"%s\"\n", buffer);
1632
1633     MsiCloseHandle( hrec );
1634 }
1635
1636 static void test_formatrecord_package(void)
1637 {
1638     char buffer[100];
1639     MSIHANDLE hrec;
1640     MSIHANDLE package;
1641     UINT r;
1642     DWORD sz=100;
1643
1644     r = helper_createpackage( msifile, &package );
1645     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
1646     {
1647         skip("Not enough rights to perform tests\n");
1648         return;
1649     }
1650     ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r );
1651
1652     hrec = MsiCreateRecord(12);
1653     ok( hrec, "failed to create record\n");
1654
1655     r = MsiFormatRecord(package, 0, NULL, NULL );
1656     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
1657
1658     r = MsiFormatRecord(package, hrec, NULL, NULL );
1659     ok( r == ERROR_SUCCESS, "format failed\n");
1660
1661     r = MsiRecordSetString(hrec,0,NULL);
1662     r = MsiRecordSetString(hrec,1,NULL);
1663     r = MsiRecordSetString(hrec,2,NULL);
1664     r = MsiRecordSetString(hrec,3,NULL);
1665     r = MsiRecordSetString(hrec,4,NULL);
1666     r = MsiRecordSetString(hrec,5,NULL);
1667     r = MsiRecordSetString(hrec,6,NULL);
1668     r = MsiRecordSetString(hrec,7,NULL);
1669     r = MsiRecordSetString(hrec,8,NULL);
1670     r = MsiRecordSetString(hrec,9,NULL);
1671     r = MsiRecordSetString(hrec,10,NULL);
1672     r = MsiRecordSetString(hrec,11,NULL);
1673     r = MsiRecordSetString(hrec,12,NULL);
1674     ok( r == ERROR_SUCCESS, "set string failed\n");
1675
1676     sz = sizeof buffer;
1677     r = MsiFormatRecord(package, hrec, buffer, &sz);
1678     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1679     ok( sz == 51, "size wrong (%i)\n",sz);
1680     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
1681
1682     r = MsiSetProperty(package, "prop", "val");
1683     ok( r == ERROR_SUCCESS, "failed to set propertY: %d\n", r);
1684
1685     r = MsiRecordSetString(hrec, 0, NULL);
1686     r = MsiRecordSetString(hrec, 1, "[2]");
1687     r = MsiRecordSetString(hrec, 2, "stuff");
1688     r = MsiRecordSetString(hrec, 3, "prop");
1689     r = MsiRecordSetString(hrec, 4, "[prop]");
1690     r = MsiRecordSetString(hrec, 5, "[noprop]");
1691     sz = sizeof buffer;
1692     r = MsiFormatRecord(package, hrec, buffer, &sz);
1693     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1694     todo_wine
1695     {
1696         ok( sz == 66, "size wrong (%i)\n",sz);
1697         ok( !lstrcmpA(buffer,
1698             "1: [2] 2: stuff 3: prop 4: val 5:  6:  7:  8:  9:  10:  11:  12:  "),
1699             "wrong output(%s)\n",buffer);
1700     }
1701
1702     /* now put play games with escaping */
1703     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
1704     r = MsiRecordSetString(hrec, 1, "boo");
1705     r = MsiRecordSetString(hrec, 2, "hoo");
1706     ok( r == ERROR_SUCCESS, "set string failed\n");
1707     sz = sizeof buffer;
1708     r = MsiFormatRecord(package, hrec, buffer, &sz);
1709     ok( r == ERROR_SUCCESS, "format failed\n");
1710     ok( sz == 9, "size wrong(%i)\n",sz);
1711     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
1712
1713     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
1714     r = MsiRecordSetString(hrec, 1, "boo");
1715     r = MsiRecordSetString(hrec, 2, "hoo");
1716     ok( r == ERROR_SUCCESS, "set string failed\n");
1717     sz = sizeof buffer;
1718     r = MsiFormatRecord(package, hrec, buffer, &sz);
1719     ok( r == ERROR_SUCCESS, "format failed\n");
1720     ok( sz == 9, "size wrong(%i)\n",sz);
1721     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
1722
1723     MsiRecordSetString(hrec, 0, "[\\x]");
1724     sz = sizeof buffer;
1725     r = MsiFormatRecord(package, hrec, buffer, &sz);
1726     ok( r == ERROR_SUCCESS, "format failed\n");
1727     ok( sz == 1, "size wrong: %d\n", sz);
1728     ok( 0 == strcmp(buffer,"x"), "wrong output: %s\n", buffer);
1729
1730     MsiRecordSetString(hrec, 0, "{\\x}");
1731     sz = sizeof buffer;
1732     r = MsiFormatRecord(package, hrec, buffer, &sz);
1733     ok( r == ERROR_SUCCESS, "format failed\n");
1734     ok( sz == 4, "size wrong: %d\n", sz);
1735     ok( 0 == strcmp(buffer,"{\\x}"), "wrong output: %s\n", buffer);
1736
1737     MsiRecordSetString(hrec, 0, "[abc\\x]");
1738     sz = sizeof buffer;
1739     r = MsiFormatRecord(package, hrec, buffer, &sz);
1740     ok( r == ERROR_SUCCESS, "format failed\n");
1741     ok( sz == 0, "size wrong: %d\n", sz);
1742     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
1743
1744     MsiRecordSetString(hrec, 0, "[abc\\xdef]");
1745     sz = sizeof buffer;
1746     r = MsiFormatRecord(package, hrec, buffer, &sz);
1747     ok( r == ERROR_SUCCESS, "format failed\n");
1748     ok( sz == 0, "size wrong: %d\n", sz);
1749     ok( 0 == strcmp(buffer,""), "wrong output: %s\n", buffer);
1750
1751     MsiRecordSetString(hrec, 0, "\\x");
1752     sz = sizeof(buffer);
1753     r = MsiFormatRecord(package, hrec, buffer, &sz);
1754     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1755     ok(sz == 2, "Expected 2, got %d\n", sz);
1756     ok(!lstrcmpA(buffer, "\\x"), "Expected \"\\x\", got \"%s\"\n", buffer);
1757
1758     MsiRecordSetString(hrec, 0, "[\\[");
1759     sz = sizeof(buffer);
1760     r = MsiFormatRecord(package, hrec, buffer, &sz);
1761     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1762     ok(sz == 3, "Expected 3, got %d\n", sz);
1763     ok(!lstrcmpA(buffer, "[\\["), "Expected \"[\\[\", got \"%s\"\n", buffer);
1764
1765     MsiRecordSetString(hrec, 0, "[\\[]");
1766     sz = sizeof(buffer);
1767     r = MsiFormatRecord(package, hrec, buffer, &sz);
1768     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1769     ok(sz == 1, "Expected 1, got %d\n", sz);
1770     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
1771
1772     MsiRecordSetString(hrec, 0, "[[]");
1773     sz = sizeof(buffer);
1774     r = MsiFormatRecord(package, hrec, buffer, &sz);
1775     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1776     ok(sz == 3, "Expected 3, got %d\n", sz);
1777     ok(!lstrcmpA(buffer, "[[]"), "Expected \"[]\", got \"%s\"\n", buffer);
1778
1779     MsiRecordSetString(hrec, 0, "[\\[]]");
1780     sz = sizeof(buffer);
1781     r = MsiFormatRecord(package, hrec, buffer, &sz);
1782     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1783     ok(sz == 2, "Expected 2, got %d\n", sz);
1784     ok(!lstrcmpA(buffer, "[]"), "Expected \"[]\", got \"%s\"\n", buffer);
1785
1786     MsiRecordSetString(hrec, 0, "[\\[a]");
1787     sz = sizeof(buffer);
1788     r = MsiFormatRecord(package, hrec, buffer, &sz);
1789     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1790     ok(sz == 1, "Expected 1, got %d\n", sz);
1791     ok(!lstrcmpA(buffer, "["), "Expected \"[\", got \"%s\"\n", buffer);
1792
1793     MsiRecordSetString(hrec, 0, "[\\a[]");
1794     sz = sizeof(buffer);
1795     r = MsiFormatRecord(package, hrec, buffer, &sz);
1796     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1797     todo_wine
1798     {
1799         ok(sz == 1, "Expected 1, got %d\n", sz);
1800         ok(!lstrcmpA(buffer, "a"), "Expected \"a\", got \"%s\"\n", buffer);
1801     }
1802
1803     MsiRecordSetString(hrec, 0, "[prop]");
1804     sz = sizeof(buffer);
1805     r = MsiFormatRecord(package, hrec, buffer, &sz);
1806     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1807     ok(sz == 3, "Expected 3, got %d\n", sz);
1808     ok(!lstrcmpA(buffer, "val"), "Expected \"val\", got \"%s\"\n", buffer);
1809
1810     MsiRecordSetString(hrec, 0, "[prop] [pro\\pblah] [prop]");
1811     sz = sizeof(buffer);
1812     r = MsiFormatRecord(package, hrec, buffer, &sz);
1813     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1814     ok(sz == 8, "Expected 8, got %d\n", sz);
1815     ok(!lstrcmpA(buffer, "val  val"), "Expected \"val  val\", got \"%s\"\n", buffer);
1816
1817     MsiSetPropertyA(package, "b", "ball");
1818     MsiRecordSetString(hrec, 0, "[\\b]");
1819     sz = sizeof(buffer);
1820     r = MsiFormatRecord(package, hrec, buffer, &sz);
1821     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1822     ok(sz == 1, "Expected 1, got %d\n", sz);
1823     ok(!lstrcmpA(buffer, "b"), "Expected \"b\", got \"%s\"\n", buffer);
1824
1825     MsiRecordSetString(hrec, 0, "[\\c]");
1826     sz = sizeof(buffer);
1827     r = MsiFormatRecord(package, hrec, buffer, &sz);
1828     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1829     ok(sz == 1, "Expected 1, got %d\n", sz);
1830     ok(!lstrcmpA(buffer, "c"), "Expected \"c\", got \"%s\"\n", buffer);
1831
1832     MsiRecordSetString(hrec, 0, "[\\[]prop]");
1833     sz = sizeof(buffer);
1834     r = MsiFormatRecord(package, hrec, buffer, &sz);
1835     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1836     ok(sz == 6, "Expected 6, got %d\n", sz);
1837     ok(!lstrcmpA(buffer, "[prop]"), "Expected \"[prop]\", got \"%s\"\n", buffer);
1838
1839     MsiRecordSetString(hrec, 0, "[\\a]prop]");
1840     sz = sizeof(buffer);
1841     r = MsiFormatRecord(package, hrec, buffer, &sz);
1842     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1843     ok(sz == 6, "Expected 6, got %d\n", sz);
1844     ok(!lstrcmpA(buffer, "aprop]"), "Expected \"aprop]\", got \"%s\"\n", buffer);
1845
1846     MsiRecordSetString(hrec, 0, "[\\[]Bracket Text[\\]]");
1847     sz = sizeof buffer;
1848     r = MsiFormatRecord(package, hrec, buffer, &sz);
1849     ok( r == ERROR_SUCCESS, "format failed\n");
1850     ok( sz == 14, "size wrong: %d\n", sz);
1851     ok( 0 == strcmp(buffer,"[Bracket Text]"), "wrong output: %s\n", buffer);
1852
1853     /* null characters */
1854     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
1855     r = MsiRecordSetString(hrec, 1, "boo");
1856     r = MsiRecordSetString(hrec, 2, "hoo");
1857     ok( r == ERROR_SUCCESS, "set string failed\n");
1858     sz = sizeof buffer;
1859     r = MsiFormatRecord(package, hrec, buffer, &sz);
1860     ok( r == ERROR_SUCCESS, "format failed\n");
1861     ok( sz == 9, "size wrong: %d\n", sz);
1862     ok( 0 == strcmp(buffer,"boo "), "wrong output: %s\n", buffer);
1863     ok(!lstrcmpA(&buffer[5], " hoo"),
1864        "Expected \" hoo\", got \"%s\"\n", &buffer[5]);
1865
1866     MsiRecordSetString(hrec, 0, "[1] [~abc] [2]");
1867     MsiRecordSetString(hrec, 1, "boo");
1868     MsiRecordSetString(hrec, 2, "hoo");
1869     sz = sizeof(buffer);
1870     r = MsiFormatRecord(package, hrec, buffer, &sz);
1871     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
1872     ok(sz == 8, "Expected 8, got %d\n", sz);
1873     ok(!lstrcmpA(buffer, "boo  hoo"), "Expected \"boo  hoo\", got \"%s\"\n", buffer);
1874
1875     /* properties */
1876     r = MsiSetProperty(package,"dummy","Bork");
1877     ok( r == ERROR_SUCCESS, "set property failed\n");
1878     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
1879     r = MsiRecordSetString(hrec, 1, "boo");
1880     r = MsiRecordSetString(hrec, 2, "hoo");
1881     ok( r == ERROR_SUCCESS, "set string failed\n");
1882     sz = sizeof buffer;
1883     r = MsiFormatRecord(package, hrec, buffer, &sz);
1884     ok( r == ERROR_SUCCESS, "format failed\n");
1885     ok( sz == 12, "size wrong\n");
1886     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
1887
1888     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
1889     r = MsiRecordSetString(hrec, 1, "boo");
1890     r = MsiRecordSetString(hrec, 2, "hoo");
1891     ok( r == ERROR_SUCCESS, "set string failed\n");
1892     sz = sizeof buffer;
1893     r = MsiFormatRecord(package, hrec, buffer, &sz);
1894     ok( r == ERROR_SUCCESS, "format failed\n");
1895     ok( sz == 8, "size wrong\n");
1896     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
1897
1898     /* nesting tests */
1899     r = MsiSetProperty(package,"dummya","foo");
1900     r = MsiSetProperty(package,"dummyb","baa");
1901     r = MsiSetProperty(package,"adummyc","whoa");
1902     ok( r == ERROR_SUCCESS, "set property failed\n");
1903     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
1904     r = MsiRecordSetString(hrec, 1, "a");
1905     r = MsiRecordSetString(hrec, 2, "b");
1906     r = MsiRecordSetString(hrec, 3, "c");
1907     ok( r == ERROR_SUCCESS, "set string failed\n");
1908     sz = sizeof buffer;
1909     r = MsiFormatRecord(package, hrec, buffer, &sz);
1910     ok( r == ERROR_SUCCESS, "format failed\n");
1911     ok( sz == 12, "size wrong(%i)\n",sz);
1912     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
1913
1914     r = MsiSetProperty(package,"dummya","1");
1915     r = MsiSetProperty(package,"dummyb","[2]");
1916     ok( r == ERROR_SUCCESS, "set property failed\n");
1917     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
1918     r = MsiRecordSetString(hrec, 1, "aaa");
1919     r = MsiRecordSetString(hrec, 2, "bbb");
1920     r = MsiRecordSetString(hrec, 3, "ccc");
1921     ok( r == ERROR_SUCCESS, "set string failed\n");
1922     sz = sizeof buffer;
1923     r = MsiFormatRecord(package, hrec, buffer, &sz);
1924     ok( r == ERROR_SUCCESS, "format failed\n");
1925     todo_wine
1926     {
1927         ok( sz == 9, "size wrong(%i)\n",sz);
1928         ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
1929     }
1930
1931     r = MsiSetProperty(package,"dummya","1");
1932     r = MsiSetProperty(package,"dummyb","a");
1933     r = MsiSetProperty(package,"dummyc","\\blath");
1934     r = MsiSetProperty(package,"dummyd","[\\blath]");
1935     ok( r == ERROR_SUCCESS, "set property failed\n");
1936     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
1937     r = MsiRecordSetString(hrec, 1, "aaa");
1938     r = MsiRecordSetString(hrec, 2, "bbb");
1939     r = MsiRecordSetString(hrec, 3, "ccc");
1940     ok( r == ERROR_SUCCESS, "set string failed\n");
1941     sz = sizeof buffer;
1942     r = MsiFormatRecord(package, hrec, buffer, &sz);
1943     ok( r == ERROR_SUCCESS, "format failed\n");
1944     ok( sz == 10, "size wrong(%i)\n",sz);
1945     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
1946
1947     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
1948     r = MsiRecordSetString(hrec, 1, "boo");
1949     r = MsiRecordSetString(hrec, 2, "hoo");
1950     r = MsiRecordSetString(hrec, 3, "yeah");
1951     ok( r == ERROR_SUCCESS, "set string failed\n");
1952     sz = sizeof buffer;
1953     r = MsiFormatRecord(package, hrec, buffer, &sz);
1954     ok( r == ERROR_SUCCESS, "format failed\n");
1955     todo_wine
1956     {
1957         ok( sz == 11, "size wrong(%i)\n",sz);
1958         ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
1959     }
1960
1961     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
1962     r = MsiRecordSetString(hrec, 1, "boo");
1963     r = MsiRecordSetString(hrec, 2, "hoo");
1964     r = MsiRecordSetString(hrec, 3, "\\help");
1965     ok( r == ERROR_SUCCESS, "set string failed\n");
1966     sz = sizeof buffer;
1967     r = MsiFormatRecord(package, hrec, buffer, &sz);
1968     ok( r == ERROR_SUCCESS, "format failed\n");
1969     ok( sz == 9, "size wrong(%i)\n",sz);
1970     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
1971
1972     /* nested properties */
1973     MsiSetProperty(package, "PropA", "surprise");
1974     MsiSetProperty(package, "PropB", "[PropA]");
1975     MsiSetProperty(package, "PropC", "[PropB]");
1976     sz = sizeof buffer;
1977     MsiRecordSetString(hrec, 0, "[PropC]");
1978     r = MsiFormatRecord(package, hrec, buffer, &sz);
1979     ok( r == ERROR_SUCCESS, "format failed\n");
1980     ok( sz == 7, "size wrong(%i)\n",sz);
1981     ok( 0 == strcmp(buffer,"[PropB]"), "wrong output (%s)\n",buffer);
1982
1983     MsiSetProperty(package, "PropA", "surprise");
1984     MsiSetProperty(package, "PropB", "PropA");
1985     MsiSetProperty(package, "PropC", "PropB");
1986     sz = sizeof buffer;
1987     MsiRecordSetString(hrec, 0, "[PropC]");
1988     r = MsiFormatRecord(package, hrec, buffer, &sz);
1989     ok( r == ERROR_SUCCESS, "format failed\n");
1990     ok( sz == 5, "size wrong(%i)\n",sz);
1991     ok( 0 == strcmp(buffer,"PropB"), "wrong output (%s)\n",buffer);
1992
1993     MsiSetProperty(package, "PropA", "surprise");
1994     MsiSetProperty(package, "PropB", "[PropA]");
1995     MsiSetProperty(package, "PropC", "[PropB]");
1996     sz = sizeof buffer;
1997     MsiRecordSetString(hrec, 0, "[[PropC]]");
1998     r = MsiFormatRecord(package, hrec, buffer, &sz);
1999     ok( r == ERROR_SUCCESS, "format failed\n");
2000     ok( sz == 0, "size wrong(%i)\n",sz);
2001     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2002
2003     MsiSetProperty(package, "PropA", "surprise");
2004     MsiSetProperty(package, "PropB", "[PropA]");
2005     MsiSetProperty(package, "PropC", "PropB");
2006     sz = sizeof buffer;
2007     MsiRecordSetString(hrec, 0, "[[PropC]]");
2008     r = MsiFormatRecord(package, hrec, buffer, &sz);
2009     ok( r == ERROR_SUCCESS, "format failed\n");
2010     ok( sz == 7, "size wrong(%i)\n",sz);
2011     ok( 0 == strcmp(buffer,"[PropA]"), "wrong output (%s)\n",buffer);
2012
2013     MsiSetProperty(package, "PropA", "surprise");
2014     MsiSetProperty(package, "PropB", "PropA");
2015     MsiSetProperty(package, "PropC", "PropB");
2016     sz = sizeof buffer;
2017     MsiRecordSetString(hrec, 0, "[[PropC]]");
2018     r = MsiFormatRecord(package, hrec, buffer, &sz);
2019     ok( r == ERROR_SUCCESS, "format failed\n");
2020     ok( sz == 5, "size wrong(%i)\n",sz);
2021     ok( 0 == strcmp(buffer,"PropA"), "wrong output (%s)\n",buffer);
2022
2023     MsiSetProperty(package, "PropA", "surprise");
2024     MsiSetProperty(package, "PropB", "PropA");
2025     MsiSetProperty(package, "PropC", "PropB");
2026     sz = sizeof buffer;
2027     MsiRecordSetString(hrec, 0, "[[[PropC]]]");
2028     r = MsiFormatRecord(package, hrec, buffer, &sz);
2029     ok( r == ERROR_SUCCESS, "format failed\n");
2030     ok( sz == 8, "size wrong(%i)\n",sz);
2031     ok( 0 == strcmp(buffer,"surprise"), "wrong output (%s)\n",buffer);
2032
2033     /* properties inside braces */
2034     sz = sizeof buffer;
2035     MsiRecordSetString(hrec, 0, "{abcd}");
2036     r = MsiFormatRecord(package, hrec, buffer, &sz);
2037     ok( r == ERROR_SUCCESS, "format failed\n");
2038     ok( sz == 6, "size wrong(%i)\n",sz);
2039     ok( 0 == strcmp(buffer,"{abcd}"), "wrong output (%s)\n",buffer);
2040
2041     MsiSetProperty(package, "one", "mercury");
2042     MsiSetProperty(package, "two", "venus");
2043     sz = sizeof buffer;
2044     MsiRecordSetString(hrec, 0, "{a[one]bc[two]de[one]f}");
2045     r = MsiFormatRecord(package, hrec, buffer, &sz);
2046     ok( r == ERROR_SUCCESS, "format failed: %d\n", r);
2047     ok( sz == 25, "size wrong(%i)\n",sz);
2048     ok( 0 == strcmp(buffer,"amercurybcvenusdemercuryf"), "wrong output (%s)\n",buffer);
2049
2050     MsiSetProperty(package, "one", "mercury");
2051     MsiSetProperty(package, "two", "venus");
2052     MsiSetProperty(package, "bad", "");
2053     sz = sizeof buffer;
2054     MsiRecordSetString(hrec, 0, "{a[one]bc[bad]de[two]f}");
2055     r = MsiFormatRecord(package, hrec, buffer, &sz);
2056     ok( r == ERROR_SUCCESS, "format failed\n");
2057     ok( sz == 0, "size wrong(%i)\n",sz);
2058     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2059
2060     MsiSetProperty(package, "bad", "");
2061     sz = sizeof buffer;
2062     MsiRecordSetString(hrec, 0, "{[bad]}");
2063     r = MsiFormatRecord(package, hrec, buffer, &sz);
2064     ok( r == ERROR_SUCCESS, "format failed\n");
2065     ok( sz == 0, "size wrong(%i)\n",sz);
2066     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2067
2068     MsiSetProperty(package, "one", "mercury");
2069     sz = sizeof buffer;
2070     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}"); /* missing final brace */
2071     r = MsiFormatRecord(package, hrec, buffer, &sz);
2072     ok( r == ERROR_SUCCESS, "format failed\n");
2073     todo_wine
2074     {
2075         ok( sz == 14, "size wrong(%i)\n",sz);
2076         ok( 0 == strcmp(buffer,"abc{dmercuryef"), "wrong output (%s)\n",buffer);
2077     }
2078
2079     MsiSetProperty(package, "one", "mercury");
2080     sz = sizeof buffer;
2081     MsiRecordSetString(hrec, 0, "{abc{d[one]ef}}");
2082     r = MsiFormatRecord(package, hrec, buffer, &sz);
2083     ok( r == ERROR_SUCCESS, "format failed\n");
2084     todo_wine
2085     {
2086         ok( sz == 15, "size wrong(%i)\n",sz);
2087         ok( 0 == strcmp(buffer,"abc{dmercuryef}"), "wrong output (%s)\n",buffer);
2088     }
2089
2090     MsiSetProperty(package, "one", "mercury");
2091     sz = sizeof buffer;
2092     MsiRecordSetString(hrec, 0, "{abc}{{def}hi{j[one]k}}");
2093     r = MsiFormatRecord(package, hrec, buffer, &sz);
2094     ok( r == ERROR_SUCCESS, "format failed\n");
2095     ok( sz == 5, "size wrong(%i)\n",sz);
2096     ok( 0 == strcmp(buffer,"{abc}"), "wrong output (%s)\n",buffer);
2097
2098     MsiSetProperty(package, "one", "mercury");
2099
2100     sz = sizeof buffer;
2101     MsiRecordSetString(hrec, 0, "{{def}hi{j[one]k}}");
2102     r = MsiFormatRecord(package, hrec, buffer, &sz);
2103     ok( r == ERROR_SUCCESS, "format failed\n");
2104     ok( sz == 0, "size wrong(%i)\n",sz);
2105     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
2106
2107     sz = sizeof(buffer);
2108     MsiRecordSetString(hrec, 0, "[1] {[noprop] [twoprop]} {abcdef}");
2109     MsiRecordSetString(hrec, 1, "one");
2110     r = MsiFormatRecord(package, hrec, buffer, &sz);
2111     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2112     ok(sz == 13, "Expected 13, got %d\n",sz);
2113     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2114        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2115
2116     sz = sizeof(buffer);
2117     MsiRecordSetString(hrec, 0, "[1] {[noprop] [one]} {abcdef}");
2118     MsiRecordSetString(hrec, 1, "one");
2119     r = MsiFormatRecord(package, hrec, buffer, &sz);
2120     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2121     ok(sz == 13, "Expected 13, got %d\n",sz);
2122     ok(!lstrcmpA(buffer, "one  {abcdef}"),
2123        "Expected \"one  {abcdef}\", got \"%s\"\n", buffer);
2124
2125     sz = sizeof(buffer);
2126     MsiRecordSetString(hrec, 0, "[1] {[one]} {abcdef}");
2127     MsiRecordSetString(hrec, 1, "one");
2128     r = MsiFormatRecord(package, hrec, buffer, &sz);
2129     ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2130     ok(sz == 20, "Expected 20, got %d\n",sz);
2131     ok(!lstrcmpA(buffer, "one mercury {abcdef}"),
2132        "Expected \"one mercury {abcdef}\", got \"%s\"\n", buffer);
2133
2134     MsiCloseHandle(hrec);
2135
2136     r = MsiCloseHandle(package);
2137     ok(r==ERROR_SUCCESS, "Unable to close package\n");
2138
2139     DeleteFile( msifile );
2140 }
2141
2142 static void test_formatrecord_tables(void)
2143 {
2144     MSIHANDLE hdb, hrec, hpkg = 0;
2145     CHAR buf[MAX_PATH];
2146     CHAR curr_dir[MAX_PATH];
2147     CHAR expected[MAX_PATH];
2148     CHAR root[MAX_PATH];
2149     DWORD size;
2150     UINT r;
2151
2152     GetCurrentDirectory( MAX_PATH, curr_dir );
2153
2154     hdb = create_package_db();
2155     ok ( hdb, "failed to create package database\n");
2156
2157     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
2158     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2159
2160     r = add_directory_entry( hdb, "'ReallyLongDir', 'TARGETDIR', "
2161                              "'I am a really long directory'" );
2162     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r);
2163
2164     r = create_feature_table( hdb );
2165     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r);
2166
2167     r = add_feature_entry( hdb, "'occipitofrontalis', '', '', '', 2, 1, '', 0" );
2168     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2169
2170     r = create_component_table( hdb );
2171     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r);
2172
2173     r = add_component_entry( hdb, "'frontal', '', 'TARGETDIR', 0, '', 'frontal_file'" );
2174     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2175
2176     r = add_component_entry( hdb, "'parietal', '', 'TARGETDIR', 1, '', 'parietal_file'" );
2177     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2178
2179     r = add_component_entry( hdb, "'temporal', '', 'ReallyLongDir', 0, '', 'temporal_file'" );
2180     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r);
2181
2182     r = create_feature_components_table( hdb );
2183     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r);
2184
2185     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'frontal'" );
2186     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2187
2188     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'parietal'" );
2189     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2190
2191     r = add_feature_components_entry( hdb, "'occipitofrontalis', 'temporal'" );
2192     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r);
2193
2194     r = create_file_table( hdb );
2195     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r);
2196
2197     r = add_file_entry( hdb, "'frontal_file', 'frontal', 'frontal.txt', 0, '', '1033', 8192, 1" );
2198     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2199
2200     r = add_file_entry( hdb, "'parietal_file', 'parietal', 'parietal.txt', 0, '', '1033', 8192, 1" );
2201     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2202
2203     r = add_file_entry( hdb, "'temporal_file', 'temporal', 'temporal.txt', 0, '', '1033', 8192, 1" );
2204     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2205
2206     r = create_custom_action_table( hdb );
2207     ok( r == ERROR_SUCCESS, "cannot create CustomAction table: %d\n", r);
2208
2209     r = add_custom_action_entry( hdb, "'MyCustom', 51, 'prop', '[!temporal_file]'" );
2210     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2211
2212     r = add_custom_action_entry( hdb, "'EscapeIt1', 51, 'prop', '[\\[]Bracket Text[\\]]'" );
2213     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2214
2215     r = add_custom_action_entry( hdb, "'EscapeIt2', 51, 'prop', '[\\xabcd]'" );
2216     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2217
2218     r = add_custom_action_entry( hdb, "'EscapeIt3', 51, 'prop', '[abcd\\xefgh]'" );
2219     ok( r == ERROR_SUCCESS, "cannt add custom action: %d\n", r);
2220
2221     r = package_from_db( hdb, &hpkg );
2222     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2223     {
2224         skip("Not enough rights to perform tests\n");
2225         MsiCloseHandle( hdb );
2226         DeleteFile( msifile );
2227         return;
2228     }
2229     ok( r == ERROR_SUCCESS, "failed to create package %u\n", r );
2230
2231     MsiCloseHandle( hdb );
2232
2233     r = MsiSetPropertyA( hpkg, "imaprop", "ringer" );
2234     ok( r == ERROR_SUCCESS, "cannot set property: %d\n", r);
2235
2236     hrec = MsiCreateRecord( 1 );
2237
2238     /* property doesn't exist */
2239     size = MAX_PATH;
2240     /*MsiRecordSetString( hrec, 0, "[1]" ); */
2241     MsiRecordSetString( hrec, 1, "[idontexist]" );
2242     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2243     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2244     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2245
2246     /* property exists */
2247     size = MAX_PATH;
2248     MsiRecordSetString( hrec, 1, "[imaprop]" );
2249     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2250     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2251     ok( !lstrcmp( buf, "1: ringer " ), "Expected '1: ringer ', got %s\n", buf );
2252
2253     /* environment variable doesn't exist */
2254     size = MAX_PATH;
2255     MsiRecordSetString( hrec, 1, "[%idontexist]" );
2256     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2257     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2258     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2259
2260     /* environment variable exists */
2261     size = MAX_PATH;
2262     SetEnvironmentVariable( "crazyvar", "crazyval" );
2263     MsiRecordSetString( hrec, 1, "[%crazyvar]" );
2264     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2265     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2266     ok( !lstrcmp( buf, "1: crazyval " ), "Expected '1: crazyval ', got %s\n", buf );
2267
2268     /* file key before CostInitialize */
2269     size = MAX_PATH;
2270     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2271     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2272     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2273     ok( !lstrcmp( buf, "1:  " ), "Expected '1:  ', got %s\n", buf );
2274
2275     MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
2276
2277     r = MsiDoAction(hpkg, "CostInitialize");
2278     ok( r == ERROR_SUCCESS, "CostInitialize failed: %d\n", r);
2279
2280     r = MsiDoAction(hpkg, "FileCost");
2281     ok( r == ERROR_SUCCESS, "FileCost failed: %d\n", r);
2282
2283     r = MsiDoAction(hpkg, "CostFinalize");
2284     ok( r == ERROR_SUCCESS, "CostFinalize failed: %d\n", r);
2285
2286     size = MAX_PATH;
2287     MsiGetProperty( hpkg, "ROOTDRIVE", root, &size );
2288
2289     sprintf( expected, "1: %sfrontal.txt ", root);
2290
2291     /* frontal full file key */
2292     size = MAX_PATH;
2293     MsiRecordSetString( hrec, 1, "[#frontal_file]" );
2294     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2295     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2296     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2297
2298     /* frontal short file key */
2299     size = MAX_PATH;
2300     MsiRecordSetString( hrec, 1, "[!frontal_file]" );
2301     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2302     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2303     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2304
2305     sprintf( expected, "1: %sI am a really long directory\\temporal.txt ", root);
2306
2307     /* temporal full file key */
2308     size = MAX_PATH;
2309     MsiRecordSetString( hrec, 1, "[#temporal_file]" );
2310     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2311     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2312     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2313
2314     /* temporal short file key */
2315     size = MAX_PATH;
2316     MsiRecordSetString( hrec, 1, "[!temporal_file]" );
2317     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2318     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2319     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2320
2321     /* custom action 51, files don't exist */
2322     r = MsiDoAction( hpkg, "MyCustom" );
2323     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2324
2325     sprintf( expected, "%sI am a really long directory\\temporal.txt", root);
2326
2327     size = MAX_PATH;
2328     r = MsiGetProperty( hpkg, "prop", buf, &size );
2329     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2330     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2331
2332     sprintf( buf, "%sI am a really long directory", root );
2333     CreateDirectory( buf, NULL );
2334
2335     lstrcat( buf, "\\temporal.txt" );
2336     create_test_file( buf );
2337
2338     /* custom action 51, files exist */
2339     r = MsiDoAction( hpkg, "MyCustom" );
2340     ok( r == ERROR_SUCCESS, "MyCustom failed: %d\n", r);
2341
2342     size = MAX_PATH;
2343     r = MsiGetProperty( hpkg, "prop", buf, &size );
2344     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2345     todo_wine
2346     {
2347         ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2348     }
2349
2350     /* custom action 51, escaped text 1 */
2351     r = MsiDoAction( hpkg, "EscapeIt1" );
2352     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2353
2354     size = MAX_PATH;
2355     r = MsiGetProperty( hpkg, "prop", buf, &size );
2356     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2357     ok( !lstrcmp( buf, "[Bracket Text]" ), "Expected '[Bracket Text]', got %s\n", buf);
2358
2359     /* custom action 51, escaped text 2 */
2360     r = MsiDoAction( hpkg, "EscapeIt2" );
2361     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2362
2363     size = MAX_PATH;
2364     r = MsiGetProperty( hpkg, "prop", buf, &size );
2365     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2366     ok( !lstrcmp( buf, "x" ), "Expected 'x', got %s\n", buf);
2367
2368     /* custom action 51, escaped text 3 */
2369     r = MsiDoAction( hpkg, "EscapeIt3" );
2370     ok( r == ERROR_SUCCESS, "EscapeIt failed: %d\n", r);
2371
2372     size = MAX_PATH;
2373     r = MsiGetProperty( hpkg, "prop", buf, &size );
2374     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2375     ok( !lstrcmp( buf, "" ), "Expected '', got %s\n", buf);
2376
2377     sprintf( expected, "1: %sI am a really long directory\\ ", root);
2378
2379     /* component with INSTALLSTATE_LOCAL */
2380     size = MAX_PATH;
2381     MsiRecordSetString( hrec, 1, "[$temporal]" );
2382     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2383     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2384     ok( !lstrcmp( buf, expected ), "Expected \"%s\", got \"%s\"\n", expected, buf);
2385
2386     r = MsiSetComponentState( hpkg, "temporal", INSTALLSTATE_SOURCE );
2387     ok( r == ERROR_SUCCESS, "failed to set install state: %d\n", r);
2388
2389     /* component with INSTALLSTATE_SOURCE */
2390     lstrcpy( expected, "1: " );
2391     lstrcat( expected, curr_dir );
2392     if (strlen(curr_dir) > 3)
2393         lstrcat( expected, "\\" );
2394     lstrcat( expected, " " );
2395     size = MAX_PATH;
2396     MsiRecordSetString( hrec, 1, "[$parietal]" );
2397     r = MsiFormatRecord( hpkg, hrec, buf, &size );
2398     ok( r == ERROR_SUCCESS, "format record failed: %d\n", r);
2399     ok( !lstrcmp( buf, expected ), "Expected '%s', got '%s'\n", expected, buf);
2400
2401     sprintf( buf, "%sI am a really long directory\\temporal.txt", root );
2402     DeleteFile( buf );
2403
2404     sprintf( buf, "%sI am a really long directory", root );
2405     RemoveDirectory( buf );
2406
2407     MsiCloseHandle( hrec );
2408     MsiCloseHandle( hpkg );
2409     DeleteFile( msifile );
2410 }
2411
2412 static void test_processmessage(void)
2413 {
2414     MSIHANDLE hrec, package;
2415     UINT r;
2416
2417     MsiSetInternalUI(INSTALLUILEVEL_BASIC, NULL);
2418
2419     r = helper_createpackage( msifile, &package );
2420     if (r == ERROR_INSTALL_PACKAGE_REJECTED)
2421     {
2422         skip("Not enough rights to perform tests\n");
2423         return;
2424     }
2425     ok( r == ERROR_SUCCESS, "Unable to create package %u\n", r );
2426
2427     hrec = MsiCreateRecord(3);
2428     ok( hrec, "failed to create record\n");
2429
2430     r = MsiRecordSetString(hrec, 1, "");
2431     ok( r == ERROR_SUCCESS, "set string failed\n");
2432
2433     r = MsiProcessMessage(package, INSTALLMESSAGE_ACTIONSTART, hrec);
2434     ok( r == IDOK, "expected IDOK, got %i\n", r);
2435
2436     MsiCloseHandle(hrec);
2437     MsiCloseHandle(package);
2438
2439     DeleteFile(msifile);
2440 }
2441
2442 START_TEST(format)
2443 {
2444     test_createpackage();
2445     test_formatrecord();
2446     test_formatrecord_package();
2447     test_formatrecord_tables();
2448     test_processmessage();
2449 }