@@ -751,6 +751,22 @@ static UINT create_actiontext_table( MSIHANDLE hdb )
751751 return r ;
752752}
753753
754+ static UINT create_upgrade_table ( MSIHANDLE hdb )
755+ {
756+ UINT r = run_query ( hdb ,
757+ "CREATE TABLE `Upgrade` ("
758+ "`UpgradeCode` CHAR(38) NOT NULL, "
759+ "`VersionMin` CHAR(20), "
760+ "`VersionMax` CHAR(20), "
761+ "`Language` CHAR(255), "
762+ "`Attributes` SHORT, "
763+ "`Remove` CHAR(255), "
764+ "`ActionProperty` CHAR(72) NOT NULL "
765+ "PRIMARY KEY `UpgradeCode`, `VersionMin`, `VersionMax`, `Language`)" );
766+ ok (r == ERROR_SUCCESS , "Failed to create Upgrade table: %u\n" , r );
767+ return r ;
768+ }
769+
754770static inline UINT add_entry (const char * file , int line , const char * type , MSIHANDLE hdb , const char * values , const char * insert )
755771{
756772 char * query ;
@@ -805,6 +821,12 @@ static inline UINT add_entry(const char *file, int line, const char *type, MSIHA
805821#define add_property_entry (hdb , values ) add_entry(__FILE__, __LINE__, "Property", hdb, values, \
806822 "INSERT INTO `Property` (`Property`, `Value`) VALUES( %s )")
807823
824+ #define update_ProductVersion_property (hdb , value ) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
825+ "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductVersion'")
826+
827+ #define update_ProductCode_property (hdb , value ) add_entry(__FILE__, __LINE__, "Property", hdb, value, \
828+ "UPDATE `Property` SET `Value` = '%s' WHERE `Property` = 'ProductCode'")
829+
808830#define add_install_execute_sequence_entry (hdb , values ) add_entry(__FILE__, __LINE__, "InstallExecuteSequence", hdb, values, \
809831 "INSERT INTO `InstallExecuteSequence` " \
810832 "(`Action`, `Condition`, `Sequence`) VALUES( %s )")
@@ -854,6 +876,10 @@ static inline UINT add_entry(const char *file, int line, const char *type, MSIHA
854876 "INSERT INTO `ActionText` " \
855877 "(`Action`, `Description`, `Template`) VALUES( %s )");
856878
879+ #define add_upgrade_entry (hdb , values ) add_entry(__FILE__, __LINE__, "Upgrade", hdb, values, \
880+ "INSERT INTO `Upgrade` " \
881+ "(`UpgradeCode`, `VersionMin`, `VersionMax`, `Language`, `Attributes`, `Remove`, `ActionProperty`) VALUES( %s )");
882+
857883static UINT add_reglocator_entry ( MSIHANDLE hdb , const char * sig , UINT root , const char * path ,
858884 const char * name , UINT type )
859885{
@@ -3072,10 +3098,12 @@ static void test_states(void)
30723098 char msi_cache_file [MAX_PATH ];
30733099 DWORD cache_file_name_len ;
30743100 INSTALLSTATE state ;
3075- MSIHANDLE hpkg ;
3101+ MSIHANDLE hpkg , hprod ;
30763102 UINT r ;
30773103 MSIHANDLE hdb ;
30783104 BOOL is_broken ;
3105+ char value [MAX_PATH ];
3106+ DWORD size ;
30793107
30803108 if (is_process_limited ())
30813109 {
@@ -3094,6 +3122,7 @@ static void test_states(void)
30943122 add_property_entry ( hdb , "'ProductName', 'MSITEST'" );
30953123 add_property_entry ( hdb , "'ProductVersion', '1.1.1'" );
30963124 add_property_entry ( hdb , "'MSIFASTINSTALL', '1'" );
3125+ add_property_entry ( hdb , "'UpgradeCode', '{3494EEEA-4221-4A66-802E-DED8916BC5C5}'" );
30973126
30983127 create_install_execute_sequence_table ( hdb );
30993128 add_install_execute_sequence_entry ( hdb , "'CostInitialize', '', '800'" );
@@ -3779,8 +3808,53 @@ static void test_states(void)
37793808 state = MsiQueryFeatureStateA ("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}" , "three" );
37803809 ok (state == INSTALLSTATE_LOCAL , "state = %d\n" , state );
37813810
3811+ /* minor upgrade test with no REINSTALL argument */
3812+ r = MsiOpenProductA ("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}" , & hprod );
3813+ ok (r == ERROR_SUCCESS , "Expected ERROR_SUCCESS, got %d\n" , r );
3814+ size = MAX_PATH ;
3815+ r = MsiGetProductPropertyA (hprod , "ProductVersion" , value , & size );
3816+ ok (r == ERROR_SUCCESS , "Expected ERROR_SUCCESS, got %d\n" , r );
3817+ ok (!strcmp (value , "1.1.1" ), "ProductVersion = %s\n" , value );
3818+ MsiCloseHandle (hprod );
3819+
3820+ r = MsiOpenDatabaseA (msifile2 , (const char * )MSIDBOPEN_DIRECT , & hdb );
3821+ ok (r == ERROR_SUCCESS , "failed to open database: %d\n" , r );
3822+ add_install_execute_sequence_entry ( hdb , "'FindRelatedProducts', '', '100'" );
3823+ add_install_execute_sequence_entry ( hdb , "'RemoveExistingProducts', '', '1401'" );
3824+ create_upgrade_table ( hdb );
3825+ add_upgrade_entry ( hdb , "'{3494EEEA-4221-4A66-802E-DED8916BC5C5}', NULL, '1.1.2', NULL, 0, NULL, 'OLDERVERSIONBEINGUPGRADED'" );
3826+ update_ProductVersion_property ( hdb , "1.1.2" );
3827+ set_summary_str (hdb , PID_REVNUMBER , "{A219A62A-D931-4F1B-89DB-FF1C300A8D43}" );
3828+ r = MsiDatabaseCommit (hdb );
3829+ ok (r == ERROR_SUCCESS , "MsiDatabaseCommit failed: %d\n" , r );
3830+ MsiCloseHandle (hdb );
3831+
3832+ r = MsiInstallProductA (msifile2 , "" );
3833+ todo_wine ok (r == ERROR_PRODUCT_VERSION , "Expected ERROR_PRODUCT_VERSION, got %d\n" , r );
3834+
3835+ /* major upgrade test */
3836+ r = MsiOpenDatabaseA (msifile2 , (const char * )MSIDBOPEN_DIRECT , & hdb );
3837+ ok (r == ERROR_SUCCESS , "failed to open database: %d\n" , r );
3838+ update_ProductCode_property ( hdb , "{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" );
3839+ r = MsiDatabaseCommit (hdb );
3840+ ok (r == ERROR_SUCCESS , "MsiDatabaseCommit failed: %d\n" , r );
3841+ MsiCloseHandle (hdb );
3842+
3843+ r = MsiInstallProductA (msifile2 , "" );
3844+ ok (r == S_OK , "Expected ERROR_PRODUCT_VERSION, got %d\n" , r );
3845+
3846+ r = MsiOpenProductA ("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}" , & hprod );
3847+ ok (r == ERROR_UNKNOWN_PRODUCT , "Expected ERROR_UNKNOWN_PRODUCT, got %d\n" , r );
3848+ r = MsiOpenProductA ("{333DB27A-C25E-4EBC-9BEC-0F49546C19A6}" , & hprod );
3849+ ok (r == ERROR_SUCCESS , "Expected ERROR_SUCCESS, got %d\n" , r );
3850+ size = MAX_PATH ;
3851+ r = MsiGetProductPropertyA (hprod , "ProductVersion" , value , & size );
3852+ ok (r == ERROR_SUCCESS , "Expected ERROR_SUCCESS, got %d\n" , r );
3853+ ok (!strcmp (value , "1.1.2" ), "ProductVersion = %s\n" , value );
3854+ MsiCloseHandle (hprod );
3855+
37823856 /* uninstall the product */
3783- r = MsiInstallProductA (msifile4 , "REMOVE=ALL" );
3857+ r = MsiInstallProductA (msifile2 , "REMOVE=ALL" );
37843858 ok (r == ERROR_SUCCESS , "Expected ERROR_SUCCESS, got %d\n" , r );
37853859
37863860 DeleteFileA (msifile );
0 commit comments