2 * tests for Microsoft Installer functionality
4 * Copyright 2005 Mike McCormack for CodeWeavers
5 * Copyright 2005 Aric Stewart for CodeWeavers
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.
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.
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
29 #include "wine/test.h"
31 static const char msifile[] = "winetest.msi";
33 static UINT run_query( MSIHANDLE hdb, const char *query )
38 r = MsiDatabaseOpenView(hdb, query, &hview);
39 if( r != ERROR_SUCCESS )
42 r = MsiViewExecute(hview, 0);
43 if( r == ERROR_SUCCESS )
44 r = MsiViewClose(hview);
45 MsiCloseHandle(hview);
49 static UINT set_summary_info(MSIHANDLE hdb)
54 /* build summmary info */
55 res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
56 ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
58 res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
59 "Installation Database");
60 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
62 res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
63 "Installation Database");
64 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
66 res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
68 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
70 res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
72 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
74 res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
75 "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
76 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
78 res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
79 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
81 res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
82 ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
84 res = MsiSummaryInfoPersist(suminfo);
85 ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
87 res = MsiCloseHandle( suminfo);
88 ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
94 MSIHANDLE create_package_db(void)
101 /* create an empty database */
102 res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
103 ok( res == ERROR_SUCCESS , "Failed to create database\n" );
104 if( res != ERROR_SUCCESS )
107 res = MsiDatabaseCommit( hdb );
108 ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
110 res = set_summary_info(hdb);
112 res = run_query( hdb,
113 "CREATE TABLE `Directory` ( "
114 "`Directory` CHAR(255) NOT NULL, "
115 "`Directory_Parent` CHAR(255), "
116 "`DefaultDir` CHAR(255) NOT NULL "
117 "PRIMARY KEY `Directory`)" );
118 ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
123 MSIHANDLE package_from_db(MSIHANDLE hdb)
129 sprintf(szPackage,"#%li",hdb);
130 res = MsiOpenPackage(szPackage,&hPackage);
131 ok( res == ERROR_SUCCESS , "Failed to open package\n" );
133 res = MsiCloseHandle(hdb);
134 ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
139 static void test_createpackage(void)
141 MSIHANDLE hPackage = 0;
144 hPackage = package_from_db(create_package_db());
145 ok( hPackage != 0, " Failed to create package\n");
147 res = MsiCloseHandle( hPackage);
148 ok( res == ERROR_SUCCESS , "Failed to close package\n" );
152 static void test_getsourcepath_bad( void )
154 static const char str[] = { 0 };
159 r = MsiGetSourcePath( -1, NULL, NULL, NULL );
160 ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
163 r = MsiGetSourcePath( -1, NULL, buffer, &sz );
164 ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
167 r = MsiGetSourcePath( -1, str, NULL, &sz );
168 ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
171 r = MsiGetSourcePath( -1, str, NULL, NULL );
172 ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
175 r = MsiGetSourcePath( -1, str, buffer, &sz );
176 ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
179 static UINT add_directory_entry( MSIHANDLE hdb, char *values )
181 char insert[] = "INSERT INTO `Directory` (`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )";
185 sz = strlen(values) + sizeof insert;
186 query = HeapAlloc(GetProcessHeap(),0,sz);
187 sprintf(query,insert,values);
188 r = run_query( hdb, query );
189 HeapFree(GetProcessHeap(), 0, query);
193 static void test_getsourcepath( void )
195 static const char str[] = { 0 };
201 hpkg = package_from_db(create_package_db());
202 ok( hpkg, "failed to create package\n");
206 r = MsiGetSourcePath( hpkg, str, buffer, &sz );
207 ok( r == ERROR_DIRECTORY, "return value wrong\n");
208 ok( buffer[0] == 'x', "buffer modified\n");
212 r = MsiGetSourcePath( hpkg, str, buffer, &sz );
213 ok( r == ERROR_DIRECTORY, "return value wrong\n");
214 ok( buffer[0] == 'x', "buffer modified\n");
216 MsiCloseHandle( hpkg );
219 /* another test but try create a directory this time */
220 hdb = create_package_db();
221 ok( hdb, "failed to create database\n");
223 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
224 ok( r == S_OK, "failed\n");
226 hpkg = package_from_db(hdb);
227 ok( hpkg, "failed to create package\n");
229 sz = sizeof buffer -1;
230 strcpy(buffer,"x bad");
231 r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
232 ok( r == ERROR_DIRECTORY, "return value wrong\n");
235 r = MsiDoAction( hpkg, "CostInitialize");
236 ok( r == ERROR_SUCCESS, "cost init failed\n");
238 r = MsiDoAction( hpkg, "CostFinalize");
239 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
242 sz = sizeof buffer -1;
244 r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
245 ok( r == ERROR_SUCCESS, "return value wrong\n");
246 ok( sz == strlen(buffer), "returned length wrong\n");
249 strcpy(buffer,"x bad");
250 r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
251 ok( r == ERROR_MORE_DATA, "return value wrong\n");
253 ok( buffer[0] == 'x', "buffer modified\n");
256 r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, NULL );
257 ok( r == ERROR_SUCCESS, "return value wrong\n");
260 r = MsiGetSourcePath( hpkg, "TARGETDIR ", NULL, NULL );
261 ok( r == ERROR_DIRECTORY, "return value wrong\n");
263 r = MsiGetSourcePath( hpkg, "targetdir", NULL, NULL );
264 ok( r == ERROR_DIRECTORY, "return value wrong\n");
266 r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, NULL );
267 ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
270 r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, &sz );
271 ok( r == ERROR_SUCCESS, "return value wrong\n");
274 MsiCloseHandle( hpkg );
278 static void test_doaction( void )
283 r = MsiDoAction( -1, NULL );
284 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
286 hpkg = package_from_db(create_package_db());
287 ok( hpkg, "failed to create package\n");
289 r = MsiDoAction(hpkg, NULL);
290 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
292 r = MsiDoAction(0, "boo");
293 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
295 r = MsiDoAction(hpkg, "boo");
296 ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
298 MsiCloseHandle( hpkg );
302 static void test_gettargetpath_bad(void)
309 hpkg = package_from_db(create_package_db());
310 ok( hpkg, "failed to create package\n");
312 r = MsiGetTargetPath( 0, NULL, NULL, NULL );
313 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
315 r = MsiGetTargetPath( 0, NULL, NULL, &sz );
316 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
318 r = MsiGetTargetPath( 0, "boo", NULL, NULL );
319 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
321 r = MsiGetTargetPath( 0, "boo", NULL, NULL );
322 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
324 r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
325 ok( r == ERROR_DIRECTORY, "wrong return val\n");
327 r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
328 ok( r == ERROR_DIRECTORY, "wrong return val\n");
330 MsiCloseHandle( hpkg );
334 static void test_settargetpath(void)
336 char tempdir[MAX_PATH+8], buffer[MAX_PATH];
342 hdb = create_package_db();
343 ok ( hdb, "failed to create package database\n" );
345 r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
346 ok( r == S_OK, "failed to add directory entry: %d\n" , r );
348 r = run_query( hdb, /* these tables required by Windows Installer for MsiSetTargetPath */
349 "CREATE TABLE `Component` ( "
350 "`Component` CHAR(72) NOT NULL, "
351 "`ComponentId` CHAR(38), "
352 "`Directory_` CHAR(72) NOT NULL, "
353 "`Attributes` SHORT NOT NULL, "
354 "`Condition` CHAR(255), "
355 "`KeyPath` CHAR(72) "
356 "PRIMARY KEY `Component`)" );
357 ok( r == S_OK, "cannot create Component table: %d\n", r );
360 "INSERT INTO `Component` "
361 "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
362 "VALUES( 'WinWorkAround', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'FL_dummycomponent')" );
363 ok( r == S_OK, "cannot add dummy component: %d\n", r );
366 "CREATE TABLE `Feature` ( "
367 "`Feature` CHAR(38) NOT NULL, "
368 "`Feature_Parent` CHAR(38), "
370 "`Description` CHAR(255), "
371 "`Display` SHORT NOT NULL, "
372 "`Level` SHORT NOT NULL, "
373 "`Directory_` CHAR(72), "
374 "`Attributes` SHORT NOT NULL "
375 "PRIMARY KEY `Feature`)" );
376 ok( r == S_OK, "cannot create Feature table: %d\n", r );
378 hpkg = package_from_db( hdb );
379 ok( hpkg, "failed to create package\n");
381 r = MsiDoAction( hpkg, "CostInitialize");
382 ok( r == ERROR_SUCCESS, "cost init failed\n");
384 r = MsiDoAction( hpkg, "CostFinalize");
385 ok( r == ERROR_SUCCESS, "cost finalize failed\n");
387 r = MsiSetTargetPath( 0, NULL, NULL );
388 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
390 r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
391 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
393 r = MsiSetTargetPath( hpkg, "boo", NULL );
394 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
396 r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
397 ok( r == ERROR_DIRECTORY, "wrong return val\n");
399 sz = sizeof tempdir - 1;
400 r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
403 if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
405 sprintf( tempdir, "%s\\subdir", buffer );
406 r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
407 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
409 r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
410 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
412 DeleteFile( buffer );
414 r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
415 ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
417 r = GetFileAttributes( buffer );
418 ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
420 r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
421 ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
423 trace("GetTempFileName failed, cannot do some tests\n");
426 trace( "MsiGetTargetPath failed: %d\n", r );
429 MsiCloseHandle( hpkg );
432 static void test_condition(void)
437 hpkg = package_from_db(create_package_db());
438 ok( hpkg, "failed to create package\n");
440 r = MsiEvaluateCondition(0, NULL);
441 ok( r == MSICONDITION_ERROR, "wrong return val\n");
443 r = MsiEvaluateCondition(hpkg, NULL);
444 ok( r == MSICONDITION_NONE, "wrong return val\n");
446 r = MsiEvaluateCondition(hpkg, "");
447 ok( r == MSICONDITION_NONE, "wrong return val\n");
449 r = MsiEvaluateCondition(hpkg, "1");
450 ok( r == MSICONDITION_TRUE, "wrong return val\n");
452 r = MsiEvaluateCondition(hpkg, "0");
453 ok( r == MSICONDITION_FALSE, "wrong return val\n");
455 r = MsiEvaluateCondition(hpkg, "0 = 0");
456 ok( r == MSICONDITION_TRUE, "wrong return val\n");
458 r = MsiEvaluateCondition(hpkg, "0 <> 0");
459 ok( r == MSICONDITION_FALSE, "wrong return val\n");
461 r = MsiEvaluateCondition(hpkg, "0 = 1");
462 ok( r == MSICONDITION_FALSE, "wrong return val\n");
464 r = MsiEvaluateCondition(hpkg, "0 > 1");
465 ok( r == MSICONDITION_FALSE, "wrong return val\n");
467 r = MsiEvaluateCondition(hpkg, "0 ~> 1");
468 ok( r == MSICONDITION_FALSE, "wrong return val\n");
470 r = MsiEvaluateCondition(hpkg, "1 > 1");
471 ok( r == MSICONDITION_FALSE, "wrong return val\n");
473 r = MsiEvaluateCondition(hpkg, "1 ~> 1");
474 ok( r == MSICONDITION_FALSE, "wrong return val\n");
476 r = MsiEvaluateCondition(hpkg, "0 >= 1");
477 ok( r == MSICONDITION_FALSE, "wrong return val\n");
479 r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
480 ok( r == MSICONDITION_FALSE, "wrong return val\n");
482 r = MsiEvaluateCondition(hpkg, "1 >= 1");
483 ok( r == MSICONDITION_TRUE, "wrong return val\n");
485 r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
486 ok( r == MSICONDITION_TRUE, "wrong return val\n");
488 r = MsiEvaluateCondition(hpkg, "0 < 1");
489 ok( r == MSICONDITION_TRUE, "wrong return val\n");
491 r = MsiEvaluateCondition(hpkg, "0 ~< 1");
492 ok( r == MSICONDITION_TRUE, "wrong return val\n");
494 r = MsiEvaluateCondition(hpkg, "1 < 1");
495 ok( r == MSICONDITION_FALSE, "wrong return val\n");
497 r = MsiEvaluateCondition(hpkg, "1 ~< 1");
498 ok( r == MSICONDITION_FALSE, "wrong return val\n");
500 r = MsiEvaluateCondition(hpkg, "0 <= 1");
501 ok( r == MSICONDITION_TRUE, "wrong return val\n");
503 r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
504 ok( r == MSICONDITION_TRUE, "wrong return val\n");
506 r = MsiEvaluateCondition(hpkg, "1 <= 1");
507 ok( r == MSICONDITION_TRUE, "wrong return val\n");
509 r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
510 ok( r == MSICONDITION_TRUE, "wrong return val\n");
512 r = MsiEvaluateCondition(hpkg, "0 >=");
513 ok( r == MSICONDITION_ERROR, "wrong return val\n");
515 r = MsiEvaluateCondition(hpkg, " ");
516 ok( r == MSICONDITION_NONE, "wrong return val\n");
518 r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
519 ok( r == MSICONDITION_TRUE, "wrong return val\n");
521 r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
522 ok( r == MSICONDITION_TRUE, "wrong return val\n");
524 r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
525 ok( r == MSICONDITION_FALSE, "wrong return val\n");
527 r = MsiEvaluateCondition(hpkg, "not 0");
528 ok( r == MSICONDITION_TRUE, "wrong return val\n");
530 r = MsiEvaluateCondition(hpkg, "not LicView");
531 ok( r == MSICONDITION_TRUE, "wrong return val\n");
533 r = MsiEvaluateCondition(hpkg, "not \"A\"");
534 ok( r == MSICONDITION_FALSE, "wrong return val\n");
536 r = MsiEvaluateCondition(hpkg, "~not \"A\"");
537 ok( r == MSICONDITION_ERROR, "wrong return val\n");
539 r = MsiEvaluateCondition(hpkg, "\"0\"");
540 ok( r == MSICONDITION_TRUE, "wrong return val\n");
542 r = MsiEvaluateCondition(hpkg, "1 and 2");
543 ok( r == MSICONDITION_TRUE, "wrong return val\n");
545 r = MsiEvaluateCondition(hpkg, "not 0 and 3");
546 ok( r == MSICONDITION_TRUE, "wrong return val\n");
548 r = MsiEvaluateCondition(hpkg, "not 0 and 0");
549 ok( r == MSICONDITION_FALSE, "wrong return val\n");
551 r = MsiEvaluateCondition(hpkg, "not 0 or 1");
552 ok( r == MSICONDITION_TRUE, "wrong return val\n");
554 r = MsiEvaluateCondition(hpkg, "(0)");
555 ok( r == MSICONDITION_FALSE, "wrong return val\n");
557 r = MsiEvaluateCondition(hpkg, "(((((1))))))");
558 ok( r == MSICONDITION_ERROR, "wrong return val\n");
560 r = MsiEvaluateCondition(hpkg, "(((((1)))))");
561 ok( r == MSICONDITION_TRUE, "wrong return val\n");
563 r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
564 ok( r == MSICONDITION_TRUE, "wrong return val\n");
566 r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
567 ok( r == MSICONDITION_FALSE, "wrong return val\n");
569 r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
570 ok( r == MSICONDITION_FALSE, "wrong return val\n");
572 r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
573 ok( r == MSICONDITION_TRUE, "wrong return val\n");
575 r = MsiEvaluateCondition(hpkg, "0 < > 0");
576 ok( r == MSICONDITION_ERROR, "wrong return val\n");
578 r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
579 ok( r == MSICONDITION_ERROR, "wrong return val\n");
581 r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
582 ok( r == MSICONDITION_FALSE, "wrong return val\n");
584 r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
585 ok( r == MSICONDITION_ERROR, "wrong return val\n");
587 r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
588 ok( r == MSICONDITION_TRUE, "wrong return val\n");
590 r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
591 ok( r == MSICONDITION_FALSE, "wrong return val\n");
593 r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
594 ok( r == MSICONDITION_FALSE, "wrong return val\n");
596 r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
597 ok( r == MSICONDITION_TRUE, "wrong return val\n");
599 r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
600 ok( r == MSICONDITION_FALSE, "wrong return val\n");
602 r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
603 ok( r == MSICONDITION_FALSE, "wrong return val\n");
605 r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
606 ok( r == MSICONDITION_FALSE, "wrong return val\n");
608 r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
609 ok( r == MSICONDITION_FALSE, "wrong return val\n");
611 r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
612 ok( r == MSICONDITION_FALSE, "wrong return val\n");
614 r = MsiEvaluateCondition(hpkg, "1 XOR 1");
615 ok( r == MSICONDITION_FALSE, "wrong return val\n");
617 r = MsiEvaluateCondition(hpkg, "1 IMP 1");
618 ok( r == MSICONDITION_TRUE, "wrong return val\n");
620 r = MsiEvaluateCondition(hpkg, "1 IMP 0");
621 ok( r == MSICONDITION_FALSE, "wrong return val\n");
623 r = MsiEvaluateCondition(hpkg, "0 IMP 0");
624 ok( r == MSICONDITION_TRUE, "wrong return val\n");
626 r = MsiEvaluateCondition(hpkg, "0 EQV 0");
627 ok( r == MSICONDITION_TRUE, "wrong return val\n");
629 r = MsiEvaluateCondition(hpkg, "0 EQV 1");
630 ok( r == MSICONDITION_FALSE, "wrong return val\n");
632 r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
633 ok( r == MSICONDITION_TRUE, "wrong return val\n");
635 r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
636 ok( r == MSICONDITION_ERROR, "wrong return val\n");
638 r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
639 ok( r == MSICONDITION_TRUE, "wrong return val\n");
641 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
642 ok( r == MSICONDITION_TRUE, "wrong return val\n");
644 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
645 ok( r == MSICONDITION_TRUE, "wrong return val\n");
647 r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
648 ok( r == MSICONDITION_FALSE, "wrong return val\n");
650 MsiSetProperty(hpkg, "mm", "5" );
652 r = MsiEvaluateCondition(hpkg, "mm = 5");
653 ok( r == MSICONDITION_TRUE, "wrong return val\n");
655 r = MsiEvaluateCondition(hpkg, "mm < 6");
656 ok( r == MSICONDITION_TRUE, "wrong return val\n");
658 r = MsiEvaluateCondition(hpkg, "mm <= 5");
659 ok( r == MSICONDITION_TRUE, "wrong return val\n");
661 r = MsiEvaluateCondition(hpkg, "mm > 4");
662 ok( r == MSICONDITION_TRUE, "wrong return val\n");
664 r = MsiEvaluateCondition(hpkg, "mm < 12");
665 ok( r == MSICONDITION_TRUE, "wrong return val\n");
667 r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
668 ok( r == MSICONDITION_TRUE, "wrong return val\n");
670 r = MsiEvaluateCondition(hpkg, "0 = \"\"");
671 ok( r == MSICONDITION_FALSE, "wrong return val\n");
673 r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
674 ok( r == MSICONDITION_FALSE, "wrong return val\n");
676 r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
677 ok( r == MSICONDITION_FALSE, "wrong return val\n");
679 r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
680 ok( r == MSICONDITION_TRUE, "wrong return val\n");
682 r = MsiEvaluateCondition(hpkg, "3 >< 1");
683 ok( r == MSICONDITION_TRUE, "wrong return val\n");
685 r = MsiEvaluateCondition(hpkg, "3 >< 4");
686 ok( r == MSICONDITION_FALSE, "wrong return val\n");
688 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
689 ok( r == MSICONDITION_FALSE, "wrong return val\n");
691 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
692 ok( r == MSICONDITION_TRUE, "wrong return val\n");
694 r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
695 ok( r == MSICONDITION_FALSE, "wrong return val\n");
697 r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
698 ok( r == MSICONDITION_TRUE, "wrong return val\n");
700 r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
701 ok( r == MSICONDITION_TRUE, "wrong return val\n");
703 r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
704 ok( r == MSICONDITION_TRUE, "wrong return val\n");
706 r = MsiEvaluateCondition(hpkg, "_1 = _1");
707 ok( r == MSICONDITION_TRUE, "wrong return val\n");
709 r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
710 ok( r == MSICONDITION_ERROR, "wrong return val\n");
712 r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
713 ok( r == MSICONDITION_FALSE, "wrong return val\n");
715 r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
716 ok( r == MSICONDITION_FALSE, "wrong return val\n");
718 r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
719 ok( r == MSICONDITION_FALSE, "wrong return val\n");
721 r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
722 ok( r == MSICONDITION_FALSE, "wrong return val\n");
724 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
725 ok( r == MSICONDITION_FALSE, "wrong return val\n");
727 r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
728 ok( r == MSICONDITION_TRUE, "wrong return val\n");
730 r = MsiEvaluateCondition(hpkg, "bandalmael<0");
731 ok( r == MSICONDITION_FALSE, "wrong return val\n");
733 r = MsiEvaluateCondition(hpkg, "bandalmael>0");
734 ok( r == MSICONDITION_FALSE, "wrong return val\n");
736 r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
737 ok( r == MSICONDITION_FALSE, "wrong return val\n");
739 r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
740 ok( r == MSICONDITION_FALSE, "wrong return val\n");
742 r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
743 ok( r == MSICONDITION_TRUE, "wrong return val\n");
745 MsiSetProperty(hpkg, "bandalmael", "0" );
746 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
747 ok( r == MSICONDITION_TRUE, "wrong return val\n");
749 MsiSetProperty(hpkg, "bandalmael", "" );
750 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
751 ok( r == MSICONDITION_FALSE, "wrong return val\n");
753 MsiSetProperty(hpkg, "bandalmael", "asdf" );
754 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
755 ok( r == MSICONDITION_FALSE, "wrong return val\n");
757 MsiSetProperty(hpkg, "bandalmael", "0asdf" );
758 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
759 ok( r == MSICONDITION_FALSE, "wrong return val\n");
761 MsiSetProperty(hpkg, "bandalmael", "0 " );
762 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
763 ok( r == MSICONDITION_FALSE, "wrong return val\n");
765 MsiSetProperty(hpkg, "bandalmael", "-0" );
766 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
767 ok( r == MSICONDITION_TRUE, "wrong return val\n");
769 MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
770 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
771 ok( r == MSICONDITION_TRUE, "wrong return val\n");
773 MsiSetProperty(hpkg, "bandalmael", "--0" );
774 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
775 ok( r == MSICONDITION_FALSE, "wrong return val\n");
777 MsiSetProperty(hpkg, "bandalmael", "0x00" );
778 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
779 ok( r == MSICONDITION_FALSE, "wrong return val\n");
781 MsiSetProperty(hpkg, "bandalmael", "-" );
782 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
783 ok( r == MSICONDITION_FALSE, "wrong return val\n");
785 MsiSetProperty(hpkg, "bandalmael", "+0" );
786 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
787 ok( r == MSICONDITION_FALSE, "wrong return val\n");
789 MsiSetProperty(hpkg, "bandalmael", "0.0" );
790 r = MsiEvaluateCondition(hpkg, "bandalmael=0");
791 ok( r == MSICONDITION_FALSE, "wrong return val\n");
792 r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
793 ok( r == MSICONDITION_TRUE, "wrong return val\n");
795 MsiCloseHandle( hpkg );
799 static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
807 r = MsiGetProperty( hpkg, prop, buffer, &sz );
808 return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
811 static void test_props(void)
818 hpkg = package_from_db(create_package_db());
819 ok( hpkg, "failed to create package\n");
821 /* test invalid values */
822 r = MsiGetProperty( 0, NULL, NULL, NULL );
823 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
825 r = MsiGetProperty( hpkg, NULL, NULL, NULL );
826 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
828 r = MsiGetProperty( hpkg, "boo", NULL, NULL );
829 ok( r == ERROR_SUCCESS, "wrong return val\n");
831 r = MsiGetProperty( hpkg, "boo", buffer, NULL );
832 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
834 /* test retrieving an empty/nonexistent property */
836 r = MsiGetProperty( hpkg, "boo", NULL, &sz );
837 ok( r == ERROR_SUCCESS, "wrong return val\n");
838 ok( sz == 0, "wrong size returned\n");
840 check_prop_empty( hpkg, "boo");
843 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
844 ok( r == ERROR_MORE_DATA, "wrong return val\n");
845 ok( !strcmp(buffer,"x"), "buffer was changed\n");
846 ok( sz == 0, "wrong size returned\n");
850 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
851 ok( r == ERROR_SUCCESS, "wrong return val\n");
852 ok( buffer[0] == 0, "buffer was not changed\n");
853 ok( sz == 0, "wrong size returned\n");
855 /* set the property to something */
856 r = MsiSetProperty( 0, NULL, NULL );
857 ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
859 r = MsiSetProperty( hpkg, NULL, NULL );
860 ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
862 r = MsiSetProperty( hpkg, "", NULL );
863 ok( r == ERROR_SUCCESS, "wrong return val\n");
865 /* try set and get some illegal property identifiers */
866 r = MsiSetProperty( hpkg, "", "asdf" );
867 ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
869 r = MsiSetProperty( hpkg, "=", "asdf" );
870 ok( r == ERROR_SUCCESS, "wrong return val\n");
872 r = MsiSetProperty( hpkg, " ", "asdf" );
873 ok( r == ERROR_SUCCESS, "wrong return val\n");
875 r = MsiSetProperty( hpkg, "'", "asdf" );
876 ok( r == ERROR_SUCCESS, "wrong return val\n");
880 r = MsiGetProperty( hpkg, "'", buffer, &sz );
881 ok( r == ERROR_SUCCESS, "wrong return val\n");
882 ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
884 /* set empty values */
885 r = MsiSetProperty( hpkg, "boo", NULL );
886 ok( r == ERROR_SUCCESS, "wrong return val\n");
887 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
889 r = MsiSetProperty( hpkg, "boo", "" );
890 ok( r == ERROR_SUCCESS, "wrong return val\n");
891 ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
893 /* set a non-empty value */
894 r = MsiSetProperty( hpkg, "boo", "xyz" );
895 ok( r == ERROR_SUCCESS, "wrong return val\n");
899 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
900 ok( r == ERROR_MORE_DATA, "wrong return val\n");
901 ok( buffer[0] == 0, "buffer was not changed\n");
902 ok( sz == 3, "wrong size returned\n");
906 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
907 ok( r == ERROR_SUCCESS, "wrong return val\n");
908 ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
909 ok( sz == 3, "wrong size returned\n");
913 r = MsiGetProperty( hpkg, "boo", buffer, &sz );
914 ok( r == ERROR_MORE_DATA, "wrong return val\n");
915 ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
916 ok( sz == 3, "wrong size returned\n");
918 MsiCloseHandle( hpkg );
922 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
927 res = MsiDatabaseOpenView( hdb, szQuery, &htab );
928 if( res == ERROR_SUCCESS )
932 r = MsiViewExecute( htab, hrec );
933 if( r != ERROR_SUCCESS )
936 fprintf(stderr,"MsiViewExecute failed %08x\n", res);
939 r = MsiViewClose( htab );
940 if( r != ERROR_SUCCESS )
943 r = MsiCloseHandle( htab );
944 if( r != ERROR_SUCCESS )
950 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
952 return try_query_param( hdb, szQuery, 0 );
955 static void test_msipackage(void)
957 MSIHANDLE hdb = 0, hpack = 100;
966 r = MsiOpenPackage(name, &hpack);
967 ok(r == ERROR_SUCCESS, "failed to open package with no name\n");
968 r = MsiCloseHandle(hpack);
969 ok(r == ERROR_SUCCESS, "failed to close package\n");
972 /* just MsiOpenDatabase should not create a file */
973 r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
974 ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
978 r = MsiOpenPackage(name, &hpack);
979 ok(r == ERROR_INVALID_HANDLE, "MsiOpenPackage returned wrong code\n");
982 /* now try again with our empty database */
983 sprintf(name, "#%ld", hdb);
984 r = MsiOpenPackage(name, &hpack);
985 ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
986 if (!r) MsiCloseHandle(hpack);
990 query = "CREATE TABLE `Property` ( "
991 "`Property` CHAR(72), `Value` CHAR(0) "
992 "PRIMARY KEY `Property`)";
993 r = try_query(hdb, query);
994 ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
997 query = "CREATE TABLE `InstallExecuteSequence` ("
998 "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
999 "PRIMARY KEY `Action`)";
1000 r = try_query(hdb, query);
1001 ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
1003 sprintf(name, "#%ld", hdb);
1004 r = MsiOpenPackage(name, &hpack);
1005 ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1006 if (!r) MsiCloseHandle(hpack);
1009 r = MsiCloseHandle(hdb);
1010 ok(r == ERROR_SUCCESS, "MsiCloseHandle(database) failed\n");
1011 DeleteFile(msifile);
1014 static void test_formatrecord2(void)
1016 MSIHANDLE hpkg, hrec ;
1021 hpkg = package_from_db(create_package_db());
1022 ok( hpkg, "failed to create package\n");
1024 r = MsiSetProperty(hpkg, "Manufacturer", " " );
1025 ok( r == ERROR_SUCCESS, "set property failed\n");
1027 hrec = MsiCreateRecord(2);
1028 ok(hrec, "create record failed\n");
1030 r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
1031 ok( r == ERROR_SUCCESS, "format record failed\n");
1035 r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
1037 r = MsiRecordSetString(hrec, 0, "[foo][1]");
1038 r = MsiRecordSetString(hrec, 1, "hoo");
1040 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1041 ok( sz == 3, "size wrong\n");
1042 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1043 ok( r == ERROR_SUCCESS, "format failed\n");
1045 r = MsiRecordSetString(hrec, 0, "x[~]x");
1047 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1048 ok( sz == 3, "size wrong\n");
1049 ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
1050 ok( r == ERROR_SUCCESS, "format failed\n");
1052 r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
1053 r = MsiRecordSetString(hrec, 1, "hoo");
1055 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1056 ok( sz == 3, "size wrong\n");
1057 ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1058 ok( r == ERROR_SUCCESS, "format failed\n");
1060 r = MsiRecordSetString(hrec, 0, "[\\[]");
1062 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1063 ok( sz == 1, "size wrong\n");
1064 ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
1065 ok( r == ERROR_SUCCESS, "format failed\n");
1067 SetEnvironmentVariable("FOO", "BAR");
1068 r = MsiRecordSetString(hrec, 0, "[%FOO]");
1070 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1071 ok( sz == 3, "size wrong\n");
1072 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1073 ok( r == ERROR_SUCCESS, "format failed\n");
1075 r = MsiRecordSetString(hrec, 0, "[[1]]");
1076 r = MsiRecordSetString(hrec, 1, "%FOO");
1078 r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1079 ok( sz == 3, "size wrong\n");
1080 ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1081 ok( r == ERROR_SUCCESS, "format failed\n");
1083 MsiCloseHandle( hrec );
1084 MsiCloseHandle( hpkg );
1085 DeleteFile(msifile);
1090 test_createpackage();
1091 test_getsourcepath_bad();
1092 test_getsourcepath();
1094 test_gettargetpath_bad();
1095 test_settargetpath();
1099 test_formatrecord2();