comctl32: A couple fixes for tab icon offsets.
[wine] / dlls / msi / tests / package.c
1 /*
2  * tests for Microsoft Installer functionality
3  *
4  * Copyright 2005 Mike McCormack for CodeWeavers
5  * Copyright 2005 Aric Stewart for CodeWeavers
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 #define COBJMACROS
23
24 #include <stdio.h>
25 #include <windows.h>
26 #include <msi.h>
27 #include <msiquery.h>
28
29 #include "wine/test.h"
30
31 static UINT run_query( MSIHANDLE hdb, const char *query )
32 {
33     MSIHANDLE hview = 0;
34     UINT r;
35
36     r = MsiDatabaseOpenView(hdb, query, &hview);
37     if( r != ERROR_SUCCESS )
38         return r;
39
40     r = MsiViewExecute(hview, 0);
41     if( r == ERROR_SUCCESS )
42         r = MsiViewClose(hview);
43     MsiCloseHandle(hview);
44     return r;
45 }
46
47 static UINT set_summary_info(MSIHANDLE hdb)
48 {
49     UINT res;
50     MSIHANDLE suminfo;
51
52     /* build summmary info */
53     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
54     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
55
56     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
57                         "Installation Database");
58     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
59
60     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
61                         "Installation Database");
62     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
63
64     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
65                         "Wine Hackers");
66     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
67
68     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
69                     ";1033");
70     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
71
72     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
73                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
74     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
75
76     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
77     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
78
79     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
80     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
81
82     res = MsiSummaryInfoPersist(suminfo);
83     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
84
85     res = MsiCloseHandle( suminfo);
86     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
87
88     return res;
89 }
90
91
92 MSIHANDLE create_package_db(void)
93 {
94     MSIHANDLE hdb = 0;
95     CHAR szName[] = "winetest.msi";
96     UINT res;
97
98     DeleteFile(szName);
99
100     /* create an empty database */
101     res = MsiOpenDatabase(szName, MSIDBOPEN_CREATE, &hdb );
102     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
103     if( res != ERROR_SUCCESS )
104         return hdb;
105
106     res = MsiDatabaseCommit( hdb );
107     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
108
109     res = set_summary_info(hdb);
110
111     res = run_query( hdb,
112             "CREATE TABLE `Directory` ( "
113             "`Directory` CHAR(255) NOT NULL, "
114             "`Directory_Parent` CHAR(255), "
115             "`DefaultDir` CHAR(255) NOT NULL "
116             "PRIMARY KEY `Directory`)" );
117     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
118
119     return hdb;
120 }
121
122 MSIHANDLE package_from_db(MSIHANDLE hdb)
123 {
124     UINT res;
125     CHAR szPackage[10];
126     MSIHANDLE hPackage;
127
128     sprintf(szPackage,"#%li",hdb);
129     res = MsiOpenPackage(szPackage,&hPackage);
130     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
131
132     res = MsiCloseHandle(hdb);
133     ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
134
135     return hPackage;
136 }
137
138 static void test_createpackage(void)
139 {
140     MSIHANDLE hPackage = 0;
141     UINT res;
142
143     hPackage = package_from_db(create_package_db());
144     ok( hPackage != 0, " Failed to create package\n");
145
146     res = MsiCloseHandle( hPackage);
147     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
148 }
149
150 static void test_getsourcepath_bad( void )
151 {
152     static const char str[] = { 0 };
153     char buffer[0x80];
154     DWORD sz;
155     UINT r;
156
157     r = MsiGetSourcePath( -1, NULL, NULL, NULL );
158     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
159
160     sz = 0;
161     r = MsiGetSourcePath( -1, NULL, buffer, &sz );
162     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
163
164     sz = 0;
165     r = MsiGetSourcePath( -1, str, NULL, &sz );
166     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
167
168     sz = 0;
169     r = MsiGetSourcePath( -1, str, NULL, NULL );
170     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
171
172     sz = 0;
173     r = MsiGetSourcePath( -1, str, buffer, &sz );
174     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
175 }
176
177 static UINT add_directory_entry( MSIHANDLE hdb, char *values )
178 {
179     char insert[] = "INSERT INTO `Directory` (`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )";
180     char *query;
181     UINT sz, r;
182
183     sz = strlen(values) + sizeof insert;
184     query = HeapAlloc(GetProcessHeap(),0,sz);
185     sprintf(query,insert,values);
186     r = run_query( hdb, query );
187     HeapFree(GetProcessHeap(), 0, query);
188     return r;
189 }
190
191 static void test_getsourcepath( void )
192 {
193     static const char str[] = { 0 };
194     char buffer[0x80];
195     DWORD sz;
196     UINT r;
197     MSIHANDLE hpkg, hdb;
198
199     hpkg = package_from_db(create_package_db());
200     ok( hpkg, "failed to create package\n");
201
202     sz = 0;
203     buffer[0] = 'x';
204     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
205     ok( r == ERROR_DIRECTORY, "return value wrong\n");
206     ok( buffer[0] == 'x', "buffer modified\n");
207
208     sz = 1;
209     buffer[0] = 'x';
210     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
211     ok( r == ERROR_DIRECTORY, "return value wrong\n");
212     ok( buffer[0] == 'x', "buffer modified\n");
213
214     MsiCloseHandle( hpkg );
215
216
217     /* another test but try create a directory this time */
218     hdb = create_package_db();
219     ok( hdb, "failed to create database\n");
220     
221     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
222     ok( r == S_OK, "failed\n");
223
224     hpkg = package_from_db(hdb);
225     ok( hpkg, "failed to create package\n");
226
227     sz = sizeof buffer -1;
228     strcpy(buffer,"x bad");
229     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
230     ok( r == ERROR_DIRECTORY, "return value wrong\n");
231
232     todo_wine {
233     r = MsiDoAction( hpkg, "CostInitialize");
234     ok( r == ERROR_SUCCESS, "cost init failed\n");
235     }
236     r = MsiDoAction( hpkg, "CostFinalize");
237     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
238
239     todo_wine {
240     sz = sizeof buffer -1;
241     buffer[0] = 'x';
242     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
243     ok( r == ERROR_SUCCESS, "return value wrong\n");
244     ok( sz == strlen(buffer), "returned length wrong\n");
245
246     sz = 0;
247     strcpy(buffer,"x bad");
248     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
249     ok( r == ERROR_MORE_DATA, "return value wrong\n");
250     }
251     ok( buffer[0] == 'x', "buffer modified\n");
252
253     todo_wine {
254     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, NULL );
255     ok( r == ERROR_SUCCESS, "return value wrong\n");
256     }
257
258     r = MsiGetSourcePath( hpkg, "TARGETDIR ", NULL, NULL );
259     ok( r == ERROR_DIRECTORY, "return value wrong\n");
260
261     r = MsiGetSourcePath( hpkg, "targetdir", NULL, NULL );
262     ok( r == ERROR_DIRECTORY, "return value wrong\n");
263
264     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, NULL );
265     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
266
267     todo_wine {
268     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, &sz );
269     ok( r == ERROR_SUCCESS, "return value wrong\n");
270     }
271
272     MsiCloseHandle( hpkg );
273 }
274
275 static void test_doaction( void )
276 {
277     MSIHANDLE hpkg;
278     UINT r;
279
280     r = MsiDoAction( -1, NULL );
281     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
282
283     hpkg = package_from_db(create_package_db());
284     ok( hpkg, "failed to create package\n");
285
286     r = MsiDoAction(hpkg, NULL);
287     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
288
289     r = MsiDoAction(0, "boo");
290     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
291
292     r = MsiDoAction(hpkg, "boo");
293     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
294
295     MsiCloseHandle( hpkg );
296 }
297
298 static void test_gettargetpath_bad(void)
299 {
300     char buffer[0x80];
301     MSIHANDLE hpkg;
302     DWORD sz;
303     UINT r;
304
305     hpkg = package_from_db(create_package_db());
306     ok( hpkg, "failed to create package\n");
307
308     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
309     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
310
311     r = MsiGetTargetPath( 0, NULL, NULL, &sz );
312     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
313
314     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
315     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
316
317     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
318     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
319
320     r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
321     ok( r == ERROR_DIRECTORY, "wrong return val\n");
322
323     r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
324     ok( r == ERROR_DIRECTORY, "wrong return val\n");
325
326     MsiCloseHandle( hpkg );
327 }
328
329 static void test_settargetpath_bad(void)
330 {
331     MSIHANDLE hpkg;
332     UINT r;
333
334     hpkg = package_from_db(create_package_db());
335     ok( hpkg, "failed to create package\n");
336
337     r = MsiSetTargetPath( 0, NULL, NULL );
338     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
339
340     r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
341     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
342
343     r = MsiSetTargetPath( hpkg, "boo", NULL );
344     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
345
346     r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
347     ok( r == ERROR_DIRECTORY, "wrong return val\n");
348
349     MsiCloseHandle( hpkg );
350 }
351
352 static void test_condition(void)
353 {
354     MSICONDITION r;
355     MSIHANDLE hpkg;
356
357     hpkg = package_from_db(create_package_db());
358     ok( hpkg, "failed to create package\n");
359
360     r = MsiEvaluateCondition(0, NULL);
361     ok( r == MSICONDITION_ERROR, "wrong return val\n");
362
363     r = MsiEvaluateCondition(hpkg, NULL);
364     ok( r == MSICONDITION_NONE, "wrong return val\n");
365
366     r = MsiEvaluateCondition(hpkg, "");
367     ok( r == MSICONDITION_NONE, "wrong return val\n");
368
369     r = MsiEvaluateCondition(hpkg, "1");
370     ok( r == MSICONDITION_TRUE, "wrong return val\n");
371
372     r = MsiEvaluateCondition(hpkg, "0");
373     ok( r == MSICONDITION_FALSE, "wrong return val\n");
374
375     r = MsiEvaluateCondition(hpkg, "0 = 0");
376     ok( r == MSICONDITION_TRUE, "wrong return val\n");
377
378     r = MsiEvaluateCondition(hpkg, "0 <> 0");
379     ok( r == MSICONDITION_FALSE, "wrong return val\n");
380
381     r = MsiEvaluateCondition(hpkg, "0 = 1");
382     ok( r == MSICONDITION_FALSE, "wrong return val\n");
383
384     r = MsiEvaluateCondition(hpkg, "0 >= 1");
385     ok( r == MSICONDITION_FALSE, "wrong return val\n");
386
387     r = MsiEvaluateCondition(hpkg, "0 >=");
388     ok( r == MSICONDITION_ERROR, "wrong return val\n");
389
390     r = MsiEvaluateCondition(hpkg, " ");
391     ok( r == MSICONDITION_NONE, "wrong return val\n");
392
393     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
394     ok( r == MSICONDITION_TRUE, "wrong return val\n");
395
396     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
397     ok( r == MSICONDITION_TRUE, "wrong return val\n");
398
399     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
400     ok( r == MSICONDITION_FALSE, "wrong return val\n");
401
402     r = MsiEvaluateCondition(hpkg, "not 0");
403     ok( r == MSICONDITION_TRUE, "wrong return val\n");
404
405     r = MsiEvaluateCondition(hpkg, "not LicView");
406     ok( r == MSICONDITION_TRUE, "wrong return val\n");
407
408     r = MsiEvaluateCondition(hpkg, "not \"A\"");
409     ok( r == MSICONDITION_FALSE, "wrong return val\n");
410
411     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
412     ok( r == MSICONDITION_ERROR, "wrong return val\n");
413
414     r = MsiEvaluateCondition(hpkg, "\"0\"");
415     ok( r == MSICONDITION_TRUE, "wrong return val\n");
416
417     r = MsiEvaluateCondition(hpkg, "1 and 2");
418     ok( r == MSICONDITION_TRUE, "wrong return val\n");
419
420     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
421     ok( r == MSICONDITION_TRUE, "wrong return val\n");
422
423     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
424     ok( r == MSICONDITION_FALSE, "wrong return val\n");
425
426     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
427     ok( r == MSICONDITION_TRUE, "wrong return val\n");
428
429     r = MsiEvaluateCondition(hpkg, "(0)");
430     ok( r == MSICONDITION_FALSE, "wrong return val\n");
431
432     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
433     ok( r == MSICONDITION_ERROR, "wrong return val\n");
434
435     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
436     ok( r == MSICONDITION_TRUE, "wrong return val\n");
437
438     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
439     ok( r == MSICONDITION_TRUE, "wrong return val\n");
440
441     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
442     ok( r == MSICONDITION_FALSE, "wrong return val\n");
443
444     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
445     ok( r == MSICONDITION_FALSE, "wrong return val\n");
446
447     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
448     ok( r == MSICONDITION_TRUE, "wrong return val\n");
449
450     r = MsiEvaluateCondition(hpkg, "0 < > 0");
451     ok( r == MSICONDITION_ERROR, "wrong return val\n");
452
453     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
454     ok( r == MSICONDITION_ERROR, "wrong return val\n");
455
456     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
457     ok( r == MSICONDITION_FALSE, "wrong return val\n");
458
459     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
460     ok( r == MSICONDITION_ERROR, "wrong return val\n");
461
462     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
463     ok( r == MSICONDITION_TRUE, "wrong return val\n");
464
465     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
466     ok( r == MSICONDITION_FALSE, "wrong return val\n");
467
468     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
469     ok( r == MSICONDITION_FALSE, "wrong return val\n");
470
471     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
472     ok( r == MSICONDITION_TRUE, "wrong return val\n");
473
474     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
475     ok( r == MSICONDITION_FALSE, "wrong return val\n");
476
477     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
478     ok( r == MSICONDITION_FALSE, "wrong return val\n");
479
480     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
481     ok( r == MSICONDITION_FALSE, "wrong return val\n");
482
483     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
484     ok( r == MSICONDITION_FALSE, "wrong return val\n");
485
486     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
487     ok( r == MSICONDITION_FALSE, "wrong return val\n");
488
489     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
490     ok( r == MSICONDITION_FALSE, "wrong return val\n");
491
492     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
493     ok( r == MSICONDITION_TRUE, "wrong return val\n");
494
495     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
496     ok( r == MSICONDITION_FALSE, "wrong return val\n");
497
498     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
499     ok( r == MSICONDITION_TRUE, "wrong return val\n");
500
501     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
502     ok( r == MSICONDITION_TRUE, "wrong return val\n");
503
504     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
505     ok( r == MSICONDITION_FALSE, "wrong return val\n");
506
507     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
508     ok( r == MSICONDITION_TRUE, "wrong return val\n");
509
510     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
511     ok( r == MSICONDITION_ERROR, "wrong return val\n");
512
513     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
514     ok( r == MSICONDITION_TRUE, "wrong return val\n");
515
516     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
517     ok( r == MSICONDITION_TRUE, "wrong return val\n");
518
519     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
520     ok( r == MSICONDITION_TRUE, "wrong return val\n");
521
522     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
523     ok( r == MSICONDITION_FALSE, "wrong return val\n");
524
525     MsiSetProperty(hpkg, "mm", "5" );
526
527     r = MsiEvaluateCondition(hpkg, "mm = 5");
528     ok( r == MSICONDITION_TRUE, "wrong return val\n");
529
530     r = MsiEvaluateCondition(hpkg, "mm < 6");
531     ok( r == MSICONDITION_TRUE, "wrong return val\n");
532
533     r = MsiEvaluateCondition(hpkg, "mm <= 5");
534     ok( r == MSICONDITION_TRUE, "wrong return val\n");
535
536     r = MsiEvaluateCondition(hpkg, "mm > 4");
537     ok( r == MSICONDITION_TRUE, "wrong return val\n");
538
539     r = MsiEvaluateCondition(hpkg, "mm < 12");
540     ok( r == MSICONDITION_TRUE, "wrong return val\n");
541
542     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
543     ok( r == MSICONDITION_TRUE, "wrong return val\n");
544
545     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
546     ok( r == MSICONDITION_FALSE, "wrong return val\n");
547
548     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
549     ok( r == MSICONDITION_FALSE, "wrong return val\n");
550
551     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
552     ok( r == MSICONDITION_FALSE, "wrong return val\n");
553
554     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
555     ok( r == MSICONDITION_TRUE, "wrong return val\n");
556
557     r = MsiEvaluateCondition(hpkg, "3 >< 1");
558     ok( r == MSICONDITION_TRUE, "wrong return val\n");
559
560     r = MsiEvaluateCondition(hpkg, "3 >< 4");
561     ok( r == MSICONDITION_FALSE, "wrong return val\n");
562
563     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
564     ok( r == MSICONDITION_FALSE, "wrong return val\n");
565
566     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
567     ok( r == MSICONDITION_TRUE, "wrong return val\n");
568
569     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
570     ok( r == MSICONDITION_FALSE, "wrong return val\n");
571
572     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
573     ok( r == MSICONDITION_TRUE, "wrong return val\n");
574
575     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
576     ok( r == MSICONDITION_TRUE, "wrong return val\n");
577
578     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
579     ok( r == MSICONDITION_TRUE, "wrong return val\n");
580
581     r = MsiEvaluateCondition(hpkg, "_1 = _1");
582     ok( r == MSICONDITION_TRUE, "wrong return val\n");
583
584     r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
585     ok( r == MSICONDITION_ERROR, "wrong return val\n");
586
587     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
588     ok( r == MSICONDITION_FALSE, "wrong return val\n");
589
590     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
591     ok( r == MSICONDITION_FALSE, "wrong return val\n");
592
593     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
594     ok( r == MSICONDITION_FALSE, "wrong return val\n");
595
596     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
597     ok( r == MSICONDITION_FALSE, "wrong return val\n");
598
599     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
600     ok( r == MSICONDITION_FALSE, "wrong return val\n");
601
602     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
603     ok( r == MSICONDITION_TRUE, "wrong return val\n");
604
605     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
606     ok( r == MSICONDITION_FALSE, "wrong return val\n");
607
608     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
609     ok( r == MSICONDITION_FALSE, "wrong return val\n");
610
611     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
612     ok( r == MSICONDITION_FALSE, "wrong return val\n");
613
614     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
615     ok( r == MSICONDITION_FALSE, "wrong return val\n");
616
617     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
618     ok( r == MSICONDITION_TRUE, "wrong return val\n");
619
620     MsiSetProperty(hpkg, "bandalmael", "0" );
621     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
622     ok( r == MSICONDITION_TRUE, "wrong return val\n");
623
624     MsiSetProperty(hpkg, "bandalmael", "" );
625     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
626     ok( r == MSICONDITION_FALSE, "wrong return val\n");
627
628     MsiSetProperty(hpkg, "bandalmael", "asdf" );
629     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
630     ok( r == MSICONDITION_FALSE, "wrong return val\n");
631
632     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
633     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
634     ok( r == MSICONDITION_FALSE, "wrong return val\n");
635
636     MsiSetProperty(hpkg, "bandalmael", "0 " );
637     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
638     ok( r == MSICONDITION_FALSE, "wrong return val\n");
639
640     MsiSetProperty(hpkg, "bandalmael", "-0" );
641     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
642     ok( r == MSICONDITION_TRUE, "wrong return val\n");
643
644     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
645     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
646     ok( r == MSICONDITION_TRUE, "wrong return val\n");
647
648     MsiSetProperty(hpkg, "bandalmael", "--0" );
649     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
650     ok( r == MSICONDITION_FALSE, "wrong return val\n");
651
652     MsiSetProperty(hpkg, "bandalmael", "0x00" );
653     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
654     ok( r == MSICONDITION_FALSE, "wrong return val\n");
655
656     MsiSetProperty(hpkg, "bandalmael", "-" );
657     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
658     ok( r == MSICONDITION_FALSE, "wrong return val\n");
659
660     MsiSetProperty(hpkg, "bandalmael", "+0" );
661     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
662     ok( r == MSICONDITION_FALSE, "wrong return val\n");
663
664     MsiSetProperty(hpkg, "bandalmael", "0.0" );
665     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
666     ok( r == MSICONDITION_FALSE, "wrong return val\n");
667     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
668     ok( r == MSICONDITION_TRUE, "wrong return val\n");
669
670     MsiCloseHandle( hpkg );
671 }
672
673 static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
674 {
675     UINT r;
676     DWORD sz;
677     char buffer[2];
678
679     sz = sizeof buffer;
680     strcpy(buffer,"x");
681     r = MsiGetProperty( hpkg, prop, buffer, &sz );
682     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
683 }
684
685 static void test_props(void)
686 {
687     MSIHANDLE hpkg;
688     UINT r;
689     DWORD sz;
690     char buffer[0x100];
691
692     hpkg = package_from_db(create_package_db());
693     ok( hpkg, "failed to create package\n");
694
695     /* test invalid values */
696     r = MsiGetProperty( 0, NULL, NULL, NULL );
697     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
698
699     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
700     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
701
702     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
703     ok( r == ERROR_SUCCESS, "wrong return val\n");
704
705     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
706     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
707
708     /* test retrieving an empty/nonexistent property */
709     sz = sizeof buffer;
710     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
711     ok( r == ERROR_SUCCESS, "wrong return val\n");
712     ok( sz == 0, "wrong size returned\n");
713
714     check_prop_empty( hpkg, "boo");
715     sz = 0;
716     strcpy(buffer,"x");
717     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
718     ok( r == ERROR_MORE_DATA, "wrong return val\n");
719     ok( !strcmp(buffer,"x"), "buffer was changed\n");
720     ok( sz == 0, "wrong size returned\n");
721
722     sz = 1;
723     strcpy(buffer,"x");
724     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
725     ok( r == ERROR_SUCCESS, "wrong return val\n");
726     ok( buffer[0] == 0, "buffer was not changed\n");
727     ok( sz == 0, "wrong size returned\n");
728
729     /* set the property to something */
730     r = MsiSetProperty( 0, NULL, NULL );
731     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
732
733     r = MsiSetProperty( hpkg, NULL, NULL );
734     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
735
736     r = MsiSetProperty( hpkg, "", NULL );
737     ok( r == ERROR_SUCCESS, "wrong return val\n");
738
739     /* try set and get some illegal property identifiers */
740     r = MsiSetProperty( hpkg, "", "asdf" );
741     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
742
743     r = MsiSetProperty( hpkg, "=", "asdf" );
744     ok( r == ERROR_SUCCESS, "wrong return val\n");
745
746     r = MsiSetProperty( hpkg, " ", "asdf" );
747     ok( r == ERROR_SUCCESS, "wrong return val\n");
748
749     r = MsiSetProperty( hpkg, "'", "asdf" );
750     ok( r == ERROR_SUCCESS, "wrong return val\n");
751
752     sz = sizeof buffer;
753     buffer[0]=0;
754     r = MsiGetProperty( hpkg, "'", buffer, &sz );
755     ok( r == ERROR_SUCCESS, "wrong return val\n");
756     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
757
758     /* set empty values */
759     r = MsiSetProperty( hpkg, "boo", NULL );
760     ok( r == ERROR_SUCCESS, "wrong return val\n");
761     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
762
763     r = MsiSetProperty( hpkg, "boo", "" );
764     ok( r == ERROR_SUCCESS, "wrong return val\n");
765     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
766
767     /* set a non-empty value */
768     r = MsiSetProperty( hpkg, "boo", "xyz" );
769     ok( r == ERROR_SUCCESS, "wrong return val\n");
770
771     sz = 1;
772     strcpy(buffer,"x");
773     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
774     ok( r == ERROR_MORE_DATA, "wrong return val\n");
775     ok( buffer[0] == 0, "buffer was not changed\n");
776     ok( sz == 3, "wrong size returned\n");
777
778     sz = 4;
779     strcpy(buffer,"x");
780     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
781     ok( r == ERROR_SUCCESS, "wrong return val\n");
782     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
783     ok( sz == 3, "wrong size returned\n");
784
785     sz = 3;
786     strcpy(buffer,"x");
787     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
788     ok( r == ERROR_MORE_DATA, "wrong return val\n");
789     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
790     ok( sz == 3, "wrong size returned\n");
791
792     MsiCloseHandle( hpkg );
793 }
794
795 START_TEST(package)
796 {
797     test_createpackage();
798     test_getsourcepath_bad();
799     test_getsourcepath();
800     test_doaction();
801     test_gettargetpath_bad();
802     test_settargetpath_bad();
803     test_props();
804     test_condition();
805 }