Hans Leidekker : msi: Destroy assembly caches right after use.

Alexandre Julliard julliard at winehq.org
Fri May 6 13:44:13 CDT 2011


Module: wine
Branch: master
Commit: bffd5e0cbbda9e38d934ccb042ed01ee307bedcf
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bffd5e0cbbda9e38d934ccb042ed01ee307bedcf

Author: Hans Leidekker <hans at 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;
 




More information about the wine-cvs mailing list