wined3d: Implement more GLSL instructions and a little cleanup.
[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 set_summary_info(MSIHANDLE hdb)
50 {
51     UINT res;
52     MSIHANDLE suminfo;
53
54     /* build summmary info */
55     res = MsiGetSummaryInformation(hdb, NULL, 7, &suminfo);
56     ok( res == ERROR_SUCCESS , "Failed to open summaryinfo\n" );
57
58     res = MsiSummaryInfoSetProperty(suminfo,2, VT_LPSTR, 0,NULL,
59                         "Installation Database");
60     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
61
62     res = MsiSummaryInfoSetProperty(suminfo,3, VT_LPSTR, 0,NULL,
63                         "Installation Database");
64     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
65
66     res = MsiSummaryInfoSetProperty(suminfo,4, VT_LPSTR, 0,NULL,
67                         "Wine Hackers");
68     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
69
70     res = MsiSummaryInfoSetProperty(suminfo,7, VT_LPSTR, 0,NULL,
71                     ";1033");
72     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
73
74     res = MsiSummaryInfoSetProperty(suminfo,9, VT_LPSTR, 0,NULL,
75                     "{913B8D18-FBB6-4CAC-A239-C74C11E3FA74}");
76     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
77
78     res = MsiSummaryInfoSetProperty(suminfo, 14, VT_I4, 100, NULL, NULL);
79     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
80
81     res = MsiSummaryInfoSetProperty(suminfo, 15, VT_I4, 0, NULL, NULL);
82     ok( res == ERROR_SUCCESS , "Failed to set summary info\n" );
83
84     res = MsiSummaryInfoPersist(suminfo);
85     ok( res == ERROR_SUCCESS , "Failed to make summary info persist\n" );
86
87     res = MsiCloseHandle( suminfo);
88     ok( res == ERROR_SUCCESS , "Failed to close suminfo\n" );
89
90     return res;
91 }
92
93
94 MSIHANDLE create_package_db(void)
95 {
96     MSIHANDLE hdb = 0;
97     UINT res;
98
99     DeleteFile(msifile);
100
101     /* create an empty database */
102     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
103     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
104     if( res != ERROR_SUCCESS )
105         return hdb;
106
107     res = MsiDatabaseCommit( hdb );
108     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
109
110     res = set_summary_info(hdb);
111
112     res = run_query( hdb,
113             "CREATE TABLE `Directory` ( "
114             "`Directory` CHAR(255) NOT NULL, "
115             "`Directory_Parent` CHAR(255), "
116             "`DefaultDir` CHAR(255) NOT NULL "
117             "PRIMARY KEY `Directory`)" );
118     ok( res == ERROR_SUCCESS , "Failed to create directory table\n" );
119
120     return hdb;
121 }
122
123 MSIHANDLE package_from_db(MSIHANDLE hdb)
124 {
125     UINT res;
126     CHAR szPackage[10];
127     MSIHANDLE hPackage;
128
129     sprintf(szPackage,"#%li",hdb);
130     res = MsiOpenPackage(szPackage,&hPackage);
131     ok( res == ERROR_SUCCESS , "Failed to open package\n" );
132
133     res = MsiCloseHandle(hdb);
134     ok( res == ERROR_SUCCESS , "Failed to close db handle\n" );
135
136     return hPackage;
137 }
138
139 static void test_createpackage(void)
140 {
141     MSIHANDLE hPackage = 0;
142     UINT res;
143
144     hPackage = package_from_db(create_package_db());
145     ok( hPackage != 0, " Failed to create package\n");
146
147     res = MsiCloseHandle( hPackage);
148     ok( res == ERROR_SUCCESS , "Failed to close package\n" );
149     DeleteFile(msifile);
150 }
151
152 static void test_getsourcepath_bad( void )
153 {
154     static const char str[] = { 0 };
155     char buffer[0x80];
156     DWORD sz;
157     UINT r;
158
159     r = MsiGetSourcePath( -1, NULL, NULL, NULL );
160     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
161
162     sz = 0;
163     r = MsiGetSourcePath( -1, NULL, buffer, &sz );
164     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
165
166     sz = 0;
167     r = MsiGetSourcePath( -1, str, NULL, &sz );
168     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
169
170     sz = 0;
171     r = MsiGetSourcePath( -1, str, NULL, NULL );
172     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
173
174     sz = 0;
175     r = MsiGetSourcePath( -1, str, buffer, &sz );
176     ok( r == ERROR_INVALID_HANDLE, "return value wrong\n");
177 }
178
179 static UINT add_directory_entry( MSIHANDLE hdb, char *values )
180 {
181     char insert[] = "INSERT INTO `Directory` (`Directory`,`Directory_Parent`,`DefaultDir`) VALUES( %s )";
182     char *query;
183     UINT sz, r;
184
185     sz = strlen(values) + sizeof insert;
186     query = HeapAlloc(GetProcessHeap(),0,sz);
187     sprintf(query,insert,values);
188     r = run_query( hdb, query );
189     HeapFree(GetProcessHeap(), 0, query);
190     return r;
191 }
192
193 static void test_getsourcepath( void )
194 {
195     static const char str[] = { 0 };
196     char buffer[0x80];
197     DWORD sz;
198     UINT r;
199     MSIHANDLE hpkg, hdb;
200
201     hpkg = package_from_db(create_package_db());
202     ok( hpkg, "failed to create package\n");
203
204     sz = 0;
205     buffer[0] = 'x';
206     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
207     ok( r == ERROR_DIRECTORY, "return value wrong\n");
208     ok( buffer[0] == 'x', "buffer modified\n");
209
210     sz = 1;
211     buffer[0] = 'x';
212     r = MsiGetSourcePath( hpkg, str, buffer, &sz );
213     ok( r == ERROR_DIRECTORY, "return value wrong\n");
214     ok( buffer[0] == 'x', "buffer modified\n");
215
216     MsiCloseHandle( hpkg );
217
218
219     /* another test but try create a directory this time */
220     hdb = create_package_db();
221     ok( hdb, "failed to create database\n");
222     
223     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'");
224     ok( r == S_OK, "failed\n");
225
226     hpkg = package_from_db(hdb);
227     ok( hpkg, "failed to create package\n");
228
229     sz = sizeof buffer -1;
230     strcpy(buffer,"x bad");
231     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
232     ok( r == ERROR_DIRECTORY, "return value wrong\n");
233
234     todo_wine {
235     r = MsiDoAction( hpkg, "CostInitialize");
236     ok( r == ERROR_SUCCESS, "cost init failed\n");
237     }
238     r = MsiDoAction( hpkg, "CostFinalize");
239     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
240
241     todo_wine {
242     sz = sizeof buffer -1;
243     buffer[0] = 'x';
244     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
245     ok( r == ERROR_SUCCESS, "return value wrong\n");
246     ok( sz == strlen(buffer), "returned length wrong\n");
247
248     sz = 0;
249     strcpy(buffer,"x bad");
250     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, &sz );
251     ok( r == ERROR_MORE_DATA, "return value wrong\n");
252     }
253     ok( buffer[0] == 'x', "buffer modified\n");
254
255     todo_wine {
256     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, NULL );
257     ok( r == ERROR_SUCCESS, "return value wrong\n");
258     }
259
260     r = MsiGetSourcePath( hpkg, "TARGETDIR ", NULL, NULL );
261     ok( r == ERROR_DIRECTORY, "return value wrong\n");
262
263     r = MsiGetSourcePath( hpkg, "targetdir", NULL, NULL );
264     ok( r == ERROR_DIRECTORY, "return value wrong\n");
265
266     r = MsiGetSourcePath( hpkg, "TARGETDIR", buffer, NULL );
267     ok( r == ERROR_INVALID_PARAMETER, "return value wrong\n");
268
269     todo_wine {
270     r = MsiGetSourcePath( hpkg, "TARGETDIR", NULL, &sz );
271     ok( r == ERROR_SUCCESS, "return value wrong\n");
272     }
273
274     MsiCloseHandle( hpkg );
275     DeleteFile(msifile);
276 }
277
278 static void test_doaction( void )
279 {
280     MSIHANDLE hpkg;
281     UINT r;
282
283     r = MsiDoAction( -1, NULL );
284     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
285
286     hpkg = package_from_db(create_package_db());
287     ok( hpkg, "failed to create package\n");
288
289     r = MsiDoAction(hpkg, NULL);
290     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
291
292     r = MsiDoAction(0, "boo");
293     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
294
295     r = MsiDoAction(hpkg, "boo");
296     ok( r == ERROR_FUNCTION_NOT_CALLED, "wrong return val\n");
297
298     MsiCloseHandle( hpkg );
299     DeleteFile(msifile);
300 }
301
302 static void test_gettargetpath_bad(void)
303 {
304     char buffer[0x80];
305     MSIHANDLE hpkg;
306     DWORD sz;
307     UINT r;
308
309     hpkg = package_from_db(create_package_db());
310     ok( hpkg, "failed to create package\n");
311
312     r = MsiGetTargetPath( 0, NULL, NULL, NULL );
313     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
314
315     r = MsiGetTargetPath( 0, NULL, NULL, &sz );
316     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
317
318     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
319     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
320
321     r = MsiGetTargetPath( 0, "boo", NULL, NULL );
322     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
323
324     r = MsiGetTargetPath( hpkg, "boo", NULL, NULL );
325     ok( r == ERROR_DIRECTORY, "wrong return val\n");
326
327     r = MsiGetTargetPath( hpkg, "boo", buffer, NULL );
328     ok( r == ERROR_DIRECTORY, "wrong return val\n");
329
330     MsiCloseHandle( hpkg );
331     DeleteFile(msifile);
332 }
333
334 static void test_settargetpath(void)
335 {
336     char tempdir[MAX_PATH+8], buffer[MAX_PATH];
337     DWORD sz;
338     MSIHANDLE hpkg;
339     UINT r;
340     MSIHANDLE hdb;
341     
342     hdb = create_package_db();
343     ok ( hdb, "failed to create package database\n" );
344
345     r = add_directory_entry( hdb, "'TARGETDIR', '', 'SourceDir'" );
346     ok( r == S_OK, "failed to add directory entry: %d\n" , r );
347
348     r = run_query( hdb, /* these tables required by Windows Installer for MsiSetTargetPath */
349             "CREATE TABLE `Component` ( "
350             "`Component` CHAR(72) NOT NULL, "
351             "`ComponentId` CHAR(38), "
352             "`Directory_` CHAR(72) NOT NULL, "
353             "`Attributes` SHORT NOT NULL, "
354             "`Condition` CHAR(255), "
355             "`KeyPath` CHAR(72) "
356             "PRIMARY KEY `Component`)" );
357     ok( r == S_OK, "cannot create Component table: %d\n", r );
358
359     r = run_query( hdb,
360             "INSERT INTO `Component`  "
361             "(`Component`, `ComponentId`, `Directory_`, `Attributes`, `Condition`, `KeyPath`) "
362             "VALUES( 'WinWorkAround', '{83e2694d-0864-4124-9323-6d37630912a1}', 'TARGETDIR', 8, '', 'FL_dummycomponent')" );
363     ok( r == S_OK, "cannot add dummy component: %d\n", r );
364
365     r = run_query( hdb,
366             "CREATE TABLE `Feature` ( "
367             "`Feature` CHAR(38) NOT NULL, "
368             "`Feature_Parent` CHAR(38), "
369             "`Title` CHAR(64), "
370             "`Description` CHAR(255), "
371             "`Display` SHORT NOT NULL, "
372             "`Level` SHORT NOT NULL, "
373             "`Directory_` CHAR(72), "
374             "`Attributes` SHORT NOT NULL "
375             "PRIMARY KEY `Feature`)" );
376     ok( r == S_OK, "cannot create Feature table: %d\n", r );
377
378     hpkg = package_from_db( hdb );
379     ok( hpkg, "failed to create package\n");
380
381     r = MsiDoAction( hpkg, "CostInitialize");
382     ok( r == ERROR_SUCCESS, "cost init failed\n");
383
384     r = MsiDoAction( hpkg, "CostFinalize");
385     ok( r == ERROR_SUCCESS, "cost finalize failed\n");
386
387     r = MsiSetTargetPath( 0, NULL, NULL );
388     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
389
390     r = MsiSetTargetPath( 0, "boo", "C:\\bogusx" );
391     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
392
393     r = MsiSetTargetPath( hpkg, "boo", NULL );
394     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
395
396     r = MsiSetTargetPath( hpkg, "boo", "c:\\bogusx" );
397     ok( r == ERROR_DIRECTORY, "wrong return val\n");
398
399     sz = sizeof tempdir - 1;
400     r = MsiGetTargetPath( hpkg, "TARGETDIR", tempdir, &sz );
401     if ( r == S_OK )
402     {
403         if ( GetTempFileName( tempdir, "_wt", 0, buffer ) )
404         {
405             sprintf( tempdir, "%s\\subdir", buffer );
406             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
407             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on file returned %d\n", r );
408
409             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
410             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on 'subdir' of file returned %d\n", r );
411
412             DeleteFile( buffer );
413
414             r = MsiSetTargetPath( hpkg, "TARGETDIR", buffer );
415             ok( r == ERROR_SUCCESS, "MsiSetTargetPath returned %d\n", r );
416
417             r = GetFileAttributes( buffer );
418             ok ( r == INVALID_FILE_ATTRIBUTES, "file/directory exists after MsiSetTargetPath. Attributes: %08X\n", r );
419
420             r = MsiSetTargetPath( hpkg, "TARGETDIR", tempdir );
421             ok( r == ERROR_SUCCESS, "MsiSetTargetPath on subsubdir returned %d\n", r );
422         } else {
423             trace("GetTempFileName failed, cannot do some tests\n");
424         }
425     } else {
426         trace( "MsiGetTargetPath failed: %d\n", r );
427     }
428     
429     MsiCloseHandle( hpkg );
430 }
431
432 static void test_condition(void)
433 {
434     MSICONDITION r;
435     MSIHANDLE hpkg;
436
437     hpkg = package_from_db(create_package_db());
438     ok( hpkg, "failed to create package\n");
439
440     r = MsiEvaluateCondition(0, NULL);
441     ok( r == MSICONDITION_ERROR, "wrong return val\n");
442
443     r = MsiEvaluateCondition(hpkg, NULL);
444     ok( r == MSICONDITION_NONE, "wrong return val\n");
445
446     r = MsiEvaluateCondition(hpkg, "");
447     ok( r == MSICONDITION_NONE, "wrong return val\n");
448
449     r = MsiEvaluateCondition(hpkg, "1");
450     ok( r == MSICONDITION_TRUE, "wrong return val\n");
451
452     r = MsiEvaluateCondition(hpkg, "0");
453     ok( r == MSICONDITION_FALSE, "wrong return val\n");
454
455     r = MsiEvaluateCondition(hpkg, "0 = 0");
456     ok( r == MSICONDITION_TRUE, "wrong return val\n");
457
458     r = MsiEvaluateCondition(hpkg, "0 <> 0");
459     ok( r == MSICONDITION_FALSE, "wrong return val\n");
460
461     r = MsiEvaluateCondition(hpkg, "0 = 1");
462     ok( r == MSICONDITION_FALSE, "wrong return val\n");
463
464     r = MsiEvaluateCondition(hpkg, "0 > 1");
465     ok( r == MSICONDITION_FALSE, "wrong return val\n");
466
467     r = MsiEvaluateCondition(hpkg, "0 ~> 1");
468     ok( r == MSICONDITION_FALSE, "wrong return val\n");
469
470     r = MsiEvaluateCondition(hpkg, "1 > 1");
471     ok( r == MSICONDITION_FALSE, "wrong return val\n");
472
473     r = MsiEvaluateCondition(hpkg, "1 ~> 1");
474     ok( r == MSICONDITION_FALSE, "wrong return val\n");
475
476     r = MsiEvaluateCondition(hpkg, "0 >= 1");
477     ok( r == MSICONDITION_FALSE, "wrong return val\n");
478
479     r = MsiEvaluateCondition(hpkg, "0 ~>= 1");
480     ok( r == MSICONDITION_FALSE, "wrong return val\n");
481
482     r = MsiEvaluateCondition(hpkg, "1 >= 1");
483     ok( r == MSICONDITION_TRUE, "wrong return val\n");
484
485     r = MsiEvaluateCondition(hpkg, "1 ~>= 1");
486     ok( r == MSICONDITION_TRUE, "wrong return val\n");
487
488     r = MsiEvaluateCondition(hpkg, "0 < 1");
489     ok( r == MSICONDITION_TRUE, "wrong return val\n");
490
491     r = MsiEvaluateCondition(hpkg, "0 ~< 1");
492     ok( r == MSICONDITION_TRUE, "wrong return val\n");
493
494     r = MsiEvaluateCondition(hpkg, "1 < 1");
495     ok( r == MSICONDITION_FALSE, "wrong return val\n");
496
497     r = MsiEvaluateCondition(hpkg, "1 ~< 1");
498     ok( r == MSICONDITION_FALSE, "wrong return val\n");
499
500     r = MsiEvaluateCondition(hpkg, "0 <= 1");
501     ok( r == MSICONDITION_TRUE, "wrong return val\n");
502
503     r = MsiEvaluateCondition(hpkg, "0 ~<= 1");
504     ok( r == MSICONDITION_TRUE, "wrong return val\n");
505
506     r = MsiEvaluateCondition(hpkg, "1 <= 1");
507     ok( r == MSICONDITION_TRUE, "wrong return val\n");
508
509     r = MsiEvaluateCondition(hpkg, "1 ~<= 1");
510     ok( r == MSICONDITION_TRUE, "wrong return val\n");
511
512     r = MsiEvaluateCondition(hpkg, "0 >=");
513     ok( r == MSICONDITION_ERROR, "wrong return val\n");
514
515     r = MsiEvaluateCondition(hpkg, " ");
516     ok( r == MSICONDITION_NONE, "wrong return val\n");
517
518     r = MsiEvaluateCondition(hpkg, "LicView <> \"1\"");
519     ok( r == MSICONDITION_TRUE, "wrong return val\n");
520
521     r = MsiEvaluateCondition(hpkg, "LicView <> \"0\"");
522     ok( r == MSICONDITION_TRUE, "wrong return val\n");
523
524     r = MsiEvaluateCondition(hpkg, "LicView <> LicView");
525     ok( r == MSICONDITION_FALSE, "wrong return val\n");
526
527     r = MsiEvaluateCondition(hpkg, "not 0");
528     ok( r == MSICONDITION_TRUE, "wrong return val\n");
529
530     r = MsiEvaluateCondition(hpkg, "not LicView");
531     ok( r == MSICONDITION_TRUE, "wrong return val\n");
532
533     r = MsiEvaluateCondition(hpkg, "not \"A\"");
534     ok( r == MSICONDITION_FALSE, "wrong return val\n");
535
536     r = MsiEvaluateCondition(hpkg, "~not \"A\"");
537     ok( r == MSICONDITION_ERROR, "wrong return val\n");
538
539     r = MsiEvaluateCondition(hpkg, "\"0\"");
540     ok( r == MSICONDITION_TRUE, "wrong return val\n");
541
542     r = MsiEvaluateCondition(hpkg, "1 and 2");
543     ok( r == MSICONDITION_TRUE, "wrong return val\n");
544
545     r = MsiEvaluateCondition(hpkg, "not 0 and 3");
546     ok( r == MSICONDITION_TRUE, "wrong return val\n");
547
548     r = MsiEvaluateCondition(hpkg, "not 0 and 0");
549     ok( r == MSICONDITION_FALSE, "wrong return val\n");
550
551     r = MsiEvaluateCondition(hpkg, "not 0 or 1");
552     ok( r == MSICONDITION_TRUE, "wrong return val\n");
553
554     r = MsiEvaluateCondition(hpkg, "(0)");
555     ok( r == MSICONDITION_FALSE, "wrong return val\n");
556
557     r = MsiEvaluateCondition(hpkg, "(((((1))))))");
558     ok( r == MSICONDITION_ERROR, "wrong return val\n");
559
560     r = MsiEvaluateCondition(hpkg, "(((((1)))))");
561     ok( r == MSICONDITION_TRUE, "wrong return val\n");
562
563     r = MsiEvaluateCondition(hpkg, " \"A\" < \"B\" ");
564     ok( r == MSICONDITION_TRUE, "wrong return val\n");
565
566     r = MsiEvaluateCondition(hpkg, " \"A\" > \"B\" ");
567     ok( r == MSICONDITION_FALSE, "wrong return val\n");
568
569     r = MsiEvaluateCondition(hpkg, " \"1\" > \"12\" ");
570     ok( r == MSICONDITION_FALSE, "wrong return val\n");
571
572     r = MsiEvaluateCondition(hpkg, " \"100\" < \"21\" ");
573     ok( r == MSICONDITION_TRUE, "wrong return val\n");
574
575     r = MsiEvaluateCondition(hpkg, "0 < > 0");
576     ok( r == MSICONDITION_ERROR, "wrong return val\n");
577
578     r = MsiEvaluateCondition(hpkg, "(1<<1) == 2");
579     ok( r == MSICONDITION_ERROR, "wrong return val\n");
580
581     r = MsiEvaluateCondition(hpkg, " \"A\" = \"a\" ");
582     ok( r == MSICONDITION_FALSE, "wrong return val\n");
583
584     r = MsiEvaluateCondition(hpkg, " \"A\" ~ = \"a\" ");
585     ok( r == MSICONDITION_ERROR, "wrong return val\n");
586
587     r = MsiEvaluateCondition(hpkg, " \"A\" ~= \"a\" ");
588     ok( r == MSICONDITION_TRUE, "wrong return val\n");
589
590     r = MsiEvaluateCondition(hpkg, " \"A\" ~= 1 ");
591     ok( r == MSICONDITION_FALSE, "wrong return val\n");
592
593     r = MsiEvaluateCondition(hpkg, " \"A\" = 1 ");
594     ok( r == MSICONDITION_FALSE, "wrong return val\n");
595
596     r = MsiEvaluateCondition(hpkg, " 1 ~= 1 ");
597     ok( r == MSICONDITION_TRUE, "wrong return val\n");
598
599     r = MsiEvaluateCondition(hpkg, " 1 ~= \"1\" ");
600     ok( r == MSICONDITION_FALSE, "wrong return val\n");
601
602     r = MsiEvaluateCondition(hpkg, " 1 = \"1\" ");
603     ok( r == MSICONDITION_FALSE, "wrong return val\n");
604
605     r = MsiEvaluateCondition(hpkg, " 0 = \"1\" ");
606     ok( r == MSICONDITION_FALSE, "wrong return val\n");
607
608     r = MsiEvaluateCondition(hpkg, " 0 < \"100\" ");
609     ok( r == MSICONDITION_FALSE, "wrong return val\n");
610
611     r = MsiEvaluateCondition(hpkg, " 100 > \"0\" ");
612     ok( r == MSICONDITION_FALSE, "wrong return val\n");
613
614     r = MsiEvaluateCondition(hpkg, "1 XOR 1");
615     ok( r == MSICONDITION_FALSE, "wrong return val\n");
616
617     r = MsiEvaluateCondition(hpkg, "1 IMP 1");
618     ok( r == MSICONDITION_TRUE, "wrong return val\n");
619
620     r = MsiEvaluateCondition(hpkg, "1 IMP 0");
621     ok( r == MSICONDITION_FALSE, "wrong return val\n");
622
623     r = MsiEvaluateCondition(hpkg, "0 IMP 0");
624     ok( r == MSICONDITION_TRUE, "wrong return val\n");
625
626     r = MsiEvaluateCondition(hpkg, "0 EQV 0");
627     ok( r == MSICONDITION_TRUE, "wrong return val\n");
628
629     r = MsiEvaluateCondition(hpkg, "0 EQV 1");
630     ok( r == MSICONDITION_FALSE, "wrong return val\n");
631
632     r = MsiEvaluateCondition(hpkg, "1 IMP 1 OR 0");
633     ok( r == MSICONDITION_TRUE, "wrong return val\n");
634
635     r = MsiEvaluateCondition(hpkg, "1 IMPL 1");
636     ok( r == MSICONDITION_ERROR, "wrong return val\n");
637
638     r = MsiEvaluateCondition(hpkg, "\"ASFD\" >< \"S\" ");
639     ok( r == MSICONDITION_TRUE, "wrong return val\n");
640
641     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"s\" ");
642     ok( r == MSICONDITION_TRUE, "wrong return val\n");
643
644     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"\" ");
645     ok( r == MSICONDITION_TRUE, "wrong return val\n");
646
647     r = MsiEvaluateCondition(hpkg, "\"ASFD\" ~>< \"sss\" ");
648     ok( r == MSICONDITION_FALSE, "wrong return val\n");
649
650     MsiSetProperty(hpkg, "mm", "5" );
651
652     r = MsiEvaluateCondition(hpkg, "mm = 5");
653     ok( r == MSICONDITION_TRUE, "wrong return val\n");
654
655     r = MsiEvaluateCondition(hpkg, "mm < 6");
656     ok( r == MSICONDITION_TRUE, "wrong return val\n");
657
658     r = MsiEvaluateCondition(hpkg, "mm <= 5");
659     ok( r == MSICONDITION_TRUE, "wrong return val\n");
660
661     r = MsiEvaluateCondition(hpkg, "mm > 4");
662     ok( r == MSICONDITION_TRUE, "wrong return val\n");
663
664     r = MsiEvaluateCondition(hpkg, "mm < 12");
665     ok( r == MSICONDITION_TRUE, "wrong return val\n");
666
667     r = MsiEvaluateCondition(hpkg, "mm = \"5\"");
668     ok( r == MSICONDITION_TRUE, "wrong return val\n");
669
670     r = MsiEvaluateCondition(hpkg, "0 = \"\"");
671     ok( r == MSICONDITION_FALSE, "wrong return val\n");
672
673     r = MsiEvaluateCondition(hpkg, "0 AND \"\"");
674     ok( r == MSICONDITION_FALSE, "wrong return val\n");
675
676     r = MsiEvaluateCondition(hpkg, "1 AND \"\"");
677     ok( r == MSICONDITION_FALSE, "wrong return val\n");
678
679     r = MsiEvaluateCondition(hpkg, "1 AND \"1\"");
680     ok( r == MSICONDITION_TRUE, "wrong return val\n");
681
682     r = MsiEvaluateCondition(hpkg, "3 >< 1");
683     ok( r == MSICONDITION_TRUE, "wrong return val\n");
684
685     r = MsiEvaluateCondition(hpkg, "3 >< 4");
686     ok( r == MSICONDITION_FALSE, "wrong return val\n");
687
688     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 0");
689     ok( r == MSICONDITION_FALSE, "wrong return val\n");
690
691     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1");
692     ok( r == MSICONDITION_TRUE, "wrong return val\n");
693
694     r = MsiEvaluateCondition(hpkg, "NOT 1 OR 0");
695     ok( r == MSICONDITION_FALSE, "wrong return val\n");
696
697     r = MsiEvaluateCondition(hpkg, "0 AND 1 OR 1");
698     ok( r == MSICONDITION_TRUE, "wrong return val\n");
699
700     r = MsiEvaluateCondition(hpkg, "0 AND 0 OR 1");
701     ok( r == MSICONDITION_TRUE, "wrong return val\n");
702
703     r = MsiEvaluateCondition(hpkg, "NOT 0 AND 1 OR 0");
704     ok( r == MSICONDITION_TRUE, "wrong return val\n");
705
706     r = MsiEvaluateCondition(hpkg, "_1 = _1");
707     ok( r == MSICONDITION_TRUE, "wrong return val\n");
708
709     r = MsiEvaluateCondition(hpkg, "( 1 AND 1 ) = 2");
710     ok( r == MSICONDITION_ERROR, "wrong return val\n");
711
712     r = MsiEvaluateCondition(hpkg, "NOT ( 1 AND 1 )");
713     ok( r == MSICONDITION_FALSE, "wrong return val\n");
714
715     r = MsiEvaluateCondition(hpkg, "NOT A AND (BBBBBBBBBB=2 OR CCC=1) AND Ddddddddd");
716     ok( r == MSICONDITION_FALSE, "wrong return val\n");
717
718     r = MsiEvaluateCondition(hpkg, "Installed<>\"\"");
719     ok( r == MSICONDITION_FALSE, "wrong return val\n");
720
721     r = MsiEvaluateCondition(hpkg, "NOT 1 AND 0");
722     ok( r == MSICONDITION_FALSE, "wrong return val\n");
723
724     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
725     ok( r == MSICONDITION_FALSE, "wrong return val\n");
726
727     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
728     ok( r == MSICONDITION_TRUE, "wrong return val\n");
729
730     r = MsiEvaluateCondition(hpkg, "bandalmael<0");
731     ok( r == MSICONDITION_FALSE, "wrong return val\n");
732
733     r = MsiEvaluateCondition(hpkg, "bandalmael>0");
734     ok( r == MSICONDITION_FALSE, "wrong return val\n");
735
736     r = MsiEvaluateCondition(hpkg, "bandalmael>=0");
737     ok( r == MSICONDITION_FALSE, "wrong return val\n");
738
739     r = MsiEvaluateCondition(hpkg, "bandalmael<=0");
740     ok( r == MSICONDITION_FALSE, "wrong return val\n");
741
742     r = MsiEvaluateCondition(hpkg, "bandalmael~<>0");
743     ok( r == MSICONDITION_TRUE, "wrong return val\n");
744
745     MsiSetProperty(hpkg, "bandalmael", "0" );
746     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
747     ok( r == MSICONDITION_TRUE, "wrong return val\n");
748
749     MsiSetProperty(hpkg, "bandalmael", "" );
750     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
751     ok( r == MSICONDITION_FALSE, "wrong return val\n");
752
753     MsiSetProperty(hpkg, "bandalmael", "asdf" );
754     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
755     ok( r == MSICONDITION_FALSE, "wrong return val\n");
756
757     MsiSetProperty(hpkg, "bandalmael", "0asdf" );
758     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
759     ok( r == MSICONDITION_FALSE, "wrong return val\n");
760
761     MsiSetProperty(hpkg, "bandalmael", "0 " );
762     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
763     ok( r == MSICONDITION_FALSE, "wrong return val\n");
764
765     MsiSetProperty(hpkg, "bandalmael", "-0" );
766     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
767     ok( r == MSICONDITION_TRUE, "wrong return val\n");
768
769     MsiSetProperty(hpkg, "bandalmael", "0000000000000" );
770     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
771     ok( r == MSICONDITION_TRUE, "wrong return val\n");
772
773     MsiSetProperty(hpkg, "bandalmael", "--0" );
774     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
775     ok( r == MSICONDITION_FALSE, "wrong return val\n");
776
777     MsiSetProperty(hpkg, "bandalmael", "0x00" );
778     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
779     ok( r == MSICONDITION_FALSE, "wrong return val\n");
780
781     MsiSetProperty(hpkg, "bandalmael", "-" );
782     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
783     ok( r == MSICONDITION_FALSE, "wrong return val\n");
784
785     MsiSetProperty(hpkg, "bandalmael", "+0" );
786     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
787     ok( r == MSICONDITION_FALSE, "wrong return val\n");
788
789     MsiSetProperty(hpkg, "bandalmael", "0.0" );
790     r = MsiEvaluateCondition(hpkg, "bandalmael=0");
791     ok( r == MSICONDITION_FALSE, "wrong return val\n");
792     r = MsiEvaluateCondition(hpkg, "bandalmael<>0");
793     ok( r == MSICONDITION_TRUE, "wrong return val\n");
794
795     MsiCloseHandle( hpkg );
796     DeleteFile(msifile);
797 }
798
799 static BOOL check_prop_empty( MSIHANDLE hpkg, char * prop)
800 {
801     UINT r;
802     DWORD sz;
803     char buffer[2];
804
805     sz = sizeof buffer;
806     strcpy(buffer,"x");
807     r = MsiGetProperty( hpkg, prop, buffer, &sz );
808     return r == ERROR_SUCCESS && buffer[0] == 0 && sz == 0;
809 }
810
811 static void test_props(void)
812 {
813     MSIHANDLE hpkg;
814     UINT r;
815     DWORD sz;
816     char buffer[0x100];
817
818     hpkg = package_from_db(create_package_db());
819     ok( hpkg, "failed to create package\n");
820
821     /* test invalid values */
822     r = MsiGetProperty( 0, NULL, NULL, NULL );
823     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
824
825     r = MsiGetProperty( hpkg, NULL, NULL, NULL );
826     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
827
828     r = MsiGetProperty( hpkg, "boo", NULL, NULL );
829     ok( r == ERROR_SUCCESS, "wrong return val\n");
830
831     r = MsiGetProperty( hpkg, "boo", buffer, NULL );
832     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
833
834     /* test retrieving an empty/nonexistent property */
835     sz = sizeof buffer;
836     r = MsiGetProperty( hpkg, "boo", NULL, &sz );
837     ok( r == ERROR_SUCCESS, "wrong return val\n");
838     ok( sz == 0, "wrong size returned\n");
839
840     check_prop_empty( hpkg, "boo");
841     sz = 0;
842     strcpy(buffer,"x");
843     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
844     ok( r == ERROR_MORE_DATA, "wrong return val\n");
845     ok( !strcmp(buffer,"x"), "buffer was changed\n");
846     ok( sz == 0, "wrong size returned\n");
847
848     sz = 1;
849     strcpy(buffer,"x");
850     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
851     ok( r == ERROR_SUCCESS, "wrong return val\n");
852     ok( buffer[0] == 0, "buffer was not changed\n");
853     ok( sz == 0, "wrong size returned\n");
854
855     /* set the property to something */
856     r = MsiSetProperty( 0, NULL, NULL );
857     ok( r == ERROR_INVALID_HANDLE, "wrong return val\n");
858
859     r = MsiSetProperty( hpkg, NULL, NULL );
860     ok( r == ERROR_INVALID_PARAMETER, "wrong return val\n");
861
862     r = MsiSetProperty( hpkg, "", NULL );
863     ok( r == ERROR_SUCCESS, "wrong return val\n");
864
865     /* try set and get some illegal property identifiers */
866     r = MsiSetProperty( hpkg, "", "asdf" );
867     ok( r == ERROR_FUNCTION_FAILED, "wrong return val\n");
868
869     r = MsiSetProperty( hpkg, "=", "asdf" );
870     ok( r == ERROR_SUCCESS, "wrong return val\n");
871
872     r = MsiSetProperty( hpkg, " ", "asdf" );
873     ok( r == ERROR_SUCCESS, "wrong return val\n");
874
875     r = MsiSetProperty( hpkg, "'", "asdf" );
876     ok( r == ERROR_SUCCESS, "wrong return val\n");
877
878     sz = sizeof buffer;
879     buffer[0]=0;
880     r = MsiGetProperty( hpkg, "'", buffer, &sz );
881     ok( r == ERROR_SUCCESS, "wrong return val\n");
882     ok( !strcmp(buffer,"asdf"), "buffer was not changed\n");
883
884     /* set empty values */
885     r = MsiSetProperty( hpkg, "boo", NULL );
886     ok( r == ERROR_SUCCESS, "wrong return val\n");
887     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
888
889     r = MsiSetProperty( hpkg, "boo", "" );
890     ok( r == ERROR_SUCCESS, "wrong return val\n");
891     ok( check_prop_empty( hpkg, "boo"), "prop wasn't empty\n");
892
893     /* set a non-empty value */
894     r = MsiSetProperty( hpkg, "boo", "xyz" );
895     ok( r == ERROR_SUCCESS, "wrong return val\n");
896
897     sz = 1;
898     strcpy(buffer,"x");
899     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
900     ok( r == ERROR_MORE_DATA, "wrong return val\n");
901     ok( buffer[0] == 0, "buffer was not changed\n");
902     ok( sz == 3, "wrong size returned\n");
903
904     sz = 4;
905     strcpy(buffer,"x");
906     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
907     ok( r == ERROR_SUCCESS, "wrong return val\n");
908     ok( !strcmp(buffer,"xyz"), "buffer was not changed\n");
909     ok( sz == 3, "wrong size returned\n");
910
911     sz = 3;
912     strcpy(buffer,"x");
913     r = MsiGetProperty( hpkg, "boo", buffer, &sz );
914     ok( r == ERROR_MORE_DATA, "wrong return val\n");
915     ok( !strcmp(buffer,"xy"), "buffer was not changed\n");
916     ok( sz == 3, "wrong size returned\n");
917
918     MsiCloseHandle( hpkg );
919     DeleteFile(msifile);
920 }
921
922 static UINT try_query_param( MSIHANDLE hdb, LPCSTR szQuery, MSIHANDLE hrec )
923 {
924     MSIHANDLE htab = 0;
925     UINT res;
926
927     res = MsiDatabaseOpenView( hdb, szQuery, &htab );
928     if( res == ERROR_SUCCESS )
929     {
930         UINT r;
931
932         r = MsiViewExecute( htab, hrec );
933         if( r != ERROR_SUCCESS )
934         {
935             res = r;
936             fprintf(stderr,"MsiViewExecute failed %08x\n", res);
937         }
938
939         r = MsiViewClose( htab );
940         if( r != ERROR_SUCCESS )
941             res = r;
942
943         r = MsiCloseHandle( htab );
944         if( r != ERROR_SUCCESS )
945             res = r;
946     }
947     return res;
948 }
949
950 static UINT try_query( MSIHANDLE hdb, LPCSTR szQuery )
951 {
952     return try_query_param( hdb, szQuery, 0 );
953 }
954
955 static void test_msipackage(void)
956 {
957     MSIHANDLE hdb = 0, hpack = 100;
958     UINT r;
959     const char *query;
960     char name[10];
961
962     DeleteFile(msifile);
963
964     todo_wine {
965     name[0] = 0;
966     r = MsiOpenPackage(name, &hpack);
967     ok(r == ERROR_SUCCESS, "failed to open package with no name\n");
968     r = MsiCloseHandle(hpack);
969     ok(r == ERROR_SUCCESS, "failed to close package\n");
970     }
971
972     /* just MsiOpenDatabase should not create a file */
973     r = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb);
974     ok(r == ERROR_SUCCESS, "MsiOpenDatabase failed\n");
975
976     name[0]='#';
977     name[1]=0;
978     r = MsiOpenPackage(name, &hpack);
979     ok(r == ERROR_INVALID_HANDLE, "MsiOpenPackage returned wrong code\n");
980
981     todo_wine {
982     /* now try again with our empty database */
983     sprintf(name, "#%ld", hdb);
984     r = MsiOpenPackage(name, &hpack);
985     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
986     if (!r)    MsiCloseHandle(hpack);
987     }
988
989     /* create a table */
990     query = "CREATE TABLE `Property` ( "
991             "`Property` CHAR(72), `Value` CHAR(0) "
992             "PRIMARY KEY `Property`)";
993     r = try_query(hdb, query);
994     ok(r == ERROR_SUCCESS, "failed to create Properties table\n");
995
996     todo_wine {
997     query = "CREATE TABLE `InstallExecuteSequence` ("
998             "`Action` CHAR(72), `Condition` CHAR(0), `Sequence` INTEGER "
999             "PRIMARY KEY `Action`)";
1000     r = try_query(hdb, query);
1001     ok(r == ERROR_SUCCESS, "failed to create InstallExecuteSequence table\n");
1002
1003     sprintf(name, "#%ld", hdb);
1004     r = MsiOpenPackage(name, &hpack);
1005     ok(r == ERROR_INSTALL_PACKAGE_INVALID, "MsiOpenPackage returned wrong code\n");
1006     if (!r)    MsiCloseHandle(hpack);
1007     }
1008
1009     r = MsiCloseHandle(hdb);
1010     ok(r == ERROR_SUCCESS, "MsiCloseHandle(database) failed\n");
1011     DeleteFile(msifile);
1012 }
1013
1014 static void test_formatrecord2(void)
1015 {
1016     MSIHANDLE hpkg, hrec ;
1017     char buffer[0x100];
1018     DWORD sz;
1019     UINT r;
1020
1021     hpkg = package_from_db(create_package_db());
1022     ok( hpkg, "failed to create package\n");
1023
1024     r = MsiSetProperty(hpkg, "Manufacturer", " " );
1025     ok( r == ERROR_SUCCESS, "set property failed\n");
1026
1027     hrec = MsiCreateRecord(2);
1028     ok(hrec, "create record failed\n");
1029
1030     r = MsiRecordSetString( hrec, 0, "[ProgramFilesFolder][Manufacturer]\\asdf");
1031     ok( r == ERROR_SUCCESS, "format record failed\n");
1032
1033     buffer[0] = 0;
1034     sz = sizeof buffer;
1035     r = MsiFormatRecord( hpkg, hrec, buffer, &sz );
1036
1037     r = MsiRecordSetString(hrec, 0, "[foo][1]");
1038     r = MsiRecordSetString(hrec, 1, "hoo");
1039     sz = sizeof buffer;
1040     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1041     ok( sz == 3, "size wrong\n");
1042     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1043     ok( r == ERROR_SUCCESS, "format failed\n");
1044
1045     r = MsiRecordSetString(hrec, 0, "x[~]x");
1046     sz = sizeof buffer;
1047     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1048     ok( sz == 3, "size wrong\n");
1049     ok( 0 == strcmp(buffer,"x"), "wrong output %s\n",buffer);
1050     ok( r == ERROR_SUCCESS, "format failed\n");
1051
1052     r = MsiRecordSetString(hrec, 0, "[foo.$%}][1]");
1053     r = MsiRecordSetString(hrec, 1, "hoo");
1054     sz = sizeof buffer;
1055     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1056     ok( sz == 3, "size wrong\n");
1057     ok( 0 == strcmp(buffer,"hoo"), "wrong output %s\n",buffer);
1058     ok( r == ERROR_SUCCESS, "format failed\n");
1059
1060     r = MsiRecordSetString(hrec, 0, "[\\[]");
1061     sz = sizeof buffer;
1062     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1063     ok( sz == 1, "size wrong\n");
1064     ok( 0 == strcmp(buffer,"["), "wrong output %s\n",buffer);
1065     ok( r == ERROR_SUCCESS, "format failed\n");
1066
1067     SetEnvironmentVariable("FOO", "BAR");
1068     r = MsiRecordSetString(hrec, 0, "[%FOO]");
1069     sz = sizeof buffer;
1070     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1071     ok( sz == 3, "size wrong\n");
1072     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1073     ok( r == ERROR_SUCCESS, "format failed\n");
1074
1075     r = MsiRecordSetString(hrec, 0, "[[1]]");
1076     r = MsiRecordSetString(hrec, 1, "%FOO");
1077     sz = sizeof buffer;
1078     r = MsiFormatRecord(hpkg, hrec, buffer, &sz);
1079     ok( sz == 3, "size wrong\n");
1080     ok( 0 == strcmp(buffer,"BAR"), "wrong output %s\n",buffer);
1081     ok( r == ERROR_SUCCESS, "format failed\n");
1082
1083     MsiCloseHandle( hrec );
1084     MsiCloseHandle( hpkg );
1085     DeleteFile(msifile);
1086 }
1087
1088 START_TEST(package)
1089 {
1090     test_createpackage();
1091     test_getsourcepath_bad();
1092     test_getsourcepath();
1093     test_doaction();
1094     test_gettargetpath_bad();
1095     test_settargetpath();
1096     test_props();
1097     test_condition();
1098     test_msipackage();
1099     test_formatrecord2();
1100 }