Remove redundant check.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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=100;
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     r = MsiFormatRecord(0, hrec, buffer, &sz);
126     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
127     ok( sz == 16, "size wrong\n");
128     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  "), "wrong output\n");
129
130     r = MsiCloseHandle(hrec);
131     ok(r==ERROR_SUCCESS, "Unable to close record\n");
132
133     hrec = MsiCreateRecord(6);
134     ok( hrec, "failed to create record\n");
135
136     sz = 100;
137     buffer[0] = 'x';
138     buffer[1] = 0;
139     r = MsiFormatRecord(0, hrec, buffer, &sz);
140     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
141     ok( sz == 24, "size wrong\n");
142     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  "), "wrong output\n");
143
144
145     /* format a format string with everything else empty */
146     r = MsiRecordSetString(hrec, 0, "%1");
147     ok( r == ERROR_SUCCESS, "set string failed\n");
148     r = MsiFormatRecord(0, hrec, NULL, NULL );
149     ok( r == ERROR_SUCCESS, "format failed\n");
150     r = MsiFormatRecord(0, hrec, buffer, NULL);
151     ok( r == ERROR_INVALID_PARAMETER, "wrong error\n");
152
153     sz = 123;
154     r = MsiFormatRecord(0, hrec, NULL, &sz);
155     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
156     ok( sz == 2, "size wrong (%li)\n",sz);
157     sz = sizeof buffer;
158     buffer[0] = 'x';
159     buffer[1] = 0;
160     r = MsiFormatRecord(0, hrec, buffer, &sz);
161     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
162     ok( sz == 2, "size wrong\n");
163     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
164
165     /* make the buffer too small */
166     sz = 0;
167     buffer[0] = 'x';
168     buffer[1] = 0;
169     r = MsiFormatRecord(0, hrec, buffer, &sz);
170     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
171     ok( sz == 2, "size wrong\n");
172     ok( 0 == strcmp(buffer,"x"), "wrong output\n");
173
174     /* make the buffer a little bit bigger */
175     sz = 1;
176     buffer[0] = 'x';
177     buffer[1] = 0;
178     r = MsiFormatRecord(0, hrec, buffer, &sz);
179     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
180     ok( sz == 2, "size wrong\n");
181     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
182
183     /* and again */
184     sz = 2;
185     buffer[0] = 'x';
186     buffer[1] = 0;
187     r = MsiFormatRecord(0, hrec, buffer, &sz);
188     ok( r == ERROR_MORE_DATA, "format failed with empty buffer\n");
189     ok( sz == 2, "size wrong\n");
190     ok( 0 == strcmp(buffer,"%"), "wrong output\n");
191
192     /* and again */
193     sz = 3;
194     buffer[0] = 'x';
195     buffer[1] = 0;
196     r = MsiFormatRecord(0, hrec, buffer, &sz);
197     ok( r == ERROR_SUCCESS, "format failed with empty buffer\n");
198     ok( sz == 2, "size wrong\n");
199     ok( 0 == strcmp(buffer,"%1"), "wrong output\n");
200
201     /* now try a real format string */
202     r = MsiRecordSetString(hrec, 0, "[1]");
203     ok( r == ERROR_SUCCESS, "set string failed\n");
204     sz = sizeof buffer;
205     r = MsiFormatRecord(0, hrec, buffer, &sz);
206     ok( r == ERROR_SUCCESS, "format failed\n");
207     ok( sz == 0, "size wrong\n");
208     ok( 0 == strcmp(buffer,""), "wrong output\n");
209
210     /* now put something in the first field */
211     r = MsiRecordSetString(hrec, 1, "boo hoo");
212     ok( r == ERROR_SUCCESS, "set string failed\n");
213     sz = sizeof buffer;
214     r = MsiFormatRecord(0, hrec, buffer, &sz);
215     ok( r == ERROR_SUCCESS, "format failed\n");
216     ok( sz == 7, "size wrong\n");
217     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
218
219     /* now put something in the first field */
220     r = MsiRecordSetString(hrec, 0, "[1] [2]");
221     r = MsiRecordSetString(hrec, 1, "boo");
222     r = MsiRecordSetString(hrec, 2, "hoo");
223     ok( r == ERROR_SUCCESS, "set string failed\n");
224     sz = sizeof buffer;
225     r = MsiFormatRecord(0, hrec, buffer, &sz);
226     ok( r == ERROR_SUCCESS, "format failed\n");
227     ok( sz == 7, "size wrong\n");
228     ok( 0 == strcmp(buffer,"boo hoo"), "wrong output\n");
229
230
231     /* empty string */
232     r = MsiRecordSetString(hrec, 0, "");
233     sz = sizeof buffer;
234     r = MsiFormatRecord(0, hrec, buffer, &sz);
235     ok( r == ERROR_SUCCESS, "format failed\n");
236     ok( sz == 30, "size wrong %li\n",sz);
237     ok( 0 == strcmp(buffer,"1: boo 2: hoo 3:  4:  5:  6:  "), 
238                     "wrong output(%s)\n",buffer);
239
240     /* play games with recursive lookups */
241     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
242     r = MsiRecordSetString(hrec, 1, "2");
243     r = MsiRecordSetString(hrec, 2, "hey");
244     ok( r == ERROR_SUCCESS, "set string failed\n");
245     sz = sizeof buffer;
246     r = MsiFormatRecord(0, hrec, buffer, &sz);
247     ok( r == ERROR_SUCCESS, "format failed\n");
248     ok( sz == 7, "size wrong,(%li)\n",sz);
249     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
250
251     r = MsiRecordSetString(hrec, 0, "[[1]] [2]");
252     r = MsiRecordSetString(hrec, 1, "[2]");
253     r = MsiRecordSetString(hrec, 2, "hey");
254     ok( r == ERROR_SUCCESS, "set string failed\n");
255     sz = sizeof buffer;
256     r = MsiFormatRecord(0, hrec, buffer, &sz);
257     ok( r == ERROR_SUCCESS, "format failed\n");
258     ok( sz == 9, "size wrong,(%li)\n",sz);
259     ok( 0 == strcmp(buffer,"[[2]] hey"), "wrong output (%s)\n",buffer);
260
261     r = MsiRecordSetString(hrec, 0, "[[[3]]] [2]");
262     r = MsiRecordSetString(hrec, 1, "2");
263     r = MsiRecordSetString(hrec, 2, "hey");
264     r = MsiRecordSetString(hrec, 3, "1");
265     ok( r == ERROR_SUCCESS, "set string failed\n");
266     sz = sizeof buffer;
267     r = MsiFormatRecord(0, hrec, buffer, &sz);
268     ok( r == ERROR_SUCCESS, "format failed\n");
269     ok( sz == 7, "size wrong,(%li)\n",sz);
270     ok( 0 == strcmp(buffer,"hey hey"), "wrong output (%s)\n",buffer);
271
272     r = MsiCloseHandle(hrec);
273     ok(r==ERROR_SUCCESS, "Unable to close record\n");
274     hrec = MsiCreateRecord(12);
275     ok( hrec, "failed to create record\n");
276
277     r = MsiRecordSetString(hrec, 0, "[[3][1]] [2]");
278     r = MsiRecordSetString(hrec, 1, "2");
279     r = MsiRecordSetString(hrec, 2, "hey");
280     r = MsiRecordSetString(hrec, 3, "1");
281     r = MsiRecordSetString(hrec, 12, "big");
282     ok( r == ERROR_SUCCESS, "set string failed\n");
283     sz = sizeof buffer;
284     r = MsiFormatRecord(0, hrec, buffer, &sz);
285     ok( r == ERROR_SUCCESS, "format failed\n");
286     ok( sz == 7, "size wrong,(%li)\n",sz);
287     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
288
289     r = MsiRecordSetString(hrec, 0, "[[3][4][1]] [2]");
290     r = MsiRecordSetString(hrec, 1, "2");
291     r = MsiRecordSetString(hrec, 2, "hey");
292     r = MsiRecordSetString(hrec, 3, "1");
293     r = MsiRecordSetString(hrec, 4, NULL);
294     r = MsiRecordSetString(hrec, 12, "big");
295     ok( r == ERROR_SUCCESS, "set string failed\n");
296     sz = sizeof buffer;
297     r = MsiFormatRecord(0, hrec, buffer, &sz);
298     ok( r == ERROR_SUCCESS, "format failed\n");
299     ok( sz == 7, "size wrong,(%li)\n",sz);
300     ok( 0 == strcmp(buffer,"big hey"), "wrong output (%s)\n",buffer);
301
302     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]");
303     r = MsiRecordSetString(hrec, 1, "2");
304     r = MsiRecordSetString(hrec, 2, "hey");
305     r = MsiRecordSetString(hrec, 3, "1");
306     r = MsiRecordSetString(hrec, 4, NULL);
307     r = MsiRecordSetString(hrec, 12, "big");
308     ok( r == ERROR_SUCCESS, "set string failed\n");
309     sz = sizeof buffer;
310     r = MsiFormatRecord(0, hrec, buffer, &sz);
311     ok( r == ERROR_SUCCESS, "format failed\n");
312     ok( sz == 10, "size wrong,(%li)\n",sz);
313     ok( 0 == strcmp(buffer,"[1[]2] hey"), "wrong output (%s)\n",buffer);
314
315     /* incorrect  formats */
316     r = MsiRecordSetString(hrec, 0, "[[[3][[4]][1]] [2]");
317     r = MsiRecordSetString(hrec, 1, "2");
318     r = MsiRecordSetString(hrec, 2, "hey");
319     r = MsiRecordSetString(hrec, 3, "1");
320     r = MsiRecordSetString(hrec, 4, NULL);
321     r = MsiRecordSetString(hrec, 12, "big");
322     ok( r == ERROR_SUCCESS, "set string failed\n");
323     sz = sizeof buffer;
324     r = MsiFormatRecord(0, hrec, buffer, &sz);
325     ok( r == ERROR_SUCCESS, "format failed\n");
326     ok( sz == 18, "size wrong,(%li)\n",sz);
327     ok( 0 == strcmp(buffer,"[[[3][[4]][1]] [2]"), "wrong output (%s)\n",buffer);
328
329     r = MsiRecordSetString(hrec, 0, "[[3][[4]][1]] [2]]");
330     r = MsiRecordSetString(hrec, 1, "2");
331     r = MsiRecordSetString(hrec, 2, "hey");
332     r = MsiRecordSetString(hrec, 3, "1");
333     r = MsiRecordSetString(hrec, 4, NULL);
334     r = MsiRecordSetString(hrec, 12, "big");
335     ok( r == ERROR_SUCCESS, "set string failed\n");
336     sz = sizeof buffer;
337     r = MsiFormatRecord(0, hrec, buffer, &sz);
338     ok( r == ERROR_SUCCESS, "format failed\n");
339     ok( sz == 11, "size wrong,(%li)\n",sz);
340     ok( 0 == strcmp(buffer,"[1[]2] hey]"), "wrong output (%s)\n",buffer);
341
342
343     /* play games with {} */
344
345     r = MsiRecordSetString(hrec, 0, "{[3][1]} [2]");
346     r = MsiRecordSetString(hrec, 1, "2");
347     r = MsiRecordSetString(hrec, 2, "hey");
348     r = MsiRecordSetString(hrec, 3, "1");
349     r = MsiRecordSetString(hrec, 4, NULL);
350     r = MsiRecordSetString(hrec, 12, "big");
351     ok( r == ERROR_SUCCESS, "set string failed\n");
352     sz = sizeof buffer;
353     r = MsiFormatRecord(0, hrec, buffer, &sz);
354     ok( r == ERROR_SUCCESS, "format failed\n");
355     ok( sz == 6, "size wrong,(%li)\n",sz);
356     ok( 0 == strcmp(buffer,"12 hey"), "wrong output (%s)\n",buffer);
357
358     r = MsiRecordSetString(hrec, 0, "[{[3][1]}] [2]");
359     r = MsiRecordSetString(hrec, 1, "2");
360     r = MsiRecordSetString(hrec, 2, "hey");
361     r = MsiRecordSetString(hrec, 3, "1");
362     r = MsiRecordSetString(hrec, 4, NULL);
363     r = MsiRecordSetString(hrec, 12, "big");
364     ok( r == ERROR_SUCCESS, "set string failed\n");
365     sz = sizeof buffer;
366     r = MsiFormatRecord(0, hrec, buffer, &sz);
367     ok( r == ERROR_SUCCESS, "format failed\n");
368     ok( sz == 8, "size wrong,(%li)\n",sz);
369     ok( 0 == strcmp(buffer,"[12] hey"), "wrong output (%s)\n",buffer);
370
371
372     r = MsiRecordSetString(hrec, 0, "{test} [2]");
373     r = MsiRecordSetString(hrec, 1, "2");
374     r = MsiRecordSetString(hrec, 2, "hey");
375     r = MsiRecordSetString(hrec, 3, "1");
376     r = MsiRecordSetString(hrec, 4, NULL);
377     r = MsiRecordSetString(hrec, 12, "big");
378     ok( r == ERROR_SUCCESS, "set string failed\n");
379     sz = sizeof buffer;
380     r = MsiFormatRecord(0, hrec, buffer, &sz);
381     ok( r == ERROR_SUCCESS, "format failed\n");
382     ok( sz == 10, "size wrong,(%li)\n",sz);
383     ok( 0 == strcmp(buffer,"{test} hey"), "wrong output (%s)\n",buffer);
384
385     r = MsiRecordSetString(hrec, 0, "{[test]} [2]");
386     r = MsiRecordSetString(hrec, 1, "2");
387     r = MsiRecordSetString(hrec, 2, "hey");
388     r = MsiRecordSetString(hrec, 3, "1");
389     r = MsiRecordSetString(hrec, 4, NULL);
390     r = MsiRecordSetString(hrec, 12, "big");
391     ok( r == ERROR_SUCCESS, "set string failed\n");
392     sz = sizeof buffer;
393     r = MsiFormatRecord(0, hrec, buffer, &sz);
394     ok( r == ERROR_SUCCESS, "format failed\n");
395     ok( sz == 12, "size wrong,(%li)\n",sz);
396     ok( 0 == strcmp(buffer,"{[test]} hey"), "wrong output (%s)\n",buffer);
397
398     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4]} [2]");
399     r = MsiRecordSetString(hrec, 1, "2");
400     r = MsiRecordSetString(hrec, 2, "hey");
401     r = MsiRecordSetString(hrec, 3, "1");
402     r = MsiRecordSetString(hrec, 4, NULL);
403     r = MsiRecordSetString(hrec, 12, "big");
404     ok( r == ERROR_SUCCESS, "set string failed\n");
405     sz = sizeof buffer;
406     r = MsiFormatRecord(0, hrec, buffer, &sz);
407     ok( r == ERROR_SUCCESS, "format failed\n");
408     ok( sz == 4, "size wrong,(%li)\n",sz);
409     ok( 0 == strcmp(buffer," hey"), "wrong output (%s)\n",buffer);
410
411     r = MsiRecordSetString(hrec, 0, "{[1][2][3][dummy]} [2]");
412     r = MsiRecordSetString(hrec, 1, "2");
413     r = MsiRecordSetString(hrec, 2, "hey");
414     r = MsiRecordSetString(hrec, 3, "1");
415     r = MsiRecordSetString(hrec, 4, NULL);
416     r = MsiRecordSetString(hrec, 12, "big");
417     ok( r == ERROR_SUCCESS, "set string failed\n");
418     sz = sizeof buffer;
419     r = MsiFormatRecord(0, hrec, buffer, &sz);
420     ok( r == ERROR_SUCCESS, "format failed\n");
421     ok( sz == 18, "size wrong,(%li)\n",sz);
422     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
423
424     r = MsiRecordSetString(hrec, 0, "{[1][2][3][4][dummy]} [2]");
425     r = MsiRecordSetString(hrec, 1, "2");
426     r = MsiRecordSetString(hrec, 2, "hey");
427     r = MsiRecordSetString(hrec, 3, "1");
428     r = MsiRecordSetString(hrec, 4, NULL);
429     r = MsiRecordSetString(hrec, 12, "big");
430     ok( r == ERROR_SUCCESS, "set string failed\n");
431     sz = sizeof buffer;
432     r = MsiFormatRecord(0, hrec, buffer, &sz);
433     ok( r == ERROR_SUCCESS, "format failed\n");
434     ok( sz == 18, "size wrong,(%li)\n",sz);
435     ok( 0 == strcmp(buffer,"{2hey1[dummy]} hey"), "wrong output (%s)\n",buffer);
436
437     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3][4][dummy]}");
438     r = MsiRecordSetString(hrec, 1, "2");
439     r = MsiRecordSetString(hrec, 2, "hey");
440     r = MsiRecordSetString(hrec, 3, "1");
441     r = MsiRecordSetString(hrec, 4, NULL);
442     r = MsiRecordSetString(hrec, 12, "big");
443     ok( r == ERROR_SUCCESS, "set string failed\n");
444     sz = sizeof buffer;
445     r = MsiFormatRecord(0, hrec, buffer, &sz);
446     ok( r == ERROR_SUCCESS, "format failed\n");
447
448     todo_wine{
449     ok( sz == 16, "size wrong,(%li)\n",sz);
450     ok( 0 == strcmp(buffer,"{{2hey}1[dummy]}"), "wrong output (%s)\n",buffer);
451     }
452
453     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]{[4][dummy]}}");
454     r = MsiRecordSetString(hrec, 1, "2");
455     r = MsiRecordSetString(hrec, 2, "hey");
456     r = MsiRecordSetString(hrec, 3, "1");
457     r = MsiRecordSetString(hrec, 4, NULL);
458     r = MsiRecordSetString(hrec, 12, "big");
459     ok( r == ERROR_SUCCESS, "set string failed\n");
460     sz = sizeof buffer;
461     r = MsiFormatRecord(0, hrec, buffer, &sz);
462     ok( r == ERROR_SUCCESS, "format failed\n");
463     todo_wine{
464     ok( sz == 0, "size wrong,(%li)\n",sz);
465     ok( 0 == strcmp(buffer,""), "wrong output (%s)\n",buffer);
466     }
467
468     r = MsiRecordSetString(hrec, 0, "{{[1][2]}[3]} {[1][2]}");
469     r = MsiRecordSetString(hrec, 1, "1");
470     r = MsiRecordSetString(hrec, 2, "2");
471     r = MsiRecordSetString(hrec, 3, "3");
472     r = MsiRecordSetString(hrec, 4, NULL);
473     r = MsiRecordSetString(hrec, 12, "big");
474     ok( r == ERROR_SUCCESS, "set string failed\n");
475     sz = sizeof buffer;
476     r = MsiFormatRecord(0, hrec, buffer, &sz);
477     ok( r == ERROR_SUCCESS, "format failed\n");
478     todo_wine{
479     ok( sz == 12, "size wrong,(%li)\n",sz);
480     ok( 0 == strcmp(buffer,"{{12}3} {12}"), "wrong output (%s)\n",buffer);
481     }
482
483     r = MsiRecordSetString(hrec, 0, "{[1][2]} {{[1][2]}[3]} {[1][2]}");
484     r = MsiRecordSetString(hrec, 1, "1");
485     r = MsiRecordSetString(hrec, 2, "2");
486     r = MsiRecordSetString(hrec, 3, "3");
487     r = MsiRecordSetString(hrec, 4, NULL);
488     r = MsiRecordSetString(hrec, 12, "big");
489     ok( r == ERROR_SUCCESS, "set string failed\n");
490     sz = sizeof buffer;
491     r = MsiFormatRecord(0, hrec, buffer, &sz);
492     ok( r == ERROR_SUCCESS, "format failed\n");
493     todo_wine{
494     ok( sz == 15, "size wrong,(%li)\n",sz);
495     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
496     }
497
498     r = MsiRecordSetString(hrec, 0, "{[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
499     r = MsiRecordSetString(hrec, 1, "1");
500     r = MsiRecordSetString(hrec, 2, "2");
501     r = MsiRecordSetString(hrec, 3, "3");
502     r = MsiRecordSetString(hrec, 4, NULL);
503     r = MsiRecordSetString(hrec, 12, "big");
504     ok( r == ERROR_SUCCESS, "set string failed\n");
505     sz = sizeof buffer;
506     r = MsiFormatRecord(0, hrec, buffer, &sz);
507     ok( r == ERROR_SUCCESS, "format failed\n");
508     todo_wine{
509     ok( sz == 15, "size wrong,(%li)\n",sz);
510     ok( 0 == strcmp(buffer,"12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
511     }
512
513
514     r = MsiRecordSetString(hrec, 0, "{blah} {[4]}{[1][2]} {{[1][2]}[3]} {[1][2]}");
515     r = MsiRecordSetString(hrec, 1, "1");
516     r = MsiRecordSetString(hrec, 2, "2");
517     r = MsiRecordSetString(hrec, 3, "3");
518     r = MsiRecordSetString(hrec, 4, NULL);
519     r = MsiRecordSetString(hrec, 12, "big");
520     ok( r == ERROR_SUCCESS, "set string failed\n");
521     sz = sizeof buffer;
522     r = MsiFormatRecord(0, hrec, buffer, &sz);
523     ok( r == ERROR_SUCCESS, "format failed\n");
524     todo_wine{
525     ok( sz == 22, "size wrong,(%li)\n",sz);
526     ok( 0 == strcmp(buffer,"{blah} 12 {{12}3} {12}"), "wrong output (%s)\n",buffer);
527     }
528
529     r = MsiRecordSetString(hrec, 0, "{{[1]}[2]} {[4]}{[1][2]}");
530     r = MsiRecordSetString(hrec, 1, "1");
531     r = MsiRecordSetString(hrec, 2, "2");
532     r = MsiRecordSetString(hrec, 3, "3");
533     r = MsiRecordSetString(hrec, 4, NULL);
534     r = MsiRecordSetString(hrec, 12, "big");
535     ok( r == ERROR_SUCCESS, "set string failed\n");
536     sz = sizeof buffer;
537     r = MsiFormatRecord(0, hrec, buffer, &sz);
538     ok( r == ERROR_SUCCESS, "format failed\n");
539     todo_wine{
540     ok( sz == 13, "size wrong,(%li)\n",sz);
541     ok( 0 == strcmp(buffer,"{{1}2} {}{12}"), "wrong output (%s)\n",buffer);
542     }
543
544     r = MsiRecordSetString(hrec, 0, "{{[1]}} {[4]}{[1][2]}");
545     r = MsiRecordSetString(hrec, 1, "1");
546     r = MsiRecordSetString(hrec, 2, "2");
547     r = MsiRecordSetString(hrec, 3, "3");
548     r = MsiRecordSetString(hrec, 4, NULL);
549     r = MsiRecordSetString(hrec, 12, "big");
550     ok( r == ERROR_SUCCESS, "set string failed\n");
551     sz = sizeof buffer;
552     r = MsiFormatRecord(0, hrec, buffer, &sz);
553     ok( r == ERROR_SUCCESS, "format failed\n");
554     todo_wine{
555     ok( sz == 3, "size wrong,(%li)\n",sz);
556     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
557     }
558
559     r = MsiRecordSetString(hrec, 0, "{{{[1]}} {[4]}{[1][2]}");
560     r = MsiRecordSetString(hrec, 1, "1");
561     r = MsiRecordSetString(hrec, 2, "2");
562     r = MsiRecordSetString(hrec, 3, "3");
563     r = MsiRecordSetString(hrec, 4, NULL);
564     r = MsiRecordSetString(hrec, 12, "big");
565     ok( r == ERROR_SUCCESS, "set string failed\n");
566     sz = sizeof buffer;
567     r = MsiFormatRecord(0, hrec, buffer, &sz);
568     ok( r == ERROR_SUCCESS, "format failed\n");
569     todo_wine{
570     ok( sz == 3, "size wrong,(%li)\n",sz);
571     ok( 0 == strcmp(buffer," 12"), "wrong output (%s)\n",buffer);
572     }
573     
574     /* now put play games with escaping */
575     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
576     r = MsiRecordSetString(hrec, 1, "boo");
577     r = MsiRecordSetString(hrec, 2, "hoo");
578     ok( r == ERROR_SUCCESS, "set string failed\n");
579     sz = sizeof buffer;
580     r = MsiFormatRecord(0, hrec, buffer, &sz);
581     ok( r == ERROR_SUCCESS, "format failed\n");
582     ok( sz == 16, "size wrong\n");
583     ok( 0 == strcmp(buffer,"boo hoo [\\3asdf]"), "wrong output\n");
584
585     /* now put play games with escaping */
586     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
587     r = MsiRecordSetString(hrec, 1, "boo");
588     r = MsiRecordSetString(hrec, 2, "hoo");
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 == 12, "size wrong\n");
594     ok( 0 == strcmp(buffer,"boo hoo [\\x]"), "wrong output\n");
595
596     /* now try other formats without a package */
597     r = MsiRecordSetString(hrec, 0, "[1] [2] [property]");
598     r = MsiRecordSetString(hrec, 1, "boo");
599     r = MsiRecordSetString(hrec, 2, "hoo");
600     ok( r == ERROR_SUCCESS, "set string failed\n");
601     sz = sizeof buffer;
602     r = MsiFormatRecord(0, hrec, buffer, &sz);
603     ok( r == ERROR_SUCCESS, "format failed\n");
604     ok( sz == 18, "size wrong\n");
605     ok( 0 == strcmp(buffer,"boo hoo [property]"), "wrong output\n");
606
607     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
608     r = MsiRecordSetString(hrec, 1, "boo");
609     r = MsiRecordSetString(hrec, 2, "hoo");
610     ok( r == ERROR_SUCCESS, "set string failed\n");
611     sz = sizeof buffer;
612     r = MsiFormatRecord(0, hrec, buffer, &sz);
613     ok( r == ERROR_SUCCESS, "format failed\n");
614     ok( sz == 11, "size wrong\n");
615     ok( 0 == strcmp(buffer,"boo [~] hoo"), "wrong output (%s)\n",buffer);
616 }
617
618 static void test_formatrecord_package(void)
619 {
620     static const CHAR filename[] = "winetest.msi";
621     char buffer[100];
622     MSIHANDLE hrec;
623     MSIHANDLE package;
624     UINT r;
625     DWORD sz=100;
626
627     package = helper_createpackage( filename );
628     ok(package!=0, "Unable to create package\n");
629
630     hrec = MsiCreateRecord(12);
631     ok( hrec, "failed to create record\n");
632
633     r = MsiFormatRecord(package, 0, NULL, NULL );
634     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
635
636     r = MsiFormatRecord(package, hrec, NULL, NULL );
637     ok( r == ERROR_SUCCESS, "format failed\n");
638
639     r = MsiRecordSetString(hrec,0,NULL);
640     r = MsiRecordSetString(hrec,1,NULL);
641     r = MsiRecordSetString(hrec,2,NULL);
642     r = MsiRecordSetString(hrec,3,NULL);
643     r = MsiRecordSetString(hrec,4,NULL);
644     r = MsiRecordSetString(hrec,5,NULL);
645     r = MsiRecordSetString(hrec,6,NULL);
646     r = MsiRecordSetString(hrec,7,NULL);
647     r = MsiRecordSetString(hrec,8,NULL);
648     r = MsiRecordSetString(hrec,9,NULL);
649     r = MsiRecordSetString(hrec,10,NULL);
650     r = MsiRecordSetString(hrec,11,NULL);
651     r = MsiRecordSetString(hrec,12,NULL);
652     ok( r == ERROR_SUCCESS, "set string failed\n");
653
654     sz = sizeof buffer;
655     r = MsiFormatRecord(package, hrec, buffer, &sz);
656     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
657     ok( sz == 51, "size wrong (%li)\n",sz);
658     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
659
660     /* now put play games with escaping */
661     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
662     r = MsiRecordSetString(hrec, 1, "boo");
663     r = MsiRecordSetString(hrec, 2, "hoo");
664     ok( r == ERROR_SUCCESS, "set string failed\n");
665     sz = sizeof buffer;
666     r = MsiFormatRecord(package, hrec, buffer, &sz);
667     ok( r == ERROR_SUCCESS, "format failed\n");
668     ok( sz == 9, "size wrong(%li)\n",sz);
669     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
670
671     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
672     r = MsiRecordSetString(hrec, 1, "boo");
673     r = MsiRecordSetString(hrec, 2, "hoo");
674     ok( r == ERROR_SUCCESS, "set string failed\n");
675     sz = sizeof buffer;
676     r = MsiFormatRecord(package, hrec, buffer, &sz);
677     ok( r == ERROR_SUCCESS, "format failed\n");
678     ok( sz == 9, "size wrong(%li)\n",sz);
679     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
680
681     /* null characters */
682     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
683     r = MsiRecordSetString(hrec, 1, "boo");
684     r = MsiRecordSetString(hrec, 2, "hoo");
685     ok( r == ERROR_SUCCESS, "set string failed\n");
686     sz = sizeof buffer;
687     r = MsiFormatRecord(package, hrec, buffer, &sz);
688     ok( r == ERROR_SUCCESS, "format failed\n");
689     ok( sz == 9, "size wrong\n");
690     ok( 0 == strcmp(buffer,"boo "), "wrong output\n");
691
692     /* properties */
693     r = MsiSetProperty(package,"dummy","Bork");
694     ok( r == ERROR_SUCCESS, "set property failed\n");
695     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
696     r = MsiRecordSetString(hrec, 1, "boo");
697     r = MsiRecordSetString(hrec, 2, "hoo");
698     ok( r == ERROR_SUCCESS, "set string failed\n");
699     sz = sizeof buffer;
700     r = MsiFormatRecord(package, hrec, buffer, &sz);
701     ok( r == ERROR_SUCCESS, "format failed\n");
702     ok( sz == 12, "size wrong\n");
703     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
704
705     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
706     r = MsiRecordSetString(hrec, 1, "boo");
707     r = MsiRecordSetString(hrec, 2, "hoo");
708     ok( r == ERROR_SUCCESS, "set string failed\n");
709     sz = sizeof buffer;
710     r = MsiFormatRecord(package, hrec, buffer, &sz);
711     ok( r == ERROR_SUCCESS, "format failed\n");
712     ok( sz == 8, "size wrong\n");
713     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
714
715
716     /* nesting tests */
717     r = MsiSetProperty(package,"dummya","foo");
718     r = MsiSetProperty(package,"dummyb","baa");
719     r = MsiSetProperty(package,"adummyc","whoa");
720     ok( r == ERROR_SUCCESS, "set property failed\n");
721     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
722     r = MsiRecordSetString(hrec, 1, "a");
723     r = MsiRecordSetString(hrec, 2, "b");
724     r = MsiRecordSetString(hrec, 3, "c");
725     ok( r == ERROR_SUCCESS, "set string failed\n");
726     sz = sizeof buffer;
727     r = MsiFormatRecord(package, hrec, buffer, &sz);
728     ok( r == ERROR_SUCCESS, "format failed\n");
729     ok( sz == 12, "size wrong(%li)\n",sz);
730     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
731
732
733     r = MsiSetProperty(package,"dummya","1");
734     r = MsiSetProperty(package,"dummyb","[2]");
735     ok( r == ERROR_SUCCESS, "set property failed\n");
736     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
737     r = MsiRecordSetString(hrec, 1, "aaa");
738     r = MsiRecordSetString(hrec, 2, "bbb");
739     r = MsiRecordSetString(hrec, 3, "ccc");
740     ok( r == ERROR_SUCCESS, "set string failed\n");
741     sz = sizeof buffer;
742     r = MsiFormatRecord(package, hrec, buffer, &sz);
743     ok( r == ERROR_SUCCESS, "format failed\n");
744     ok( sz == 9, "size wrong(%li)\n",sz);
745     ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
746
747     r = MsiSetProperty(package,"dummya","1");
748     r = MsiSetProperty(package,"dummyb","a");
749     r = MsiSetProperty(package,"dummyc","\\blath");
750     r = MsiSetProperty(package,"dummyd","[\\blath]");
751     ok( r == ERROR_SUCCESS, "set property failed\n");
752     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
753     r = MsiRecordSetString(hrec, 1, "aaa");
754     r = MsiRecordSetString(hrec, 2, "bbb");
755     r = MsiRecordSetString(hrec, 3, "ccc");
756     ok( r == ERROR_SUCCESS, "set string failed\n");
757     sz = sizeof buffer;
758     r = MsiFormatRecord(package, hrec, buffer, &sz);
759     ok( r == ERROR_SUCCESS, "format failed\n");
760     ok( sz == 10, "size wrong(%li)\n",sz);
761     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
762
763     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
764     r = MsiRecordSetString(hrec, 1, "boo");
765     r = MsiRecordSetString(hrec, 2, "hoo");
766     r = MsiRecordSetString(hrec, 3, "yeah");
767     ok( r == ERROR_SUCCESS, "set string failed\n");
768     sz = sizeof buffer;
769     r = MsiFormatRecord(package, hrec, buffer, &sz);
770     ok( r == ERROR_SUCCESS, "format failed\n");
771     ok( sz == 11, "size wrong(%li)\n",sz);
772     ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
773
774     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
775     r = MsiRecordSetString(hrec, 1, "boo");
776     r = MsiRecordSetString(hrec, 2, "hoo");
777     r = MsiRecordSetString(hrec, 3, "\\help");
778     ok( r == ERROR_SUCCESS, "set string failed\n");
779     sz = sizeof buffer;
780     r = MsiFormatRecord(package, hrec, buffer, &sz);
781     ok( r == ERROR_SUCCESS, "format failed\n");
782     ok( sz == 9, "size wrong(%li)\n",sz);
783     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
784
785     r = MsiCloseHandle(package);
786     ok(r==ERROR_SUCCESS, "Unable to close package\n");
787
788     DeleteFile( filename );
789 }
790
791 START_TEST(format)
792 {
793     test_createpackage();
794     test_formatrecord();
795     test_formatrecord_package();
796 }