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>
This commit is contained in:
parent
0657d966ff
commit
5924321ad6
|
@ -294,15 +294,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;
|
||||
}
|
||||
|
||||
|
@ -378,6 +381,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;
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -1509,6 +1509,16 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
|
|||
}
|
||||
delete_on_close = TRUE;
|
||||
}
|
||||
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 );
|
||||
|
@ -1662,7 +1672,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 );
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue