https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a237138534221e4e074657...
commit a237138534221e4e074657207110244d152b8f8f Author: winesync ros-dev@reactos.org AuthorDate: Sat Mar 12 16:57:00 2022 +0100 Commit: Mark Jansen mark.jansen@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@codeweavers.com Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
wine commit id 5924321ad63edc1d3fabf22d7b047e4efacbce66 by Piotr Caban piotr@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 */