comctl32: A couple fixes for tab icon offsets.
[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;
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     MsiCloseHandle(hrec);
634 }
635
636 static void test_formatrecord_package(void)
637 {
638     static const CHAR filename[] = "winetest.msi";
639     char buffer[100];
640     MSIHANDLE hrec;
641     MSIHANDLE package;
642     UINT r;
643     DWORD sz=100;
644
645     package = helper_createpackage( filename );
646     ok(package!=0, "Unable to create package\n");
647
648     hrec = MsiCreateRecord(12);
649     ok( hrec, "failed to create record\n");
650
651     r = MsiFormatRecord(package, 0, NULL, NULL );
652     ok( r == ERROR_INVALID_HANDLE, "wrong error\n");
653
654     r = MsiFormatRecord(package, hrec, NULL, NULL );
655     ok( r == ERROR_SUCCESS, "format failed\n");
656
657     r = MsiRecordSetString(hrec,0,NULL);
658     r = MsiRecordSetString(hrec,1,NULL);
659     r = MsiRecordSetString(hrec,2,NULL);
660     r = MsiRecordSetString(hrec,3,NULL);
661     r = MsiRecordSetString(hrec,4,NULL);
662     r = MsiRecordSetString(hrec,5,NULL);
663     r = MsiRecordSetString(hrec,6,NULL);
664     r = MsiRecordSetString(hrec,7,NULL);
665     r = MsiRecordSetString(hrec,8,NULL);
666     r = MsiRecordSetString(hrec,9,NULL);
667     r = MsiRecordSetString(hrec,10,NULL);
668     r = MsiRecordSetString(hrec,11,NULL);
669     r = MsiRecordSetString(hrec,12,NULL);
670     ok( r == ERROR_SUCCESS, "set string failed\n");
671
672     sz = sizeof buffer;
673     r = MsiFormatRecord(package, hrec, buffer, &sz);
674     ok( r == ERROR_SUCCESS, "format failed with empty buffer (%i)\n",r);
675     ok( sz == 51, "size wrong (%li)\n",sz);
676     ok( 0 == strcmp(buffer,"1:  2:  3:  4:  5:  6:  7:  8:  9:  10:  11:  12:  "), "wrong output(%s)\n",buffer);
677
678     /* now put play games with escaping */
679     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\3asdf]");
680     r = MsiRecordSetString(hrec, 1, "boo");
681     r = MsiRecordSetString(hrec, 2, "hoo");
682     ok( r == ERROR_SUCCESS, "set string failed\n");
683     sz = sizeof buffer;
684     r = MsiFormatRecord(package, hrec, buffer, &sz);
685     ok( r == ERROR_SUCCESS, "format failed\n");
686     ok( sz == 9, "size wrong(%li)\n",sz);
687     ok( 0 == strcmp(buffer,"boo hoo 3"), "wrong output (%s)\n",buffer);
688
689     r = MsiRecordSetString(hrec, 0, "[1] [2] [\\x]");
690     r = MsiRecordSetString(hrec, 1, "boo");
691     r = MsiRecordSetString(hrec, 2, "hoo");
692     ok( r == ERROR_SUCCESS, "set string failed\n");
693     sz = sizeof buffer;
694     r = MsiFormatRecord(package, hrec, buffer, &sz);
695     ok( r == ERROR_SUCCESS, "format failed\n");
696     ok( sz == 9, "size wrong(%li)\n",sz);
697     ok( 0 == strcmp(buffer,"boo hoo x"), "wrong output (%s)\n",buffer);
698
699     /* null characters */
700     r = MsiRecordSetString(hrec, 0, "[1] [~] [2]");
701     r = MsiRecordSetString(hrec, 1, "boo");
702     r = MsiRecordSetString(hrec, 2, "hoo");
703     ok( r == ERROR_SUCCESS, "set string failed\n");
704     sz = sizeof buffer;
705     r = MsiFormatRecord(package, hrec, buffer, &sz);
706     ok( r == ERROR_SUCCESS, "format failed\n");
707     ok( sz == 9, "size wrong\n");
708     ok( 0 == strcmp(buffer,"boo "), "wrong output\n");
709
710     /* properties */
711     r = MsiSetProperty(package,"dummy","Bork");
712     ok( r == ERROR_SUCCESS, "set property failed\n");
713     r = MsiRecordSetString(hrec, 0, "[1] [dummy] [2]");
714     r = MsiRecordSetString(hrec, 1, "boo");
715     r = MsiRecordSetString(hrec, 2, "hoo");
716     ok( r == ERROR_SUCCESS, "set string failed\n");
717     sz = sizeof buffer;
718     r = MsiFormatRecord(package, hrec, buffer, &sz);
719     ok( r == ERROR_SUCCESS, "format failed\n");
720     ok( sz == 12, "size wrong\n");
721     ok( 0 == strcmp(buffer,"boo Bork hoo"), "wrong output\n");
722
723     r = MsiRecordSetString(hrec, 0, "[1] [invalid] [2]");
724     r = MsiRecordSetString(hrec, 1, "boo");
725     r = MsiRecordSetString(hrec, 2, "hoo");
726     ok( r == ERROR_SUCCESS, "set string failed\n");
727     sz = sizeof buffer;
728     r = MsiFormatRecord(package, hrec, buffer, &sz);
729     ok( r == ERROR_SUCCESS, "format failed\n");
730     ok( sz == 8, "size wrong\n");
731     ok( 0 == strcmp(buffer,"boo  hoo"), "wrong output\n");
732
733
734     /* nesting tests */
735     r = MsiSetProperty(package,"dummya","foo");
736     r = MsiSetProperty(package,"dummyb","baa");
737     r = MsiSetProperty(package,"adummyc","whoa");
738     ok( r == ERROR_SUCCESS, "set property failed\n");
739     r = MsiRecordSetString(hrec, 0, "[dummy[1]] [dummy[2]] [[1]dummy[3]]");
740     r = MsiRecordSetString(hrec, 1, "a");
741     r = MsiRecordSetString(hrec, 2, "b");
742     r = MsiRecordSetString(hrec, 3, "c");
743     ok( r == ERROR_SUCCESS, "set string failed\n");
744     sz = sizeof buffer;
745     r = MsiFormatRecord(package, hrec, buffer, &sz);
746     ok( r == ERROR_SUCCESS, "format failed\n");
747     ok( sz == 12, "size wrong(%li)\n",sz);
748     ok( 0 == strcmp(buffer,"foo baa whoa"), "wrong output (%s)\n",buffer);
749
750
751     r = MsiSetProperty(package,"dummya","1");
752     r = MsiSetProperty(package,"dummyb","[2]");
753     ok( r == ERROR_SUCCESS, "set property failed\n");
754     r = MsiRecordSetString(hrec, 0, "[dummya] [[dummya]] [dummyb]");
755     r = MsiRecordSetString(hrec, 1, "aaa");
756     r = MsiRecordSetString(hrec, 2, "bbb");
757     r = MsiRecordSetString(hrec, 3, "ccc");
758     ok( r == ERROR_SUCCESS, "set string failed\n");
759     sz = sizeof buffer;
760     r = MsiFormatRecord(package, hrec, buffer, &sz);
761     ok( r == ERROR_SUCCESS, "format failed\n");
762     ok( sz == 9, "size wrong(%li)\n",sz);
763     ok( 0 == strcmp(buffer,"1 [1] [2]"), "wrong output (%s)\n",buffer);
764
765     r = MsiSetProperty(package,"dummya","1");
766     r = MsiSetProperty(package,"dummyb","a");
767     r = MsiSetProperty(package,"dummyc","\\blath");
768     r = MsiSetProperty(package,"dummyd","[\\blath]");
769     ok( r == ERROR_SUCCESS, "set property failed\n");
770     r = MsiRecordSetString(hrec, 0, "[dummyc] [[dummyc]] [dummy[dummyb]]");
771     r = MsiRecordSetString(hrec, 1, "aaa");
772     r = MsiRecordSetString(hrec, 2, "bbb");
773     r = MsiRecordSetString(hrec, 3, "ccc");
774     ok( r == ERROR_SUCCESS, "set string failed\n");
775     sz = sizeof buffer;
776     r = MsiFormatRecord(package, hrec, buffer, &sz);
777     ok( r == ERROR_SUCCESS, "format failed\n");
778     ok( sz == 10, "size wrong(%li)\n",sz);
779     ok( 0 == strcmp(buffer,"\\blath b 1"), "wrong output (%s)\n",buffer);
780
781     r = MsiRecordSetString(hrec, 0, "[1] [2] [[\\3asdf]]");
782     r = MsiRecordSetString(hrec, 1, "boo");
783     r = MsiRecordSetString(hrec, 2, "hoo");
784     r = MsiRecordSetString(hrec, 3, "yeah");
785     ok( r == ERROR_SUCCESS, "set string failed\n");
786     sz = sizeof buffer;
787     r = MsiFormatRecord(package, hrec, buffer, &sz);
788     ok( r == ERROR_SUCCESS, "format failed\n");
789     ok( sz == 11, "size wrong(%li)\n",sz);
790     ok( 0 == strcmp(buffer,"boo hoo [3]"), "wrong output (%s)\n",buffer);
791
792     r = MsiRecordSetString(hrec, 0, "[1] [2] [[3]]");
793     r = MsiRecordSetString(hrec, 1, "boo");
794     r = MsiRecordSetString(hrec, 2, "hoo");
795     r = MsiRecordSetString(hrec, 3, "\\help");
796     ok( r == ERROR_SUCCESS, "set string failed\n");
797     sz = sizeof buffer;
798     r = MsiFormatRecord(package, hrec, buffer, &sz);
799     ok( r == ERROR_SUCCESS, "format failed\n");
800     ok( sz == 9, "size wrong(%li)\n",sz);
801     ok( 0 == strcmp(buffer,"boo hoo h"), "wrong output (%s)\n",buffer);
802
803     MsiCloseHandle(hrec);
804
805     r = MsiCloseHandle(package);
806     ok(r==ERROR_SUCCESS, "Unable to close package\n");
807
808     DeleteFile( filename );
809 }
810
811 START_TEST(format)
812 {
813     test_createpackage();
814     test_formatrecord();
815     test_formatrecord_package();
816 }