https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b7b9c0c4cb69ef3b40047…
commit b7b9c0c4cb69ef3b4004793bdf2291b61acb918e
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sat Mar 12 16:34:12 2022 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:27:56 2022 +0100
[WINESYNC] msi: Report error when cached installer has different version.
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
wine commit id 0657d966ffb9afdcd7cf8bd0c2ac7289a8bfbe5e by Piotr Caban
<piotr(a)codeweavers.com>
---
dll/win32/msi/package.c | 114 ++++++++++++++++---------------
modules/rostests/winetests/msi/package.c | 6 +-
2 files changed, 63 insertions(+), 57 deletions(-)
diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c
index 9e1e2be4a28..0846ad76f84 100644
--- a/dll/win32/msi/package.c
+++ b/dll/win32/msi/package.c
@@ -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,20 +1482,31 @@ 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)
{
DWORD localfile_attr;
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;
@@ -1528,10 +1516,28 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
if (localfile_attr & FILE_ATTRIBUTE_READONLY)
SetFileAttributesW( localfile, localfile_attr &
~FILE_ATTRIBUTE_READONLY);
}
+ 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 );
diff --git a/modules/rostests/winetests/msi/package.c
b/modules/rostests/winetests/msi/package.c
index 52a4bfd2f75..b1c7a76783f 100644
--- a/modules/rostests/winetests/msi/package.c
+++ b/modules/rostests/winetests/msi/package.c
@@ -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 */