https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a237138534221e4e07465…
commit a237138534221e4e074657207110244d152b8f8f
Author: winesync <ros-dev(a)reactos.org>
AuthorDate: Sat Mar 12 16:57:00 2022 +0100
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Sun Mar 20 19:27:56 2022 +0100
[WINESYNC] msi: Add support for re-caching package.
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 5924321ad63edc1d3fabf22d7b047e4efacbce66 by Piotr Caban
<piotr(a)codeweavers.com>
---
dll/win32/msi/action.c | 42 +++++++++++++++++++++++++++++---
dll/win32/msi/msi.c | 27 +++++++++++++++-----
dll/win32/msi/msipriv.h | 4 ++-
dll/win32/msi/package.c | 14 +++++++++--
modules/rostests/winetests/msi/package.c | 6 ++---
5 files changed, 77 insertions(+), 16 deletions(-)
diff --git a/dll/win32/msi/action.c b/dll/win32/msi/action.c
index c33326af387..bfecf68f5cc 100644
--- a/dll/win32/msi/action.c
+++ b/dll/win32/msi/action.c
@@ -301,15 +301,18 @@ static int parse_prop( const WCHAR *str, WCHAR *value, int *quotes
)
default: break;
}
- if (!ignore) *out++ = *p;
+ if (!ignore && value) *out++ = *p;
if (!count) in_quotes = FALSE;
}
done:
- if (!len) *value = 0;
- else *out = 0;
+ if (value)
+ {
+ if (!len) *value = 0;
+ else *out = 0;
+ }
- *quotes = count;
+ if(quotes) *quotes = count;
return p - str;
}
@@ -385,6 +388,37 @@ UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR
szCommandLine,
return ERROR_SUCCESS;
}
+const WCHAR *msi_get_command_line_option(const WCHAR *cmd, const WCHAR *option, UINT
*len)
+{
+ DWORD opt_len = strlenW(option);
+
+ if (!cmd)
+ return NULL;
+
+ while (*cmd)
+ {
+ BOOL found = FALSE;
+
+ while (*cmd == ' ') cmd++;
+ if (!*cmd) break;
+
+ if(!strncmpiW(cmd, option, opt_len))
+ found = TRUE;
+
+ cmd = strchrW( cmd, '=' );
+ if(!cmd) break;
+ cmd++;
+ while (*cmd == ' ') cmd++;
+ if (!*cmd) break;
+
+ *len = parse_prop( cmd, NULL, NULL);
+ if (found) return cmd;
+ cmd += *len;
+ }
+
+ return NULL;
+}
+
WCHAR **msi_split_string( const WCHAR *str, WCHAR sep )
{
LPCWSTR pc;
diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c
index 734246930ce..1043452388c 100644
--- a/dll/win32/msi/msi.c
+++ b/dll/win32/msi/msi.c
@@ -137,7 +137,7 @@ static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
goto done;
}
- r = MSI_OpenPackageW(path, package);
+ r = MSI_OpenPackageW(path, 0, package);
done:
RegCloseKey(props);
@@ -236,7 +236,9 @@ end:
UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
{
MSIPACKAGE *package = NULL;
- UINT r;
+ const WCHAR *reinstallmode;
+ DWORD options = 0;
+ UINT r, len;
TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
@@ -246,7 +248,20 @@ UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR
szCommandLine)
if (!*szPackagePath)
return ERROR_PATH_NOT_FOUND;
- r = MSI_OpenPackageW( szPackagePath, &package );
+ reinstallmode = msi_get_command_line_option(szCommandLine, szReinstallMode,
&len);
+ if (reinstallmode)
+ {
+ while (len > 0)
+ {
+ if (reinstallmode[--len] == 'v' || reinstallmode[len] ==
'V')
+ {
+ options |= WINE_OPENPACKAGEFLAGS_RECACHE;
+ break;
+ }
+ }
+ }
+
+ r = MSI_OpenPackageW( szPackagePath, options, &package );
if (r == ERROR_SUCCESS)
{
r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
@@ -732,7 +747,7 @@ UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR
szProductPackagePath,
TRACE("%s, %u, %p\n", debugstr_w(szProductPackagePath), cPatchInfo,
pPatchInfo);
- r = MSI_OpenPackageW( szProductPackagePath, &package );
+ r = MSI_OpenPackageW( szProductPackagePath, 0, &package );
if (r != ERROR_SUCCESS)
{
ERR("failed to open package %u\n", r);
@@ -810,7 +825,7 @@ static UINT open_package( const WCHAR *product, const WCHAR *usersid,
if (GetFileAttributesW( sourcepath ) == INVALID_FILE_ATTRIBUTES)
return ERROR_INSTALL_SOURCE_ABSENT;
- return MSI_OpenPackageW( sourcepath, package );
+ return MSI_OpenPackageW( sourcepath, 0, package );
}
UINT WINAPI MsiDeterminePatchSequenceW( LPCWSTR product, LPCWSTR usersid,
@@ -4027,7 +4042,7 @@ UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR
szFeature, DWORD dw
strcatW( sourcepath, filename );
if (dwReinstallMode & REINSTALLMODE_PACKAGE)
- r = MSI_OpenPackageW( sourcepath, &package );
+ r = MSI_OpenPackageW( sourcepath, 0, &package );
else
r = MSI_OpenProductW( szProduct, &package );
diff --git a/dll/win32/msi/msipriv.h b/dll/win32/msi/msipriv.h
index 845b32b5d8a..3519d83f1c6 100644
--- a/dll/win32/msi/msipriv.h
+++ b/dll/win32/msi/msipriv.h
@@ -799,6 +799,7 @@ extern UINT ACTION_ForceReboot(MSIPACKAGE *package) DECLSPEC_HIDDEN;
extern UINT MSI_Sequence( MSIPACKAGE *package, LPCWSTR szTable ) DECLSPEC_HIDDEN;
extern UINT MSI_SetFeatureStates( MSIPACKAGE *package ) DECLSPEC_HIDDEN;
extern UINT msi_parse_command_line( MSIPACKAGE *package, LPCWSTR szCommandLine, BOOL
preserve_case ) DECLSPEC_HIDDEN;
+extern const WCHAR *msi_get_command_line_option( const WCHAR *cmd, const WCHAR *option,
UINT *len ) DECLSPEC_HIDDEN;
extern UINT msi_schedule_action( MSIPACKAGE *package, UINT script, const WCHAR *action )
DECLSPEC_HIDDEN;
extern INSTALLSTATE msi_get_component_action( MSIPACKAGE *package, MSICOMPONENT *comp )
DECLSPEC_HIDDEN;
extern INSTALLSTATE msi_get_feature_action( MSIPACKAGE *package, MSIFEATURE *feature )
DECLSPEC_HIDDEN;
@@ -863,8 +864,9 @@ extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD
**) DECLS
extern UINT MSI_SetInstallLevel( MSIPACKAGE *package, int iInstallLevel )
DECLSPEC_HIDDEN;
/* package internals */
+#define WINE_OPENPACKAGEFLAGS_RECACHE 0x80000000
extern MSIPACKAGE *MSI_CreatePackage( MSIDATABASE * ) DECLSPEC_HIDDEN;
-extern UINT MSI_OpenPackageW( LPCWSTR szPackage, MSIPACKAGE **pPackage )
DECLSPEC_HIDDEN;
+extern UINT MSI_OpenPackageW( LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage )
DECLSPEC_HIDDEN;
extern UINT MSI_SetTargetPathW( MSIPACKAGE *, LPCWSTR, LPCWSTR ) DECLSPEC_HIDDEN;
extern INT MSI_ProcessMessageVerbatim( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * )
DECLSPEC_HIDDEN;
extern INT MSI_ProcessMessage( MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD * )
DECLSPEC_HIDDEN;
diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c
index 0846ad76f84..6b3f46353a3 100644
--- a/dll/win32/msi/package.c
+++ b/dll/win32/msi/package.c
@@ -1433,7 +1433,7 @@ UINT msi_set_original_database_property( MSIDATABASE *db, const
WCHAR *package )
return r;
}
-UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
+UINT MSI_OpenPackageW(LPCWSTR szPackage, DWORD dwOptions, MSIPACKAGE **pPackage)
{
static const WCHAR dotmsi[] = {'.','m','s','i',0};
MSIDATABASE *db;
@@ -1516,6 +1516,16 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
if (localfile_attr & FILE_ATTRIBUTE_READONLY)
SetFileAttributesW( localfile, localfile_attr &
~FILE_ATTRIBUTE_READONLY);
}
+ else if (dwOptions & WINE_OPENPACKAGEFLAGS_RECACHE)
+ {
+ if (!CopyFileW( file, localfile, FALSE ))
+ {
+ r = GetLastError();
+ WARN("unable to update cached package (%u)\n", r);
+ msiobj_release( &db->hdr );
+ return r;
+ }
+ }
else
product_version = get_product_version( db );
msiobj_release( &db->hdr );
@@ -1669,7 +1679,7 @@ UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions,
MSIHANDLE *phP
if( dwOptions )
FIXME("dwOptions %08x not supported\n", dwOptions);
- ret = MSI_OpenPackageW( szPackage, &package );
+ ret = MSI_OpenPackageW( szPackage, 0, &package );
if( ret == ERROR_SUCCESS )
{
*phPackage = alloc_msihandle( &package->hdr );
diff --git a/modules/rostests/winetests/msi/package.c
b/modules/rostests/winetests/msi/package.c
index b1c7a76783f..ace9b354f91 100644
--- a/modules/rostests/winetests/msi/package.c
+++ b/modules/rostests/winetests/msi/package.c
@@ -3840,15 +3840,15 @@ static void test_states(void)
r = MsiInstallProductA(msifile2, "");
ok(r == ERROR_PRODUCT_VERSION, "Expected ERROR_PRODUCT_VERSION, got %d\n",
r);
- r = MsiInstallProductA(msifile2, "REINSTALLMODE=v");
- todo_wine ok(r == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", r);
+ r = MsiInstallProductA(msifile2, "REINSTALLMODe=V");
+ 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);
- todo_wine ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n",
value);
+ ok(!strcmp(value, "1.1.2"), "ProductVersion = %s\n", value);
MsiCloseHandle(hprod);
/* major upgrade test */