msi: Write-strings warnings fix.
[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 add_component_entry( MSIHANDLE hdb, const char *values )
102 {
103     char insert[] = "INSERT INTO `Component`  "
104             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
105             "VALUES( %s )";
106     char *query;
107     UINT sz, r;
108
109     sz = strlen(values) + sizeof insert;
110     query = HeapAlloc(GetProcessHeap(),0,sz);
111     sprintf(query,insert,values);
112     r = run_query( hdb, query );
113     HeapFree(GetProcessHeap(), 0, query);
114     return r;
115 }
116
117 static UINT add_feature_entry( MSIHANDLE hdb, const char *values )
118 {
119     char insert[] = "INSERT INTO `Feature` (`Feature`, `Feature_Parent`, "
120                     "`Title`, `Description`, `Display`, `Level`, `Directory_`, `Attributes`) VALUES( %s )";
121     char *query;
122     UINT sz, r;
123
124     sz = strlen(values) + sizeof insert;
125     query = HeapAlloc(GetProcessHeap(),0,sz);
126     sprintf(query,insert,values);
127     r = run_query( hdb, query );
128     HeapFree(GetProcessHeap(), 0, query);
129     return r;
130 }
131
132 static UINT add_feature_components_entry( MSIHANDLE hdb, const char *values )
133 {
134     char insert[] = "INSERT INTO `FeatureComponents` "
135             "(`Feature_`, `Component_`) "
136             "VALUES( %s )";
137     char *query;
138     UINT sz, r;
139
140     sz = strlen(values) + sizeof insert;
141     query = HeapAlloc(GetProcessHeap(),0,sz);
142     sprintf(query,insert,values);
143     r = run_query( hdb, query );
144     HeapFree(GetProcessHeap(), 0, query);
145     return r;
146 }
147
148 static UINT add_file_entry( MSIHANDLE hdb, const char *values )
149 {
150     char insert[] = "INSERT INTO `File` "
151             "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
152             "VALUES( %s )";
153     char *query;
154     UINT sz, r;
155
156     sz = strlen(values) + sizeof insert;
157     query = HeapAlloc(GetProcessHeap(),0,sz);
158     sprintf(query,insert,values);
159     r = run_query( hdb, query );
160     HeapFree(GetProcessHeap(), 0, query);
161     return r;
162 }
163
164 static UINT set_summary_info(MSIHANDLE hdb)
165 {
166     UINT res;
167     MSIHANDLE suminfo;
168
169     /* build summmary info */
170     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
171     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
172
173     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
174                         "Installation Database");
175     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
176
177     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
178                         "Installation Database");
179     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
180
181     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
182                         "Wine Hackers");
183     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
184
185     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
186                     ";1033");
187     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
188
189     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
190                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
191     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
192
193     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
194     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
195
196     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
197     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
198
199     res = MsiSummaryInfoPersist(suminfo);
200     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
201
202     res = MsiCloseHandle( suminfo);
203     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
204
205     return res;
206 }
207
208
209 MSIHANDLE create_package_db(void)
210 {
211     MSIHANDLE hdb = 0;
212     UINT res;
213
214     DeleteFile(msifile);
215
216     /* create an empty database */
217     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
218     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
219     if( res != ERROR_SUCCESS )
220         return hdb;
221
222     res = MsiDatabaseCommit( hdb );
223     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
224
225     res = set_summary_info(hdb);
226
227     res = run_query( hdb,
228             "CREATE TABLE `Directory` ( "
229             "`Directory` CHAR(255) NOT NULL, "
230             "`Directory_Parent` CHAR(255), "
231             "`DefaultDir` CHAR(255) NOT NULL "
232             "PRIMARY KEY `Directory`)" );
233     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
234
235     return hdb;
236 }
237
238 MSIHANDLE package_from_db(MSIHANDLE hdb)
239 {
240     UINT res;
241     CHAR szPackage[10];
242     MSIHANDLE hPackage;
243
244     sprintf(szPackage,"#%li",hdb);
245     res = MsiOpenPackage(szPackage,&hPackage);
246     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
247
248     res = MsiCloseHandle(hdb);
249     ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
250
251     return hPackage;
252 }
253
254 static void test_createpackage(void)
255 {
256     MSIHANDLE hPackage = 0;
257     UINT res;
258
259     hPackage = package_from_db(create_package_db());
260     ok( hPackage != 0, " Failed to create package\n");
261
262     res = MsiCloseHandle( hPackage);
263     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
264     DeleteFile(msifile);
265 }
266
267 static void test_getsourcepath_bad( void )
268 {
269     static const char str[] = { 0 };
270     char buffer[0x80];
271     DWORD sz;
272     UINT r;
273
274     r = MsiGetSourcePath( -1, NULL, NULL, NULL );
275     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
276
277     sz = 0;
278     r = MsiGetSourcePath( -1, NULL, buffer, &sz );
279     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
280
281     sz = 0;
282     r = MsiGetSourcePath( -1, str, NULL, &sz );
283     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
284
285     sz = 0;
286     r = MsiGetSourcePath( -1, str, NULL, NULL );
287     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
288
289     sz = 0;
290     r = MsiGetSourcePath( -1, str, buffer, &sz );
291     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
292 }
293
294 static UINT add_directory_entry( MSIHANDLE hdb, const char *values )
295 {
296     char insert[] = "INSERT INTO `Directory` (`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )";
297     char *query;
298     UINT sz, r;
299
300     sz = strlen(values) + sizeof insert;
301     query = HeapAlloc(GetProcessHeap(),0,sz);
302     sprintf(query,insert,values);
303     r = run_query( hdb, query );
304     HeapFree(GetProcessHeap(), 0, query);
305     return r;
306 }
307
308 static void test_getsourcepath( void )
309 {
310     static const char str[] = { 0 };
311     char buffer[0x80];
312     DWORD sz;
313     UINT r;
314     MSIHANDLE hpkg, hdb;
315
316     hpkg = package_from_db(create_package_db());
317     ok( hpkg, "failed to create package\n");
318
319     sz = 0;
320     buffer[0] = 'x';
321     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
322     ok( r == ERROR_DIRECTORY, "return value wrong\n");
323     ok( buffer[0] == 'x', "buffer modified\n");
324
325     sz = 1;
326     buffer[0] = 'x';
327     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
328     ok( r == ERROR_DIRECTORY, "return value wrong\n");
329     ok( buffer[0] == 'x', "buffer modified\n");
330
331     MsiCloseHandle( hpkg );
332
333
334     /* another test but try create a directory this time */
335     hdb = create_package_db();
336     ok( hdb, "failed to create database\n");
337
338     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
339     ok( r == S_OK, "failed\n");
340
341     hpkg = package_from_db(hdb);
342     ok( hpkg, "failed to create package\n");
343
344     sz = sizeof buffer -1;
345     strcpy(buffer,"x bad");
346     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
347     ok( r == ERROR_DIRECTORY, "return value wrong\n");
348
349     r = MsiDoAction( hpkg, "CostInitialize");
350     ok( r == ERROR_SUCCESS, "cost init failed\n");
351     r = MsiDoAction( hpkg, "CostFinalize");
352     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
353
354     todo_wine {
355     sz = sizeof buffer -1;
356     buffer[0] = 'x';
357     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
358     ok( r == ERROR_SUCCESS, "return value wrong\n");
359     ok( sz == strlen(buffer), "returned length wrong\n");
360
361     sz = 0;
362     strcpy(buffer,"x bad");
363     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
364     ok( r == ERROR_MORE_DATA, "return value wrong\n");
365     }
366     ok( buffer[0] == 'x', "buffer modified\n");
367
368     todo_wine {
369     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, NULL );
370     ok( r == ERROR_SUCCESS, "return value wrong\n");
371     }
372
373     r = MsiGetSourcePath( hpkg, "TARGETDIR ", NULL, NULL );
374     ok( r == ERROR_DIRECTORY, "return value wrong\n");
375
376     r = MsiGetSourcePath( hpkg, "targetdir", NULL, NULL );
377     ok( r == ERROR_DIRECTORY, "return value wrong\n");
378
379     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, NULL );
380     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
381
382     todo_wine {
383     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, &sz );
384     ok( r == ERROR_SUCCESS, "return value wrong\n");
385     }
386
387     MsiCloseHandle( hpkg );
388     DeleteFile(msifile);
389 }
390
391 static void test_doaction( void )
392 {
393     MSIHANDLE hpkg;
394     UINT r;
395
396     r = MsiDoAction( -1, NULL );
397     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
398
399     hpkg = package_from_db(create_package_db());
400     ok( hpkg, "failed to create package\n");
401
402     r = MsiDoAction(hpkg, NULL);
403     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
404
405     r = MsiDoAction(0, "boo");
406     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
407
408     r = MsiDoAction(hpkg, "boo");
409     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
410
411     MsiCloseHandle( hpkg );
412     DeleteFile(msifile);
413 }
414
415 static void test_gettargetpath_bad(void)
416 {
417     char buffer[0x80];
418     MSIHANDLE hpkg;
419     DWORD sz;
420     UINT r;
421
422     hpkg = package_from_db(create_package_db());
423     ok( hpkg, "failed to create package\n");
424
425     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
426     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
427
428     r = MsiGetTargetPath( 0, NULL, NULL, &sz );
429     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
430
431     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
432     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
433
434     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
435     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
436
437     r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
438     ok( r == ERROR_DIRECTORY, "wrong return val\n");
439
440     r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
441     ok( r == ERROR_DIRECTORY, "wrong return val\n");
442
443     MsiCloseHandle( hpkg );
444     DeleteFile(msifile);
445 }
446
447 static void query_file_path(MSIHANDLE hpkg, LPCSTR file, LPSTR buff)
448 {
449     UINT r;
450     DWORD size;
451     MSIHANDLE rec;
452
453     rec = MsiCreateRecord( 1 );
454     ok(rec, "MsiCreate record failed\n");
455
456     r = MsiRecordSetString( rec, 0, file );
457     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
458
459     size = MAX_PATH;
460     r = MsiFormatRecord( hpkg, rec, buff, &size );
461     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", r );
462
463     MsiCloseHandle( rec );
464 }
465
466 static void test_settargetpath(void)
467 {
468     char tempdir[MAX_PATH+8], buffer[MAX_PATH];
469     DWORD sz;
470     MSIHANDLE hpkg;
471     UINT r;
472     MSIHANDLE hdb;
473
474     hdb = create_package_db();
475     ok ( hdb, "failed to create package database\n" );
476
477     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
478     ok( r == S_OK, "failed to add directory entry: %d\n" , r );
479
480     r = run_query( hdb, /* these tables required by Windows Installer for MsiSetTargetPath */
481             "CREATE TABLE `Component` ( "
482             "`Component` CHAR(72) NOT NULL, "
483             "`ComponentId` CHAR(38), "
484             "`Directory_` CHAR(72) NOT NULL, "
485             "`Attributes` SHORT NOT NULL, "
486             "`Condition` CHAR(255), "
487             "`KeyPath` CHAR(72) "
488             "PRIMARY KEY `Component`)" );
489     ok( r == S_OK, "cannot create Component table: %d\n", r );
490
491     r = run_query( hdb,
492             "INSERT INTO `Component`  "
493             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
494             "VALUES( 'WinWorkAround', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'FL_dummycomponent')" );
495     ok( r == S_OK, "cannot add dummy component: %d\n", r );
496
497     r = run_query( hdb,
498             "INSERT INTO `Component`  "
499             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
500             "VALUES( 'TestComp', '{A3FB59C8-C293-4F7E-B8C5-F0E1D8EEE4E5}', 'TestDir', 0, '', 'TestFile')" );
501     ok( r == S_OK, "cannot add test component: %d\n", r );
502
503     r = run_query( hdb,
504             "CREATE TABLE `Feature` ( "
505             "`Feature` CHAR(38) NOT NULL, "
506             "`Feature_Parent` CHAR(38), "
507             "`Title` CHAR(64), "
508             "`Description` CHAR(255), "
509             "`Display` SHORT NOT NULL, "
510             "`Level` SHORT NOT NULL, "
511             "`Directory_` CHAR(72), "
512             "`Attributes` SHORT NOT NULL "
513             "PRIMARY KEY `Feature`)" );
514     ok( r == S_OK, "cannot create Feature table: %d\n", r );
515
516     r = run_query( hdb,
517             "INSERT INTO `Feature` "
518             "(`Feature`, `Feature_Parent`, `Display`, `Level`, `Attributes`) "
519             "VALUES( 'TestFeature', '', 0, 1, 0 )" );
520     ok( r == ERROR_SUCCESS, "cannot add TestFeature to Feature table: %d\n", r );
521
522     r = run_query( hdb,
523             "CREATE TABLE `FeatureComponents` ( "
524             "`Feature_` CHAR(38) NOT NULL, "
525             "`Component_` CHAR(72) NOT NULL "
526             "PRIMARY KEY `Feature_` )" );
527     ok( r == S_OK, "cannot create FeatureComponents table: %d\n", r );
528
529     r = run_query( hdb,
530             "INSERT INTO `FeatureComponents` "
531             "(`Feature_`, `Component_`) "
532             "VALUES( 'TestFeature', 'TestComp' )" );
533     ok( r == S_OK, "cannot insert component into FeatureComponents table: %d\n", r );
534
535     add_directory_entry( hdb, "'TestParent', 'TARGETDIR', 'TestParent'" );
536     add_directory_entry( hdb, "'TestDir', 'TestParent', 'TestDir'" );
537
538     r = run_query( hdb,
539             "CREATE TABLE `File` ("
540             "`File` CHAR(72) NOT NULL, "
541             "`Component_` CHAR(72) NOT NULL, "
542             "`FileName` CHAR(255) NOT NULL, "
543             "`FileSize` LONG NOT NULL, "
544             "`Version` CHAR(72), "
545             "`Language` CHAR(20), "
546             "`Attributes` SHORT, "
547             "`Sequence` SHORT NOT NULL "
548             "PRIMARY KEY `File`)" );
549     ok( r == S_OK, "cannot create File table: %d\n", r );
550
551     r = run_query( hdb,
552             "INSERT INTO `File` "
553             "(`File`, `Component_`, `FileName`, `FileSize`, `Version`, `Language`, `Attributes`, `Sequence`) "
554             "VALUES( 'TestFile', 'TestComp', 'testfile.txt', 0, '', '1033', 8192, 1 )" );
555     ok( r == S_OK, "cannot add file to the File table: %d\n", r );
556
557     hpkg = package_from_db( hdb );
558     ok( hpkg, "failed to create package\n");
559
560     r = MsiDoAction( hpkg, "CostInitialize");
561     ok( r == ERROR_SUCCESS, "cost init failed\n");
562
563     r = MsiDoAction( hpkg, "FileCost");
564     ok( r == ERROR_SUCCESS, "file cost failed\n");
565
566     r = MsiDoAction( hpkg, "CostFinalize");
567     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
568
569     r = MsiSetTargetPath( 0, NULL, NULL );
570     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
571
572     r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
573     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
574
575     r = MsiSetTargetPath( hpkg, "boo", NULL );
576     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
577
578     r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
579     ok( r == ERROR_DIRECTORY, "wrong return val\n");
580
581     sz = sizeof tempdir - 1;
582     r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
583     if ( r == S_OK )
584     {
585         if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
586         {
587             sprintf( tempdir, "%s\\subdir", buffer );
588             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
589             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
590
591             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
592             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
593
594             DeleteFile( buffer );
595
596             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
597             ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
598
599             r = GetFileAttributes( buffer );
600             ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
601
602             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
603             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
604         } else {
605             trace("GetTempFileName failed, cannot do some tests\n");
606         }
607     } else {
608         trace( "MsiGetTargetPath failed: %d\n", r );
609     }
610
611     r = MsiSetTargetPath( hpkg, "TestParent", "C:\\one\\two" );
612     ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
613
614     query_file_path( hpkg, "[#TestFile]", buffer );
615     ok( !lstrcmp(buffer, "C:\\one\\two\\TestDir\\testfile.txt"),
616         "Expected C:\\one\\two\\TestDir\\testfile.txt, got %s\n", buffer );
617     
618     MsiCloseHandle( hpkg );
619 }
620
621 static void test_condition(void)
622 {
623     MSICONDITION r;
624     MSIHANDLE hpkg;
625
626     hpkg = package_from_db(create_package_db());
627     ok( hpkg, "failed to create package\n");
628
629     r = MsiEvaluateCondition(0, NULL);
630     ok( r == MSICONDITION_ERROR, "wrong return val\n");
631
632     r = MsiEvaluateCondition(hpkg, NULL);
633     ok( r == MSICONDITION_NONE, "wrong return val\n");
634
635     r = MsiEvaluateCondition(hpkg, "");
636     ok( r == MSICONDITION_NONE, "wrong return val\n");
637
638     r = MsiEvaluateCondition(hpkg, "1");
639     ok( r == MSICONDITION_TRUE, "wrong return val\n");
640
641     r = MsiEvaluateCondition(hpkg, "0");
642     ok( r == MSICONDITION_FALSE, "wrong return val\n");
643
644     r = MsiEvaluateCondition(hpkg, "0 = 0");
645     ok( r == MSICONDITION_TRUE, "wrong return val\n");
646
647     r = MsiEvaluateCondition(hpkg, "0 <> 0");
648     ok( r == MSICONDITION_FALSE, "wrong return val\n");
649
650     r = MsiEvaluateCondition(hpkg, "0 = 1");
651     ok( r == MSICONDITION_FALSE, "wrong return val\n");
652
653     r = MsiEvaluateCondition(hpkg, "0 > 1");
654     ok( r == MSICONDITION_FALSE, "wrong return val\n");
655
656     r = MsiEvaluateCondition(hpkg, "0 ~> 1");
657     ok( r == MSICONDITION_FALSE, "wrong return val\n");
658
659     r = MsiEvaluateCondition(hpkg, "1 > 1");
660     ok( r == MSICONDITION_FALSE, "wrong return val\n");
661
662     r = MsiEvaluateCondition(hpkg, "1 ~> 1");
663     ok( r == MSICONDITION_FALSE, "wrong return val\n");
664
665     r = MsiEvaluateCondition(hpkg, "0 >= 1");
666     ok( r == MSICONDITION_FALSE, "wrong return val\n");
667
668     r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
669     ok( r == MSICONDITION_FALSE, "wrong return val\n");
670
671     r = MsiEvaluateCondition(hpkg, "1 >= 1");
672     ok( r == MSICONDITION_TRUE, "wrong return val\n");
673
674     r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
675     ok( r == MSICONDITION_TRUE, "wrong return val\n");
676
677     r = MsiEvaluateCondition(hpkg, "0 < 1");
678     ok( r == MSICONDITION_TRUE, "wrong return val\n");
679
680     r = MsiEvaluateCondition(hpkg, "0 ~< 1");
681     ok( r == MSICONDITION_TRUE, "wrong return val\n");
682
683     r = MsiEvaluateCondition(hpkg, "1 < 1");
684     ok( r == MSICONDITION_FALSE, "wrong return val\n");
685
686     r = MsiEvaluateCondition(hpkg, "1 ~< 1");
687     ok( r == MSICONDITION_FALSE, "wrong return val\n");
688
689     r = MsiEvaluateCondition(hpkg, "0 <= 1");
690     ok( r == MSICONDITION_TRUE, "wrong return val\n");
691
692     r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
693     ok( r == MSICONDITION_TRUE, "wrong return val\n");
694
695     r = MsiEvaluateCondition(hpkg, "1 <= 1");
696     ok( r == MSICONDITION_TRUE, "wrong return val\n");
697
698     r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
699     ok( r == MSICONDITION_TRUE, "wrong return val\n");
700
701     r = MsiEvaluateCondition(hpkg, "0 >=");
702     ok( r == MSICONDITION_ERROR, "wrong return val\n");
703
704     r = MsiEvaluateCondition(hpkg, " ");
705     ok( r == MSICONDITION_NONE, "wrong return val\n");
706
707     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
708     ok( r == MSICONDITION_TRUE, "wrong return val\n");
709
710     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
711     ok( r == MSICONDITION_TRUE, "wrong return val\n");
712
713     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
714     ok( r == MSICONDITION_FALSE, "wrong return val\n");
715
716     r = MsiEvaluateCondition(hpkg, "not 0");
717     ok( r == MSICONDITION_TRUE, "wrong return val\n");
718
719     r = MsiEvaluateCondition(hpkg, "not LicView");
720     ok( r == MSICONDITION_TRUE, "wrong return val\n");
721
722     r = MsiEvaluateCondition(hpkg, "not \"A\"");
723     ok( r == MSICONDITION_FALSE, "wrong return val\n");
724
725     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
726     ok( r == MSICONDITION_ERROR, "wrong return val\n");
727
728     r = MsiEvaluateCondition(hpkg, "\"0\"");
729     ok( r == MSICONDITION_TRUE, "wrong return val\n");
730
731     r = MsiEvaluateCondition(hpkg, "1 and 2");
732     ok( r == MSICONDITION_TRUE, "wrong return val\n");
733
734     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
735     ok( r == MSICONDITION_TRUE, "wrong return val\n");
736
737     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
738     ok( r == MSICONDITION_FALSE, "wrong return val\n");
739
740     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
741     ok( r == MSICONDITION_TRUE, "wrong return val\n");
742
743     r = MsiEvaluateCondition(hpkg, "(0)");
744     ok( r == MSICONDITION_FALSE, "wrong return val\n");
745
746     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
747     ok( r == MSICONDITION_ERROR, "wrong return val\n");
748
749     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
750     ok( r == MSICONDITION_TRUE, "wrong return val\n");
751
752     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
753     ok( r == MSICONDITION_TRUE, "wrong return val\n");
754
755     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
756     ok( r == MSICONDITION_FALSE, "wrong return val\n");
757
758     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
759     ok( r == MSICONDITION_FALSE, "wrong return val\n");
760
761     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
762     ok( r == MSICONDITION_TRUE, "wrong return val\n");
763
764     r = MsiEvaluateCondition(hpkg, "0 < > 0");
765     ok( r == MSICONDITION_ERROR, "wrong return val\n");
766
767     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
768     ok( r == MSICONDITION_ERROR, "wrong return val\n");
769
770     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
771     ok( r == MSICONDITION_FALSE, "wrong return val\n");
772
773     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
774     ok( r == MSICONDITION_ERROR, "wrong return val\n");
775
776     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
777     ok( r == MSICONDITION_TRUE, "wrong return val\n");
778
779     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
780     ok( r == MSICONDITION_FALSE, "wrong return val\n");
781
782     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
783     ok( r == MSICONDITION_FALSE, "wrong return val\n");
784
785     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
786     ok( r == MSICONDITION_TRUE, "wrong return val\n");
787
788     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
789     ok( r == MSICONDITION_FALSE, "wrong return val\n");
790
791     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
792     ok( r == MSICONDITION_FALSE, "wrong return val\n");
793
794     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
795     ok( r == MSICONDITION_FALSE, "wrong return val\n");
796
797     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
798     ok( r == MSICONDITION_FALSE, "wrong return val\n");
799
800     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
801     ok( r == MSICONDITION_FALSE, "wrong return val\n");
802
803     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
804     ok( r == MSICONDITION_FALSE, "wrong return val\n");
805
806     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
807     ok( r == MSICONDITION_TRUE, "wrong return val\n");
808
809     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
810     ok( r == MSICONDITION_FALSE, "wrong return val\n");
811
812     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
813     ok( r == MSICONDITION_TRUE, "wrong return val\n");
814
815     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
816     ok( r == MSICONDITION_TRUE, "wrong return val\n");
817
818     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
819     ok( r == MSICONDITION_FALSE, "wrong return val\n");
820
821     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
822     ok( r == MSICONDITION_TRUE, "wrong return val\n");
823
824     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
825     ok( r == MSICONDITION_ERROR, "wrong return val\n");
826
827     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
828     ok( r == MSICONDITION_TRUE, "wrong return val\n");
829
830     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
831     ok( r == MSICONDITION_TRUE, "wrong return val\n");
832
833     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
834     ok( r == MSICONDITION_TRUE, "wrong return val\n");
835
836     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
837     ok( r == MSICONDITION_FALSE, "wrong return val\n");
838
839     MsiSetProperty(hpkg, "mm", "5" );
840
841     r = MsiEvaluateCondition(hpkg, "mm = 5");
842     ok( r == MSICONDITION_TRUE, "wrong return val\n");
843
844     r = MsiEvaluateCondition(hpkg, "mm < 6");
845     ok( r == MSICONDITION_TRUE, "wrong return val\n");
846
847     r = MsiEvaluateCondition(hpkg, "mm <= 5");
848     ok( r == MSICONDITION_TRUE, "wrong return val\n");
849
850     r = MsiEvaluateCondition(hpkg, "mm > 4");
851     ok( r == MSICONDITION_TRUE, "wrong return val\n");
852
853     r = MsiEvaluateCondition(hpkg, "mm < 12");
854     ok( r == MSICONDITION_TRUE, "wrong return val\n");
855
856     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
857     ok( r == MSICONDITION_TRUE, "wrong return val\n");
858
859     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
860     ok( r == MSICONDITION_FALSE, "wrong return val\n");
861
862     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
863     ok( r == MSICONDITION_FALSE, "wrong return val\n");
864
865     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
866     ok( r == MSICONDITION_FALSE, "wrong return val\n");
867
868     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
869     ok( r == MSICONDITION_TRUE, "wrong return val\n");
870
871     r = MsiEvaluateCondition(hpkg, "3 >< 1");
872     ok( r == MSICONDITION_TRUE, "wrong return val\n");
873
874     r = MsiEvaluateCondition(hpkg, "3 >< 4");
875     ok( r == MSICONDITION_FALSE, "wrong return val\n");
876
877     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
878     ok( r == MSICONDITION_FALSE, "wrong return val\n");
879
880     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
881     ok( r == MSICONDITION_TRUE, "wrong return val\n");
882
883     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
884     ok( r == MSICONDITION_FALSE, "wrong return val\n");
885
886     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
887     ok( r == MSICONDITION_TRUE, "wrong return val\n");
888
889     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
890     ok( r == MSICONDITION_TRUE, "wrong return val\n");
891
892     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
893     ok( r == MSICONDITION_TRUE, "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 AND 1 ) = 2");
899     ok( r == MSICONDITION_ERROR, "wrong return val\n");
900
901     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
902     ok( r == MSICONDITION_FALSE, "wrong return val\n");
903
904     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
905     ok( r == MSICONDITION_FALSE, "wrong return val\n");
906
907     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
908     ok( r == MSICONDITION_FALSE, "wrong return val\n");
909
910     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
911     ok( r == MSICONDITION_FALSE, "wrong return val\n");
912
913     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
914     ok( r == MSICONDITION_FALSE, "wrong return val\n");
915
916     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
917     ok( r == MSICONDITION_TRUE, "wrong return val\n");
918
919     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
920     ok( r == MSICONDITION_FALSE, "wrong return val\n");
921
922     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
923     ok( r == MSICONDITION_FALSE, "wrong return val\n");
924
925     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
926     ok( r == MSICONDITION_FALSE, "wrong return val\n");
927
928     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
929     ok( r == MSICONDITION_FALSE, "wrong return val\n");
930
931     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
932     ok( r == MSICONDITION_TRUE, "wrong return val\n");
933
934     MsiSetProperty(hpkg, "bandalmael", "0" );
935     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
936     ok( r == MSICONDITION_TRUE, "wrong return val\n");
937
938     MsiSetProperty(hpkg, "bandalmael", "" );
939     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
940     ok( r == MSICONDITION_FALSE, "wrong return val\n");
941
942     MsiSetProperty(hpkg, "bandalmael", "asdf" );
943     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
944     ok( r == MSICONDITION_FALSE, "wrong return val\n");
945
946     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
947     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
948     ok( r == MSICONDITION_FALSE, "wrong return val\n");
949
950     MsiSetProperty(hpkg, "bandalmael", "0 " );
951     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
952     ok( r == MSICONDITION_FALSE, "wrong return val\n");
953
954     MsiSetProperty(hpkg, "bandalmael", "-0" );
955     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
956     ok( r == MSICONDITION_TRUE, "wrong return val\n");
957
958     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
959     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
960     ok( r == MSICONDITION_TRUE, "wrong return val\n");
961
962     MsiSetProperty(hpkg, "bandalmael", "--0" );
963     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
964     ok( r == MSICONDITION_FALSE, "wrong return val\n");
965
966     MsiSetProperty(hpkg, "bandalmael", "0x00" );
967     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
968     ok( r == MSICONDITION_FALSE, "wrong return val\n");
969
970     MsiSetProperty(hpkg, "bandalmael", "-" );
971     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
972     ok( r == MSICONDITION_FALSE, "wrong return val\n");
973
974     MsiSetProperty(hpkg, "bandalmael", "+0" );
975     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
976     ok( r == MSICONDITION_FALSE, "wrong return val\n");
977
978     MsiSetProperty(hpkg, "bandalmael", "0.0" );
979     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
980     ok( r == MSICONDITION_FALSE, "wrong return val\n");
981     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
982     ok( r == MSICONDITION_TRUE, "wrong return val\n");
983
984     MsiCloseHandle( hpkg );
985     DeleteFile(msifile);
986 }
987
988 static BOOL check_prop_empty( MSIHANDLE hpkg, const char * prop)
989 {
990     UINT r;
991     DWORD sz;
992     char buffer[2];
993
994     sz = sizeof buffer;
995     strcpy(buffer,"x");
996     r = MsiGetProperty( hpkg, prop, buffer, &sz );
997     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
998 }
999
1000 static void test_props(void)
1001 {
1002     MSIHANDLE hpkg;
1003     UINT r;
1004     DWORD sz;
1005     char buffer[0x100];
1006
1007     hpkg = package_from_db(create_package_db());
1008     ok( hpkg, "failed to create package\n");
1009
1010     /* test invalid values */
1011     r = MsiGetProperty( 0, NULL, NULL, NULL );
1012     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1013
1014     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
1015     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1016
1017     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
1018     ok( r == ERROR_SUCCESS, "wrong return val\n");
1019
1020     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
1021     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1022
1023     /* test retrieving an empty/nonexistent property */
1024     sz = sizeof buffer;
1025     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
1026     ok( r == ERROR_SUCCESS, "wrong return val\n");
1027     ok( sz == 0, "wrong size returned\n");
1028
1029     check_prop_empty( hpkg, "boo");
1030     sz = 0;
1031     strcpy(buffer,"x");
1032     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1033     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1034     ok( !strcmp(buffer,"x"), "buffer was changed\n");
1035     ok( sz == 0, "wrong size returned\n");
1036
1037     sz = 1;
1038     strcpy(buffer,"x");
1039     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1040     ok( r == ERROR_SUCCESS, "wrong return val\n");
1041     ok( buffer[0] == 0, "buffer was not changed\n");
1042     ok( sz == 0, "wrong size returned\n");
1043
1044     /* set the property to something */
1045     r = MsiSetProperty( 0, NULL, NULL );
1046     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
1047
1048     r = MsiSetProperty( hpkg, NULL, NULL );
1049     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
1050
1051     r = MsiSetProperty( hpkg, "", NULL );
1052     ok( r == ERROR_SUCCESS, "wrong return val\n");
1053
1054     /* try set and get some illegal property identifiers */
1055     r = MsiSetProperty( hpkg, "", "asdf" );
1056     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
1057
1058     r = MsiSetProperty( hpkg, "=", "asdf" );
1059     ok( r == ERROR_SUCCESS, "wrong return val\n");
1060
1061     r = MsiSetProperty( hpkg, " ", "asdf" );
1062     ok( r == ERROR_SUCCESS, "wrong return val\n");
1063
1064     r = MsiSetProperty( hpkg, "'", "asdf" );
1065     ok( r == ERROR_SUCCESS, "wrong return val\n");
1066
1067     sz = sizeof buffer;
1068     buffer[0]=0;
1069     r = MsiGetProperty( hpkg, "'", buffer, &sz );
1070     ok( r == ERROR_SUCCESS, "wrong return val\n");
1071     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
1072
1073     /* set empty values */
1074     r = MsiSetProperty( hpkg, "boo", NULL );
1075     ok( r == ERROR_SUCCESS, "wrong return val\n");
1076     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
1077
1078     r = MsiSetProperty( hpkg, "boo", "" );
1079     ok( r == ERROR_SUCCESS, "wrong return val\n");
1080     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
1081
1082     /* set a non-empty value */
1083     r = MsiSetProperty( hpkg, "boo", "xyz" );
1084     ok( r == ERROR_SUCCESS, "wrong return val\n");
1085
1086     sz = 1;
1087     strcpy(buffer,"x");
1088     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1089     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1090     ok( buffer[0] == 0, "buffer was not changed\n");
1091     ok( sz == 3, "wrong size returned\n");
1092
1093     sz = 4;
1094     strcpy(buffer,"x");
1095     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1096     ok( r == ERROR_SUCCESS, "wrong return val\n");
1097     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
1098     ok( sz == 3, "wrong size returned\n");
1099
1100     sz = 3;
1101     strcpy(buffer,"x");
1102     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
1103     ok( r == ERROR_MORE_DATA, "wrong return val\n");
1104     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
1105     ok( sz == 3, "wrong size returned\n");
1106
1107     MsiCloseHandle( hpkg );
1108     DeleteFile(msifile);
1109 }
1110
1111 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
1112 {
1113     MSIHANDLE htab = 0;
1114     UINT res;
1115
1116     res = MsiDatabaseOpenView( hdb, szQuery, &htab );
1117     if( res == ERROR_SUCCESS )
1118     {
1119         UINT r;
1120
1121         r = MsiViewExecute( htab, hrec );
1122         if( r != ERROR_SUCCESS )
1123         {
1124             res = r;
1125             fprintf(stderr,"MsiViewExecute failed %08x\n", res);
1126         }
1127
1128         r = MsiViewClose( htab );
1129         if( r != ERROR_SUCCESS )
1130             res = r;
1131
1132         r = MsiCloseHandle( htab );
1133         if( r != ERROR_SUCCESS )
1134             res = r;
1135     }
1136     return res;
1137 }
1138
1139 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
1140 {
1141     return try_query_param( hdb, szQuery, 0 );
1142 }
1143
1144 static void test_msipackage(void)
1145 {
1146     MSIHANDLE hdb = 0, hpack = 100;
1147     UINT r;
1148     const char *query;
1149     char name[10];
1150
1151     DeleteFile(msifile);
1152
1153     todo_wine {
1154     name[0] = 0;
1155     r = MsiOpenPackage(name, &hpack);
1156     ok(r == ERROR_SUCCESS, "failed to open package with no name\n");
1157     r = MsiCloseHandle(hpack);
1158     ok(r == ERROR_SUCCESS, "failed to close package\n");
1159     }
1160
1161     /* just MsiOpenDatabase should not create a file */
1162     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
1163     ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
1164
1165     name[0]='#';
1166     name[1]=0;
1167     r = MsiOpenPackage(name, &hpack);
1168     ok(r == ERROR_INVALID_HANDLE, "MsiOpenPackage returned wrong code\n");
1169
1170     todo_wine {
1171     /* now try again with our empty database */
1172     sprintf(name, "#%ld", hdb);
1173     r = MsiOpenPackage(name, &hpack);
1174     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1175     if (!r)    MsiCloseHandle(hpack);
1176     }
1177
1178     /* create a table */
1179     query = "CREATE TABLE `Property` ( "
1180             "`Property` CHAR(72), `Value` CHAR(0) "
1181             "PRIMARY KEY `Property`)";
1182     r = try_query(hdb, query);
1183     ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
1184
1185     todo_wine {
1186     query = "CREATE TABLE `InstallExecuteSequence` ("
1187             "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
1188             "PRIMARY KEY `Action`)";
1189     r = try_query(hdb, query);
1190     ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
1191
1192     sprintf(name, "#%ld", hdb);
1193     r = MsiOpenPackage(name, &hpack);
1194     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1195     if (!r)    MsiCloseHandle(hpack);
1196     }
1197
1198     r = MsiCloseHandle(hdb);
1199     ok(r == ERROR_SUCCESS, "MsiCloseHandle(database) failed\n");
1200     DeleteFile(msifile);
1201 }
1202
1203 static void test_formatrecord2(void)
1204 {
1205     MSIHANDLE hpkg, hrec ;
1206     char buffer[0x100];
1207     DWORD sz;
1208     UINT r;
1209
1210     hpkg = package_from_db(create_package_db());
1211     ok( hpkg, "failed to create package\n");
1212
1213     r = MsiSetProperty(hpkg, "Manufacturer", " " );
1214     ok( r == ERROR_SUCCESS, "set property failed\n");
1215
1216     hrec = MsiCreateRecord(2);
1217     ok(hrec, "create record failed\n");
1218
1219     r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
1220     ok( r == ERROR_SUCCESS, "format record failed\n");
1221
1222     buffer[0] = 0;
1223     sz = sizeof buffer;
1224     r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
1225
1226     r = MsiRecordSetString(hrec, 0, "[foo][1]");
1227     r = MsiRecordSetString(hrec, 1, "hoo");
1228     sz = sizeof buffer;
1229     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1230     ok( sz == 3, "size wrong\n");
1231     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1232     ok( r == ERROR_SUCCESS, "format failed\n");
1233
1234     r = MsiRecordSetString(hrec, 0, "x[~]x");
1235     sz = sizeof buffer;
1236     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1237     ok( sz == 3, "size wrong\n");
1238     ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
1239     ok( r == ERROR_SUCCESS, "format failed\n");
1240
1241     r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
1242     r = MsiRecordSetString(hrec, 1, "hoo");
1243     sz = sizeof buffer;
1244     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1245     ok( sz == 3, "size wrong\n");
1246     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1247     ok( r == ERROR_SUCCESS, "format failed\n");
1248
1249     r = MsiRecordSetString(hrec, 0, "[\\[]");
1250     sz = sizeof buffer;
1251     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1252     ok( sz == 1, "size wrong\n");
1253     ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
1254     ok( r == ERROR_SUCCESS, "format failed\n");
1255
1256     SetEnvironmentVariable("FOO", "BAR");
1257     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1258     sz = sizeof buffer;
1259     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1260     ok( sz == 3, "size wrong\n");
1261     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1262     ok( r == ERROR_SUCCESS, "format failed\n");
1263
1264     r = MsiRecordSetString(hrec, 0, "[[1]]");
1265     r = MsiRecordSetString(hrec, 1, "%FOO");
1266     sz = sizeof buffer;
1267     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1268     ok( sz == 3, "size wrong\n");
1269     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1270     ok( r == ERROR_SUCCESS, "format failed\n");
1271
1272     MsiCloseHandle( hrec );
1273     MsiCloseHandle( hpkg );
1274     DeleteFile(msifile);
1275 }
1276
1277 static void test_states(void)
1278 {
1279     MSIHANDLE hpkg;
1280     UINT r;
1281     MSIHANDLE hdb;
1282     INSTALLSTATE state, action;
1283
1284     hdb = create_package_db();
1285     ok ( hdb, "failed to create package database\n" );
1286
1287     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
1288     ok( r == ERROR_SUCCESS, "cannot add directory: %d\n", r );
1289
1290     r = create_feature_table( hdb );
1291     ok( r == ERROR_SUCCESS, "cannot create Feature table: %d\n", r );
1292
1293     r = create_component_table( hdb );
1294     ok( r == ERROR_SUCCESS, "cannot create Component table: %d\n", r );
1295
1296     /* msidbFeatureAttributesFavorLocal */
1297     r = add_feature_entry( hdb, "'one', '', '', '', 2, 1, '', 0" );
1298     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1299
1300     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesLocalOnly */
1301     r = add_component_entry( hdb, "'alpha', '{467EC132-739D-4784-A37B-677AA43DBC94}', 'TARGETDIR', 0, '', 'alpha_file'" );
1302     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1303
1304     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesSourceOnly */
1305     r = add_component_entry( hdb, "'beta', '{2C1F189C-24A6-4C34-B26B-994A6C026506}', 'TARGETDIR', 1, '', 'beta_file'" );
1306     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1307
1308     /* msidbFeatureAttributesFavorLocal:msidbComponentAttributesOptional */
1309     r = add_component_entry( hdb, "'gamma', '{C271E2A4-DE2E-4F70-86D1-6984AF7DE2CA}', 'TARGETDIR', 2, '', 'gamma_file'" );
1310     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1311
1312     /* msidbFeatureAttributesFavorSource */
1313     r = add_feature_entry( hdb, "'two', '', '', '', 2, 1, '', 1" );
1314     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1315
1316     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesLocalOnly */
1317     r = add_component_entry( hdb, "'delta', '{938FD4F2-C648-4259-A03C-7AA3B45643F3}', 'TARGETDIR', 0, '', 'delta_file'" );
1318     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1319
1320     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
1321     r = add_component_entry( hdb, "'epsilon', '{D59713B6-C11D-47F2-A395-1E5321781190}', 'TARGETDIR', 1, '', 'epsilon_file'" );
1322     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1323
1324     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesOptional */
1325     r = add_component_entry( hdb, "'zeta', '{377D33AB-2FAA-42B9-A629-0C0DAE9B9C7A}', 'TARGETDIR', 2, '', 'zeta_file'" );
1326     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1327
1328     /* msidbFeatureAttributesFavorSource */
1329     r = add_feature_entry( hdb, "'three', '', '', '', 2, 1, '', 1" );
1330     ok( r == ERROR_SUCCESS, "cannot add feature: %d\n", r );
1331
1332     /* msidbFeatureAttributesFavorSource:msidbComponentAttributesSourceOnly */
1333     r = add_component_entry( hdb, "'eta', '{DD89003F-0DD4-41B8-81C0-3411A7DA2695}', 'TARGETDIR', 1, '', 'eta_file'" );
1334     ok( r == ERROR_SUCCESS, "cannot add component: %d\n", r );
1335
1336     r = create_feature_components_table( hdb );
1337     ok( r == ERROR_SUCCESS, "cannot create FeatureComponents table: %d\n", r );
1338
1339     r = add_feature_components_entry( hdb, "'one', 'alpha'" );
1340     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1341
1342     r = add_feature_components_entry( hdb, "'one', 'beta'" );
1343     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1344
1345     r = add_feature_components_entry( hdb, "'one', 'gamma'" );
1346     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1347
1348     r = add_feature_components_entry( hdb, "'two', 'delta'" );
1349     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1350
1351     r = add_feature_components_entry( hdb, "'two', 'epsilon'" );
1352     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1353
1354     r = add_feature_components_entry( hdb, "'two', 'zeta'" );
1355     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1356
1357     r = add_feature_components_entry( hdb, "'three', 'eta'" );
1358     ok( r == ERROR_SUCCESS, "cannot add feature components: %d\n", r );
1359
1360     r = create_file_table( hdb );
1361     ok( r == ERROR_SUCCESS, "cannot create File table: %d\n", r );
1362
1363     r = add_file_entry( hdb, "'alpha_file', 'alpha', 'alpha.txt', 100, '', '1033', 8192, 1" );
1364     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1365
1366     r = add_file_entry( hdb, "'beta_file', 'beta', 'beta.txt', 0, '', '1033', 8192, 1" );
1367     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1368
1369     r = add_file_entry( hdb, "'gamma_file', 'gamma', 'gamma.txt', 0, '', '1033', 8192, 1" );
1370     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1371
1372     r = add_file_entry( hdb, "'delta_file', 'delta', 'delta.txt', 0, '', '1033', 8192, 1" );
1373     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1374
1375     r = add_file_entry( hdb, "'epsilon_file', 'epsilon', 'epsilon.txt', 0, '', '1033', 8192, 1" );
1376     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1377
1378     r = add_file_entry( hdb, "'zeta_file', 'zeta', 'zeta.txt', 0, '', '1033', 8192, 1" );
1379     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1380
1381     /* compressed file */
1382     r = add_file_entry( hdb, "'eta_file', 'eta', 'eta.txt', 0, '', '1033', 16384, 1" );
1383     ok( r == ERROR_SUCCESS, "cannot add file: %d\n", r);
1384
1385     hpkg = package_from_db( hdb );
1386     ok( hpkg, "failed to create package\n");
1387
1388     state = 0xdeadbee;
1389     action = 0xdeadbee;
1390     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1391     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1392     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1393     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1394
1395     state = 0xdeadbee;
1396     action = 0xdeadbee;
1397     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1398     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1399     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1400     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1401
1402     state = 0xdeadbee;
1403     action = 0xdeadbee;
1404     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1405     ok( r == ERROR_UNKNOWN_FEATURE, "Expected ERROR_UNKNOWN_FEATURE, got %d\n", r );
1406     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1407     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1408
1409     state = 0xdeadbee;
1410     action = 0xdeadbee;
1411     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1412     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1413     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1414     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1415
1416     state = 0xdeadbee;
1417     action = 0xdeadbee;
1418     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1419     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1420     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1421     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1422
1423     state = 0xdeadbee;
1424     action = 0xdeadbee;
1425     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1426     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1427     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1428     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1429
1430     state = 0xdeadbee;
1431     action = 0xdeadbee;
1432     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1433     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1434     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1435     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1436
1437     state = 0xdeadbee;
1438     action = 0xdeadbee;
1439     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1440     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1441     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1442     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1443
1444     state = 0xdeadbee;
1445     action = 0xdeadbee;
1446     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1447     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1448     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1449     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1450
1451     state = 0xdeadbee;
1452     action = 0xdeadbee;
1453     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1454     ok( r == ERROR_UNKNOWN_COMPONENT, "Expected ERROR_UNKNOWN_COMPONENT, got %d\n", r );
1455     ok( state == 0xdeadbee, "Expected 0xdeadbee, got %d\n", state);
1456     ok( action == 0xdeadbee, "Expected 0xdeadbee, got %d\n", action);
1457
1458     r = MsiDoAction( hpkg, "CostInitialize");
1459     ok( r == ERROR_SUCCESS, "cost init failed\n");
1460
1461     state = 0xdeadbee;
1462     action = 0xdeadbee;
1463     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1464     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1465     todo_wine
1466     {
1467         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1468     }
1469     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1470
1471     state = 0xdeadbee;
1472     action = 0xdeadbee;
1473     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1474     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1475     todo_wine
1476     {
1477         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1478     }
1479     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1480
1481     state = 0xdeadbee;
1482     action = 0xdeadbee;
1483     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1484     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1485     todo_wine
1486     {
1487         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1488     }
1489     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1490
1491     state = 0xdeadbee;
1492     action = 0xdeadbee;
1493     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1494     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1495     todo_wine
1496     {
1497         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1498         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1499     }
1500
1501     state = 0xdeadbee;
1502     action = 0xdeadbee;
1503     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1504     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1505     todo_wine
1506     {
1507         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1508         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1509     }
1510
1511     state = 0xdeadbee;
1512     action = 0xdeadbee;
1513     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1514     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1515     todo_wine
1516     {
1517         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1518         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1519     }
1520
1521     state = 0xdeadbee;
1522     action = 0xdeadbee;
1523     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1524     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1525     todo_wine
1526     {
1527         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1528         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1529     }
1530
1531     state = 0xdeadbee;
1532     action = 0xdeadbee;
1533     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1534     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1535     todo_wine
1536     {
1537         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1538         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1539     }
1540
1541     state = 0xdeadbee;
1542     action = 0xdeadbee;
1543     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1544     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1545     todo_wine
1546     {
1547         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1548         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1549     }
1550
1551     state = 0xdeadbee;
1552     action = 0xdeadbee;
1553     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1554     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1555     todo_wine
1556     {
1557         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1558         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1559     }
1560
1561     r = MsiDoAction( hpkg, "FileCost");
1562     ok( r == ERROR_SUCCESS, "file cost failed\n");
1563
1564     state = 0xdeadbee;
1565     action = 0xdeadbee;
1566     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1567     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1568     todo_wine
1569     {
1570         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1571     }
1572     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1573
1574     state = 0xdeadbee;
1575     action = 0xdeadbee;
1576     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1577     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1578     todo_wine
1579     {
1580         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1581     }
1582     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1583
1584     state = 0xdeadbee;
1585     action = 0xdeadbee;
1586     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1587     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1588     todo_wine
1589     {
1590         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1591     }
1592     ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1593
1594     state = 0xdeadbee;
1595     action = 0xdeadbee;
1596     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1597     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1598     todo_wine
1599     {
1600         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1601         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1602     }
1603
1604     state = 0xdeadbee;
1605     action = 0xdeadbee;
1606     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1607     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1608     todo_wine
1609     {
1610         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1611         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1612     }
1613
1614     state = 0xdeadbee;
1615     action = 0xdeadbee;
1616     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1617     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1618     todo_wine
1619     {
1620         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1621         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1622     }
1623
1624     state = 0xdeadbee;
1625     action = 0xdeadbee;
1626     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1627     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1628     todo_wine
1629     {
1630         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1631         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1632     }
1633
1634     state = 0xdeadbee;
1635     action = 0xdeadbee;
1636     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1637     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1638     todo_wine
1639     {
1640         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1641         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1642     }
1643
1644     state = 0xdeadbee;
1645     action = 0xdeadbee;
1646     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1647     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1648     todo_wine
1649     {
1650         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1651         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1652     }
1653
1654     state = 0xdeadbee;
1655     action = 0xdeadbee;
1656     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1657     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1658     todo_wine
1659     {
1660         ok( state == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", state);
1661         ok( action == INSTALLSTATE_UNKNOWN, "Expected INSTALLSTATE_UNKNOWN, got %d\n", action);
1662     }
1663
1664     r = MsiDoAction( hpkg, "CostFinalize");
1665     ok( r == ERROR_SUCCESS, "cost finalize failed: %d\n", r);
1666
1667     state = 0xdeadbee;
1668     action = 0xdeadbee;
1669     r = MsiGetFeatureState(hpkg, "one", &state, &action);
1670     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1671     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1672     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1673
1674     state = 0xdeadbee;
1675     action = 0xdeadbee;
1676     r = MsiGetFeatureState(hpkg, "two", &state, &action);
1677     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1678     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1679     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
1680
1681     state = 0xdeadbee;
1682     action = 0xdeadbee;
1683     r = MsiGetFeatureState(hpkg, "three", &state, &action);
1684     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1685     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1686     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1687
1688     state = 0xdeadbee;
1689     action = 0xdeadbee;
1690     r = MsiGetComponentState(hpkg, "alpha", &state, &action);
1691     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1692     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1693     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1694
1695     state = 0xdeadbee;
1696     action = 0xdeadbee;
1697     r = MsiGetComponentState(hpkg, "beta", &state, &action);
1698     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1699     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1700     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
1701
1702     state = 0xdeadbee;
1703     action = 0xdeadbee;
1704     r = MsiGetComponentState(hpkg, "gamma", &state, &action);
1705     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1706     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1707     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1708
1709     state = 0xdeadbee;
1710     action = 0xdeadbee;
1711     r = MsiGetComponentState(hpkg, "delta", &state, &action);
1712     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1713     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1714     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1715
1716     state = 0xdeadbee;
1717     action = 0xdeadbee;
1718     r = MsiGetComponentState(hpkg, "epsilon", &state, &action);
1719     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1720     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1721     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
1722
1723     state = 0xdeadbee;
1724     action = 0xdeadbee;
1725     r = MsiGetComponentState(hpkg, "zeta", &state, &action);
1726     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1727     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1728     ok( action == INSTALLSTATE_SOURCE, "Expected INSTALLSTATE_SOURCE, got %d\n", action);
1729
1730     state = 0xdeadbee;
1731     action = 0xdeadbee;
1732     r = MsiGetComponentState(hpkg, "eta", &state, &action);
1733     ok( r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r );
1734     ok( state == INSTALLSTATE_ABSENT, "Expected INSTALLSTATE_ABSENT, got %d\n", state);
1735     ok( action == INSTALLSTATE_LOCAL, "Expected INSTALLSTATE_LOCAL, got %d\n", action);
1736     
1737     MsiCloseHandle( hpkg );
1738 }
1739
1740 START_TEST(package)
1741 {
1742     test_createpackage();
1743     test_getsourcepath_bad();
1744     test_getsourcepath();
1745     test_doaction();
1746     test_gettargetpath_bad();
1747     test_settargetpath();
1748     test_props();
1749     test_condition();
1750     test_msipackage();
1751     test_formatrecord2();
1752     test_states();
1753 }