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->Action = INSTALLSTATE_UNKNOWN;
comp->ActionRequest = INSTALLSTATE_UNKNOWN; comp->ActionRequest = INSTALLSTATE_UNKNOWN;
comp->assembly = load_assembly( package, comp ); comp->assembly = msi_load_assembly( package, comp );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -1755,8 +1755,17 @@ static UINT load_all_components( MSIPACKAGE *package )
if (r != ERROR_SUCCESS) if (r != ERROR_SUCCESS)
return r; 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); r = MSI_IterateRecords(view, NULL, load_component, package);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
msi_destroy_assembly_caches( package );
return r; 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 *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * ); static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
static HMODULE hfusion11, hfusion20, hmscoree, hsxs;
static BOOL init_function_pointers( void ) static BOOL init_function_pointers( void )
{ {
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0}; 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 szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',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; if (pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE;
@ -71,7 +72,7 @@ error:
return FALSE; return FALSE;
} }
static BOOL init_assembly_caches( MSIPACKAGE *package ) BOOL msi_init_assembly_caches( MSIPACKAGE *package )
{ {
if (!init_function_pointers()) return FALSE; if (!init_function_pointers()) return FALSE;
if (package->cache_net[CLR_VERSION_V11] || package->cache_net[CLR_VERSION_V20]) return TRUE; 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; 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 MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
@ -239,18 +265,13 @@ static const WCHAR *get_clr_version_str( enum clr_version version )
return 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; MSIRECORD *rec;
MSIASSEMBLY *a; MSIASSEMBLY *a;
if (!(rec = get_assembly_record( package, comp->Component ))) return NULL; 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) ))) if (!(a = msi_alloc_zero( sizeof(MSIASSEMBLY) )))
{ {
msiobj_release( &rec->hdr ); msiobj_release( &rec->hdr );
@ -334,7 +355,7 @@ static enum clr_version get_clr_version( const WCHAR *filename )
return version; return version;
} }
UINT install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{ {
HRESULT hr; HRESULT hr;
const WCHAR *manifest; const WCHAR *manifest;

View File

@ -20,7 +20,7 @@
/* /*
* Actions dealing with files These are * Actions dealing with files:
* *
* InstallFiles * InstallFiles
* DuplicateFiles * DuplicateFiles
@ -390,12 +390,13 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
goto done; goto done;
} }
} }
msi_init_assembly_caches( package );
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{ {
if (comp->ActionRequest == INSTALLSTATE_LOCAL && comp->Enabled && if (comp->ActionRequest == INSTALLSTATE_LOCAL && comp->Enabled &&
comp->assembly && !comp->assembly->installed) comp->assembly && !comp->assembly->installed)
{ {
rc = install_assembly( package, comp ); rc = msi_install_assembly( package, comp );
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
{ {
ERR("Failed to install assembly\n"); ERR("Failed to install assembly\n");
@ -404,6 +405,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
} }
} }
} }
msi_destroy_assembly_caches( package );
done: done:
msi_free_media_info(mi); 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; MSIINSTALLCONTEXT context, DWORD options, LPCWSTR value) DECLSPEC_HIDDEN;
extern UINT msi_get_local_package_name(LPWSTR path, LPCWSTR suffix) 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 UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) DECLSPEC_HIDDEN;
extern MSIASSEMBLY *load_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN; extern MSIASSEMBLY *msi_load_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN;
extern UINT install_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 *font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN;
extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN; extern WCHAR **msi_split_string(const WCHAR *, WCHAR) DECLSPEC_HIDDEN;