Assorted spelling and case fixes.
[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 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 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     MsiCloseHandle( hpkg );
597 }
598
599 static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
600 {
601     UINT r;
602     DWORD sz;
603     char buffer[2];
604
605     sz = sizeof buffer;
606     strcpy(buffer,"x");
607     r = MsiGetProperty( hpkg, prop, buffer, &sz );
608     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
609 }
610
611 static void test_props(void)
612 {
613     MSIHANDLE hpkg;
614     UINT r;
615     DWORD sz;
616     char buffer[0x100];
617
618     hpkg = package_from_db(create_package_db());
619     ok( hpkg, "failed to create package\n");
620
621     /* test invalid values */
622     r = MsiGetProperty( 0, NULL, NULL, NULL );
623     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
624
625     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
626     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
627
628     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
629     ok( r == ERROR_SUCCESS, "wrong return val\n");
630
631     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
632     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
633
634     /* test retrieving an empty/nonexistent property */
635     sz = sizeof buffer;
636     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
637     ok( r == ERROR_SUCCESS, "wrong return val\n");
638     ok( sz == 0, "wrong size returned\n");
639
640     check_prop_empty( hpkg, "boo");
641     sz = 0;
642     strcpy(buffer,"x");
643     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
644     ok( r == ERROR_MORE_DATA, "wrong return val\n");
645     ok( !strcmp(buffer,"x"), "buffer was changed\n");
646     ok( sz == 0, "wrong size returned\n");
647
648     sz = 1;
649     strcpy(buffer,"x");
650     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
651     ok( r == ERROR_SUCCESS, "wrong return val\n");
652     ok( buffer[0] == 0, "buffer was not changed\n");
653     ok( sz == 0, "wrong size returned\n");
654
655     /* set the property to something */
656     r = MsiSetProperty( 0, NULL, NULL );
657     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
658
659     r = MsiSetProperty( hpkg, NULL, NULL );
660     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
661
662     r = MsiSetProperty( hpkg, "", NULL );
663     ok( r == ERROR_SUCCESS, "wrong return val\n");
664
665     /* try set and get some illegal property identifiers */
666     r = MsiSetProperty( hpkg, "", "asdf" );
667     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
668
669     r = MsiSetProperty( hpkg, "=", "asdf" );
670     ok( r == ERROR_SUCCESS, "wrong return val\n");
671
672     r = MsiSetProperty( hpkg, " ", "asdf" );
673     ok( r == ERROR_SUCCESS, "wrong return val\n");
674
675     r = MsiSetProperty( hpkg, "'", "asdf" );
676     ok( r == ERROR_SUCCESS, "wrong return val\n");
677
678     sz = sizeof buffer;
679     buffer[0]=0;
680     r = MsiGetProperty( hpkg, "'", buffer, &sz );
681     ok( r == ERROR_SUCCESS, "wrong return val\n");
682     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
683
684     /* set empty values */
685     r = MsiSetProperty( hpkg, "boo", NULL );
686     ok( r == ERROR_SUCCESS, "wrong return val\n");
687     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
688
689     r = MsiSetProperty( hpkg, "boo", "" );
690     ok( r == ERROR_SUCCESS, "wrong return val\n");
691     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
692
693     /* set a non-empty value */
694     r = MsiSetProperty( hpkg, "boo", "xyz" );
695     ok( r == ERROR_SUCCESS, "wrong return val\n");
696
697     sz = 1;
698     strcpy(buffer,"x");
699     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
700     ok( r == ERROR_MORE_DATA, "wrong return val\n");
701     ok( buffer[0] == 0, "buffer was not changed\n");
702     ok( sz == 3, "wrong size returned\n");
703
704     sz = 4;
705     strcpy(buffer,"x");
706     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
707     ok( r == ERROR_SUCCESS, "wrong return val\n");
708     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
709     ok( sz == 3, "wrong size returned\n");
710
711     sz = 3;
712     strcpy(buffer,"x");
713     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
714     ok( r == ERROR_MORE_DATA, "wrong return val\n");
715     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
716     ok( sz == 3, "wrong size returned\n");
717
718     MsiCloseHandle( hpkg );
719 }
720
721 START_TEST(package)
722 {
723     test_createpackage();
724     test_getsourcepath_bad();
725     test_getsourcepath();
726     test_doaction();
727     test_gettargetpath_bad();
728     test_settargetpath_bad();
729     test_props();
730 }