msi: Report error when cached installer has different version.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2018-06-21 21:48:50 +02:00 committed by Alexandre Julliard
parent 9ef8fa2a0b
commit 0657d966ff
2 changed files with 63 additions and 57 deletions

View File

@ -1310,17 +1310,19 @@ static UINT validate_package( MSIPACKAGE *package )
return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
}
static WCHAR *get_product_code( MSIDATABASE *db )
static WCHAR *get_property( MSIDATABASE *db, const WCHAR *prop )
{
static const WCHAR query[] = {
static const WCHAR select_query[] = {
'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
'F','R','O','M',' ','`','P','r','o','p','e','r','t','y','`',' ',
'W','H','E','R','E',' ','`','P','r','o','p','e','r','t','y','`','=',
'\'','P','r','o','d','u','c','t','C','o','d','e','\'',0};
'\'','%','s','\'',0};
WCHAR query[MAX_PATH];
MSIQUERY *view;
MSIRECORD *rec;
WCHAR *ret = NULL;
sprintfW(query, select_query, prop);
if (MSI_DatabaseOpenViewW( db, query, &view ) != ERROR_SUCCESS)
{
return NULL;
@ -1341,48 +1343,39 @@ static WCHAR *get_product_code( MSIDATABASE *db )
return ret;
}
static UINT get_registered_local_package( const WCHAR *product, const WCHAR *package, WCHAR *localfile )
static WCHAR *get_product_code( MSIDATABASE *db )
{
return get_property( db, szProductCode );
}
static WCHAR *get_product_version( MSIDATABASE *db )
{
return get_property( db, szProductVersion );
}
static UINT get_registered_local_package( const WCHAR *product, WCHAR *localfile )
{
MSIINSTALLCONTEXT context;
HKEY product_key, props_key;
WCHAR *registered_package = NULL, unsquashed[GUID_SIZE];
WCHAR *filename;
HKEY props_key;
UINT r;
r = msi_locate_product( product, &context );
if (r != ERROR_SUCCESS)
return r;
r = MSIREG_OpenProductKey( product, NULL, context, &product_key, FALSE );
if (r != ERROR_SUCCESS)
return r;
r = MSIREG_OpenInstallProps( product, context, NULL, &props_key, FALSE );
if (r != ERROR_SUCCESS)
{
RegCloseKey( product_key );
return r;
}
r = ERROR_FUNCTION_FAILED;
registered_package = msi_reg_get_val_str( product_key, INSTALLPROPERTY_PACKAGECODEW );
if (!registered_package)
goto done;
unsquash_guid( registered_package, unsquashed );
if (!strcmpiW( package, unsquashed ))
{
WCHAR *filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW );
if (!filename)
goto done;
strcpyW( localfile, filename );
msi_free( filename );
r = ERROR_SUCCESS;
}
done:
msi_free( registered_package );
filename = msi_reg_get_val_str( props_key, INSTALLPROPERTY_LOCALPACKAGEW );
RegCloseKey( props_key );
RegCloseKey( product_key );
return r;
if (!filename)
return ERROR_FUNCTION_FAILED;
strcpyW( localfile, filename );
msi_free( filename );
return ERROR_SUCCESS;
}
WCHAR *msi_get_package_code( MSIDATABASE *db )
@ -1406,33 +1399,15 @@ WCHAR *msi_get_package_code( MSIDATABASE *db )
return ret;
}
static UINT get_local_package( const WCHAR *filename, WCHAR *localfile )
static UINT get_local_package( MSIDATABASE *db, WCHAR *localfile )
{
WCHAR *product_code, *package_code;
MSIDATABASE *db;
WCHAR *product_code;
UINT r;
if ((r = MSI_OpenDatabaseW( filename, MSIDBOPEN_READONLY, &db )) != ERROR_SUCCESS)
{
if (GetFileAttributesW( filename ) == INVALID_FILE_ATTRIBUTES)
return ERROR_FILE_NOT_FOUND;
return r;
}
if (!(product_code = get_product_code( db )))
{
msiobj_release( &db->hdr );
return ERROR_INSTALL_PACKAGE_INVALID;
}
if (!(package_code = msi_get_package_code( db )))
{
msi_free( product_code );
msiobj_release( &db->hdr );
return ERROR_INSTALL_PACKAGE_INVALID;
}
r = get_registered_local_package( product_code, package_code, localfile );
msi_free( package_code );
r = get_registered_local_package( product_code, localfile );
msi_free( product_code );
msiobj_release( &db->hdr );
return r;
}
@ -1497,6 +1472,8 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
}
else
{
WCHAR *product_version = NULL;
if ( UrlIsW( szPackage, URLIS_URL ) )
{
r = msi_download_file( szPackage, cachefile );
@ -1505,26 +1482,55 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
file = cachefile;
}
r = get_local_package( file, localfile );
r = MSI_OpenDatabaseW( file, MSIDBOPEN_READONLY, &db );
if (r != ERROR_SUCCESS)
{
if (GetFileAttributesW( file ) == INVALID_FILE_ATTRIBUTES)
return ERROR_FILE_NOT_FOUND;
return r;
}
r = get_local_package( db, localfile );
if (r != ERROR_SUCCESS || GetFileAttributesW( localfile ) == INVALID_FILE_ATTRIBUTES)
{
r = msi_create_empty_local_file( localfile, dotmsi );
if (r != ERROR_SUCCESS)
{
msiobj_release( &db->hdr );
return r;
}
if (!CopyFileW( file, localfile, FALSE ))
{
r = GetLastError();
WARN("unable to copy package %s to %s (%u)\n", debugstr_w(file), debugstr_w(localfile), r);
DeleteFileW( localfile );
msiobj_release( &db->hdr );
return r;
}
delete_on_close = TRUE;
}
else
product_version = get_product_version( db );
msiobj_release( &db->hdr );
TRACE("opening package %s\n", debugstr_w( localfile ));
r = MSI_OpenDatabaseW( localfile, MSIDBOPEN_TRANSACT, &db );
if (r != ERROR_SUCCESS)
return r;
if (product_version)
{
WCHAR *cache_version = get_product_version( db );
if (!product_version != !cache_version ||
(product_version && strcmpW(product_version, cache_version)))
{
msiobj_release( &db->hdr );
msi_free(product_version);
msi_free(cache_version);
return ERROR_PRODUCT_VERSION;
}
msi_free(product_version);
msi_free(cache_version);
}
}
package = MSI_CreatePackage( db );
msiobj_release( &db->hdr );

View File

@ -3838,17 +3838,17 @@ static void test_states(void)
MsiCloseHandle(hdb);
r = MsiInstallProductA(msifile2, "");
todo_wine ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n", r);
r = MsiInstallProductA(msifile2, "REINSTALLMODE=v");
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
r = MsiOpenProductA("{7262AC98-EEBD-4364-8CE3-D654F6A425B9}", &hprod);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
size = MAX_PATH;
r = MsiGetProductPropertyA(hprod, "ProductVersion", value, &size);
ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
todo_wine ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
MsiCloseHandle(hprod);
/* major upgrade test */