Update the address of the Free Software Foundation.
[wine] / dlls / msi / tests / format.c
1 /*
2  * Copyright (C) 2005 Mike McCormack for CodeWeavers
3  * Copyright (C) 2005 Aric Stewart for CodeWeavers
4  *
5  * A test program for MSI record formatting
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #include <stdio.h>
23 #include <windows.h>
24 #include <msi.h>
25 #include <msiquery.h>
26
27 #include "wine/test.h"
28
29 static MSIHANDLE helper_createpackage( const char *szName )
30 {
31     MSIHANDLE hdb = 0;
32     UINT res;
33     CHAR szPackage[10];
34     MSIHANDLE hPackage;
35     MSIHANDLE suminfo;
36
37     DeleteFile(szName);
38
39     /* create an empty database */
40     res = MsiOpenDatabase(szName, MSIDBOPEN_CREATE, &hdb );
41     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
42
43     res = MsiDatabaseCommit( hdb );
44     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
45
46     /* build summmary info */
47     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
48     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
49
50     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
51                         "Installation Database");
52     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
53
54     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
55                         "Installation Database");
56     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
57
58     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
59                         "Wine Hackers");
60     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
61
62     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
63                     ";1033");
64     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
65
66     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
67                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
68     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
69
70     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
71     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
72
73     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
74     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
75
76     res = MsiSummaryInfoPersist(suminfo);
77     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
78
79     res = MsiCloseHandle( suminfo);
80     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
81
82     sprintf(szPackage,"#%li",(DWORD)hdb);
83     res = MsiOpenPackage(szPackage,&hPackage);
84     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
85
86     res = MsiCloseHandle( hdb );
87     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
88
89     return hPackage;
90 }
91
92 static void test_createpackage(void)
93 {
94     static const CHAR filename[] = "winetest.msi";
95     MSIHANDLE hPackage = 0;
96     UINT res;
97
98     hPackage = helper_createpackage( filename );
99     ok ( hPackage != 0, " Failed to create package\n");
100
101     res = MsiCloseHandle( hPackage);
102     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
103
104     DeleteFile( filename );
105 }
106
107 static void test_formatrecord(void)
108 {
109     char buffer[100];
110     MSIHANDLE hrec;
111     UINT r;
112     DWORD sz;
113
114     r = MsiFormatRecord(0, 0, NULL, NULL );
115     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
116
117     hrec = MsiCreateRecord(4);
118     ok( hrec, "failed to create record\n");
119
120     /* format an empty record */
121     r = MsiFormatRecord(0, hrec, NULL, NULL );
122     ok( r == ERROR_SUCCESS, "format failed\n");
123     buffer[0] = 'x';
124     buffer[1] = 0;
125     sz=0;
126     r = MsiFormatRecord(0, hrec, buffer+1, &sz);
127     ok( r == ERROR_MORE_DATA && buffer[0] == 'x', "format failed measuring with buffer\n");
128     ok( sz == 16, "size wrong\n");
129     sz=100;
130     r = MsiFormatRecord(0, hrec, buffer, &sz);
131     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
132     ok( sz == 16, "size wrong\n");
133     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  "), "wrong output\n");
134
135     r = MsiCloseHandle(hrec);
136     ok(r==ERROR_SUCCESS, "Unable to close record\n");
137
138     hrec = MsiCreateRecord(6);
139     ok( hrec, "failed to create record\n");
140
141     sz = 100;
142     buffer[0] = 'x';
143     buffer[1] = 0;
144     r = MsiFormatRecord(0, hrec, buffer, &sz);
145     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
146     ok( sz == 24, "size wrong\n");
147     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  "), "wrong output\n");
148
149
150     /* format a format string with everything else empty */
151     r = MsiRecordSetString(hrec, 0, "%1");
152     ok( r == ERROR_SUCCESS, "set string failed\n");
153     r = MsiFormatRecord(0, hrec, NULL, NULL );
154     ok( r == ERROR_SUCCESS, "format failed\n");
155     r = MsiFormatRecord(0, hrec, buffer, NULL);
156     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
157
158     sz = 123;
159     r = MsiFormatRecord(0, hrec, NULL, &sz);
160     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
161     ok( sz == 2, "size wrong (%li)\n",sz);
162     sz = sizeof buffer;
163     buffer[0] = 'x';
164     buffer[1] = 0;
165     r = MsiFormatRecord(0, hrec, buffer, &sz);
166     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
167     ok( sz == 2, "size wrong\n");
168     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
169
170     /* make the buffer too small */
171     sz = 0;
172     buffer[0] = 'x';
173     buffer[1] = 0;
174     r = MsiFormatRecord(0, hrec, buffer, &sz);
175     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
176     ok( sz == 2, "size wrong\n");
177     ok( 0 == strcmp(buffer,"x"), "wrong output\n");
178
179     /* make the buffer a little bit bigger */
180     sz = 1;
181     buffer[0] = 'x';
182     buffer[1] = 0;
183     r = MsiFormatRecord(0, hrec, buffer, &sz);
184     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
185     ok( sz == 2, "size wrong\n");
186     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
187
188     /* and again */
189     sz = 2;
190     buffer[0] = 'x';
191     buffer[1] = 0;
192     r = MsiFormatRecord(0, hrec, buffer, &sz);
193     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
194     ok( sz == 2, "size wrong\n");
195     ok( 0 == strcmp(buffer,"%"), "wrong output\n");
196
197     /* and again */
198     sz = 3;
199     buffer[0] = 'x';
200     buffer[1] = 0;
201     r = MsiFormatRecord(0, hrec, buffer, &sz);
202     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
203     ok( sz == 2, "size wrong\n");
204     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
205
206     /* now try a real format string */
207     r = MsiRecordSetString(hrec, 0, "[1]");
208     ok( r == ERROR_SUCCESS, "set string failed\n");
209     sz = sizeof buffer;
210     r = MsiFormatRecord(0, hrec, buffer, &sz);
211     ok( r == ERROR_SUCCESS, "format failed\n");
212     ok( sz == 0, "size wrong\n");
213     ok( 0 == strcmp(buffer,""), "wrong output\n");
214
215     /* now put something in the first field */
216     r = MsiRecordSetString(hrec, 1, "boo hoo");
217     ok( r == ERROR_SUCCESS, "set string failed\n");
218     sz = sizeof buffer;
219     r = MsiFormatRecord(0, hrec, buffer, &sz);
220     ok( r == ERROR_SUCCESS, "format failed\n");
221     ok( sz == 7, "size wrong\n");
222     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
223
224     /* now put something in the first field */
225     r = MsiRecordSetString(hrec, 0, "[1] [2]");
226     r = MsiRecordSetString(hrec, 1, "boo");
227     r = MsiRecordSetString(hrec, 2, "hoo");
228     ok( r == ERROR_SUCCESS, "set string failed\n");
229     sz = sizeof buffer;
230     r = MsiFormatRecord(0, hrec, buffer, &sz);
231     ok( r == ERROR_SUCCESS, "format failed\n");
232     ok( sz == 7, "size wrong\n");
233     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
234
235
236     /* empty string */
237     r = MsiRecordSetString(hrec, 0, "");
238     sz = sizeof buffer;
239     r = MsiFormatRecord(0, hrec, buffer, &sz);
240     ok( r == ERROR_SUCCESS, "format failed\n");
241     ok( sz == 30, "size wrong %li\n",sz);
242     ok( 0 == strcmp(buffer,"1: boo 2: hoo 3:  4:  5:  6:  "), 
243                     "wrong output(%s)\n",buffer);
244
245     /* play games with recursive lookups */
246     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
247     r = MsiRecordSetString(hrec, 1, "2");
248     r = MsiRecordSetString(hrec, 2, "hey");
249     ok( r == ERROR_SUCCESS, "set string failed\n");
250     sz = sizeof buffer;
251     r = MsiFormatRecord(0, hrec, buffer, &sz);
252     ok( r == ERROR_SUCCESS, "format failed\n");
253     ok( sz == 7, "size wrong,(%li)\n",sz);
254     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
255
256     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
257     r = MsiRecordSetString(hrec, 1, "[2]");
258     r = MsiRecordSetString(hrec, 2, "hey");
259     ok( r == ERROR_SUCCESS, "set string failed\n");
260     sz = sizeof buffer;
261     r = MsiFormatRecord(0, hrec, buffer, &sz);
262     ok( r == ERROR_SUCCESS, "format failed\n");
263     ok( sz == 9, "size wrong,(%li)\n",sz);
264     ok( 0 == strcmp(buffer,"[[2]] hey"), "wrong output (%s)\n",buffer);
265
266     r = MsiRecordSetString(hrec, 0, "[[[3]]] [2]");
267     r = MsiRecordSetString(hrec, 1, "2");
268     r = MsiRecordSetString(hrec, 2, "hey");
269     r = MsiRecordSetString(hrec, 3, "1");
270     ok( r == ERROR_SUCCESS, "set string failed\n");
271     sz = sizeof buffer;
272     r = MsiFormatRecord(0, hrec, buffer, &sz);
273     ok( r == ERROR_SUCCESS, "format failed\n");
274     ok( sz == 7, "size wrong,(%li)\n",sz);
275     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
276
277     r = MsiCloseHandle(hrec);
278     ok(r==ERROR_SUCCESS, "Unable to close record\n");
279     hrec = MsiCreateRecord(12);
280     ok( hrec, "failed to create record\n");
281
282     r = MsiRecordSetString(hrec, 0, "[[3][1]] [2]");
283     r = MsiRecordSetString(hrec, 1, "2");
284     r = MsiRecordSetString(hrec, 2, "hey");
285     r = MsiRecordSetString(hrec, 3, "1");
286     r = MsiRecordSetString(hrec, 12, "big");
287     ok( r == ERROR_SUCCESS, "set string failed\n");
288     sz = sizeof buffer;
289     r = MsiFormatRecord(0, hrec, buffer, &sz);
290     ok( r == ERROR_SUCCESS, "format failed\n");
291     ok( sz == 7, "size wrong,(%li)\n",sz);
292     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
293
294     r = MsiRecordSetString(hrec, 0, "[[3][4][1]] [2]");
295     r = MsiRecordSetString(hrec, 1, "2");
296     r = MsiRecordSetString(hrec, 2, "hey");
297     r = MsiRecordSetString(hrec, 3, "1");
298     r = MsiRecordSetString(hrec, 4, NULL);
299     r = MsiRecordSetString(hrec, 12, "big");
300     ok( r == ERROR_SUCCESS, "set string failed\n");
301     sz = sizeof buffer;
302     r = MsiFormatRecord(0, hrec, buffer, &sz);
303     ok( r == ERROR_SUCCESS, "format failed\n");
304     ok( sz == 7, "size wrong,(%li)\n",sz);
305     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
306
307     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]");
308     r = MsiRecordSetString(hrec, 1, "2");
309     r = MsiRecordSetString(hrec, 2, "hey");
310     r = MsiRecordSetString(hrec, 3, "1");
311     r = MsiRecordSetString(hrec, 4, NULL);
312     r = MsiRecordSetString(hrec, 12, "big");
313     ok( r == ERROR_SUCCESS, "set string failed\n");
314     sz = sizeof buffer;
315     r = MsiFormatRecord(0, hrec, buffer, &sz);
316     ok( r == ERROR_SUCCESS, "format failed\n");
317     ok( sz == 10, "size wrong,(%li)\n",sz);
318     ok( 0 == strcmp(buffer,"[1[]2] hey"), "wrong output (%s)\n",buffer);
319
320     /* incorrect  formats */
321     r = MsiRecordSetString(hrec, 0, "[[[3][[4]][1]] [2]");
322     r = MsiRecordSetString(hrec, 1, "2");
323     r = MsiRecordSetString(hrec, 2, "hey");
324     r = MsiRecordSetString(hrec, 3, "1");
325     r = MsiRecordSetString(hrec, 4, NULL);
326     r = MsiRecordSetString(hrec, 12, "big");
327     ok( r == ERROR_SUCCESS, "set string failed\n");
328     sz = sizeof buffer;
329     r = MsiFormatRecord(0, hrec, buffer, &sz);
330     ok( r == ERROR_SUCCESS, "format failed\n");
331     ok( sz == 18, "size wrong,(%li)\n",sz);
332     ok( 0 == strcmp(buffer,"[[[3][[4]][1]] [2]"), "wrong output (%s)\n",buffer);
333
334     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]]");
335     r = MsiRecordSetString(hrec, 1, "2");
336     r = MsiRecordSetString(hrec, 2, "hey");
337     r = MsiRecordSetString(hrec, 3, "1");
338     r = MsiRecordSetString(hrec, 4, NULL);
339     r = MsiRecordSetString(hrec, 12, "big");
340     ok( r == ERROR_SUCCESS, "set string failed\n");
341     sz = sizeof buffer;
342     r = MsiFormatRecord(0, hrec, buffer, &sz);
343     ok( r == ERROR_SUCCESS, "format failed\n");
344     ok( sz == 11, "size wrong,(%li)\n",sz);
345     ok( 0 == strcmp(buffer,"[1[]2] hey]"), "wrong output (%s)\n",buffer);
346
347
348     /* play games with {} */
349
350     r = MsiRecordSetString(hrec, 0, "{[3][1]} [2]");
351     r = MsiRecordSetString(hrec, 1, "2");
352     r = MsiRecordSetString(hrec, 2, "hey");
353     r = MsiRecordSetString(hrec, 3, "1");
354     r = MsiRecordSetString(hrec, 4, NULL);
355     r = MsiRecordSetString(hrec, 12, "big");
356     ok( r == ERROR_SUCCESS, "set string failed\n");
357     sz = sizeof buffer;
358     r = MsiFormatRecord(0, hrec, buffer, &sz);
359     ok( r == ERROR_SUCCESS, "format failed\n");
360     ok( sz == 6, "size wrong,(%li)\n",sz);
361     ok( 0 == strcmp(buffer,"12 hey"), "wrong output (%s)\n",buffer);
362
363     r = MsiRecordSetString(hrec, 0, "[{[3][1]}] [2]");
364     r = MsiRecordSetString(hrec, 1, "2");
365     r = MsiRecordSetString(hrec, 2, "hey");
366     r = MsiRecordSetString(hrec, 3, "1");
367     r = MsiRecordSetString(hrec, 4, NULL);
368     r = MsiRecordSetString(hrec, 12, "big");
369     ok( r == ERROR_SUCCESS, "set string failed\n");
370     sz = sizeof buffer;
371     r = MsiFormatRecord(0, hrec, buffer, &sz);
372     ok( r == ERROR_SUCCESS, "format failed\n");
373     ok( sz == 8, "size wrong,(%li)\n",sz);
374     ok( 0 == strcmp(buffer,"[12] hey"), "wrong output (%s)\n",buffer);
375
376
377     r = MsiRecordSetString(hrec, 0, "{test} [2]");
378     r = MsiRecordSetString(hrec, 1, "2");
379     r = MsiRecordSetString(hrec, 2, "hey");
380     r = MsiRecordSetString(hrec, 3, "1");
381     r = MsiRecordSetString(hrec, 4, NULL);
382     r = MsiRecordSetString(hrec, 12, "big");
383     ok( r == ERROR_SUCCESS, "set string failed\n");
384     sz = sizeof buffer;
385     r = MsiFormatRecord(0, hrec, buffer, &sz);
386     ok( r == ERROR_SUCCESS, "format failed\n");
387     ok( sz == 10, "size wrong,(%li)\n",sz);
388     ok( 0 == strcmp(buffer,"{test} hey"), "wrong output (%s)\n",buffer);
389
390     r = MsiRecordSetString(hrec, 0, "{[test]} [2]");
391     r = MsiRecordSetString(hrec, 1, "2");
392     r = MsiRecordSetString(hrec, 2, "hey");
393     r = MsiRecordSetString(hrec, 3, "1");
394     r = MsiRecordSetString(hrec, 4, NULL);
395     r = MsiRecordSetString(hrec, 12, "big");
396     ok( r == ERROR_SUCCESS, "set string failed\n");
397     sz = sizeof buffer;
398     r = MsiFormatRecord(0, hrec, buffer, &sz);
399     ok( r == ERROR_SUCCESS, "format failed\n");
400     ok( sz == 12, "size wrong,(%li)\n",sz);
401     ok( 0 == strcmp(buffer,"{[test]} hey"), "wrong output (%s)\n",buffer);
402
403     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4]} [2]");
404     r = MsiRecordSetString(hrec, 1, "2");
405     r = MsiRecordSetString(hrec, 2, "hey");
406     r = MsiRecordSetString(hrec, 3, "1");
407     r = MsiRecordSetString(hrec, 4, NULL);
408     r = MsiRecordSetString(hrec, 12, "big");
409     ok( r == ERROR_SUCCESS, "set string failed\n");
410     sz = sizeof buffer;
411     r = MsiFormatRecord(0, hrec, buffer, &sz);
412     ok( r == ERROR_SUCCESS, "format failed\n");
413     ok( sz == 4, "size wrong,(%li)\n",sz);
414     ok( 0 == strcmp(buffer," hey"), "wrong output (%s)\n",buffer);
415
416     r = MsiRecordSetString(hrec, 0, "{[1][2][3][dummy]} [2]");
417     r = MsiRecordSetString(hrec, 1, "2");
418     r = MsiRecordSetString(hrec, 2, "hey");
419     r = MsiRecordSetString(hrec, 3, "1");
420     r = MsiRecordSetString(hrec, 4, NULL);
421     r = MsiRecordSetString(hrec, 12, "big");
422     ok( r == ERROR_SUCCESS, "set string failed\n");
423     sz = sizeof buffer;
424     r = MsiFormatRecord(0, hrec, buffer, &sz);
425     ok( r == ERROR_SUCCESS, "format failed\n");
426     ok( sz == 18, "size wrong,(%li)\n",sz);
427     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
428
429     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4][dummy]} [2]");
430     r = MsiRecordSetString(hrec, 1, "2");
431     r = MsiRecordSetString(hrec, 2, "hey");
432     r = MsiRecordSetString(hrec, 3, "1");
433     r = MsiRecordSetString(hrec, 4, NULL);
434     r = MsiRecordSetString(hrec, 12, "big");
435     ok( r == ERROR_SUCCESS, "set string failed\n");
436     sz = sizeof buffer;
437     r = MsiFormatRecord(0, hrec, buffer, &sz);
438     ok( r == ERROR_SUCCESS, "format failed\n");
439     ok( sz == 18, "size wrong,(%li)\n",sz);
440     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
441
442     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3][4][dummy]}");
443     r = MsiRecordSetString(hrec, 1, "2");
444     r = MsiRecordSetString(hrec, 2, "hey");
445     r = MsiRecordSetString(hrec, 3, "1");
446     r = MsiRecordSetString(hrec, 4, NULL);
447     r = MsiRecordSetString(hrec, 12, "big");
448     ok( r == ERROR_SUCCESS, "set string failed\n");
449     sz = sizeof buffer;
450     r = MsiFormatRecord(0, hrec, buffer, &sz);
451     ok( r == ERROR_SUCCESS, "format failed\n");
452
453     todo_wine{
454     ok( sz == 16, "size wrong,(%li)\n",sz);
455     ok( 0 == strcmp(buffer,"{{2hey}1[dummy]}"), "wrong output (%s)\n",buffer);
456     }
457
458     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]{[4][dummy]}}");
459     r = MsiRecordSetString(hrec, 1, "2");
460     r = MsiRecordSetString(hrec, 2, "hey");
461     r = MsiRecordSetString(hrec, 3, "1");
462     r = MsiRecordSetString(hrec, 4, NULL);
463     r = MsiRecordSetString(hrec, 12, "big");
464     ok( r == ERROR_SUCCESS, "set string failed\n");
465     sz = sizeof buffer;
466     r = MsiFormatRecord(0, hrec, buffer, &sz);
467     ok( r == ERROR_SUCCESS, "format failed\n");
468     todo_wine{
469     ok( sz == 0, "size wrong,(%li)\n",sz);
470     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
471     }
472
473     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]} {[1][2]}");
474     r = MsiRecordSetString(hrec, 1, "1");
475     r = MsiRecordSetString(hrec, 2, "2");
476     r = MsiRecordSetString(hrec, 3, "3");
477     r = MsiRecordSetString(hrec, 4, NULL);
478     r = MsiRecordSetString(hrec, 12, "big");
479     ok( r == ERROR_SUCCESS, "set string failed\n");
480     sz = sizeof buffer;
481     r = MsiFormatRecord(0, hrec, buffer, &sz);
482     ok( r == ERROR_SUCCESS, "format failed\n");
483     todo_wine{
484     ok( sz == 12, "size wrong,(%li)\n",sz);
485     ok( 0 == strcmp(buffer,"{{12}3} {12}"), "wrong output (%s)\n",buffer);
486     }
487
488     r = MsiRecordSetString(hrec, 0, "{[1][2]} {{[1][2]}[3]} {[1][2]}");
489     r = MsiRecordSetString(hrec, 1, "1");
490     r = MsiRecordSetString(hrec, 2, "2");
491     r = MsiRecordSetString(hrec, 3, "3");
492     r = MsiRecordSetString(hrec, 4, NULL);
493     r = MsiRecordSetString(hrec, 12, "big");
494     ok( r == ERROR_SUCCESS, "set string failed\n");
495     sz = sizeof buffer;
496     r = MsiFormatRecord(0, hrec, buffer, &sz);
497     ok( r == ERROR_SUCCESS, "format failed\n");
498     todo_wine{
499     ok( sz == 15, "size wrong,(%li)\n",sz);
500     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
501     }
502
503     r = MsiRecordSetString(hrec, 0, "{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
504     r = MsiRecordSetString(hrec, 1, "1");
505     r = MsiRecordSetString(hrec, 2, "2");
506     r = MsiRecordSetString(hrec, 3, "3");
507     r = MsiRecordSetString(hrec, 4, NULL);
508     r = MsiRecordSetString(hrec, 12, "big");
509     ok( r == ERROR_SUCCESS, "set string failed\n");
510     sz = sizeof buffer;
511     r = MsiFormatRecord(0, hrec, buffer, &sz);
512     ok( r == ERROR_SUCCESS, "format failed\n");
513     todo_wine{
514     ok( sz == 15, "size wrong,(%li)\n",sz);
515     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
516     }
517
518
519     r = MsiRecordSetString(hrec, 0, "{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
520     r = MsiRecordSetString(hrec, 1, "1");
521     r = MsiRecordSetString(hrec, 2, "2");
522     r = MsiRecordSetString(hrec, 3, "3");
523     r = MsiRecordSetString(hrec, 4, NULL);
524     r = MsiRecordSetString(hrec, 12, "big");
525     ok( r == ERROR_SUCCESS, "set string failed\n");
526     sz = sizeof buffer;
527     r = MsiFormatRecord(0, hrec, buffer, &sz);
528     ok( r == ERROR_SUCCESS, "format failed\n");
529     todo_wine{
530     ok( sz == 22, "size wrong,(%li)\n",sz);
531     ok( 0 == strcmp(buffer,"{blah} 12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
532     }
533
534     r = MsiRecordSetString(hrec, 0, "{{[1]}[2]} {[4]}{[1][2]}");
535     r = MsiRecordSetString(hrec, 1, "1");
536     r = MsiRecordSetString(hrec, 2, "2");
537     r = MsiRecordSetString(hrec, 3, "3");
538     r = MsiRecordSetString(hrec, 4, NULL);
539     r = MsiRecordSetString(hrec, 12, "big");
540     ok( r == ERROR_SUCCESS, "set string failed\n");
541     sz = sizeof buffer;
542     r = MsiFormatRecord(0, hrec, buffer, &sz);
543     ok( r == ERROR_SUCCESS, "format failed\n");
544     todo_wine{
545     ok( sz == 13, "size wrong,(%li)\n",sz);
546     ok( 0 == strcmp(buffer,"{{1}2} {}{12}"), "wrong output (%s)\n",buffer);
547     }
548
549     r = MsiRecordSetString(hrec, 0, "{{[1]}} {[4]}{[1][2]}");
550     r = MsiRecordSetString(hrec, 1, "1");
551     r = MsiRecordSetString(hrec, 2, "2");
552     r = MsiRecordSetString(hrec, 3, "3");
553     r = MsiRecordSetString(hrec, 4, NULL);
554     r = MsiRecordSetString(hrec, 12, "big");
555     ok( r == ERROR_SUCCESS, "set string failed\n");
556     sz = sizeof buffer;
557     r = MsiFormatRecord(0, hrec, buffer, &sz);
558     ok( r == ERROR_SUCCESS, "format failed\n");
559     todo_wine{
560     ok( sz == 3, "size wrong,(%li)\n",sz);
561     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
562     }
563
564     r = MsiRecordSetString(hrec, 0, "{{{[1]}} {[4]}{[1][2]}");
565     r = MsiRecordSetString(hrec, 1, "1");
566     r = MsiRecordSetString(hrec, 2, "2");
567     r = MsiRecordSetString(hrec, 3, "3");
568     r = MsiRecordSetString(hrec, 4, NULL);
569     r = MsiRecordSetString(hrec, 12, "big");
570     ok( r == ERROR_SUCCESS, "set string failed\n");
571     sz = sizeof buffer;
572     r = MsiFormatRecord(0, hrec, buffer, &sz);
573     ok( r == ERROR_SUCCESS, "format failed\n");
574     todo_wine{
575     ok( sz == 3, "size wrong,(%li)\n",sz);
576     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
577     }
578     
579     /* now put play games with escaping */
580     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
581     r = MsiRecordSetString(hrec, 1, "boo");
582     r = MsiRecordSetString(hrec, 2, "hoo");
583     ok( r == ERROR_SUCCESS, "set string failed\n");
584     sz = sizeof buffer;
585     r = MsiFormatRecord(0, hrec, buffer, &sz);
586     ok( r == ERROR_SUCCESS, "format failed\n");
587     ok( sz == 16, "size wrong\n");
588     ok( 0 == strcmp(buffer,"boo hoo [\\3asdf]"), "wrong output\n");
589
590     /* now put play games with escaping */
591     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
592     r = MsiRecordSetString(hrec, 1, "boo");
593     r = MsiRecordSetString(hrec, 2, "hoo");
594     ok( r == ERROR_SUCCESS, "set string failed\n");
595     sz = sizeof buffer;
596     r = MsiFormatRecord(0, hrec, buffer, &sz);
597     ok( r == ERROR_SUCCESS, "format failed\n");
598     ok( sz == 12, "size wrong\n");
599     ok( 0 == strcmp(buffer,"boo hoo [\\x]"), "wrong output\n");
600
601     /* now try other formats without a package */
602     r = MsiRecordSetString(hrec, 0, "[1] [2] [property]");
603     r = MsiRecordSetString(hrec, 1, "boo");
604     r = MsiRecordSetString(hrec, 2, "hoo");
605     ok( r == ERROR_SUCCESS, "set string failed\n");
606     sz = sizeof buffer;
607     r = MsiFormatRecord(0, hrec, buffer, &sz);
608     ok( r == ERROR_SUCCESS, "format failed\n");
609     ok( sz == 18, "size wrong\n");
610     ok( 0 == strcmp(buffer,"boo hoo [property]"), "wrong output\n");
611
612     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
613     r = MsiRecordSetString(hrec, 1, "boo");
614     r = MsiRecordSetString(hrec, 2, "hoo");
615     ok( r == ERROR_SUCCESS, "set string failed\n");
616     sz = sizeof buffer;
617     r = MsiFormatRecord(0, hrec, buffer, &sz);
618     ok( r == ERROR_SUCCESS, "format failed\n");
619     ok( sz == 11, "size wrong\n");
620     ok( 0 == strcmp(buffer,"boo [~] hoo"), "wrong output (%s)\n",buffer);
621
622     r = MsiRecordSetString(hrec, 0, "[1]");
623     r = MsiRecordSetInteger(hrec, 1, 123456);
624     ok( r == ERROR_SUCCESS, "set integer failed\n");
625     sz = sizeof buffer;
626     r = MsiFormatRecord(0, hrec, buffer, &sz);
627     ok( r == ERROR_SUCCESS, "format failed\n");
628     todo_wine{
629     ok( sz == 6, "size wrong\n");
630     ok( 0 == strcmp(buffer,"123456"), "wrong output (%s)\n",buffer);
631     }
632
633     r = MsiRecordSetString(hrec, 0, "[~]");
634     sz = sizeof buffer;
635     r = MsiFormatRecord(0, hrec, buffer, &sz);
636     ok( sz == 3, "size wrong\n");
637     ok( 0 == strcmp(buffer,"[~]"), "wrong output\n");
638     ok( r == ERROR_SUCCESS, "format failed\n");
639
640     r = MsiRecordSetString(hrec, 0, "[]");
641     sz = sizeof buffer;
642     r = MsiFormatRecord(0, hrec, buffer, &sz);
643     ok( sz == 2, "size wrong\n");
644     ok( 0 == strcmp(buffer,"[]"), "wrong output\n");
645     ok( r == ERROR_SUCCESS, "format failed\n");
646
647     /* MsiFormatRecord doesn't seem to handle a negative too well */
648     r = MsiRecordSetString(hrec, 0, "[-1]");
649     sz = sizeof buffer;
650     r = MsiFormatRecord(0, hrec, buffer, &sz);
651     ok( sz == 4, "size wrong\n");
652     ok( 0 == strcmp(buffer,"[-1]"), "wrong output\n");
653     ok( r == ERROR_SUCCESS, "format failed\n");
654
655     r = MsiRecordSetString(hrec, 0, "{[]}");
656     sz = sizeof buffer;
657     r = MsiFormatRecord(0, hrec, buffer, &sz);
658     ok( sz == 4, "size wrong\n");
659     ok( 0 == strcmp(buffer,"{[]}"), "wrong output\n");
660     ok( r == ERROR_SUCCESS, "format failed\n");
661
662     r = MsiRecordSetString(hrec, 0, "[0]");
663     sz = sizeof buffer;
664     r = MsiFormatRecord(0, hrec, buffer, &sz);
665     ok( sz == 3, "size wrong\n");
666     ok( 0 == strcmp(buffer,"[0]"), "wrong output\n");
667     ok( r == ERROR_SUCCESS, "format failed\n");
668
669     r = MsiRecordSetString(hrec, 0, "[100]");
670     sz = sizeof buffer;
671     r = MsiFormatRecord(0, hrec, buffer, &sz);
672     ok( sz == 0, "size wrong\n");
673     ok( 0 == strcmp(buffer,""), "wrong output\n");
674     ok( r == ERROR_SUCCESS, "format failed\n");
675
676     r = MsiRecordSetString(hrec, 0, "{[1] [2]}");
677     r = MsiRecordSetString(hrec, 1, "boo");
678     r = MsiRecordSetString(hrec, 2, "hoo");
679     sz = sizeof buffer;
680     r = MsiFormatRecord(0, hrec, buffer, &sz);
681     ok( sz == 7, "size wrong\n");
682     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
683     ok( r == ERROR_SUCCESS, "format failed\n");
684
685     r = MsiRecordSetString(hrec, 0, "{}");
686     sz = sizeof buffer;
687     r = MsiFormatRecord(0, hrec, buffer, &sz);
688     ok( sz == 0, "size wrong\n");
689     ok( 0 == strcmp(buffer,""), "wrong output\n");
690     ok( r == ERROR_SUCCESS, "format failed\n");
691
692     r = MsiRecordSetString(hrec, 0, "{foo}");
693     sz = sizeof buffer;
694     r = MsiFormatRecord(0, hrec, buffer, &sz);
695     ok( sz == 5, "size wrong\n");
696     ok( 0 == strcmp(buffer,"{foo}"), "wrong output\n");
697     ok( r == ERROR_SUCCESS, "format failed\n");
698
699     r = MsiRecordSetString(hrec, 0, "{boo [1]}");
700     r = MsiRecordSetString(hrec, 1, "hoo");
701     sz = sizeof buffer;
702     r = MsiFormatRecord(0, hrec, buffer, &sz);
703     ok( sz == 7, "size wrong\n");
704     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
705     ok( r == ERROR_SUCCESS, "format failed\n");
706
707     todo_wine {
708     r = MsiRecordSetString(hrec, 0, "{{[1]}}");
709     r = MsiRecordSetString(hrec, 1, "hoo");
710     sz = sizeof buffer;
711     r = MsiFormatRecord(0, hrec, buffer, &sz);
712     ok( sz == 0, "size wrong\n");
713     ok( 0 == strcmp(buffer,""), "wrong output\n");
714     }
715     ok( r == ERROR_SUCCESS, "format failed\n");
716
717     r = MsiRecordSetString(hrec, 0, "{ {[1]}}");
718     r = MsiRecordSetString(hrec, 1, "hoo");
719     sz = sizeof buffer;
720     r = MsiFormatRecord(0, hrec, buffer, &sz);
721     ok( 0 == strcmp(buffer," {hoo}"), "wrong output\n");
722     ok( sz == 6, "size wrong\n");
723     ok( r == ERROR_SUCCESS, "format failed\n");
724
725     todo_wine {
726     r = MsiRecordSetString(hrec, 0, "{{[1]} }");
727     r = MsiRecordSetString(hrec, 1, "hoo");
728     sz = sizeof buffer;
729     r = MsiFormatRecord(0, hrec, buffer, &sz);
730     ok( sz == 8, "size wrong\n");
731     ok( 0 == strcmp(buffer,"{{hoo} }"), "wrong output\n");
732     }
733     ok( r == ERROR_SUCCESS, "format failed\n");
734
735     todo_wine {
736     r = MsiRecordSetString(hrec, 0, "{{ [1]}}");
737     r = MsiRecordSetString(hrec, 1, "hoo");
738     sz = sizeof buffer;
739     r = MsiFormatRecord(0, hrec, buffer, &sz);
740     ok( sz == 0, "size wrong\n");
741     ok( 0 == strcmp(buffer,""), "wrong output\n");
742     }
743     ok( r == ERROR_SUCCESS, "format failed\n");
744
745     todo_wine {
746     r = MsiRecordSetString(hrec, 0, "{{[1] }}");
747     r = MsiRecordSetString(hrec, 1, "hoo");
748     sz = sizeof buffer;
749     r = MsiFormatRecord(0, hrec, buffer, &sz);
750     ok( sz == 0, "size wrong\n");
751     ok( 0 == strcmp(buffer,""), "wrong output\n");
752     }
753     ok( r == ERROR_SUCCESS, "format failed\n");
754
755     todo_wine {
756     r = MsiRecordSetString(hrec, 0, "{{a}{b}{c }{ d}{any text}}");
757     sz = sizeof buffer;
758     r = MsiFormatRecord(0, hrec, buffer, &sz);
759     ok( sz == 0, "size wrong\n");
760     ok( 0 == strcmp(buffer,""), "wrong output\n");
761     }
762     ok( r == ERROR_SUCCESS, "format failed\n");
763
764     r = MsiRecordSetString(hrec, 0, "{{a} }");
765     sz = sizeof buffer;
766     r = MsiFormatRecord(0, hrec, buffer, &sz);
767     ok( sz == 6, "size wrong\n");
768     ok( 0 == strcmp(buffer,"{{a} }"), "wrong output\n");
769     ok( r == ERROR_SUCCESS, "format failed\n");
770
771     todo_wine {
772     r = MsiRecordSetString(hrec, 0, "{{a} {b}}");
773     sz = sizeof buffer;
774     r = MsiFormatRecord(0, hrec, buffer, &sz);
775     ok( sz == 0, "size wrong\n");
776     ok( 0 == strcmp(buffer,""), "wrong output\n");
777     }
778     ok( r == ERROR_SUCCESS, "format failed\n");
779
780     todo_wine {
781     r = MsiRecordSetString(hrec, 0, "{{a} b}}");
782     sz = sizeof buffer;
783     r = MsiFormatRecord(0, hrec, buffer, &sz);
784     ok( sz == 0, "size wrong\n");
785     ok( 0 == strcmp(buffer,""), "wrong output\n");
786     }
787     ok( r == ERROR_SUCCESS, "format failed\n");
788
789     todo_wine {
790     r = MsiRecordSetString(hrec, 0, "{{a b}}");
791     sz = sizeof buffer;
792     r = MsiFormatRecord(0, hrec, buffer, &sz);
793     ok( sz == 0, "size wrong\n");
794     ok( 0 == strcmp(buffer,""), "wrong output\n");
795     }
796     ok( r == ERROR_SUCCESS, "format failed\n");
797
798     r = MsiRecordSetString(hrec, 0, "{ }");
799     sz = sizeof buffer;
800     r = MsiFormatRecord(0, hrec, buffer, &sz);
801     ok( sz == 3, "size wrong\n");
802     ok( 0 == strcmp(buffer,"{ }"), "wrong output\n");
803     ok( r == ERROR_SUCCESS, "format failed\n");
804
805     todo_wine {
806     r = MsiRecordSetString(hrec, 0, " {{a}}}");
807     sz = sizeof buffer;
808     r = MsiFormatRecord(0, hrec, buffer, &sz);
809     ok( sz == 2, "size wrong\n");
810     ok( 0 == strcmp(buffer," }"), "wrong output\n");
811     }
812     ok( r == ERROR_SUCCESS, "format failed\n");
813
814     todo_wine {
815     r = MsiRecordSetString(hrec, 0, "{{ almost {{ any }} text }}");
816     sz = sizeof buffer;
817     r = MsiFormatRecord(0, hrec, buffer, &sz);
818     ok( sz == 8, "size wrong\n");
819     ok( 0 == strcmp(buffer," text }}"), "wrong output\n");
820     }
821     ok( r == ERROR_SUCCESS, "format failed\n");
822
823     todo_wine {
824     r = MsiRecordSetString(hrec, 0, "{{ } { hidden ][ [ }}");
825     sz = sizeof buffer;
826     r = MsiFormatRecord(0, hrec, buffer, &sz);
827     ok( sz == 0, "size wrong\n");
828     ok( 0 == strcmp(buffer,""), "wrong output\n");
829     }
830     ok( r == ERROR_SUCCESS, "format failed\n");
831
832     r = MsiRecordSetString(hrec, 0, "[ 1]");
833     r = MsiRecordSetString(hrec, 1, "hoo");
834     sz = sizeof buffer;
835     r = MsiFormatRecord(0, hrec, buffer, &sz);
836     ok( sz == 4, "size wrong\n");
837     ok( 0 == strcmp(buffer,"[ 1]"), "wrong output\n");
838     ok( r == ERROR_SUCCESS, "format failed\n");
839
840     r = MsiRecordSetString(hrec, 0, "[01]");
841     r = MsiRecordSetString(hrec, 1, "hoo");
842     sz = sizeof buffer;
843     r = MsiFormatRecord(0, hrec, buffer, &sz);
844     ok( sz == 3, "size wrong\n");
845     ok( 0 == strcmp(buffer,"hoo"), "wrong output\n");
846     ok( r == ERROR_SUCCESS, "format failed\n");
847
848     todo_wine {
849     r = MsiRecordSetString(hrec, 0, "{{test}} [01");
850     r = MsiRecordSetString(hrec, 1, "hoo");
851     sz = sizeof buffer;
852     r = MsiFormatRecord(0, hrec, buffer, &sz);
853     ok( sz == 4, "size wrong\n");
854     ok( 0 == strcmp(buffer," [01"), "wrong output\n");
855     }
856     ok( r == ERROR_SUCCESS, "format failed\n");
857
858     r = MsiRecordSetString(hrec, 0, "[\\[]");
859     r = MsiRecordSetString(hrec, 1, "hoo");
860     sz = sizeof buffer;
861     r = MsiFormatRecord(0, hrec, buffer, &sz);
862     ok( sz == 4, "size wrong\n");
863     ok( 0 == strcmp(buffer,"[\\[]"), "wrong output\n");
864     ok( r == ERROR_SUCCESS, "format failed\n");
865
866     r = MsiRecordSetString(hrec, 0, "[foo]");
867     r = MsiRecordSetString(hrec, 1, "hoo");
868     sz = sizeof buffer;
869     r = MsiFormatRecord(0, hrec, buffer, &sz);
870     ok( sz == 5, "size wrong\n");
871     ok( 0 == strcmp(buffer,"[foo]"), "wrong output\n");
872     ok( r == ERROR_SUCCESS, "format failed\n");
873
874     r = MsiRecordSetString(hrec, 0, "[01.]");
875     r = MsiRecordSetString(hrec, 1, "hoo");
876     sz = sizeof buffer;
877     r = MsiFormatRecord(0, hrec, buffer, &sz);
878     ok( sz == 5, "size wrong\n");
879     ok( 0 == strcmp(buffer,"[01.]"), "wrong output\n");
880     ok( r == ERROR_SUCCESS, "format failed\n");
881
882     SetEnvironmentVariable("FOO", "BAR");
883     r = MsiRecordSetString(hrec, 0, "[%FOO]");
884     sz = sizeof buffer;
885     r = MsiFormatRecord(0, hrec, buffer, &sz);
886     ok( sz == 6, "size wrong\n");
887     ok( 0 == strcmp(buffer,"[%FOO]"), "wrong output\n");
888     ok( r == ERROR_SUCCESS, "format failed\n");
889
890     todo_wine {
891     r = MsiRecordSetString(hrec, 0, "{{[1]}");
892     r = MsiRecordSetString(hrec, 1, "hoo");
893     sz = sizeof buffer;
894     r = MsiFormatRecord(0, hrec, buffer, &sz);
895     ok( sz == 6, "size wrong\n");
896     ok( 0 == strcmp(buffer,"{{hoo}"), "wrong output\n");
897     }
898     ok( r == ERROR_SUCCESS, "format failed\n");
899
900     todo_wine {
901     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
902     r = MsiRecordSetString(hrec, 1, "hoo");
903     sz = sizeof buffer;
904     r = MsiFormatRecord(0, hrec, buffer, &sz);
905     ok( sz == 8, "size wrong\n");
906     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
907     }
908     ok( r == ERROR_SUCCESS, "format failed\n");
909
910     todo_wine {
911     r = MsiRecordSetString(hrec, 0, "{{ {[1]}");
912     r = MsiRecordSetString(hrec, 1, "hoo");
913     sz = sizeof buffer;
914     r = MsiFormatRecord(0, hrec, buffer, &sz);
915     ok( sz == 8, "size wrong\n");
916     ok( 0 == strcmp(buffer,"{{ {hoo}"), "wrong output\n");
917     }
918     ok( r == ERROR_SUCCESS, "format failed\n");
919
920     todo_wine {
921     r = MsiRecordSetString(hrec, 0, "{{ {{[1]}");
922     r = MsiRecordSetString(hrec, 1, "hoo");
923     sz = sizeof buffer;
924     r = MsiFormatRecord(0, hrec, buffer, &sz);
925     ok( sz == 9, "size wrong\n");
926     ok( 0 == strcmp(buffer,"{{ {{hoo}"), "wrong output\n");
927     }
928     ok( r == ERROR_SUCCESS, "format failed\n");
929
930     r = MsiRecordSetString(hrec, 0, "[1]}");
931     r = MsiRecordSetString(hrec, 1, "hoo");
932     sz = sizeof buffer;
933     r = MsiFormatRecord(0, hrec, buffer, &sz);
934     ok( sz == 4, "size wrong\n");
935     ok( 0 == strcmp(buffer,"hoo}"), "wrong output\n");
936     ok( r == ERROR_SUCCESS, "format failed\n");
937
938     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
939     sz = sizeof buffer;
940     r = MsiFormatRecord(0, hrec, buffer, &sz);
941     ok( sz == 7, "size wrong\n");
942     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
943     ok( r == ERROR_SUCCESS, "format failed\n");
944
945     r = MsiRecordSetString(hrec, 0, "{{ {{a}");
946     sz = sizeof buffer;
947     r = MsiFormatRecord(0, hrec, buffer, &sz);
948     ok( sz == 7, "size wrong\n");
949     ok( 0 == strcmp(buffer,"{{ {{a}"), "wrong output\n");
950     ok( r == ERROR_SUCCESS, "format failed\n");
951
952     r = MsiRecordSetString(hrec, 0, "0{1{2{3{4[1]5}6}7}8}9");
953     r = MsiRecordSetString(hrec, 1, "hoo");
954     sz = sizeof buffer;
955     r = MsiFormatRecord(0, hrec, buffer, &sz);
956     ok( sz == 19, "size wrong\n");
957     ok( 0 == strcmp(buffer,"01{2{3{4hoo56}7}8}9"), "wrong output\n");
958     ok( r == ERROR_SUCCESS, "format failed\n");
959
960     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
961     r = MsiRecordSetString(hrec, 1, "hoo");
962     sz = sizeof buffer;
963     r = MsiFormatRecord(0, hrec, buffer, &sz);
964     ok( sz == 9, "size wrong\n");
965     ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
966     ok( r == ERROR_SUCCESS, "format failed\n");
967
968     r = MsiRecordSetString(hrec, 0, "0{1{2[1]3}4");
969     r = MsiRecordSetString(hrec, 1, "hoo");
970     sz = sizeof buffer;
971     r = MsiFormatRecord(0, hrec, buffer, &sz);
972     ok( sz == 9, "size wrong\n");
973     ok( 0 == strcmp(buffer,"01{2hoo34"), "wrong output\n");
974     ok( r == ERROR_SUCCESS, "format failed\n");
975
976     r = MsiRecordSetString(hrec, 0, "{[1.} [1]");
977     r = MsiRecordSetString(hrec, 1, "hoo");
978     sz = sizeof buffer;
979     r = MsiFormatRecord(0, hrec, buffer, &sz);
980     ok( sz == 9, "size wrong\n");
981     ok( 0 == strcmp(buffer,"{[1.} hoo"), "wrong output\n");
982     ok( r == ERROR_SUCCESS, "format failed\n");
983
984     r = MsiRecordSetString(hrec, 0, "{[{[1]}]}");
985     r = MsiRecordSetString(hrec, 1, "2");
986     r = MsiRecordSetString(hrec, 2, "foo");
987     sz = sizeof buffer;
988     r = MsiFormatRecord(0, hrec, buffer, &sz);
989     ok( sz == 9, "size wrong\n");
990     ok( 0 == strcmp(buffer,"{[{[1]}]}"), "wrong output\n");
991     ok( r == ERROR_SUCCESS, "format failed\n");
992
993     r = MsiRecordSetString(hrec, 0, "{[1][}");
994     r = MsiRecordSetString(hrec, 1, "2");
995     r = MsiRecordSetString(hrec, 2, "foo");
996     sz = sizeof buffer;
997     r = MsiFormatRecord(0, hrec, buffer, &sz);
998     ok( sz == 2, "size wrong\n");
999     ok( 0 == strcmp(buffer,"2["), "wrong output\n");
1000     ok( r == ERROR_SUCCESS, "format failed\n");
1001
1002     r = MsiRecordSetString(hrec, 0, "[1]");
1003     r = MsiRecordSetString(hrec, 1, "[2]");
1004     r = MsiRecordSetString(hrec, 2, "foo");
1005     sz = sizeof buffer;
1006     r = MsiFormatRecord(0, hrec, buffer, &sz);
1007     ok( sz == 3, "size wrong\n");
1008     ok( 0 == strcmp(buffer,"[2]"), "wrong output\n");
1009     ok( r == ERROR_SUCCESS, "format failed\n");
1010
1011     todo_wine {
1012     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1013     r = MsiRecordSetString(hrec, 1, "hoo");
1014     sz = sizeof buffer;
1015     r = MsiFormatRecord(0, hrec, buffer, &sz);
1016     ok( sz == 3, "size wrong\n");
1017     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1018     }
1019     ok( r == ERROR_SUCCESS, "format failed\n");
1020
1021     todo_wine {
1022     r = MsiRecordSetString(hrec, 0, "[{{boo}}1]");
1023     r = MsiRecordSetString(hrec, 0, "[1{{boo}}]");
1024     r = MsiRecordSetString(hrec, 1, "hoo");
1025     sz = sizeof buffer;
1026     r = MsiFormatRecord(0, hrec, buffer, &sz);
1027     ok( sz == 3, "size wrong\n");
1028     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1029     }
1030     ok( r == ERROR_SUCCESS, "format failed\n");
1031
1032     r = MsiRecordSetString(hrec, 0, "{[1]{{boo} }}");
1033     r = MsiRecordSetString(hrec, 1, "hoo");
1034     sz = sizeof buffer;
1035     r = MsiFormatRecord(0, hrec, buffer, &sz);
1036     ok( sz == 11, "size wrong\n");
1037     ok( 0 == strcmp(buffer,"hoo{{boo }}"), "wrong output\n");
1038     ok( r == ERROR_SUCCESS, "format failed\n");
1039
1040     todo_wine {
1041     r = MsiRecordSetString(hrec, 0, "{[1{{boo}}]}");
1042     r = MsiRecordSetString(hrec, 1, "hoo");
1043     sz = sizeof buffer;
1044     r = MsiFormatRecord(0, hrec, buffer, &sz);
1045     ok( sz == 3, "size wrong\n");
1046     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1047     }
1048     ok( r == ERROR_SUCCESS, "format failed\n");
1049
1050     todo_wine {
1051     r = MsiRecordSetString(hrec, 0, "{{[1]}");
1052     r = MsiRecordSetString(hrec, 1, "hoo");
1053     sz = sizeof buffer;
1054     r = MsiFormatRecord(0, hrec, buffer, &sz);
1055     ok( sz == 3, "size wrong\n");
1056     ok( 0 == strcmp(buffer,"[1]"), "wrong output\n");
1057     }
1058     ok( r == ERROR_SUCCESS, "format failed\n");
1059
1060     r = MsiRecordSetString(hrec, 0, "{[1{{bo}o}}]}");
1061     r = MsiRecordSetString(hrec, 1, "hoo");
1062     sz = sizeof buffer;
1063     r = MsiFormatRecord(0, hrec, buffer, &sz);
1064     ok( sz == 13, "size wrong\n");
1065     ok( 0 == strcmp(buffer,"{[1{{bo}o}}]}"), "wrong output\n");
1066     ok( r == ERROR_SUCCESS, "format failed\n");
1067
1068     r = MsiRecordSetString(hrec, 0, "{[1{{b{o}o}}]}");
1069     r = MsiRecordSetString(hrec, 1, "hoo");
1070     sz = sizeof buffer;
1071     r = MsiFormatRecord(0, hrec, buffer, &sz);
1072     ok( sz == 14, "size wrong\n");
1073     ok( 0 == strcmp(buffer,"{[1{{b{o}o}}]}"), "wrong output\n");
1074     ok( r == ERROR_SUCCESS, "format failed\n");
1075
1076     MsiCloseHandle(hrec);
1077 }
1078
1079 static void test_formatrecord_package(void)
1080 {
1081     static const CHAR filename[] = "winetest.msi";
1082     char buffer[100];
1083     MSIHANDLE hrec;
1084     MSIHANDLE package;
1085     UINT r;
1086     DWORD sz=100;
1087
1088     package = helper_createpackage( filename );
1089     ok(package!=0, "Unable to create package\n");
1090
1091     hrec = MsiCreateRecord(12);
1092     ok( hrec, "failed to create record\n");
1093
1094     r = MsiFormatRecord(package, 0, NULL, NULL );
1095     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
1096
1097     r = MsiFormatRecord(package, hrec, NULL, NULL );
1098     ok( r == ERROR_SUCCESS, "format failed\n");
1099
1100     r = MsiRecordSetString(hrec,0,NULL);
1101     r = MsiRecordSetString(hrec,1,NULL);
1102     r = MsiRecordSetString(hrec,2,NULL);
1103     r = MsiRecordSetString(hrec,3,NULL);
1104     r = MsiRecordSetString(hrec,4,NULL);
1105     r = MsiRecordSetString(hrec,5,NULL);
1106     r = MsiRecordSetString(hrec,6,NULL);
1107     r = MsiRecordSetString(hrec,7,NULL);
1108     r = MsiRecordSetString(hrec,8,NULL);
1109     r = MsiRecordSetString(hrec,9,NULL);
1110     r = MsiRecordSetString(hrec,10,NULL);
1111     r = MsiRecordSetString(hrec,11,NULL);
1112     r = MsiRecordSetString(hrec,12,NULL);
1113     ok( r == ERROR_SUCCESS, "set string failed\n");
1114
1115     sz = sizeof buffer;
1116     r = MsiFormatRecord(package, hrec, buffer, &sz);
1117     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
1118     ok( sz == 51, "size wrong (%li)\n",sz);
1119     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
1120
1121     /* now put play games with escaping */
1122     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
1123     r = MsiRecordSetString(hrec, 1, "boo");
1124     r = MsiRecordSetString(hrec, 2, "hoo");
1125     ok( r == ERROR_SUCCESS, "set string failed\n");
1126     sz = sizeof buffer;
1127     r = MsiFormatRecord(package, hrec, buffer, &sz);
1128     ok( r == ERROR_SUCCESS, "format failed\n");
1129     ok( sz == 9, "size wrong(%li)\n",sz);
1130     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
1131
1132     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
1133     r = MsiRecordSetString(hrec, 1, "boo");
1134     r = MsiRecordSetString(hrec, 2, "hoo");
1135     ok( r == ERROR_SUCCESS, "set string failed\n");
1136     sz = sizeof buffer;
1137     r = MsiFormatRecord(package, hrec, buffer, &sz);
1138     ok( r == ERROR_SUCCESS, "format failed\n");
1139     ok( sz == 9, "size wrong(%li)\n",sz);
1140     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
1141
1142     /* null characters */
1143     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
1144     r = MsiRecordSetString(hrec, 1, "boo");
1145     r = MsiRecordSetString(hrec, 2, "hoo");
1146     ok( r == ERROR_SUCCESS, "set string failed\n");
1147     sz = sizeof buffer;
1148     r = MsiFormatRecord(package, hrec, buffer, &sz);
1149     ok( r == ERROR_SUCCESS, "format failed\n");
1150     ok( sz == 9, "size wrong\n");
1151     ok( 0 == strcmp(buffer,"boo "), "wrong output\n");
1152
1153     /* properties */
1154     r = MsiSetProperty(package,"dummy","Bork");
1155     ok( r == ERROR_SUCCESS, "set property failed\n");
1156     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
1157     r = MsiRecordSetString(hrec, 1, "boo");
1158     r = MsiRecordSetString(hrec, 2, "hoo");
1159     ok( r == ERROR_SUCCESS, "set string failed\n");
1160     sz = sizeof buffer;
1161     r = MsiFormatRecord(package, hrec, buffer, &sz);
1162     ok( r == ERROR_SUCCESS, "format failed\n");
1163     ok( sz == 12, "size wrong\n");
1164     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
1165
1166     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
1167     r = MsiRecordSetString(hrec, 1, "boo");
1168     r = MsiRecordSetString(hrec, 2, "hoo");
1169     ok( r == ERROR_SUCCESS, "set string failed\n");
1170     sz = sizeof buffer;
1171     r = MsiFormatRecord(package, hrec, buffer, &sz);
1172     ok( r == ERROR_SUCCESS, "format failed\n");
1173     ok( sz == 8, "size wrong\n");
1174     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
1175
1176
1177     /* nesting tests */
1178     r = MsiSetProperty(package,"dummya","foo");
1179     r = MsiSetProperty(package,"dummyb","baa");
1180     r = MsiSetProperty(package,"adummyc","whoa");
1181     ok( r == ERROR_SUCCESS, "set property failed\n");
1182     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
1183     r = MsiRecordSetString(hrec, 1, "a");
1184     r = MsiRecordSetString(hrec, 2, "b");
1185     r = MsiRecordSetString(hrec, 3, "c");
1186     ok( r == ERROR_SUCCESS, "set string failed\n");
1187     sz = sizeof buffer;
1188     r = MsiFormatRecord(package, hrec, buffer, &sz);
1189     ok( r == ERROR_SUCCESS, "format failed\n");
1190     ok( sz == 12, "size wrong(%li)\n",sz);
1191     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
1192
1193
1194     r = MsiSetProperty(package,"dummya","1");
1195     r = MsiSetProperty(package,"dummyb","[2]");
1196     ok( r == ERROR_SUCCESS, "set property failed\n");
1197     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
1198     r = MsiRecordSetString(hrec, 1, "aaa");
1199     r = MsiRecordSetString(hrec, 2, "bbb");
1200     r = MsiRecordSetString(hrec, 3, "ccc");
1201     ok( r == ERROR_SUCCESS, "set string failed\n");
1202     sz = sizeof buffer;
1203     r = MsiFormatRecord(package, hrec, buffer, &sz);
1204     ok( r == ERROR_SUCCESS, "format failed\n");
1205     ok( sz == 9, "size wrong(%li)\n",sz);
1206     ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
1207
1208     r = MsiSetProperty(package,"dummya","1");
1209     r = MsiSetProperty(package,"dummyb","a");
1210     r = MsiSetProperty(package,"dummyc","\\blath");
1211     r = MsiSetProperty(package,"dummyd","[\\blath]");
1212     ok( r == ERROR_SUCCESS, "set property failed\n");
1213     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
1214     r = MsiRecordSetString(hrec, 1, "aaa");
1215     r = MsiRecordSetString(hrec, 2, "bbb");
1216     r = MsiRecordSetString(hrec, 3, "ccc");
1217     ok( r == ERROR_SUCCESS, "set string failed\n");
1218     sz = sizeof buffer;
1219     r = MsiFormatRecord(package, hrec, buffer, &sz);
1220     ok( r == ERROR_SUCCESS, "format failed\n");
1221     ok( sz == 10, "size wrong(%li)\n",sz);
1222     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
1223
1224     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
1225     r = MsiRecordSetString(hrec, 1, "boo");
1226     r = MsiRecordSetString(hrec, 2, "hoo");
1227     r = MsiRecordSetString(hrec, 3, "yeah");
1228     ok( r == ERROR_SUCCESS, "set string failed\n");
1229     sz = sizeof buffer;
1230     r = MsiFormatRecord(package, hrec, buffer, &sz);
1231     ok( r == ERROR_SUCCESS, "format failed\n");
1232     ok( sz == 11, "size wrong(%li)\n",sz);
1233     ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
1234
1235     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
1236     r = MsiRecordSetString(hrec, 1, "boo");
1237     r = MsiRecordSetString(hrec, 2, "hoo");
1238     r = MsiRecordSetString(hrec, 3, "\\help");
1239     ok( r == ERROR_SUCCESS, "set string failed\n");
1240     sz = sizeof buffer;
1241     r = MsiFormatRecord(package, hrec, buffer, &sz);
1242     ok( r == ERROR_SUCCESS, "format failed\n");
1243     ok( sz == 9, "size wrong(%li)\n",sz);
1244     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
1245
1246     MsiCloseHandle(hrec);
1247
1248     r = MsiCloseHandle(package);
1249     ok(r==ERROR_SUCCESS, "Unable to close package\n");
1250
1251     DeleteFile( filename );
1252 }
1253
1254 START_TEST(format)
1255 {
1256     test_createpackage();
1257     test_formatrecord();
1258     test_formatrecord_package();
1259 }