Commit 82d7b04c authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

msi: Apply registered patches in MsiOpenPackage.

parent 881ef984
...@@ -492,7 +492,7 @@ done: ...@@ -492,7 +492,7 @@ done:
return r; return r;
} }
static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
{ {
MSIPATCHINFO *pi; MSIPATCHINFO *pi;
UINT r = ERROR_SUCCESS; UINT r = ERROR_SUCCESS;
...@@ -520,15 +520,40 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch ) ...@@ -520,15 +520,40 @@ static UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch )
return r; return r;
} }
UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch )
{
UINT i, r = ERROR_SUCCESS;
WCHAR **substorage;
/* apply substorage transforms */
substorage = msi_split_string( patch->transforms, ';' );
for (i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++)
r = msi_apply_substorage_transform( package, patch_db, substorage[i] );
msi_free( substorage );
if (r != ERROR_SUCCESS)
return r;
msi_set_media_source_prop( package );
/*
* There might be a CAB file in the patch package,
* so append it to the list of storages to search for streams.
*/
append_storage_to_db( package->db, patch_db->storage );
list_add_tail( &package->patches, &patch->entry );
return ERROR_SUCCESS;
}
static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file ) static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
{ {
static const WCHAR dotmsp[] = {'.','m','s','p',0}; static const WCHAR dotmsp[] = {'.','m','s','p',0};
MSIDATABASE *patch_db = NULL; MSIDATABASE *patch_db = NULL;
WCHAR localfile[MAX_PATH]; WCHAR localfile[MAX_PATH];
LPWSTR *substorage;
MSISUMMARYINFO *si; MSISUMMARYINFO *si;
MSIPATCHINFO *patch = NULL; MSIPATCHINFO *patch = NULL;
UINT i, r = ERROR_SUCCESS; UINT r = ERROR_SUCCESS;
TRACE("%p %s\n", package, debugstr_w( file ) ); TRACE("%p %s\n", package, debugstr_w( file ) );
...@@ -573,23 +598,9 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file ) ...@@ -573,23 +598,9 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, LPCWSTR file )
} }
patch->localfile = strdupW( localfile ); patch->localfile = strdupW( localfile );
/* apply substorage transforms */ r = msi_apply_patch_db( package, patch_db, patch );
substorage = msi_split_string( patch->transforms, ';' ); if ( r != ERROR_SUCCESS )
for ( i = 0; substorage && substorage[i] && r == ERROR_SUCCESS; i++ ) WARN("patch failed to apply %u\n", r);
r = msi_apply_substorage_transform( package, patch_db, substorage[i] );
msi_free( substorage );
if (r != ERROR_SUCCESS)
goto done;
msi_set_media_source_prop( package );
/*
* There might be a CAB file in the patch package,
* so append it to the list of storages to search for streams.
*/
append_storage_to_db( package->db, patch_db->storage );
list_add_tail( &package->patches, &patch->entry );
done: done:
msiobj_release( &si->hdr ); msiobj_release( &si->hdr );
...@@ -729,7 +740,7 @@ static BOOL needs_ui_sequence(MSIPACKAGE *package) ...@@ -729,7 +740,7 @@ static BOOL needs_ui_sequence(MSIPACKAGE *package)
return (level & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED; return (level & INSTALLUILEVEL_MASK) >= INSTALLUILEVEL_REDUCED;
} }
static UINT msi_set_context(MSIPACKAGE *package) UINT msi_set_context(MSIPACKAGE *package)
{ {
int num; int num;
......
...@@ -685,7 +685,10 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db, ...@@ -685,7 +685,10 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
LPCWSTR szTransformFile, int iErrorCond ); LPCWSTR szTransformFile, int iErrorCond );
extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg ); extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg );
/* patch functions */
extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si ); extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si );
extern UINT msi_parse_patch_summary( MSISUMMARYINFO *si, MSIPATCHINFO **patch );
extern UINT msi_apply_patch_db( MSIPACKAGE *package, MSIDATABASE *patch_db, MSIPATCHINFO *patch );
/* action internals */ /* action internals */
extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR ); extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
...@@ -758,6 +761,7 @@ extern UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename ); ...@@ -758,6 +761,7 @@ extern UINT msi_download_file( LPCWSTR szUrl, LPWSTR filename );
extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR); extern UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR);
extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR); extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR);
extern UINT msi_clone_properties(MSIPACKAGE *); extern UINT msi_clone_properties(MSIPACKAGE *);
extern UINT msi_set_context(MSIPACKAGE *);
extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT); extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE, LPINT);
/* for deformating */ /* for deformating */
......
...@@ -1048,6 +1048,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url ) ...@@ -1048,6 +1048,8 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
msi_clone_properties( package ); msi_clone_properties( package );
package->ProductCode = msi_dup_property( package->db, szProductCode ); package->ProductCode = msi_dup_property( package->db, szProductCode );
package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
set_installed_prop( package ); set_installed_prop( package );
set_installer_properties( package ); set_installer_properties( package );
...@@ -1167,6 +1169,60 @@ UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix ) ...@@ -1167,6 +1169,60 @@ UINT msi_get_local_package_name( LPWSTR path, LPCWSTR suffix )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
static UINT apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code )
{
UINT r;
DWORD len;
WCHAR patch_file[MAX_PATH];
MSIDATABASE *patch_db;
MSIPATCHINFO *patch_info;
MSISUMMARYINFO *si;
len = sizeof(patch_file) / sizeof(WCHAR);
r = MsiGetPatchInfoExW( patch_code, package->ProductCode, NULL, package->Context,
INSTALLPROPERTY_LOCALPACKAGEW, patch_file, &len );
if (r != ERROR_SUCCESS)
{
ERR("failed to get patch filename %u\n", r);
return r;
}
r = MSI_OpenDatabaseW( patch_file, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &patch_db );
if (r != ERROR_SUCCESS)
{
ERR("failed to open patch database %s\n", debugstr_w( patch_file ));
return r;
}
si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
if (!si)
{
msiobj_release( &patch_db->hdr );
return ERROR_FUNCTION_FAILED;
}
r = msi_parse_patch_summary( si, &patch_info );
msiobj_release( &si->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to parse patch summary %u\n", r);
msiobj_release( &patch_db->hdr );
return r;
}
r = msi_apply_patch_db( package, patch_db, patch_info );
msiobj_release( &patch_db->hdr );
if (r != ERROR_SUCCESS)
{
ERR("failed to apply patch %u\n", r);
msi_free( patch_info->patchcode );
msi_free( patch_info->transforms );
msi_free( patch_info->localfile );
msi_free( patch_info );
}
return r;
}
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{ {
static const WCHAR OriginalDatabase[] = static const WCHAR OriginalDatabase[] =
...@@ -1180,6 +1236,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) ...@@ -1180,6 +1236,7 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
UINT r; UINT r;
WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH]; WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH];
LPCWSTR file = szPackage; LPCWSTR file = szPackage;
DWORD index = 0;
TRACE("%s %p\n", debugstr_w(szPackage), pPackage); TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
...@@ -1293,9 +1350,30 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage) ...@@ -1293,9 +1350,30 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
msi_set_property( package->db, OriginalDatabase, fullpath ); msi_set_property( package->db, OriginalDatabase, fullpath );
} }
package->script = msi_alloc_zero( sizeof(MSISCRIPT) ); msi_set_context( package );
*pPackage = package;
while (1)
{
WCHAR patch_code[GUID_SIZE];
r = MsiEnumPatchesExW( package->ProductCode, NULL, package->Context,
MSIPATCHSTATE_APPLIED, index, patch_code, NULL, NULL, NULL, NULL );
if (r != ERROR_SUCCESS)
break;
TRACE("found registered patch %s\n", debugstr_w(patch_code));
r = apply_registered_patch( package, patch_code );
if (r != ERROR_SUCCESS)
{
ERR("registered patch failed to apply %u\n", r);
MSI_FreePackage( (MSIOBJECTHDR *)package );
return r;
}
index++;
}
*pPackage = package;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
......
...@@ -731,7 +731,7 @@ static void test_simple_patch( void ) ...@@ -731,7 +731,7 @@ static void test_simple_patch( void )
ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
r = MsiViewFetch( hview, &hrec ); r = MsiViewFetch( hview, &hrec );
todo_wine ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r ); ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
MsiCloseHandle( hrec ); MsiCloseHandle( hrec );
MsiViewClose( hview ); MsiViewClose( hview );
...@@ -942,13 +942,13 @@ static void test_system_tables( void ) ...@@ -942,13 +942,13 @@ static void test_system_tables( void )
ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
r = find_entry( hdb, "_Tables", "MsiPatchHeaders" ); r = find_entry( hdb, "_Tables", "MsiPatchHeaders" );
todo_wine ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
r = find_entry( hdb, "_Tables", "Patch" ); r = find_entry( hdb, "_Tables", "Patch" );
todo_wine ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
r = find_entry( hdb, "_Tables", "PatchPackage" ); r = find_entry( hdb, "_Tables", "PatchPackage" );
todo_wine ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r ); ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
MsiCloseHandle( hdb ); MsiCloseHandle( hdb );
MsiCloseHandle( hproduct ); MsiCloseHandle( hproduct );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment