Module: wine Branch: master Commit: bffd5e0cbbda9e38d934ccb042ed01ee307bedcf URL: http://source.winehq.org/git/wine.git/?a=commit;h=bffd5e0cbbda9e38d934ccb042...
Author: Hans Leidekker hans@codeweavers.com Date: Fri May 6 14:39:58 2011 +0200
msi: Destroy assembly caches right after use.
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;