[4/7] msi: Destroy assembly caches right after use.
Hans Leidekker
hans at codeweavers.com
Fri May 6 07:39:58 CDT 2011
This avoids keeping dlls loaded that the .NET service pack installers want to replace.
---
dlls/msi/action.c | 11 ++++++++++-
dlls/msi/assembly.c | 41 +++++++++++++++++++++++++++++++----------
dlls/msi/files.c | 6 ++++--
dlls/msi/msipriv.h | 6 ++++--
4 files changed, 49 insertions(+), 15 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 227e661..669881c 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -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;
}
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c
index 6bccc79..a81bcde 100644
--- a/dlls/msi/assembly.c
+++ b/dlls/msi/assembly.c
@@ -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;
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 6608874..ff21604 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -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);
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 78d1972..d13868f 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -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;
--
1.7.4.1
More information about the wine-patches
mailing list