ole32: Implement FTMarshalImpl_GetMarshalSizeMax.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 ~> 1");
388     ok( r == MSICONDITION_FALSE, "wrong return val\n");
389
390     r = MsiEvaluateCondition(hpkg, "1 > 1");
391     ok( r == MSICONDITION_FALSE, "wrong return val\n");
392
393     r = MsiEvaluateCondition(hpkg, "1 ~> 1");
394     ok( r == MSICONDITION_FALSE, "wrong return val\n");
395
396     r = MsiEvaluateCondition(hpkg, "0 >= 1");
397     ok( r == MSICONDITION_FALSE, "wrong return val\n");
398
399     r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
400     ok( r == MSICONDITION_FALSE, "wrong return val\n");
401
402     r = MsiEvaluateCondition(hpkg, "1 >= 1");
403     ok( r == MSICONDITION_TRUE, "wrong return val\n");
404
405     r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
406     ok( r == MSICONDITION_TRUE, "wrong return val\n");
407
408     r = MsiEvaluateCondition(hpkg, "0 < 1");
409     ok( r == MSICONDITION_TRUE, "wrong return val\n");
410
411     r = MsiEvaluateCondition(hpkg, "0 ~< 1");
412     ok( r == MSICONDITION_TRUE, "wrong return val\n");
413
414     r = MsiEvaluateCondition(hpkg, "1 < 1");
415     ok( r == MSICONDITION_FALSE, "wrong return val\n");
416
417     r = MsiEvaluateCondition(hpkg, "1 ~< 1");
418     ok( r == MSICONDITION_FALSE, "wrong return val\n");
419
420     r = MsiEvaluateCondition(hpkg, "0 <= 1");
421     ok( r == MSICONDITION_TRUE, "wrong return val\n");
422
423     r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
424     ok( r == MSICONDITION_TRUE, "wrong return val\n");
425
426     r = MsiEvaluateCondition(hpkg, "1 <= 1");
427     ok( r == MSICONDITION_TRUE, "wrong return val\n");
428
429     r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
430     ok( r == MSICONDITION_TRUE, "wrong return val\n");
431
432     r = MsiEvaluateCondition(hpkg, "0 >=");
433     ok( r == MSICONDITION_ERROR, "wrong return val\n");
434
435     r = MsiEvaluateCondition(hpkg, " ");
436     ok( r == MSICONDITION_NONE, "wrong return val\n");
437
438     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
439     ok( r == MSICONDITION_TRUE, "wrong return val\n");
440
441     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
442     ok( r == MSICONDITION_TRUE, "wrong return val\n");
443
444     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
445     ok( r == MSICONDITION_FALSE, "wrong return val\n");
446
447     r = MsiEvaluateCondition(hpkg, "not 0");
448     ok( r == MSICONDITION_TRUE, "wrong return val\n");
449
450     r = MsiEvaluateCondition(hpkg, "not LicView");
451     ok( r == MSICONDITION_TRUE, "wrong return val\n");
452
453     r = MsiEvaluateCondition(hpkg, "not \"A\"");
454     ok( r == MSICONDITION_FALSE, "wrong return val\n");
455
456     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
457     ok( r == MSICONDITION_ERROR, "wrong return val\n");
458
459     r = MsiEvaluateCondition(hpkg, "\"0\"");
460     ok( r == MSICONDITION_TRUE, "wrong return val\n");
461
462     r = MsiEvaluateCondition(hpkg, "1 and 2");
463     ok( r == MSICONDITION_TRUE, "wrong return val\n");
464
465     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
466     ok( r == MSICONDITION_TRUE, "wrong return val\n");
467
468     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
469     ok( r == MSICONDITION_FALSE, "wrong return val\n");
470
471     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
472     ok( r == MSICONDITION_TRUE, "wrong return val\n");
473
474     r = MsiEvaluateCondition(hpkg, "(0)");
475     ok( r == MSICONDITION_FALSE, "wrong return val\n");
476
477     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
478     ok( r == MSICONDITION_ERROR, "wrong return val\n");
479
480     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
481     ok( r == MSICONDITION_TRUE, "wrong return val\n");
482
483     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
484     ok( r == MSICONDITION_TRUE, "wrong return val\n");
485
486     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
487     ok( r == MSICONDITION_FALSE, "wrong return val\n");
488
489     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
490     ok( r == MSICONDITION_FALSE, "wrong return val\n");
491
492     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
493     ok( r == MSICONDITION_TRUE, "wrong return val\n");
494
495     r = MsiEvaluateCondition(hpkg, "0 < > 0");
496     ok( r == MSICONDITION_ERROR, "wrong return val\n");
497
498     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
499     ok( r == MSICONDITION_ERROR, "wrong return val\n");
500
501     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
502     ok( r == MSICONDITION_FALSE, "wrong return val\n");
503
504     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
505     ok( r == MSICONDITION_ERROR, "wrong return val\n");
506
507     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
508     ok( r == MSICONDITION_TRUE, "wrong return val\n");
509
510     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
511     ok( r == MSICONDITION_FALSE, "wrong return val\n");
512
513     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
514     ok( r == MSICONDITION_FALSE, "wrong return val\n");
515
516     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
517     ok( r == MSICONDITION_TRUE, "wrong return val\n");
518
519     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
520     ok( r == MSICONDITION_FALSE, "wrong return val\n");
521
522     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
523     ok( r == MSICONDITION_FALSE, "wrong return val\n");
524
525     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
526     ok( r == MSICONDITION_FALSE, "wrong return val\n");
527
528     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
529     ok( r == MSICONDITION_FALSE, "wrong return val\n");
530
531     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
532     ok( r == MSICONDITION_FALSE, "wrong return val\n");
533
534     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
535     ok( r == MSICONDITION_FALSE, "wrong return val\n");
536
537     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
538     ok( r == MSICONDITION_TRUE, "wrong return val\n");
539
540     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
541     ok( r == MSICONDITION_FALSE, "wrong return val\n");
542
543     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
544     ok( r == MSICONDITION_TRUE, "wrong return val\n");
545
546     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
547     ok( r == MSICONDITION_TRUE, "wrong return val\n");
548
549     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
550     ok( r == MSICONDITION_FALSE, "wrong return val\n");
551
552     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
553     ok( r == MSICONDITION_TRUE, "wrong return val\n");
554
555     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
556     ok( r == MSICONDITION_ERROR, "wrong return val\n");
557
558     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
559     ok( r == MSICONDITION_TRUE, "wrong return val\n");
560
561     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
562     ok( r == MSICONDITION_TRUE, "wrong return val\n");
563
564     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
565     ok( r == MSICONDITION_TRUE, "wrong return val\n");
566
567     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
568     ok( r == MSICONDITION_FALSE, "wrong return val\n");
569
570     MsiSetProperty(hpkg, "mm", "5" );
571
572     r = MsiEvaluateCondition(hpkg, "mm = 5");
573     ok( r == MSICONDITION_TRUE, "wrong return val\n");
574
575     r = MsiEvaluateCondition(hpkg, "mm < 6");
576     ok( r == MSICONDITION_TRUE, "wrong return val\n");
577
578     r = MsiEvaluateCondition(hpkg, "mm <= 5");
579     ok( r == MSICONDITION_TRUE, "wrong return val\n");
580
581     r = MsiEvaluateCondition(hpkg, "mm > 4");
582     ok( r == MSICONDITION_TRUE, "wrong return val\n");
583
584     r = MsiEvaluateCondition(hpkg, "mm < 12");
585     ok( r == MSICONDITION_TRUE, "wrong return val\n");
586
587     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
588     ok( r == MSICONDITION_TRUE, "wrong return val\n");
589
590     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
591     ok( r == MSICONDITION_FALSE, "wrong return val\n");
592
593     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
594     ok( r == MSICONDITION_FALSE, "wrong return val\n");
595
596     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
597     ok( r == MSICONDITION_FALSE, "wrong return val\n");
598
599     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
600     ok( r == MSICONDITION_TRUE, "wrong return val\n");
601
602     r = MsiEvaluateCondition(hpkg, "3 >< 1");
603     ok( r == MSICONDITION_TRUE, "wrong return val\n");
604
605     r = MsiEvaluateCondition(hpkg, "3 >< 4");
606     ok( r == MSICONDITION_FALSE, "wrong return val\n");
607
608     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
609     ok( r == MSICONDITION_FALSE, "wrong return val\n");
610
611     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
612     ok( r == MSICONDITION_TRUE, "wrong return val\n");
613
614     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
615     ok( r == MSICONDITION_FALSE, "wrong return val\n");
616
617     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
618     ok( r == MSICONDITION_TRUE, "wrong return val\n");
619
620     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
621     ok( r == MSICONDITION_TRUE, "wrong return val\n");
622
623     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
624     ok( r == MSICONDITION_TRUE, "wrong return val\n");
625
626     r = MsiEvaluateCondition(hpkg, "_1 = _1");
627     ok( r == MSICONDITION_TRUE, "wrong return val\n");
628
629     r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
630     ok( r == MSICONDITION_ERROR, "wrong return val\n");
631
632     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
633     ok( r == MSICONDITION_FALSE, "wrong return val\n");
634
635     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
636     ok( r == MSICONDITION_FALSE, "wrong return val\n");
637
638     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
639     ok( r == MSICONDITION_FALSE, "wrong return val\n");
640
641     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
642     ok( r == MSICONDITION_FALSE, "wrong return val\n");
643
644     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
645     ok( r == MSICONDITION_FALSE, "wrong return val\n");
646
647     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
648     ok( r == MSICONDITION_TRUE, "wrong return val\n");
649
650     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
651     ok( r == MSICONDITION_FALSE, "wrong return val\n");
652
653     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
654     ok( r == MSICONDITION_FALSE, "wrong return val\n");
655
656     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
657     ok( r == MSICONDITION_FALSE, "wrong return val\n");
658
659     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
660     ok( r == MSICONDITION_FALSE, "wrong return val\n");
661
662     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
663     ok( r == MSICONDITION_TRUE, "wrong return val\n");
664
665     MsiSetProperty(hpkg, "bandalmael", "0" );
666     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
667     ok( r == MSICONDITION_TRUE, "wrong return val\n");
668
669     MsiSetProperty(hpkg, "bandalmael", "" );
670     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
671     ok( r == MSICONDITION_FALSE, "wrong return val\n");
672
673     MsiSetProperty(hpkg, "bandalmael", "asdf" );
674     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
675     ok( r == MSICONDITION_FALSE, "wrong return val\n");
676
677     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
678     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
679     ok( r == MSICONDITION_FALSE, "wrong return val\n");
680
681     MsiSetProperty(hpkg, "bandalmael", "0 " );
682     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
683     ok( r == MSICONDITION_FALSE, "wrong return val\n");
684
685     MsiSetProperty(hpkg, "bandalmael", "-0" );
686     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
687     ok( r == MSICONDITION_TRUE, "wrong return val\n");
688
689     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
690     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
691     ok( r == MSICONDITION_TRUE, "wrong return val\n");
692
693     MsiSetProperty(hpkg, "bandalmael", "--0" );
694     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
695     ok( r == MSICONDITION_FALSE, "wrong return val\n");
696
697     MsiSetProperty(hpkg, "bandalmael", "0x00" );
698     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
699     ok( r == MSICONDITION_FALSE, "wrong return val\n");
700
701     MsiSetProperty(hpkg, "bandalmael", "-" );
702     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
703     ok( r == MSICONDITION_FALSE, "wrong return val\n");
704
705     MsiSetProperty(hpkg, "bandalmael", "+0" );
706     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
707     ok( r == MSICONDITION_FALSE, "wrong return val\n");
708
709     MsiSetProperty(hpkg, "bandalmael", "0.0" );
710     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
711     ok( r == MSICONDITION_FALSE, "wrong return val\n");
712     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
713     ok( r == MSICONDITION_TRUE, "wrong return val\n");
714
715     MsiCloseHandle( hpkg );
716 }
717
718 static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
719 {
720     UINT r;
721     DWORD sz;
722     char buffer[2];
723
724     sz = sizeof buffer;
725     strcpy(buffer,"x");
726     r = MsiGetProperty( hpkg, prop, buffer, &sz );
727     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
728 }
729
730 static void test_props(void)
731 {
732     MSIHANDLE hpkg;
733     UINT r;
734     DWORD sz;
735     char buffer[0x100];
736
737     hpkg = package_from_db(create_package_db());
738     ok( hpkg, "failed to create package\n");
739
740     /* test invalid values */
741     r = MsiGetProperty( 0, NULL, NULL, NULL );
742     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
743
744     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
745     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
746
747     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
748     ok( r == ERROR_SUCCESS, "wrong return val\n");
749
750     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
751     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
752
753     /* test retrieving an empty/nonexistent property */
754     sz = sizeof buffer;
755     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
756     ok( r == ERROR_SUCCESS, "wrong return val\n");
757     ok( sz == 0, "wrong size returned\n");
758
759     check_prop_empty( hpkg, "boo");
760     sz = 0;
761     strcpy(buffer,"x");
762     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
763     ok( r == ERROR_MORE_DATA, "wrong return val\n");
764     ok( !strcmp(buffer,"x"), "buffer was changed\n");
765     ok( sz == 0, "wrong size returned\n");
766
767     sz = 1;
768     strcpy(buffer,"x");
769     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
770     ok( r == ERROR_SUCCESS, "wrong return val\n");
771     ok( buffer[0] == 0, "buffer was not changed\n");
772     ok( sz == 0, "wrong size returned\n");
773
774     /* set the property to something */
775     r = MsiSetProperty( 0, NULL, NULL );
776     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
777
778     r = MsiSetProperty( hpkg, NULL, NULL );
779     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
780
781     r = MsiSetProperty( hpkg, "", NULL );
782     ok( r == ERROR_SUCCESS, "wrong return val\n");
783
784     /* try set and get some illegal property identifiers */
785     r = MsiSetProperty( hpkg, "", "asdf" );
786     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
787
788     r = MsiSetProperty( hpkg, "=", "asdf" );
789     ok( r == ERROR_SUCCESS, "wrong return val\n");
790
791     r = MsiSetProperty( hpkg, " ", "asdf" );
792     ok( r == ERROR_SUCCESS, "wrong return val\n");
793
794     r = MsiSetProperty( hpkg, "'", "asdf" );
795     ok( r == ERROR_SUCCESS, "wrong return val\n");
796
797     sz = sizeof buffer;
798     buffer[0]=0;
799     r = MsiGetProperty( hpkg, "'", buffer, &sz );
800     ok( r == ERROR_SUCCESS, "wrong return val\n");
801     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
802
803     /* set empty values */
804     r = MsiSetProperty( hpkg, "boo", NULL );
805     ok( r == ERROR_SUCCESS, "wrong return val\n");
806     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
807
808     r = MsiSetProperty( hpkg, "boo", "" );
809     ok( r == ERROR_SUCCESS, "wrong return val\n");
810     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
811
812     /* set a non-empty value */
813     r = MsiSetProperty( hpkg, "boo", "xyz" );
814     ok( r == ERROR_SUCCESS, "wrong return val\n");
815
816     sz = 1;
817     strcpy(buffer,"x");
818     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
819     ok( r == ERROR_MORE_DATA, "wrong return val\n");
820     ok( buffer[0] == 0, "buffer was not changed\n");
821     ok( sz == 3, "wrong size returned\n");
822
823     sz = 4;
824     strcpy(buffer,"x");
825     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
826     ok( r == ERROR_SUCCESS, "wrong return val\n");
827     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
828     ok( sz == 3, "wrong size returned\n");
829
830     sz = 3;
831     strcpy(buffer,"x");
832     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
833     ok( r == ERROR_MORE_DATA, "wrong return val\n");
834     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
835     ok( sz == 3, "wrong size returned\n");
836
837     MsiCloseHandle( hpkg );
838 }
839
840 START_TEST(package)
841 {
842     test_createpackage();
843     test_getsourcepath_bad();
844     test_getsourcepath();
845     test_doaction();
846     test_gettargetpath_bad();
847     test_settargetpath_bad();
848     test_props();
849     test_condition();
850 }