msi: Disable child features of parent features that are unselected because of the...
[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 const char msifile[] = "winetest.msi";
32
33 static UINT run_query( MSIHANDLE hdb, const char *query )
34 {
35     MSIHANDLE hview = 0;
36     UINT r;
37
38     r = MsiDatabaseOpenView(hdb, query, &hview);
39     if( r != ERROR_SUCCESS )
40         return r;
41
42     r = MsiViewExecute(hview, 0);
43     if( r == ERROR_SUCCESS )
44         r = MsiViewClose(hview);
45     MsiCloseHandle(hview);
46     return r;
47 }
48
49 static UINT create_component_table( MSIHANDLE hdb )
50 {
51     return run_query( hdb,
52             "CREATE TABLE `Component` ( "
53             "`Component` CHAR(72) NOT NULL, "
54             "`ComponentId` CHAR(38), "
55             "`Directory_` CHAR(72) NOT NULL, "
56             "`Attributes` SHORT NOT NULL, "
57             "`Condition` CHAR(255), "
58             "`KeyPath` CHAR(72) "
59             "PRIMARY KEY `Component`)" );
60 }
61
62 static UINT create_feature_table( MSIHANDLE hdb )
63 {
64     return run_query( hdb,
65             "CREATE TABLE `Feature` ( "
66             "`Feature` CHAR(38) NOT NULL, "
67             "`Feature_Parent` CHAR(38), "
68             "`Title` CHAR(64), "
69             "`Description` CHAR(255), "
70             "`Display` SHORT NOT NULL, "
71             "`Level` SHORT NOT NULL, "
72             "`Directory_` CHAR(72), "
73             "`Attributes` SHORT NOT NULL "
74             "PRIMARY KEY `Feature`)" );
75 }
76
77 static UINT create_feature_components_table( MSIHANDLE hdb )
78 {
79     return run_query( hdb,
80             "CREATE TABLE `FeatureComponents` ( "
81             "`Feature_` CHAR(38) NOT NULL, "
82             "`Component_` CHAR(72) NOT NULL "
83             "PRIMARY KEY `Feature_`, `Component_` )" );
84 }
85
86 static UINT create_file_table( MSIHANDLE hdb )
87 {
88     return run_query( hdb,
89             "CREATE TABLE `File` ("
90             "`File` CHAR(72) NOT NULL, "
91             "`Component_` CHAR(72) NOT NULL, "
92             "`FileName` CHAR(255) NOT NULL, "
93             "`FileSize` LONG NOT NULL, "
94             "`Version` CHAR(72), "
95             "`Language` CHAR(20), "
96             "`Attributes` SHORT, "
97             "`Sequence` SHORT NOT NULL "
98             "PRIMARY KEY `File`)" );
99 }
100
101 static UINT create_remove_file_table( MSIHANDLE hdb )
102 {
103     return run_query( hdb,
104             "CREATE TABLE `RemoveFile` ("
105             "`FileKey` CHAR(72) NOT NULL, "
106             "`Component_` CHAR(72) NOT NULL, "
107             "`FileName` CHAR(255) LOCALIZABLE, "
108             "`DirProperty` CHAR(72) NOT NULL, "
109             "`InstallMode` SHORT NOT NULL "
110             "PRIMARY KEY `FileKey`)" );
111 }
112
113 static UINT create_appsearch_table( MSIHANDLE hdb )
114 {
115     return run_query( hdb,
116             "CREATE TABLE `AppSearch` ("
117             "`Property` CHAR(72) NOT NULL, "
118             "`Signature_` CHAR(72) NOT NULL "
119             "PRIMARY KEY `Property`, `Signature_`)" );
120 }
121
122 static UINT create_reglocator_table( MSIHANDLE hdb )
123 {
124     return run_query( hdb,
125             "CREATE TABLE `RegLocator` ("
126             "`Signature_` CHAR(72) NOT NULL, "
127             "`Root` SHORT NOT NULL, "
128             "`Key` CHAR(255) NOT NULL, "
129             "`Name` CHAR(255), "
130             "`Type` SHORT "
131             "PRIMARY KEY `Signature_`)" );
132 }
133
134 static UINT create_signature_table( MSIHANDLE hdb )
135 {
136     return run_query( hdb,
137             "CREATE TABLE `Signature` ("
138             "`Signature` CHAR(72) NOT NULL, "
139             "`FileName` CHAR(255) NOT NULL, "
140             "`MinVersion` CHAR(20), "
141             "`MaxVersion` CHAR(20), "
142             "`MinSize` LONG, "
143             "`MaxSize` LONG, "
144             "`MinDate` LONG, "
145             "`MaxDate` LONG, "
146             "`Languages` CHAR(255) "
147             "PRIMARY KEY `Signature`)" );
148 }
149
150 static UINT add_component_entry( MSIHANDLE hdb, const char *values )
151 {
152     char insert[] = "INSERT INTO `Component`  "
153             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
154             "VALUES( %s )";
155     char *query;
156     UINT sz, r;
157
158     sz = strlen(values) + sizeof insert;
159     query = HeapAlloc(GetProcessHeap(),0,sz);
160     sprintf(query,insert,values);
161     r = run_query( hdb, query );
162     HeapFree(GetProcessHeap(), 0, query);
163     return r;
164 }
165
166 static UINT add_feature_entry( MSIHANDLE hdb, const char *values )
167 {
168     char insert[] = "INSERT INTO `Feature` (`Feature`, `Feature_Parent`, "
169                     "`Title`, `Description`, `Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )";
170     char *query;
171     UINT sz, r;
172
173     sz = strlen(values) + sizeof insert;
174     query = HeapAlloc(GetProcessHeap(),0,sz);
175     sprintf(query,insert,values);
176     r = run_query( hdb, query );
177     HeapFree(GetProcessHeap(), 0, query);
178     return r;
179 }
180
181 static UINT add_feature_components_entry( MSIHANDLE hdb, const char *values )
182 {
183     char insert[] = "INSERT INTO `FeatureComponents` "
184             "(`Feature_`, `Component_`) "
185             "VALUES( %s )";
186     char *query;
187     UINT sz, r;
188
189     sz = strlen(values) + sizeof insert;
190     query = HeapAlloc(GetProcessHeap(),0,sz);
191     sprintf(query,insert,values);
192     r = run_query( hdb, query );
193     HeapFree(GetProcessHeap(), 0, query);
194     return r;
195 }
196
197 static UINT add_file_entry( MSIHANDLE hdb, const char *values )
198 {
199     char insert[] = "INSERT INTO `File` "
200             "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
201             "VALUES( %s )";
202     char *query;
203     UINT sz, r;
204
205     sz = strlen(values) + sizeof insert;
206     query = HeapAlloc(GetProcessHeap(),0,sz);
207     sprintf(query,insert,values);
208     r = run_query( hdb, query );
209     HeapFree(GetProcessHeap(), 0, query);
210     return r;
211 }
212
213 static UINT add_appsearch_entry( MSIHANDLE hdb, const char *values )
214 {
215     char insert[] = "INSERT INTO `AppSearch` "
216             "(`Property`, `Signature_`) "
217             "VALUES( %s )";
218     char *query;
219     UINT sz, r;
220
221     sz = strlen(values) + sizeof insert;
222     query = HeapAlloc(GetProcessHeap(),0,sz);
223     sprintf(query,insert,values);
224     r = run_query( hdb, query );
225     HeapFree(GetProcessHeap(), 0, query);
226     return r;
227 }
228
229 static UINT add_reglocator_entry( MSIHANDLE hdb, const char *values )
230 {
231     char insert[] = "INSERT INTO `RegLocator` "
232             "(`Signature_`, `Root`, `Key`, `Name`, `Type`) "
233             "VALUES( %s )";
234     char *query;
235     UINT sz, r;
236
237     sz = strlen(values) + sizeof insert;
238     query = HeapAlloc(GetProcessHeap(),0,sz);
239     sprintf(query,insert,values);
240     r = run_query( hdb, query );
241     HeapFree(GetProcessHeap(), 0, query);
242     return r;
243 }
244
245 static UINT add_signature_entry( MSIHANDLE hdb, const char *values )
246 {
247     char insert[] = "INSERT INTO `Signature` "
248             "(`Signature`, `FileName`, `MinVersion`, `MaxVersion`,"
249             " `MinSize`, `MaxSize`, `MinDate`, `MaxDate`, `Languages`) "
250             "VALUES( %s )";
251     char *query;
252     UINT sz, r;
253
254     sz = strlen(values) + sizeof insert;
255     query = HeapAlloc(GetProcessHeap(),0,sz);
256     sprintf(query,insert,values);
257     r = run_query( hdb, query );
258     HeapFree(GetProcessHeap(), 0, query);
259     return r;
260 }
261
262 static UINT set_summary_info(MSIHANDLE hdb)
263 {
264     UINT res;
265     MSIHANDLE suminfo;
266
267     /* build summmary info */
268     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
269     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
270
271     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
272                         "Installation Database");
273     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
274
275     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
276                         "Installation Database");
277     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
278
279     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
280                         "Wine Hackers");
281     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
282
283     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
284                     ";1033");
285     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
286
287     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
288                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
289     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
290
291     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
292     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
293
294     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
295     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
296
297     res = MsiSummaryInfoPersist(suminfo);
298     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
299
300     res = MsiCloseHandle( suminfo);
301     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
302
303     return res;
304 }
305
306
307 static MSIHANDLE create_package_db(void)
308 {
309     MSIHANDLE hdb = 0;
310     UINT res;
311
312     DeleteFile(msifile);
313
314     /* create an empty database */
315     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
316     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
317     if( res != ERROR_SUCCESS )
318         return hdb;
319
320     res = MsiDatabaseCommit( hdb );
321     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
322
323     res = set_summary_info(hdb);
324
325     res = run_query( hdb,
326             "CREATE TABLE `Directory` ( "
327             "`Directory` CHAR(255) NOT NULL, "
328             "`Directory_Parent` CHAR(255), "
329             "`DefaultDir` CHAR(255) NOT NULL "
330             "PRIMARY KEY `Directory`)" );
331     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
332
333     return hdb;
334 }
335
336 static MSIHANDLE package_from_db(MSIHANDLE hdb)
337 {
338     UINT res;
339     CHAR szPackage[10];
340     MSIHANDLE hPackage;
341
342     sprintf(szPackage,"#%li",hdb);
343     res = MsiOpenPackage(szPackage,&hPackage);
344     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
345
346     res = MsiCloseHandle(hdb);
347     ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
348
349     return hPackage;
350 }
351
352 static void create_test_file(const CHAR *name)
353 {
354     HANDLE file;
355     DWORD written;
356
357     file = CreateFileA(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
358     ok(file != INVALID_HANDLE_VALUE, "Failure to open file %s\n", name);
359     WriteFile(file, name, strlen(name), &written, NULL);
360     WriteFile(file, "\n", strlen("\n"), &written, NULL);
361     CloseHandle(file);
362 }
363
364 static void test_createpackage(void)
365 {
366     MSIHANDLE hPackage = 0;
367     UINT res;
368
369     hPackage = package_from_db(create_package_db());
370     ok( hPackage != 0, " Failed to create package\n");
371
372     res = MsiCloseHandle( hPackage);
373     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
374     DeleteFile(msifile);
375 }
376
377 static void test_getsourcepath_bad( void )
378 {
379     static const char str[] = { 0 };
380     char buffer[0x80];
381     DWORD sz;
382     UINT r;
383
384     r = MsiGetSourcePath( -1, NULL, NULL, NULL );
385     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
386
387     sz = 0;
388     r = MsiGetSourcePath( -1, NULL, buffer, &sz );
389     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
390
391     sz = 0;
392     r = MsiGetSourcePath( -1, str, NULL, &sz );
393     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
394
395     sz = 0;
396     r = MsiGetSourcePath( -1, str, NULL, NULL );
397     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
398
399     sz = 0;
400     r = MsiGetSourcePath( -1, str, buffer, &sz );
401     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
402 }
403
404 static UINT add_directory_entry( MSIHANDLE hdb, const char *values )
405 {
406     char insert[] = "INSERT INTO `Directory` (`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )";
407     char *query;
408     UINT sz, r;
409
410     sz = strlen(values) + sizeof insert;
411     query = HeapAlloc(GetProcessHeap(),0,sz);
412     sprintf(query,insert,values);
413     r = run_query( hdb, query );
414     HeapFree(GetProcessHeap(), 0, query);
415     return r;
416 }
417
418 static void test_getsourcepath( void )
419 {
420     static const char str[] = { 0 };
421     char buffer[0x80];
422     DWORD sz;
423     UINT r;
424     MSIHANDLE hpkg, hdb;
425
426     hpkg = package_from_db(create_package_db());
427     ok( hpkg, "failed to create package\n");
428
429     sz = 0;
430     buffer[0] = 'x';
431     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
432     ok( r == ERROR_DIRECTORY, "return value wrong\n");
433     ok( buffer[0] == 'x', "buffer modified\n");
434
435     sz = 1;
436     buffer[0] = 'x';
437     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
438     ok( r == ERROR_DIRECTORY, "return value wrong\n");
439     ok( buffer[0] == 'x', "buffer modified\n");
440
441     MsiCloseHandle( hpkg );
442
443
444     /* another test but try create a directory this time */
445     hdb = create_package_db();
446     ok( hdb, "failed to create database\n");
447
448     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
449     ok( r == S_OK, "failed\n");
450
451     hpkg = package_from_db(hdb);
452     ok( hpkg, "failed to create package\n");
453
454     sz = sizeof buffer -1;
455     strcpy(buffer,"x bad");
456     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
457     ok( r == ERROR_DIRECTORY, "return value wrong\n");
458
459     r = MsiDoAction( hpkg, "CostInitialize");
460     ok( r == ERROR_SUCCESS, "cost init failed\n");
461     r = MsiDoAction( hpkg, "CostFinalize");
462     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
463
464     todo_wine {
465     sz = sizeof buffer -1;
466     buffer[0] = 'x';
467     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
468     ok( r == ERROR_SUCCESS, "return value wrong\n");
469     ok( sz == strlen(buffer), "returned length wrong\n");
470
471     sz = 0;
472     strcpy(buffer,"x bad");
473     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
474     ok( r == ERROR_MORE_DATA, "return value wrong\n");
475     }
476     ok( buffer[0] == 'x', "buffer modified\n");
477
478     todo_wine {
479     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, NULL );
480     ok( r == ERROR_SUCCESS, "return value wrong\n");
481     }
482
483     r = MsiGetSourcePath( hpkg, "TARGETDIR ", NULL, NULL );
484     ok( r == ERROR_DIRECTORY, "return value wrong\n");
485
486     r = MsiGetSourcePath( hpkg, "targetdir", NULL, NULL );
487     ok( r == ERROR_DIRECTORY, "return value wrong\n");
488
489     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, NULL );
490     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
491
492     todo_wine {
493     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, &sz );
494     ok( r == ERROR_SUCCESS, "return value wrong\n");
495     }
496
497     MsiCloseHandle( hpkg );
498     DeleteFile(msifile);
499 }
500
501 static void test_doaction( void )
502 {
503     MSIHANDLE hpkg;
504     UINT r;
505
506     r = MsiDoAction( -1, NULL );
507     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
508
509     hpkg = package_from_db(create_package_db());
510     ok( hpkg, "failed to create package\n");
511
512     r = MsiDoAction(hpkg, NULL);
513     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
514
515     r = MsiDoAction(0, "boo");
516     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
517
518     r = MsiDoAction(hpkg, "boo");
519     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
520
521     MsiCloseHandle( hpkg );
522     DeleteFile(msifile);
523 }
524
525 static void test_gettargetpath_bad(void)
526 {
527     char buffer[0x80];
528     MSIHANDLE hpkg;
529     DWORD sz;
530     UINT r;
531
532     hpkg = package_from_db(create_package_db());
533     ok( hpkg, "failed to create package\n");
534
535     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
536     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
537
538     r = MsiGetTargetPath( 0, NULL, NULL, &sz );
539     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
540
541     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
542     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
543
544     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
545     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
546
547     r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
548     ok( r == ERROR_DIRECTORY, "wrong return val\n");
549
550     r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
551     ok( r == ERROR_DIRECTORY, "wrong return val\n");
552
553     MsiCloseHandle( hpkg );
554     DeleteFile(msifile);
555 }
556
557 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
558 {
559     UINT r;
560     DWORD size;
561     MSIHANDLE rec;
562
563     rec = MsiCreateRecord( 1 );
564     ok(rec, "MsiCreate record failed\n");
565
566     r = MsiRecordSetString( rec, 0, file );
567     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
568
569     size = MAX_PATH;
570     r = MsiFormatRecord( hpkg, rec, buff, &size );
571     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
572
573     MsiCloseHandle( rec );
574 }
575
576 static void test_settargetpath(void)
577 {
578     char tempdir[MAX_PATH+8], buffer[MAX_PATH];
579     DWORD sz;
580     MSIHANDLE hpkg;
581     UINT r;
582     MSIHANDLE hdb;
583
584     hdb = create_package_db();
585     ok ( hdb, "failed to create package database\n" );
586
587     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
588     ok( r == S_OK, "failed to add directory entry: %d\n" , r );
589
590     r = run_query( hdb, /* these tables required by Windows Installer for MsiSetTargetPath */
591             "CREATE TABLE `Component` ( "
592             "`Component` CHAR(72) NOT NULL, "
593             "`ComponentId` CHAR(38), "
594             "`Directory_` CHAR(72) NOT NULL, "
595             "`Attributes` SHORT NOT NULL, "
596             "`Condition` CHAR(255), "
597             "`KeyPath` CHAR(72) "
598             "PRIMARY KEY `Component`)" );
599     ok( r == S_OK, "cannot create Component table: %d\n", r );
600
601     r = run_query( hdb,
602             "INSERT INTO `Component`  "
603             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
604             "VALUES( 'WinWorkAround', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'FL_dummycomponent')" );
605     ok( r == S_OK, "cannot add dummy component: %d\n", r );
606
607     r = run_query( hdb,
608             "INSERT INTO `Component`  "
609             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
610             "VALUES( 'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile')" );
611     ok( r == S_OK, "cannot add test component: %d\n", r );
612
613     r = run_query( hdb,
614             "CREATE TABLE `Feature` ( "
615             "`Feature` CHAR(38) NOT NULL, "
616             "`Feature_Parent` CHAR(38), "
617             "`Title` CHAR(64), "
618             "`Description` CHAR(255), "
619             "`Display` SHORT NOT NULL, "
620             "`Level` SHORT NOT NULL, "
621             "`Directory_` CHAR(72), "
622             "`Attributes` SHORT NOT NULL "
623             "PRIMARY KEY `Feature`)" );
624     ok( r == S_OK, "cannot create Feature table: %d\n", r );
625
626     r = run_query( hdb,
627             "INSERT INTO `Feature` "
628             "(`Feature`, `Feature_Parent`, `Display`, `Level`, `Attributes`) "
629             "VALUES( 'TestFeature', '', 0, 1, 0 )" );
630     ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r );
631
632     r = run_query( hdb,
633             "CREATE TABLE `FeatureComponents` ( "
634             "`Feature_` CHAR(38) NOT NULL, "
635             "`Component_` CHAR(72) NOT NULL "
636             "PRIMARY KEY `Feature_` )" );
637     ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
638
639     r = run_query( hdb,
640             "INSERT INTO `FeatureComponents` "
641             "(`Feature_`, `Component_`) "
642             "VALUES( 'TestFeature', 'TestComp' )" );
643     ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
644
645     add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
646     add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
647
648     r = run_query( hdb,
649             "CREATE TABLE `File` ("
650             "`File` CHAR(72) NOT NULL, "
651             "`Component_` CHAR(72) NOT NULL, "
652             "`FileName` CHAR(255) NOT NULL, "
653             "`FileSize` LONG NOT NULL, "
654             "`Version` CHAR(72), "
655             "`Language` CHAR(20), "
656             "`Attributes` SHORT, "
657             "`Sequence` SHORT NOT NULL "
658             "PRIMARY KEY `File`)" );
659     ok( r == S_OK, "cannot create File table: %d\n", r );
660
661     r = run_query( hdb,
662             "INSERT INTO `File` "
663             "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
664             "VALUES( 'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1 )" );
665     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
666
667     hpkg = package_from_db( hdb );
668     ok( hpkg, "failed to create package\n");
669
670     r = MsiDoAction( hpkg, "CostInitialize");
671     ok( r == ERROR_SUCCESS, "cost init failed\n");
672
673     r = MsiDoAction( hpkg, "FileCost");
674     ok( r == ERROR_SUCCESS, "file cost failed\n");
675
676     r = MsiDoAction( hpkg, "CostFinalize");
677     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
678
679     r = MsiSetTargetPath( 0, NULL, NULL );
680     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
681
682     r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
683     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
684
685     r = MsiSetTargetPath( hpkg, "boo", NULL );
686     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
687
688     r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
689     ok( r == ERROR_DIRECTORY, "wrong return val\n");
690
691     sz = sizeof tempdir - 1;
692     r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
693     if ( r == S_OK )
694     {
695         if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
696         {
697             sprintf( tempdir, "%s\\subdir", buffer );
698             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
699             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
700
701             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
702             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
703
704             DeleteFile( buffer );
705
706             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
707             ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
708
709             r = GetFileAttributes( buffer );
710             ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
711
712             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
713             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
714         } else {
715             trace("GetTempFileName failed, cannot do some tests\n");
716         }
717     } else {
718         trace( "MsiGetTargetPath failed: %d\n", r );
719     }
720
721     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );
722     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
723
724     query_file_path( hpkg, "[#TestFile]", buffer );
725     ok( !lstrcmp(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
726         "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
727     
728     MsiCloseHandle( hpkg );
729 }
730
731 static void test_condition(void)
732 {
733     MSICONDITION r;
734     MSIHANDLE hpkg;
735
736     hpkg = package_from_db(create_package_db());
737     ok( hpkg, "failed to create package\n");
738
739     r = MsiEvaluateCondition(0, NULL);
740     ok( r == MSICONDITION_ERROR, "wrong return val\n");
741
742     r = MsiEvaluateCondition(hpkg, NULL);
743     ok( r == MSICONDITION_NONE, "wrong return val\n");
744
745     r = MsiEvaluateCondition(hpkg, "");
746     ok( r == MSICONDITION_NONE, "wrong return val\n");
747
748     r = MsiEvaluateCondition(hpkg, "1");
749     ok( r == MSICONDITION_TRUE, "wrong return val\n");
750
751     r = MsiEvaluateCondition(hpkg, "0");
752     ok( r == MSICONDITION_FALSE, "wrong return val\n");
753
754     r = MsiEvaluateCondition(hpkg, "0 = 0");
755     ok( r == MSICONDITION_TRUE, "wrong return val\n");
756
757     r = MsiEvaluateCondition(hpkg, "0 <> 0");
758     ok( r == MSICONDITION_FALSE, "wrong return val\n");
759
760     r = MsiEvaluateCondition(hpkg, "0 = 1");
761     ok( r == MSICONDITION_FALSE, "wrong return val\n");
762
763     r = MsiEvaluateCondition(hpkg, "0 > 1");
764     ok( r == MSICONDITION_FALSE, "wrong return val\n");
765
766     r = MsiEvaluateCondition(hpkg, "0 ~> 1");
767     ok( r == MSICONDITION_FALSE, "wrong return val\n");
768
769     r = MsiEvaluateCondition(hpkg, "1 > 1");
770     ok( r == MSICONDITION_FALSE, "wrong return val\n");
771
772     r = MsiEvaluateCondition(hpkg, "1 ~> 1");
773     ok( r == MSICONDITION_FALSE, "wrong return val\n");
774
775     r = MsiEvaluateCondition(hpkg, "0 >= 1");
776     ok( r == MSICONDITION_FALSE, "wrong return val\n");
777
778     r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
779     ok( r == MSICONDITION_FALSE, "wrong return val\n");
780
781     r = MsiEvaluateCondition(hpkg, "1 >= 1");
782     ok( r == MSICONDITION_TRUE, "wrong return val\n");
783
784     r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
785     ok( r == MSICONDITION_TRUE, "wrong return val\n");
786
787     r = MsiEvaluateCondition(hpkg, "0 < 1");
788     ok( r == MSICONDITION_TRUE, "wrong return val\n");
789
790     r = MsiEvaluateCondition(hpkg, "0 ~< 1");
791     ok( r == MSICONDITION_TRUE, "wrong return val\n");
792
793     r = MsiEvaluateCondition(hpkg, "1 < 1");
794     ok( r == MSICONDITION_FALSE, "wrong return val\n");
795
796     r = MsiEvaluateCondition(hpkg, "1 ~< 1");
797     ok( r == MSICONDITION_FALSE, "wrong return val\n");
798
799     r = MsiEvaluateCondition(hpkg, "0 <= 1");
800     ok( r == MSICONDITION_TRUE, "wrong return val\n");
801
802     r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
803     ok( r == MSICONDITION_TRUE, "wrong return val\n");
804
805     r = MsiEvaluateCondition(hpkg, "1 <= 1");
806     ok( r == MSICONDITION_TRUE, "wrong return val\n");
807
808     r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
809     ok( r == MSICONDITION_TRUE, "wrong return val\n");
810
811     r = MsiEvaluateCondition(hpkg, "0 >=");
812     ok( r == MSICONDITION_ERROR, "wrong return val\n");
813
814     r = MsiEvaluateCondition(hpkg, " ");
815     ok( r == MSICONDITION_NONE, "wrong return val\n");
816
817     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
818     ok( r == MSICONDITION_TRUE, "wrong return val\n");
819
820     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
821     ok( r == MSICONDITION_TRUE, "wrong return val\n");
822
823     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
824     ok( r == MSICONDITION_FALSE, "wrong return val\n");
825
826     r = MsiEvaluateCondition(hpkg, "not 0");
827     ok( r == MSICONDITION_TRUE, "wrong return val\n");
828
829     r = MsiEvaluateCondition(hpkg, "not LicView");
830     ok( r == MSICONDITION_TRUE, "wrong return val\n");
831
832     r = MsiEvaluateCondition(hpkg, "not \"A\"");
833     ok( r == MSICONDITION_FALSE, "wrong return val\n");
834
835     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
836     ok( r == MSICONDITION_ERROR, "wrong return val\n");
837
838     r = MsiEvaluateCondition(hpkg, "\"0\"");
839     ok( r == MSICONDITION_TRUE, "wrong return val\n");
840
841     r = MsiEvaluateCondition(hpkg, "1 and 2");
842     ok( r == MSICONDITION_TRUE, "wrong return val\n");
843
844     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
845     ok( r == MSICONDITION_TRUE, "wrong return val\n");
846
847     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
848     ok( r == MSICONDITION_FALSE, "wrong return val\n");
849
850     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
851     ok( r == MSICONDITION_TRUE, "wrong return val\n");
852
853     r = MsiEvaluateCondition(hpkg, "(0)");
854     ok( r == MSICONDITION_FALSE, "wrong return val\n");
855
856     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
857     ok( r == MSICONDITION_ERROR, "wrong return val\n");
858
859     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
860     ok( r == MSICONDITION_TRUE, "wrong return val\n");
861
862     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
863     ok( r == MSICONDITION_TRUE, "wrong return val\n");
864
865     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
866     ok( r == MSICONDITION_FALSE, "wrong return val\n");
867
868     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
869     ok( r == MSICONDITION_FALSE, "wrong return val\n");
870
871     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
872     ok( r == MSICONDITION_TRUE, "wrong return val\n");
873
874     r = MsiEvaluateCondition(hpkg, "0 < > 0");
875     ok( r == MSICONDITION_ERROR, "wrong return val\n");
876
877     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
878     ok( r == MSICONDITION_ERROR, "wrong return val\n");
879
880     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
881     ok( r == MSICONDITION_FALSE, "wrong return val\n");
882
883     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
884     ok( r == MSICONDITION_ERROR, "wrong return val\n");
885
886     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
887     ok( r == MSICONDITION_TRUE, "wrong return val\n");
888
889     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
890     ok( r == MSICONDITION_FALSE, "wrong return val\n");
891
892     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
893     ok( r == MSICONDITION_FALSE, "wrong return val\n");
894
895     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
896     ok( r == MSICONDITION_TRUE, "wrong return val\n");
897
898     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
899     ok( r == MSICONDITION_FALSE, "wrong return val\n");
900
901     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
902     ok( r == MSICONDITION_FALSE, "wrong return val\n");
903
904     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
905     ok( r == MSICONDITION_FALSE, "wrong return val\n");
906
907     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
908     ok( r == MSICONDITION_FALSE, "wrong return val\n");
909
910     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
911     ok( r == MSICONDITION_FALSE, "wrong return val\n");
912
913     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
914     ok( r == MSICONDITION_FALSE, "wrong return val\n");
915
916     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
917     ok( r == MSICONDITION_TRUE, "wrong return val\n");
918
919     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
920     ok( r == MSICONDITION_FALSE, "wrong return val\n");
921
922     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
923     ok( r == MSICONDITION_TRUE, "wrong return val\n");
924
925     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
926     ok( r == MSICONDITION_TRUE, "wrong return val\n");
927
928     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
929     ok( r == MSICONDITION_FALSE, "wrong return val\n");
930
931     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
932     ok( r == MSICONDITION_TRUE, "wrong return val\n");
933
934     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
935     ok( r == MSICONDITION_ERROR, "wrong return val\n");
936
937     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
938     ok( r == MSICONDITION_TRUE, "wrong return val\n");
939
940     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
941     ok( r == MSICONDITION_TRUE, "wrong return val\n");
942
943     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
944     ok( r == MSICONDITION_TRUE, "wrong return val\n");
945
946     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
947     ok( r == MSICONDITION_FALSE, "wrong return val\n");
948
949     MsiSetProperty(hpkg, "mm", "5" );
950
951     r = MsiEvaluateCondition(hpkg, "mm = 5");
952     ok( r == MSICONDITION_TRUE, "wrong return val\n");
953
954     r = MsiEvaluateCondition(hpkg, "mm < 6");
955     ok( r == MSICONDITION_TRUE, "wrong return val\n");
956
957     r = MsiEvaluateCondition(hpkg, "mm <= 5");
958     ok( r == MSICONDITION_TRUE, "wrong return val\n");
959
960     r = MsiEvaluateCondition(hpkg, "mm > 4");
961     ok( r == MSICONDITION_TRUE, "wrong return val\n");
962
963     r = MsiEvaluateCondition(hpkg, "mm < 12");
964     ok( r == MSICONDITION_TRUE, "wrong return val\n");
965
966     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
967     ok( r == MSICONDITION_TRUE, "wrong return val\n");
968
969     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
970     ok( r == MSICONDITION_FALSE, "wrong return val\n");
971
972     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
973     ok( r == MSICONDITION_FALSE, "wrong return val\n");
974
975     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
976     ok( r == MSICONDITION_FALSE, "wrong return val\n");
977
978     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
979     ok( r == MSICONDITION_TRUE, "wrong return val\n");
980
981     r = MsiEvaluateCondition(hpkg, "3 >< 1");
982     ok( r == MSICONDITION_TRUE, "wrong return val\n");
983
984     r = MsiEvaluateCondition(hpkg, "3 >< 4");
985     ok( r == MSICONDITION_FALSE, "wrong return val\n");
986
987     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
988     ok( r == MSICONDITION_FALSE, "wrong return val\n");
989
990     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
991     ok( r == MSICONDITION_TRUE, "wrong return val\n");
992
993     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
994     ok( r == MSICONDITION_FALSE, "wrong return val\n");
995
996     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
997     ok( r == MSICONDITION_TRUE, "wrong return val\n");
998
999     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
1000     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1001
1002     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
1003     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1004
1005     r = MsiEvaluateCondition(hpkg, "_1 = _1");
1006     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1007
1008     r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
1009     ok( r == MSICONDITION_ERROR, "wrong return val\n");
1010
1011     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
1012     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1013
1014     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
1015     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1016
1017     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
1018     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1019
1020     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
1021     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1022
1023     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1024     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1025
1026     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1027     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1028
1029     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
1030     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1031
1032     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
1033     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1034
1035     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
1036     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1037
1038     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
1039     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1040
1041     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
1042     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1043
1044     MsiSetProperty(hpkg, "bandalmael", "0" );
1045     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1046     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1047
1048     MsiSetProperty(hpkg, "bandalmael", "" );
1049     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1050     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1051
1052     MsiSetProperty(hpkg, "bandalmael", "asdf" );
1053     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1054     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1055
1056     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
1057     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1058     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1059
1060     MsiSetProperty(hpkg, "bandalmael", "0 " );
1061     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1062     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1063
1064     MsiSetProperty(hpkg, "bandalmael", "-0" );
1065     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1066     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1067
1068     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
1069     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1070     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1071
1072     MsiSetProperty(hpkg, "bandalmael", "--0" );
1073     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1074     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1075
1076     MsiSetProperty(hpkg, "bandalmael", "0x00" );
1077     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1078     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1079
1080     MsiSetProperty(hpkg, "bandalmael", "-" );
1081     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1082     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1083
1084     MsiSetProperty(hpkg, "bandalmael", "+0" );
1085     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1086     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1087
1088     MsiSetProperty(hpkg, "bandalmael", "0.0" );
1089     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
1090     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1091     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
1092     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1093
1094     MsiSetProperty(hpkg, "one", "hi");
1095     MsiSetProperty(hpkg, "two", "hithere");
1096     r = MsiEvaluateCondition(hpkg, "one >< two");
1097     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1098
1099     MsiSetProperty(hpkg, "one", "hithere");
1100     MsiSetProperty(hpkg, "two", "hi");
1101     r = MsiEvaluateCondition(hpkg, "one >< two");
1102     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1103
1104     MsiSetProperty(hpkg, "one", "hello");
1105     MsiSetProperty(hpkg, "two", "hi");
1106     r = MsiEvaluateCondition(hpkg, "one >< two");
1107     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1108
1109     MsiSetProperty(hpkg, "one", "hellohithere");
1110     MsiSetProperty(hpkg, "two", "hi");
1111     r = MsiEvaluateCondition(hpkg, "one >< two");
1112     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1113
1114     MsiSetProperty(hpkg, "one", "");
1115     MsiSetProperty(hpkg, "two", "hi");
1116     r = MsiEvaluateCondition(hpkg, "one >< two");
1117     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1118
1119     MsiSetProperty(hpkg, "one", "hi");
1120     MsiSetProperty(hpkg, "two", "");
1121     r = MsiEvaluateCondition(hpkg, "one >< two");
1122     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1123
1124     MsiSetProperty(hpkg, "one", "");
1125     MsiSetProperty(hpkg, "two", "");
1126     r = MsiEvaluateCondition(hpkg, "one >< two");
1127     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1128
1129     MsiSetProperty(hpkg, "one", "1234");
1130     MsiSetProperty(hpkg, "two", "1");
1131     r = MsiEvaluateCondition(hpkg, "one >< two");
1132     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1133
1134     MsiSetProperty(hpkg, "one", "one 1234");
1135     MsiSetProperty(hpkg, "two", "1");
1136     r = MsiEvaluateCondition(hpkg, "one >< two");
1137     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1138
1139     MsiSetProperty(hpkg, "one", "hithere");
1140     MsiSetProperty(hpkg, "two", "hi");
1141     r = MsiEvaluateCondition(hpkg, "one << two");
1142     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1143
1144     MsiSetProperty(hpkg, "one", "hi");
1145     MsiSetProperty(hpkg, "two", "hithere");
1146     r = MsiEvaluateCondition(hpkg, "one << two");
1147     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1148
1149     MsiSetProperty(hpkg, "one", "hi");
1150     MsiSetProperty(hpkg, "two", "hi");
1151     r = MsiEvaluateCondition(hpkg, "one << two");
1152     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1153
1154     MsiSetProperty(hpkg, "one", "abcdhithere");
1155     MsiSetProperty(hpkg, "two", "hi");
1156     r = MsiEvaluateCondition(hpkg, "one << two");
1157     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1158
1159     MsiSetProperty(hpkg, "one", "");
1160     MsiSetProperty(hpkg, "two", "hi");
1161     r = MsiEvaluateCondition(hpkg, "one << two");
1162     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1163
1164     MsiSetProperty(hpkg, "one", "hithere");
1165     MsiSetProperty(hpkg, "two", "");
1166     r = MsiEvaluateCondition(hpkg, "one << two");
1167     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1168
1169     MsiSetProperty(hpkg, "one", "");
1170     MsiSetProperty(hpkg, "two", "");
1171     r = MsiEvaluateCondition(hpkg, "one << two");
1172     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1173
1174     MsiSetProperty(hpkg, "one", "1234");
1175     MsiSetProperty(hpkg, "two", "1");
1176     r = MsiEvaluateCondition(hpkg, "one << two");
1177     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1178
1179     MsiSetProperty(hpkg, "one", "1234 one");
1180     MsiSetProperty(hpkg, "two", "1");
1181     r = MsiEvaluateCondition(hpkg, "one << two");
1182     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1183
1184     MsiSetProperty(hpkg, "one", "hithere");
1185     MsiSetProperty(hpkg, "two", "there");
1186     r = MsiEvaluateCondition(hpkg, "one >> two");
1187     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1188
1189     MsiSetProperty(hpkg, "one", "hithere");
1190     MsiSetProperty(hpkg, "two", "hi");
1191     r = MsiEvaluateCondition(hpkg, "one >> two");
1192     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1193
1194     MsiSetProperty(hpkg, "one", "there");
1195     MsiSetProperty(hpkg, "two", "hithere");
1196     r = MsiEvaluateCondition(hpkg, "one >> two");
1197     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1198
1199     MsiSetProperty(hpkg, "one", "there");
1200     MsiSetProperty(hpkg, "two", "there");
1201     r = MsiEvaluateCondition(hpkg, "one >> two");
1202     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1203
1204     MsiSetProperty(hpkg, "one", "abcdhithere");
1205     MsiSetProperty(hpkg, "two", "hi");
1206     r = MsiEvaluateCondition(hpkg, "one >> two");
1207     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1208
1209     MsiSetProperty(hpkg, "one", "");
1210     MsiSetProperty(hpkg, "two", "there");
1211     r = MsiEvaluateCondition(hpkg, "one >> two");
1212     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1213
1214     MsiSetProperty(hpkg, "one", "there");
1215     MsiSetProperty(hpkg, "two", "");
1216     r = MsiEvaluateCondition(hpkg, "one >> two");
1217     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1218
1219     MsiSetProperty(hpkg, "one", "");
1220     MsiSetProperty(hpkg, "two", "");
1221     r = MsiEvaluateCondition(hpkg, "one >> two");
1222     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1223
1224     MsiSetProperty(hpkg, "one", "1234");
1225     MsiSetProperty(hpkg, "two", "4");
1226     r = MsiEvaluateCondition(hpkg, "one >> two");
1227     ok( r == MSICONDITION_FALSE, "wrong return val\n");
1228
1229     MsiSetProperty(hpkg, "one", "one 1234");
1230     MsiSetProperty(hpkg, "two", "4");
1231     r = MsiEvaluateCondition(hpkg, "one >> two");
1232     ok( r == MSICONDITION_TRUE, "wrong return val\n");
1233
1234     MsiCloseHandle( hpkg );
1235     DeleteFile(msifile);
1236 }
1237
1238 static BOOL check_prop_empty( MSIHANDLE hpkg, const char * prop)
1239 {
1240     UINT r;
1241     DWORD sz;
1242     char buffer[2];
1243
1244     sz = sizeof buffer;
1245     strcpy(buffer,"x");
1246     r = MsiGetProperty( hpkg, prop, buffer, &sz );
1247     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
1248 }
1249
1250 static void test_props(void)
1251 {
1252     MSIHANDLE hpkg;
1253     UINT r;
1254     DWORD sz;
1255     char buffer[0x100];
1256
1257     hpkg = package_from_db(create_package_db());
1258     ok( hpkg, "failed to create package\n");
1259
1260     /* test invalid values */
1261     r = MsiGetProperty( 0, NULL, NULL, NULL );
1262     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1263
1264     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
1265     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1266
1267     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
1268     ok( r == ERROR_SUCCESS, "wrong return val\n");
1269
1270     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
1271     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1272
1273     /* test retrieving an empty/nonexistent property */
1274     sz = sizeof buffer;
1275     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
1276     ok( r == ERROR_SUCCESS, "wrong return val\n");
1277     ok( sz == 0, "wrong size returned\n");
1278
1279     check_prop_empty( hpkg, "boo");
1280     sz = 0;
1281     strcpy(buffer,"x");
1282     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1283     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1284     ok( !strcmp(buffer,"x"), "buffer was changed\n");
1285     ok( sz == 0, "wrong size returned\n");
1286
1287     sz = 1;
1288     strcpy(buffer,"x");
1289     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1290     ok( r == ERROR_SUCCESS, "wrong return val\n");
1291     ok( buffer[0] == 0, "buffer was not changed\n");
1292     ok( sz == 0, "wrong size returned\n");
1293
1294     /* set the property to something */
1295     r = MsiSetProperty( 0, NULL, NULL );
1296     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1297
1298     r = MsiSetProperty( hpkg, NULL, NULL );
1299     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1300
1301     r = MsiSetProperty( hpkg, "", NULL );
1302     ok( r == ERROR_SUCCESS, "wrong return val\n");
1303
1304     /* try set and get some illegal property identifiers */
1305     r = MsiSetProperty( hpkg, "", "asdf" );
1306     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
1307
1308     r = MsiSetProperty( hpkg, "=", "asdf" );
1309     ok( r == ERROR_SUCCESS, "wrong return val\n");
1310
1311     r = MsiSetProperty( hpkg, " ", "asdf" );
1312     ok( r == ERROR_SUCCESS, "wrong return val\n");
1313
1314     r = MsiSetProperty( hpkg, "'", "asdf" );
1315     ok( r == ERROR_SUCCESS, "wrong return val\n");
1316
1317     sz = sizeof buffer;
1318     buffer[0]=0;
1319     r = MsiGetProperty( hpkg, "'", buffer, &sz );
1320     ok( r == ERROR_SUCCESS, "wrong return val\n");
1321     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
1322
1323     /* set empty values */
1324     r = MsiSetProperty( hpkg, "boo", NULL );
1325     ok( r == ERROR_SUCCESS, "wrong return val\n");
1326     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
1327
1328     r = MsiSetProperty( hpkg, "boo", "" );
1329     ok( r == ERROR_SUCCESS, "wrong return val\n");
1330     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
1331
1332     /* set a non-empty value */
1333     r = MsiSetProperty( hpkg, "boo", "xyz" );
1334     ok( r == ERROR_SUCCESS, "wrong return val\n");
1335
1336     sz = 1;
1337     strcpy(buffer,"x");
1338     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1339     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1340     ok( buffer[0] == 0, "buffer was not changed\n");
1341     ok( sz == 3, "wrong size returned\n");
1342
1343     sz = 4;
1344     strcpy(buffer,"x");
1345     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1346     ok( r == ERROR_SUCCESS, "wrong return val\n");
1347     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
1348     ok( sz == 3, "wrong size returned\n");
1349
1350     sz = 3;
1351     strcpy(buffer,"x");
1352     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1353     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1354     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
1355     ok( sz == 3, "wrong size returned\n");
1356
1357     r = MsiSetProperty(hpkg, "SourceDir", "foo");
1358     ok( r == ERROR_SUCCESS, "wrong return val\n");
1359
1360     sz = 4;
1361     r = MsiGetProperty(hpkg, "SOURCEDIR", buffer, &sz);
1362     ok( r == ERROR_SUCCESS, "wrong return val\n");
1363     ok( !strcmp(buffer,""), "buffer wrong\n");
1364     ok( sz == 0, "wrong size returned\n");
1365
1366     sz = 4;
1367     r = MsiGetProperty(hpkg, "SOMERANDOMNAME", buffer, &sz);
1368     ok( r == ERROR_SUCCESS, "wrong return val\n");
1369     ok( !strcmp(buffer,""), "buffer wrong\n");
1370     ok( sz == 0, "wrong size returned\n");
1371
1372     sz = 4;
1373     r = MsiGetProperty(hpkg, "SourceDir", buffer, &sz);
1374     ok( r == ERROR_SUCCESS, "wrong return val\n");
1375     ok( !strcmp(buffer,"foo"), "buffer wrong\n");
1376     ok( sz == 3, "wrong size returned\n");
1377
1378     MsiCloseHandle( hpkg );
1379     DeleteFile(msifile);
1380 }
1381
1382 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
1383 {
1384     MSIHANDLE htab = 0;
1385     UINT res;
1386
1387     res = MsiDatabaseOpenView( hdb, szQuery, &htab );
1388     if( res == ERROR_SUCCESS )
1389     {
1390         UINT r;
1391
1392         r = MsiViewExecute( htab, hrec );
1393         if( r != ERROR_SUCCESS )
1394         {
1395             res = r;
1396             fprintf(stderr,"MsiViewExecute failed %08x\n", res);
1397         }
1398
1399         r = MsiViewClose( htab );
1400         if( r != ERROR_SUCCESS )
1401             res = r;
1402
1403         r = MsiCloseHandle( htab );
1404         if( r != ERROR_SUCCESS )
1405             res = r;
1406     }
1407     return res;
1408 }
1409
1410 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
1411 {
1412     return try_query_param( hdb, szQuery, 0 );
1413 }
1414
1415 static void test_msipackage(void)
1416 {
1417     MSIHANDLE hdb = 0, hpack = 100;
1418     UINT r;
1419     const char *query;
1420     char name[10];
1421
1422     DeleteFile(msifile);
1423
1424     todo_wine {
1425     name[0] = 0;
1426     r = MsiOpenPackage(name, &hpack);
1427     ok(r == ERROR_SUCCESS, "failed to open package with no name\n");
1428     r = MsiCloseHandle(hpack);
1429     ok(r == ERROR_SUCCESS, "failed to close package\n");
1430     }
1431
1432     /* just MsiOpenDatabase should not create a file */
1433     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1434     ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1435
1436     name[0]='#';
1437     name[1]=0;
1438     r = MsiOpenPackage(name, &hpack);
1439     ok(r == ERROR_INVALID_HANDLE, "MsiOpenPackage returned wrong code\n");
1440
1441     todo_wine {
1442     /* now try again with our empty database */
1443     sprintf(name, "#%ld", hdb);
1444     r = MsiOpenPackage(name, &hpack);
1445     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1446     if (!r)    MsiCloseHandle(hpack);
1447     }
1448
1449     /* create a table */
1450     query = "CREATE TABLE `Property` ( "
1451             "`Property` CHAR(72), `Value` CHAR(0) "
1452             "PRIMARY KEY `Property`)";
1453     r = try_query(hdb, query);
1454     ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
1455
1456     todo_wine {
1457     query = "CREATE TABLE `InstallExecuteSequence` ("
1458             "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
1459             "PRIMARY KEY `Action`)";
1460     r = try_query(hdb, query);
1461     ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
1462
1463     sprintf(name, "#%ld", hdb);
1464     r = MsiOpenPackage(name, &hpack);
1465     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1466     if (!r)    MsiCloseHandle(hpack);
1467     }
1468
1469     r = MsiCloseHandle(hdb);
1470     ok(r == ERROR_SUCCESS, "MsiCloseHandle(database) failed\n");
1471     DeleteFile(msifile);
1472 }
1473
1474 static void test_formatrecord2(void)
1475 {
1476     MSIHANDLE hpkg, hrec ;
1477     char buffer[0x100];
1478     DWORD sz;
1479     UINT r;
1480
1481     hpkg = package_from_db(create_package_db());
1482     ok( hpkg, "failed to create package\n");
1483
1484     r = MsiSetProperty(hpkg, "Manufacturer", " " );
1485     ok( r == ERROR_SUCCESS, "set property failed\n");
1486
1487     hrec = MsiCreateRecord(2);
1488     ok(hrec, "create record failed\n");
1489
1490     r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
1491     ok( r == ERROR_SUCCESS, "format record failed\n");
1492
1493     buffer[0] = 0;
1494     sz = sizeof buffer;
1495     r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
1496
1497     r = MsiRecordSetString(hrec, 0, "[foo][1]");
1498     r = MsiRecordSetString(hrec, 1, "hoo");
1499     sz = sizeof buffer;
1500     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1501     ok( sz == 3, "size wrong\n");
1502     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1503     ok( r == ERROR_SUCCESS, "format failed\n");
1504
1505     r = MsiRecordSetString(hrec, 0, "x[~]x");
1506     sz = sizeof buffer;
1507     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1508     ok( sz == 3, "size wrong\n");
1509     ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
1510     ok( r == ERROR_SUCCESS, "format failed\n");
1511
1512     r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
1513     r = MsiRecordSetString(hrec, 1, "hoo");
1514     sz = sizeof buffer;
1515     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1516     ok( sz == 3, "size wrong\n");
1517     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1518     ok( r == ERROR_SUCCESS, "format failed\n");
1519
1520     r = MsiRecordSetString(hrec, 0, "[\\[]");
1521     sz = sizeof buffer;
1522     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1523     ok( sz == 1, "size wrong\n");
1524     ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
1525     ok( r == ERROR_SUCCESS, "format failed\n");
1526
1527     SetEnvironmentVariable("FOO", "BAR");
1528     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1529     sz = sizeof buffer;
1530     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1531     ok( sz == 3, "size wrong\n");
1532     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1533     ok( r == ERROR_SUCCESS, "format failed\n");
1534
1535     r = MsiRecordSetString(hrec, 0, "[[1]]");
1536     r = MsiRecordSetString(hrec, 1, "%FOO");
1537     sz = sizeof buffer;
1538     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1539     ok( sz == 3, "size wrong\n");
1540     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1541     ok( r == ERROR_SUCCESS, "format failed\n");
1542
1543     MsiCloseHandle( hrec );
1544     MsiCloseHandle( hpkg );
1545     DeleteFile(msifile);
1546 }
1547
1548 static void test_states(void)
1549 {
1550     MSIHANDLE hpkg;
1551     UINT r;
1552     MSIHANDLE hdb;
1553     INSTALLSTATE state, action;
1554
1555     hdb = create_package_db();
1556     ok ( hdb, "failed to create package database\n" );
1557
1558     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
1559     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
1560
1561     r = create_feature_table( hdb );
1562     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
1563
1564     r = create_component_table( hdb );
1565     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
1566
1567     /* msidbFeatureAttributesFavorLocal */
1568     r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
1569     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1570
1571     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
1572     r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
1573     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1574
1575     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
1576     r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
1577     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1578
1579     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
1580     r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
1581     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1582
1583     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSharedDllRefCount */
1584     r = add_component_entry( hdb, "'theta', '{4EB3129D-81A8-48D5-9801-75600FED3DD9}', 'TARGETDIR', 8, '', 'theta_file'" );
1585     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1586
1587     /* msidbFeatureAttributesFavorSource */
1588     r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
1589     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1590
1591     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
1592     r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
1593     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1594
1595     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
1596     r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
1597     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1598
1599     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
1600     r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
1601     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1602
1603     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSharedDllRefCount */
1604     r = add_component_entry( hdb, "'iota', '{5D36F871-B5ED-4801-9E0F-C46B9E5C9669}', 'TARGETDIR', 8, '', 'iota_file'" );
1605     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1606
1607     /* msidbFeatureAttributesFavorSource */
1608     r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
1609     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1610
1611     /* msidbFeatureAttributesFavorLocal */
1612     r = add_feature_entry( hdb, "'four', '', '', '', 2, 1, '', 0" );
1613     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1614
1615     /* disabled */
1616     r = add_feature_entry( hdb, "'five', '', '', '', 2, 0, '', 1" );
1617     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1618
1619     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
1620     r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
1621     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1622
1623     r = create_feature_components_table( hdb );
1624     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
1625
1626     r = add_feature_components_entry( hdb, "'one', 'alpha'" );
1627     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1628
1629     r = add_feature_components_entry( hdb, "'one', 'beta'" );
1630     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1631
1632     r = add_feature_components_entry( hdb, "'one', 'gamma'" );
1633     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1634
1635     r = add_feature_components_entry( hdb, "'one', 'theta'" );
1636     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1637
1638     r = add_feature_components_entry( hdb, "'two', 'delta'" );
1639     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1640
1641     r = add_feature_components_entry( hdb, "'two', 'epsilon'" );
1642     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1643
1644     r = add_feature_components_entry( hdb, "'two', 'zeta'" );
1645     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1646
1647     r = add_feature_components_entry( hdb, "'two', 'iota'" );
1648     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1649
1650     r = add_feature_components_entry( hdb, "'three', 'eta'" );
1651     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1652
1653     r = add_feature_components_entry( hdb, "'four', 'eta'" );
1654     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1655
1656     r = add_feature_components_entry( hdb, "'five', 'eta'" );
1657     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1658
1659     r = create_file_table( hdb );
1660     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
1661
1662     r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
1663     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1664
1665     r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
1666     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1667
1668     r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
1669     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1670
1671     r = add_file_entry( hdb, "'theta_file', 'theta', 'theta.txt', 0, '', '1033', 8192, 1" );
1672     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1673
1674     r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
1675     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1676
1677     r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
1678     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1679
1680     r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
1681     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1682
1683     r = add_file_entry( hdb, "'iota_file', 'iota', 'iota.txt', 0, '', '1033', 8192, 1" );
1684     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1685
1686     /* compressed file */
1687     r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
1688     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1689
1690     hpkg = package_from_db( hdb );
1691     ok( hpkg, "failed to create package\n");
1692
1693     state = 0xdeadbee;
1694     action = 0xdeadbee;
1695     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1696     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1697     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1698     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1699
1700     state = 0xdeadbee;
1701     action = 0xdeadbee;
1702     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1703     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1704     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1705     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1706
1707     state = 0xdeadbee;
1708     action = 0xdeadbee;
1709     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1710     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1711     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1712     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1713
1714     state = 0xdeadbee;
1715     action = 0xdeadbee;
1716     r = MsiGetFeatureState(hpkg, "four", &state, &action);
1717     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1718     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1719     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1720
1721     state = 0xdeadbee;
1722     action = 0xdeadbee;
1723     r = MsiGetFeatureState(hpkg, "five", &state, &action);
1724     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1725     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1726     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1727
1728     state = 0xdeadbee;
1729     action = 0xdeadbee;
1730     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1731     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1732     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1733     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1734
1735     state = 0xdeadbee;
1736     action = 0xdeadbee;
1737     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1738     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1739     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1740     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1741
1742     state = 0xdeadbee;
1743     action = 0xdeadbee;
1744     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1745     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1746     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1747     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1748
1749     state = 0xdeadbee;
1750     action = 0xdeadbee;
1751     r = MsiGetComponentState(hpkg, "theta", &state, &action);
1752     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1753     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1754     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1755
1756     state = 0xdeadbee;
1757     action = 0xdeadbee;
1758     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1759     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1760     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1761     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1762
1763     state = 0xdeadbee;
1764     action = 0xdeadbee;
1765     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1766     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1767     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1768     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1769
1770     state = 0xdeadbee;
1771     action = 0xdeadbee;
1772     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1773     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1774     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1775     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1776
1777     state = 0xdeadbee;
1778     action = 0xdeadbee;
1779     r = MsiGetComponentState(hpkg, "iota", &state, &action);
1780     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1781     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1782     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1783
1784     state = 0xdeadbee;
1785     action = 0xdeadbee;
1786     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1787     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1788     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1789     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1790
1791     r = MsiDoAction( hpkg, "CostInitialize");
1792     ok( r == ERROR_SUCCESS, "cost init failed\n");
1793
1794     state = 0xdeadbee;
1795     action = 0xdeadbee;
1796     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1797     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1798     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1799     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1800
1801     state = 0xdeadbee;
1802     action = 0xdeadbee;
1803     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1804     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1805     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1806     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1807
1808     state = 0xdeadbee;
1809     action = 0xdeadbee;
1810     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1811     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1812     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1813     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1814
1815     state = 0xdeadbee;
1816     action = 0xdeadbee;
1817     r = MsiGetFeatureState(hpkg, "four", &state, &action);
1818     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1819     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1820     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1821
1822     state = 0xdeadbee;
1823     action = 0xdeadbee;
1824     r = MsiGetFeatureState(hpkg, "five", &state, &action);
1825     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1826     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1827     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1828
1829     state = 0xdeadbee;
1830     action = 0xdeadbee;
1831     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1832     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1833     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1834     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1835
1836     state = 0xdeadbee;
1837     action = 0xdeadbee;
1838     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1839     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1840     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1841     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1842
1843     state = 0xdeadbee;
1844     action = 0xdeadbee;
1845     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1846     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1847     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1848     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1849
1850     state = 0xdeadbee;
1851     action = 0xdeadbee;
1852     r = MsiGetComponentState(hpkg, "theta", &state, &action);
1853     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1854     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1855     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1856
1857     state = 0xdeadbee;
1858     action = 0xdeadbee;
1859     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1860     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1861     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1862     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1863
1864     state = 0xdeadbee;
1865     action = 0xdeadbee;
1866     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1867     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1868     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1869     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1870
1871     state = 0xdeadbee;
1872     action = 0xdeadbee;
1873     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1874     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1875     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1876     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1877
1878     state = 0xdeadbee;
1879     action = 0xdeadbee;
1880     r = MsiGetComponentState(hpkg, "iota", &state, &action);
1881     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1882     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1883     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1884
1885     state = 0xdeadbee;
1886     action = 0xdeadbee;
1887     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1888     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1889     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1890     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1891
1892     r = MsiDoAction( hpkg, "FileCost");
1893     ok( r == ERROR_SUCCESS, "file cost failed\n");
1894
1895     state = 0xdeadbee;
1896     action = 0xdeadbee;
1897     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1898     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1899     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1900     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1901
1902     state = 0xdeadbee;
1903     action = 0xdeadbee;
1904     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1905     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1906     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1907     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1908
1909     state = 0xdeadbee;
1910     action = 0xdeadbee;
1911     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1912     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1913     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1914     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1915
1916     state = 0xdeadbee;
1917     action = 0xdeadbee;
1918     r = MsiGetFeatureState(hpkg, "four", &state, &action);
1919     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1920     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1921     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1922
1923     state = 0xdeadbee;
1924     action = 0xdeadbee;
1925     r = MsiGetFeatureState(hpkg, "five", &state, &action);
1926     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1927     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1928     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1929
1930     state = 0xdeadbee;
1931     action = 0xdeadbee;
1932     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1933     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1934     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1935     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1936
1937     state = 0xdeadbee;
1938     action = 0xdeadbee;
1939     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1940     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1941     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1942     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1943
1944     state = 0xdeadbee;
1945     action = 0xdeadbee;
1946     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1947     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1948     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1949     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1950
1951     state = 0xdeadbee;
1952     action = 0xdeadbee;
1953     r = MsiGetComponentState(hpkg, "theta", &state, &action);
1954     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1955     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1956     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1957
1958     state = 0xdeadbee;
1959     action = 0xdeadbee;
1960     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1961     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1962     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1963     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1964
1965     state = 0xdeadbee;
1966     action = 0xdeadbee;
1967     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1968     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1969     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1970     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1971
1972     state = 0xdeadbee;
1973     action = 0xdeadbee;
1974     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1975     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1976     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1977     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1978
1979     state = 0xdeadbee;
1980     action = 0xdeadbee;
1981     r = MsiGetComponentState(hpkg, "iota", &state, &action);
1982     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1983     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1984     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1985
1986     state = 0xdeadbee;
1987     action = 0xdeadbee;
1988     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1989     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1990     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1991     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1992
1993     r = MsiDoAction( hpkg, "CostFinalize");
1994     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
1995
1996     state = 0xdeadbee;
1997     action = 0xdeadbee;
1998     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1999     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2000     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2001     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2002
2003     state = 0xdeadbee;
2004     action = 0xdeadbee;
2005     r = MsiGetFeatureState(hpkg, "two", &state, &action);
2006     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2007     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2008     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2009
2010     state = 0xdeadbee;
2011     action = 0xdeadbee;
2012     r = MsiGetFeatureState(hpkg, "three", &state, &action);
2013     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2014     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2015     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2016
2017     state = 0xdeadbee;
2018     action = 0xdeadbee;
2019     r = MsiGetFeatureState(hpkg, "four", &state, &action);
2020     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2021     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2022     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2023
2024     state = 0xdeadbee;
2025     action = 0xdeadbee;
2026     r = MsiGetFeatureState(hpkg, "five", &state, &action);
2027     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2028     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2029     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2030
2031     state = 0xdeadbee;
2032     action = 0xdeadbee;
2033     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
2034     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2035     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2036     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2037
2038     state = 0xdeadbee;
2039     action = 0xdeadbee;
2040     r = MsiGetComponentState(hpkg, "beta", &state, &action);
2041     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2042     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2043     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2044
2045     state = 0xdeadbee;
2046     action = 0xdeadbee;
2047     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
2048     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2049     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2050     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2051
2052     state = 0xdeadbee;
2053     action = 0xdeadbee;
2054     r = MsiGetComponentState(hpkg, "theta", &state, &action);
2055     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2056     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2057     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2058
2059     state = 0xdeadbee;
2060     action = 0xdeadbee;
2061     r = MsiGetComponentState(hpkg, "delta", &state, &action);
2062     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2063     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2064     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2065
2066     state = 0xdeadbee;
2067     action = 0xdeadbee;
2068     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
2069     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2070     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2071     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2072
2073     state = 0xdeadbee;
2074     action = 0xdeadbee;
2075     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
2076     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2077     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2078     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2079
2080     state = 0xdeadbee;
2081     action = 0xdeadbee;
2082     r = MsiGetComponentState(hpkg, "iota", &state, &action);
2083     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2084     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2085     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2086
2087     state = 0xdeadbee;
2088     action = 0xdeadbee;
2089     r = MsiGetComponentState(hpkg, "eta", &state, &action);
2090     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2091     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2092     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2093     
2094     MsiCloseHandle( hpkg );
2095 }
2096
2097 static void test_getproperty(void)
2098 {
2099     MSIHANDLE hPackage = 0;
2100     char prop[100];
2101     static CHAR empty[] = "";
2102     DWORD size;
2103     UINT r;
2104
2105     hPackage = package_from_db(create_package_db());
2106     ok( hPackage != 0, " Failed to create package\n");
2107
2108     /* set the property */
2109     r = MsiSetProperty(hPackage, "Name", "Value");
2110     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2111
2112     /* retrieve the size, NULL pointer */
2113     size = 0;
2114     r = MsiGetProperty(hPackage, "Name", NULL, &size);
2115     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2116     ok( size == 5, "Expected 5, got %ld\n", size);
2117
2118     /* retrieve the size, empty string */
2119     size = 0;
2120     r = MsiGetProperty(hPackage, "Name", empty, &size);
2121     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2122     ok( size == 5, "Expected 5, got %ld\n", size);
2123
2124     /* don't change size */
2125     r = MsiGetProperty(hPackage, "Name", prop, &size);
2126     ok( r == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", r);
2127     ok( size == 5, "Expected 5, got %ld\n", size);
2128     ok( !lstrcmp(prop, "Valu"), "Expected Valu, got %s\n", prop);
2129
2130     /* increase the size by 1 */
2131     size++;
2132     r = MsiGetProperty(hPackage, "Name", prop, &size);
2133     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
2134     ok( size == 5, "Expected 5, got %ld\n", size);
2135     ok( !lstrcmp(prop, "Value"), "Expected Value, got %s\n", prop);
2136
2137     r = MsiCloseHandle( hPackage);
2138     ok( r == ERROR_SUCCESS , "Failed to close package\n" );
2139     DeleteFile(msifile);
2140 }
2141
2142 static void test_removefiles(void)
2143 {
2144     MSIHANDLE hpkg;
2145     UINT r;
2146     MSIHANDLE hdb;
2147     char CURR_DIR[MAX_PATH];
2148
2149     GetCurrentDirectoryA(MAX_PATH, CURR_DIR);
2150
2151     hdb = create_package_db();
2152     ok ( hdb, "failed to create package database\n" );
2153
2154     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2155     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
2156
2157     r = create_feature_table( hdb );
2158     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
2159
2160     r = create_component_table( hdb );
2161     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
2162
2163     r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
2164     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2165
2166     r = add_component_entry( hdb, "'hydrogen', '', 'TARGETDIR', 0, '', 'hydrogen_file'" );
2167     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2168
2169     r = add_component_entry( hdb, "'helium', '', 'TARGETDIR', 0, '', 'helium_file'" );
2170     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2171
2172     r = add_component_entry( hdb, "'lithium', '', 'TARGETDIR', 0, '', 'lithium_file'" );
2173     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2174
2175     r = add_component_entry( hdb, "'beryllium', '', 'TARGETDIR', 0, '', 'beryllium_file'" );
2176     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2177
2178     r = add_component_entry( hdb, "'boron', '', 'TARGETDIR', 0, '', 'boron_file'" );
2179     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2180
2181     r = add_component_entry( hdb, "'carbon', '', 'TARGETDIR', 0, '', 'carbon_file'" );
2182     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2183
2184     r = create_feature_components_table( hdb );
2185     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
2186
2187     r = add_feature_components_entry( hdb, "'one', 'hydrogen'" );
2188     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2189
2190     r = add_feature_components_entry( hdb, "'one', 'helium'" );
2191     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2192
2193     r = add_feature_components_entry( hdb, "'one', 'lithium'" );
2194     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2195
2196     r = add_feature_components_entry( hdb, "'one', 'beryllium'" );
2197     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2198
2199     r = add_feature_components_entry( hdb, "'one', 'boron'" );
2200     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2201
2202     r = add_feature_components_entry( hdb, "'one', 'carbon'" );
2203     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2204
2205     r = create_file_table( hdb );
2206     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
2207
2208     r = add_file_entry( hdb, "'hydrogen_file', 'hydrogen', 'hydrogen.txt', 0, '', '1033', 8192, 1" );
2209     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2210
2211     r = add_file_entry( hdb, "'helium_file', 'helium', 'helium.txt', 0, '', '1033', 8192, 1" );
2212     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2213
2214     r = add_file_entry( hdb, "'lithium_file', 'lithium', 'lithium.txt', 0, '', '1033', 8192, 1" );
2215     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2216
2217     r = add_file_entry( hdb, "'beryllium_file', 'beryllium', 'beryllium.txt', 0, '', '1033', 16384, 1" );
2218     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2219
2220     r = add_file_entry( hdb, "'boron_file', 'boron', 'boron.txt', 0, '', '1033', 16384, 1" );
2221     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2222
2223     r = add_file_entry( hdb, "'carbon_file', 'carbon', 'carbon.txt', 0, '', '1033', 16384, 1" );
2224     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2225
2226     r = create_remove_file_table( hdb );
2227     ok( r == ERROR_SUCCESS, "cannot create Remove File table: %d\n", r);
2228
2229     hpkg = package_from_db( hdb );
2230     ok( hpkg, "failed to create package\n");
2231
2232     create_test_file( "hydrogen.txt" );
2233     create_test_file( "helium.txt" );
2234     create_test_file( "lithium.txt" );
2235     create_test_file( "beryllium.txt" );
2236     create_test_file( "boron.txt" );
2237     create_test_file( "carbon.txt" );
2238
2239     r = MsiSetProperty( hpkg, "TARGETDIR", CURR_DIR );
2240     ok( r == ERROR_SUCCESS, "set property failed\n");
2241
2242     r = MsiDoAction( hpkg, "CostInitialize");
2243     ok( r == ERROR_SUCCESS, "cost init failed\n");
2244
2245     r = MsiDoAction( hpkg, "FileCost");
2246     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
2247
2248     r = MsiDoAction( hpkg, "CostFinalize");
2249     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
2250
2251     r = MsiDoAction( hpkg, "InstallValidate");
2252     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
2253
2254     r = MsiSetComponentState( hpkg, "hydrogen", INSTALLSTATE_ABSENT );
2255     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2256
2257     r = MsiSetComponentState( hpkg, "helium", INSTALLSTATE_LOCAL );
2258     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2259
2260     r = MsiSetComponentState( hpkg, "lithium", INSTALLSTATE_SOURCE );
2261     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2262
2263     r = MsiSetComponentState( hpkg, "beryllium", INSTALLSTATE_ABSENT );
2264     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2265
2266     r = MsiSetComponentState( hpkg, "boron", INSTALLSTATE_LOCAL );
2267     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2268
2269     r = MsiSetComponentState( hpkg, "carbon", INSTALLSTATE_SOURCE );
2270     ok( r == ERROR_SUCCESS, "failed to set component state: %d\n", r);
2271
2272     r = MsiDoAction( hpkg, "RemoveFiles");
2273     ok( r == ERROR_SUCCESS, "remove files failed\n");
2274
2275     ok(DeleteFileA("hydrogen.txt"), "Expected hydrogen.txt to exist\n");
2276     ok(DeleteFileA("lithium.txt"), "Expected lithium.txt to exist\n");    
2277     ok(DeleteFileA("beryllium.txt"), "Expected beryllium.txt to exist\n");
2278     ok(DeleteFileA("carbon.txt"), "Expected carbon.txt to exist\n");
2279     ok(DeleteFileA("helium.txt"), "Expected helium.txt to exist\n");
2280     ok(DeleteFileA("boron.txt"), "Expected boron.txt to exist\n");
2281
2282     MsiCloseHandle( hpkg );
2283     DeleteFileA(msifile);
2284 }
2285
2286 static void test_appsearch(void)
2287 {
2288     MSIHANDLE hpkg;
2289     UINT r;
2290     MSIHANDLE hdb;
2291     CHAR prop[MAX_PATH];
2292     DWORD size = MAX_PATH;
2293
2294     hdb = create_package_db();
2295     ok ( hdb, "failed to create package database\n" );
2296
2297     r = create_appsearch_table( hdb );
2298     ok( r == ERROR_SUCCESS, "cannot create AppSearch table: %d\n", r );
2299
2300     r = add_appsearch_entry( hdb, "'WEBBROWSERPROG', 'NewSignature1'" );
2301     ok( r == ERROR_SUCCESS, "cannot add entry: %d\n", r );
2302
2303     r = create_reglocator_table( hdb );
2304     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
2305
2306     r = add_reglocator_entry( hdb, "'NewSignature1', 0, 'htmlfile\\shell\\open\\command', '', 1" );
2307     ok( r == ERROR_SUCCESS, "cannot create RegLocator table: %d\n", r );
2308
2309     r = create_signature_table( hdb );
2310     ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
2311
2312     r = add_signature_entry( hdb, "'NewSignature1', 'FileName', '', '', '', '', '', '', ''" );
2313     ok( r == ERROR_SUCCESS, "cannot create Signature table: %d\n", r );
2314
2315     hpkg = package_from_db( hdb );
2316     ok( hpkg, "failed to create package\n");
2317
2318     r = MsiDoAction( hpkg, "AppSearch" );
2319     ok( r == ERROR_SUCCESS, "AppSearch failed: %d\n", r);
2320
2321     r = MsiGetPropertyA( hpkg, "WEBBROWSERPROG", prop, &size );
2322     ok( r == ERROR_SUCCESS, "get property failed: %d\n", r);
2323     todo_wine
2324     {
2325         ok( lstrlenA(prop) != 0, "Expected non-zero length\n");
2326     }
2327
2328     MsiCloseHandle( hpkg );
2329     DeleteFileA(msifile);
2330 }
2331
2332 static void test_featureparents(void)
2333 {
2334     MSIHANDLE hpkg;
2335     UINT r;
2336     MSIHANDLE hdb;
2337     INSTALLSTATE state, action;
2338
2339     hdb = create_package_db();
2340     ok ( hdb, "failed to create package database\n" );
2341
2342     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
2343     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
2344
2345     r = create_feature_table( hdb );
2346     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
2347
2348     r = create_component_table( hdb );
2349     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
2350
2351     r = create_feature_components_table( hdb );
2352     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
2353
2354     r = create_file_table( hdb );
2355     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
2356
2357     /* msidbFeatureAttributesFavorLocal */
2358     r = add_feature_entry( hdb, "'zodiac', '', '', '', 2, 1, '', 0" );
2359     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2360
2361     /* msidbFeatureAttributesFavorSource */
2362     r = add_feature_entry( hdb, "'perseus', '', '', '', 2, 1, '', 1" );
2363     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2364
2365     /* msidbFeatureAttributesFavorLocal */
2366     r = add_feature_entry( hdb, "'orion', '', '', '', 2, 1, '', 0" );
2367     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2368
2369     /* disabled because of install level */
2370     r = add_feature_entry( hdb, "'waters', '', '', '', 15, 101, '', 9" );
2371     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2372
2373     /* child feature of disabled feature */
2374     r = add_feature_entry( hdb, "'bayer', 'waters', '', '', 14, 1, '', 9" );
2375     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
2376
2377     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2378     r = add_component_entry( hdb, "'leo', '', 'TARGETDIR', 0, '', 'leo_file'" );
2379     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2380
2381     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2382     r = add_component_entry( hdb, "'virgo', '', 'TARGETDIR', 1, '', 'virgo_file'" );
2383     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2384
2385     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2386     r = add_component_entry( hdb, "'libra', '', 'TARGETDIR', 2, '', 'libra_file'" );
2387     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2388
2389     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
2390     r = add_component_entry( hdb, "'cassiopeia', '', 'TARGETDIR', 0, '', 'cassiopeia_file'" );
2391     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2392
2393     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
2394     r = add_component_entry( hdb, "'cepheus', '', 'TARGETDIR', 1, '', 'cepheus_file'" );
2395     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2396
2397     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
2398     r = add_component_entry( hdb, "'andromeda', '', 'TARGETDIR', 2, '', 'andromeda_file'" );
2399     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2400
2401     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
2402     r = add_component_entry( hdb, "'canis', '', 'TARGETDIR', 0, '', 'canis_file'" );
2403     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2404
2405     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
2406     r = add_component_entry( hdb, "'monoceros', '', 'TARGETDIR', 1, '', 'monoceros_file'" );
2407     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
2408
2409     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
2410     r = add_component_entry( hdb, "'lepus', '', 'TARGETDIR', 2, '', 'lepus_file'" );
2411
2412     r = add_feature_components_entry( hdb, "'zodiac', 'leo'" );
2413     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2414
2415     r = add_feature_components_entry( hdb, "'zodiac', 'virgo'" );
2416     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2417
2418     r = add_feature_components_entry( hdb, "'zodiac', 'libra'" );
2419     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2420
2421     r = add_feature_components_entry( hdb, "'perseus', 'cassiopeia'" );
2422     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2423
2424     r = add_feature_components_entry( hdb, "'perseus', 'cepheus'" );
2425     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2426
2427     r = add_feature_components_entry( hdb, "'perseus', 'andromeda'" );
2428     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2429
2430     r = add_feature_components_entry( hdb, "'orion', 'leo'" );
2431     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2432
2433     r = add_feature_components_entry( hdb, "'orion', 'virgo'" );
2434     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2435
2436     r = add_feature_components_entry( hdb, "'orion', 'libra'" );
2437     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2438
2439     r = add_feature_components_entry( hdb, "'orion', 'cassiopeia'" );
2440     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2441
2442     r = add_feature_components_entry( hdb, "'orion', 'cepheus'" );
2443     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2444
2445     r = add_feature_components_entry( hdb, "'orion', 'andromeda'" );
2446     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2447
2448     r = add_feature_components_entry( hdb, "'orion', 'canis'" );
2449     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2450
2451     r = add_feature_components_entry( hdb, "'orion', 'monoceros'" );
2452     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2453
2454     r = add_feature_components_entry( hdb, "'orion', 'lepus'" );
2455     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
2456
2457     r = add_file_entry( hdb, "'leo_file', 'leo', 'leo.txt', 100, '', '1033', 8192, 1" );
2458     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2459
2460     r = add_file_entry( hdb, "'virgo_file', 'virgo', 'virgo.txt', 0, '', '1033', 8192, 1" );
2461     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2462
2463     r = add_file_entry( hdb, "'libra_file', 'libra', 'libra.txt', 0, '', '1033', 8192, 1" );
2464     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2465
2466     r = add_file_entry( hdb, "'cassiopeia_file', 'cassiopeia', 'cassiopeia.txt', 0, '', '1033', 8192, 1" );
2467     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2468
2469     r = add_file_entry( hdb, "'cepheus_file', 'cepheus', 'cepheus.txt', 0, '', '1033', 8192, 1" );
2470     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2471
2472     r = add_file_entry( hdb, "'andromeda_file', 'andromeda', 'andromeda.txt', 0, '', '1033', 8192, 1" );
2473     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2474
2475     r = add_file_entry( hdb, "'canis_file', 'canis', 'canis.txt', 0, '', '1033', 8192, 1" );
2476     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2477
2478     r = add_file_entry( hdb, "'monoceros_file', 'monoceros', 'monoceros.txt', 0, '', '1033', 8192, 1" );
2479     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2480
2481     r = add_file_entry( hdb, "'lepus_file', 'lepus', 'lepus.txt', 0, '', '1033', 8192, 1" );
2482     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
2483
2484     hpkg = package_from_db( hdb );
2485     ok( hpkg, "failed to create package\n");
2486
2487     r = MsiDoAction( hpkg, "CostInitialize");
2488     ok( r == ERROR_SUCCESS, "cost init failed\n");
2489
2490     r = MsiDoAction( hpkg, "FileCost");
2491     ok( r == ERROR_SUCCESS, "file cost failed\n");
2492
2493     r = MsiDoAction( hpkg, "CostFinalize");
2494     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
2495
2496     state = 0xdeadbee;
2497     action = 0xdeadbee;
2498     r = MsiGetFeatureState(hpkg, "zodiac", &state, &action);
2499     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2500     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2501     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2502
2503     state = 0xdeadbee;
2504     action = 0xdeadbee;
2505     r = MsiGetFeatureState(hpkg, "perseus", &state, &action);
2506     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2507     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2508     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2509
2510     state = 0xdeadbee;
2511     action = 0xdeadbee;
2512     r = MsiGetFeatureState(hpkg, "orion", &state, &action);
2513     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2514     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2515     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2516
2517     state = 0xdeadbee;
2518     action = 0xdeadbee;
2519     r = MsiGetFeatureState(hpkg, "waters", &state, &action);
2520     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2521     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2522     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2523
2524     state = 0xdeadbee;
2525     action = 0xdeadbee;
2526     r = MsiGetFeatureState(hpkg, "bayer", &state, &action);
2527     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2528     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2529     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2530
2531     state = 0xdeadbee;
2532     action = 0xdeadbee;
2533     r = MsiGetComponentState(hpkg, "leo", &state, &action);
2534     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2535     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2536     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2537
2538     state = 0xdeadbee;
2539     action = 0xdeadbee;
2540     r = MsiGetComponentState(hpkg, "virgo", &state, &action);
2541     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2542     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2543     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2544
2545     state = 0xdeadbee;
2546     action = 0xdeadbee;
2547     r = MsiGetComponentState(hpkg, "libra", &state, &action);
2548     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2549     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2550     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2551
2552     state = 0xdeadbee;
2553     action = 0xdeadbee;
2554     r = MsiGetComponentState(hpkg, "cassiopeia", &state, &action);
2555     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2556     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2557     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2558
2559     state = 0xdeadbee;
2560     action = 0xdeadbee;
2561     r = MsiGetComponentState(hpkg, "cepheus", &state, &action);
2562     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2563     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2564     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2565
2566     state = 0xdeadbee;
2567     action = 0xdeadbee;
2568     r = MsiGetComponentState(hpkg, "andromeda", &state, &action);
2569     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2570     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2571     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2572
2573     state = 0xdeadbee;
2574     action = 0xdeadbee;
2575     r = MsiGetComponentState(hpkg, "canis", &state, &action);
2576     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2577     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2578     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2579
2580     state = 0xdeadbee;
2581     action = 0xdeadbee;
2582     r = MsiGetComponentState(hpkg, "monoceros", &state, &action);
2583     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2584     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2585     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2586
2587     state = 0xdeadbee;
2588     action = 0xdeadbee;
2589     r = MsiGetComponentState(hpkg, "lepus", &state, &action);
2590     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2591     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2592     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2593
2594     r = MsiSetFeatureState(hpkg, "orion", INSTALLSTATE_ABSENT);
2595     ok( r == ERROR_SUCCESS, "failed to set feature state: %d\n", r);
2596
2597     state = 0xdeadbee;
2598     action = 0xdeadbee;
2599     r = MsiGetFeatureState(hpkg, "zodiac", &state, &action);
2600     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2601     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2602     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2603
2604     state = 0xdeadbee;
2605     action = 0xdeadbee;
2606     r = MsiGetFeatureState(hpkg, "perseus", &state, &action);
2607     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2608     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2609     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2610
2611     state = 0xdeadbee;
2612     action = 0xdeadbee;
2613     r = MsiGetFeatureState(hpkg, "orion", &state, &action);
2614     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2615     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
2616     ok( action == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", action);
2617
2618     state = 0xdeadbee;
2619     action = 0xdeadbee;
2620     r = MsiGetComponentState(hpkg, "leo", &state, &action);
2621     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2622     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2623     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2624
2625     state = 0xdeadbee;
2626     action = 0xdeadbee;
2627     r = MsiGetComponentState(hpkg, "virgo", &state, &action);
2628     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2629     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2630     todo_wine
2631     {
2632         ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2633     }
2634
2635     state = 0xdeadbee;
2636     action = 0xdeadbee;
2637     r = MsiGetComponentState(hpkg, "libra", &state, &action);
2638     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2639     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2640     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2641
2642     state = 0xdeadbee;
2643     action = 0xdeadbee;
2644     r = MsiGetComponentState(hpkg, "cassiopeia", &state, &action);
2645     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2646     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2647     todo_wine
2648     {
2649         ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
2650     }
2651
2652     state = 0xdeadbee;
2653     action = 0xdeadbee;
2654     r = MsiGetComponentState(hpkg, "cepheus", &state, &action);
2655     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2656     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2657     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2658
2659     state = 0xdeadbee;
2660     action = 0xdeadbee;
2661     r = MsiGetComponentState(hpkg, "andromeda", &state, &action);
2662     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2663     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2664     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
2665
2666     state = 0xdeadbee;
2667     action = 0xdeadbee;
2668     r = MsiGetComponentState(hpkg, "canis", &state, &action);
2669     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2670     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2671     todo_wine
2672     {
2673         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2674     }
2675
2676     state = 0xdeadbee;
2677     action = 0xdeadbee;
2678     r = MsiGetComponentState(hpkg, "monoceros", &state, &action);
2679     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2680     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2681     todo_wine
2682     {
2683         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2684     }
2685
2686     state = 0xdeadbee;
2687     action = 0xdeadbee;
2688     r = MsiGetComponentState(hpkg, "lepus", &state, &action);
2689     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
2690     ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
2691     todo_wine
2692     {
2693         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
2694     }
2695     
2696     MsiCloseHandle(hpkg);
2697 }
2698
2699 START_TEST(package)
2700 {
2701     test_createpackage();
2702     test_getsourcepath_bad();
2703     test_getsourcepath();
2704     test_doaction();
2705     test_gettargetpath_bad();
2706     test_settargetpath();
2707     test_props();
2708     test_condition();
2709     test_msipackage();
2710     test_formatrecord2();
2711     test_states();
2712     test_getproperty();
2713     test_removefiles();
2714     test_appsearch();
2715     test_featureparents();
2716 }