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