msi: Destroy assembly caches right after use.

This avoids keeping dlls loaded that the .NET service pack installers want to replace.
This commit is contained in:
Hans Leidekker 2011-05-06 14:39:58 +02:00 committed by Alexandre Julliard
parent 395479f0d1
commit bffd5e0cbb
4 changed files with 49 additions and 15 deletions

View File

@ -1736,7 +1736,7 @@ static UINT load_component( MSIRECORD *row, LPVOID param )
comp->Action = INSTALLSTATE_UNKNOWN;
comp->ActionRequest = INSTALLSTATE_UNKNOWN;
comp->assembly = load_assembly( package, comp );
comp->assembly = msi_load_assembly( package, comp );
return ERROR_SUCCESS;
}
@ -1755,8 +1755,17 @@ static UINT load_all_components( MSIPACKAGE *package )
if (r != ERROR_SUCCESS)
return r;
if (!msi_init_assembly_caches( package ))
{
ERR("can't initialize assembly caches\n");
msiobj_release( &view->hdr );
return ERROR_FUNCTION_FAILED;
}
r = MSI_IterateRecords(view, NULL, load_component, package);
msiobj_release(&view->hdr);
msi_destroy_assembly_caches( package );
return r;
}

View File

@ -37,12 +37,13 @@ static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
static HMODULE hfusion11, hfusion20, hmscoree, hsxs;
static BOOL init_function_pointers( void )
{
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
HMODULE hfusion11 = NULL, hfusion20 = NULL, hmscoree, hsxs;
if (pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE;
@ -71,7 +72,7 @@ error:
return FALSE;
}
static BOOL init_assembly_caches( MSIPACKAGE *package )
BOOL msi_init_assembly_caches( MSIPACKAGE *package )
{
if (!init_function_pointers()) return FALSE;
if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20]) return TRUE;
@ -99,6 +100,31 @@ static BOOL init_assembly_caches( MSIPACKAGE *package )
return FALSE;
}
void msi_destroy_assembly_caches( MSIPACKAGE *package )
{
UINT i;
for (i = 0; i < CLR_VERSION_MAX; i++)
{
if (package->cache_net[i])
{
IAssemblyCache_Release( package->cache_net[i] );
package->cache_net[i] = NULL;
}
}
if (package->cache_sxs)
{
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
}
pCreateAssemblyCacheNet11 = NULL;
pCreateAssemblyCacheNet20 = NULL;
FreeLibrary( hfusion11 );
FreeLibrary( hfusion20 );
FreeLibrary( hmscoree );
FreeLibrary( hsxs );
}
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
{
static const WCHAR query[] = {
@ -239,18 +265,13 @@ static const WCHAR *get_clr_version_str( enum clr_version version )
return clr_version[version];
}
MSIASSEMBLY *load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
/* assembly caches must be initialized */
MSIASSEMBLY *msi_load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{
MSIRECORD *rec;
MSIASSEMBLY *a;
if (!(rec = get_assembly_record( package, comp->Component ))) return NULL;
if (!init_assembly_caches( package ))
{
ERR("can't initialize assembly caches\n");
msiobj_release( &rec->hdr );
return NULL;
}
if (!(a = msi_alloc_zero( sizeof(MSIASSEMBLY) )))
{
msiobj_release( &rec->hdr );
@ -334,7 +355,7 @@ static enum clr_version get_clr_version( const WCHAR *filename )
return version;
}
UINT install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{
HRESULT hr;
const WCHAR *manifest;

View File

@ -20,7 +20,7 @@
/*
* Actions dealing with files These are
* Actions dealing with files:
*
* InstallFiles
* DuplicateFiles
@ -390,12 +390,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
goto done;
}
}
msi_init_assembly_caches( package );
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
if (comp->ActionRequest == INSTALLSTATE_LOCAL && comp->Enabled &&
comp->assembly && !comp->assembly->installed)
{
rc = install_assembly( package, comp );
rc = msi_install_assembly( package, comp );
if (rc != ERROR_SUCCESS)
{
ERR("Failed to install assembly\n");
@ -404,6 +405,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
}
}
}
msi_destroy_assembly_caches( package );
done:
msi_free_media_info(mi);

View File

@ -999,8 +999,10 @@ extern UINT msi_set_last_used_source(LPCWSTR product, LPCWSTR usersid,
MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value) DECLSPEC_HIDDEN;
extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix) DECLSPEC_HIDDEN;
extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) DECLSPEC_HIDDEN;
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN;
extern UINT install_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN;
extern MSIASSEMBLY *msi_load_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN;
extern UINT msi_install_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN;
extern BOOL msi_init_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN;
extern void msi_destroy_assembly_caches(MSIPACKAGE *) DECLSPEC_HIDDEN;
extern WCHAR *font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN;