From 605e0b7b4176bf5e5cf5888073103016e56b8a2f Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 30 Apr 2012 09:35:25 +0200 Subject: [PATCH] msi: Add support for uninstalling global assemblies. --- dlls/msi/assembly.c | 39 +++++++++++++++++++++++++++++++++++++++ dlls/msi/files.c | 16 ++++++++++------ dlls/msi/msipriv.h | 1 + 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index af23c4af41d..712bb236a90 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -425,6 +425,45 @@ UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) return ERROR_SUCCESS; } +UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) +{ + HRESULT hr; + IAssemblyCache *cache; + MSIASSEMBLY *assembly = comp->assembly; + MSIFEATURE *feature = NULL; + + if (comp->assembly->feature) + feature = msi_get_loaded_feature( package, comp->assembly->feature ); + + if (assembly->application) + { + if (feature) feature->Action = INSTALLSTATE_ABSENT; + return ERROR_SUCCESS; + } + TRACE("removing %s\n", debugstr_w(assembly->display_name)); + + if (assembly->attributes == msidbAssemblyAttributesWin32) + { + cache = package->cache_sxs; + hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); + if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr); + } + else + { + unsigned int i; + for (i = 0; i < CLR_VERSION_MAX; i++) + { + if (!assembly->clr_version[i]) continue; + cache = package->cache_net[i]; + hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); + if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr); + } + } + if (feature) feature->Action = INSTALLSTATE_ABSENT; + assembly->installed = FALSE; + return ERROR_SUCCESS; +} + static WCHAR *build_local_assembly_path( const WCHAR *filename ) { UINT i; diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 6edf781300b..fe72c24c81d 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -1308,22 +1308,26 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package ) msi_ui_actiondata( package, szRemoveFiles, uirow ); msiobj_release( &uirow->hdr ); } + + msi_init_assembly_caches( package ); LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry ) { - MSIFOLDER *folder; - comp->Action = msi_get_component_action( package, comp ); if (comp->Action != INSTALLSTATE_ABSENT) continue; - if (comp->assembly && !comp->assembly->application) continue; - if (comp->Attributes & msidbComponentAttributesPermanent) { TRACE("permanent component, not removing directory\n"); continue; } - folder = msi_get_loaded_folder( package, comp->Directory ); - remove_folder( folder ); + if (comp->assembly && !comp->assembly->application) + msi_uninstall_assembly( package, comp ); + else + { + MSIFOLDER *folder = msi_get_loaded_folder( package, comp->Directory ); + remove_folder( folder ); + } } + msi_destroy_assembly_caches( package ); return ERROR_SUCCESS; } diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index bdce06be6c4..80f54149688 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -1027,6 +1027,7 @@ extern UINT msi_create_empty_local_file(LPWSTR path, LPCWSTR suffix) DECLSPEC_HI extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace) DECLSPEC_HIDDEN; extern MSIASSEMBLY *msi_load_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN; extern UINT msi_install_assembly(MSIPACKAGE *, MSICOMPONENT *) DECLSPEC_HIDDEN; +extern UINT msi_uninstall_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 *msi_font_version_from_file(const WCHAR *) DECLSPEC_HIDDEN;