From: Hans Leidekker hans@codeweavers.com
--- dlls/msi/assembly.c | 139 +++++++++++++++++++++++--------------------- dlls/msi/files.c | 4 +- dlls/msi/msi_main.c | 1 + dlls/msi/msipriv.h | 16 +---- dlls/msi/package.c | 2 - 5 files changed, 80 insertions(+), 82 deletions(-)
diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index 2452bb0b8d1..bec2fc629b5 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -30,92 +30,101 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
-static void load_fusion_dlls( MSIPACKAGE *package ) +static HMODULE hfusion10, hfusion11, hfusion20, hfusion40, hmscoree; + +static HRESULT (WINAPI *pGetFileVersion)( const WCHAR *, WCHAR *, DWORD, DWORD * ); +static HRESULT (WINAPI *pCreateAssemblyNameObject)( IAssemblyName **, const WCHAR *, DWORD, void * ); +static HRESULT (WINAPI *pCreateAssemblyEnum)( IAssemblyEnum **, IUnknown *, IAssemblyName *, DWORD, void * ); + +static IAssemblyCache *cache_net[CLR_VERSION_MAX]; +static IAssemblyCache *cache_sxs; + +static void load_fusion_dlls( void ) { HRESULT (WINAPI *pLoadLibraryShim)( const WCHAR *, const WCHAR *, void *, HMODULE * ); WCHAR path[MAX_PATH];
- wcscpy(path, sysdir); - lstrcpyW( path + sysdir_len, L"\mscoree.dll" ); - if (!package->hmscoree && !(package->hmscoree = LoadLibraryW( path ))) return; - if (!(pLoadLibraryShim = (void *)GetProcAddress( package->hmscoree, "LoadLibraryShim" ))) + wcscpy( path, sysdir ); + wcscpy( path + sysdir_len, L"\mscoree.dll" ); + if (!hmscoree && !(hmscoree = LoadLibraryW( path ))) return; + if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) { - FreeLibrary( package->hmscoree ); - package->hmscoree = NULL; + FreeLibrary( hmscoree ); + hmscoree = NULL; return; }
- if (!package->hfusion10) pLoadLibraryShim( L"fusion.dll", L"v1.0.3705", NULL, &package->hfusion10 ); - if (!package->hfusion11) pLoadLibraryShim( L"fusion.dll", L"v1.1.4322", NULL, &package->hfusion11 ); - if (!package->hfusion20) pLoadLibraryShim( L"fusion.dll", L"v2.0.50727", NULL, &package->hfusion20 ); - if (!package->hfusion40) pLoadLibraryShim( L"fusion.dll", L"v4.0.30319", NULL, &package->hfusion40 ); + if (!hfusion10) pLoadLibraryShim( L"fusion.dll", L"v1.0.3705", NULL, &hfusion10 ); + if (!hfusion11) pLoadLibraryShim( L"fusion.dll", L"v1.1.4322", NULL, &hfusion11 ); + if (!hfusion20) pLoadLibraryShim( L"fusion.dll", L"v2.0.50727", NULL, &hfusion20 ); + if (!hfusion40) pLoadLibraryShim( L"fusion.dll", L"v4.0.30319", NULL, &hfusion40 ); }
-static BOOL init_assembly_caches( MSIPACKAGE *package ) +static BOOL init_assembly_caches( void ) { HRESULT (WINAPI *pCreateAssemblyCache)( IAssemblyCache **, DWORD );
- if (!package->cache_sxs && CreateAssemblyCache( &package->cache_sxs, 0 ) != S_OK) return FALSE; + if (!cache_sxs && CreateAssemblyCache( &cache_sxs, 0 ) != S_OK) return FALSE;
- load_fusion_dlls( package ); - package->pGetFileVersion = (void *)GetProcAddress( package->hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */ + load_fusion_dlls(); + pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */
- if (package->hfusion10 && !package->cache_net[CLR_VERSION_V10]) + if (hfusion10 && !cache_net[CLR_VERSION_V10]) { - pCreateAssemblyCache = (void *)GetProcAddress( package->hfusion10, "CreateAssemblyCache" ); - pCreateAssemblyCache( &package->cache_net[CLR_VERSION_V10], 0 ); + pCreateAssemblyCache = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" ); + pCreateAssemblyCache( &cache_net[CLR_VERSION_V10], 0 ); } - if (package->hfusion11 && !package->cache_net[CLR_VERSION_V11]) + if (hfusion11 && !cache_net[CLR_VERSION_V11]) { - pCreateAssemblyCache = (void *)GetProcAddress( package->hfusion11, "CreateAssemblyCache" ); - pCreateAssemblyCache( &package->cache_net[CLR_VERSION_V11], 0 ); + pCreateAssemblyCache = (void *)GetProcAddress( hfusion11, "CreateAssemblyCache" ); + pCreateAssemblyCache( &cache_net[CLR_VERSION_V11], 0 ); } - if (package->hfusion20 && !package->cache_net[CLR_VERSION_V20]) + if (hfusion20 && !cache_net[CLR_VERSION_V20]) { - pCreateAssemblyCache = (void *)GetProcAddress( package->hfusion20, "CreateAssemblyCache" ); - pCreateAssemblyCache( &package->cache_net[CLR_VERSION_V20], 0 ); + pCreateAssemblyCache = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" ); + pCreateAssemblyCache( &cache_net[CLR_VERSION_V20], 0 ); } - if (package->hfusion40 && !package->cache_net[CLR_VERSION_V40]) + if (hfusion40 && !cache_net[CLR_VERSION_V40]) { - pCreateAssemblyCache = (void *)GetProcAddress( package->hfusion40, "CreateAssemblyCache" ); - pCreateAssemblyCache( &package->cache_net[CLR_VERSION_V40], 0 ); - package->pCreateAssemblyNameObject = (void *)GetProcAddress( package->hfusion40, "CreateAssemblyNameObject" ); - package->pCreateAssemblyEnum = (void *)GetProcAddress( package->hfusion40, "CreateAssemblyEnum" ); + pCreateAssemblyCache = (void *)GetProcAddress( hfusion40, "CreateAssemblyCache" ); + pCreateAssemblyCache( &cache_net[CLR_VERSION_V40], 0 ); + pCreateAssemblyNameObject = (void *)GetProcAddress( hfusion40, "CreateAssemblyNameObject" ); + pCreateAssemblyEnum = (void *)GetProcAddress( hfusion40, "CreateAssemblyEnum" ); }
return TRUE; }
-void msi_destroy_assembly_caches( MSIPACKAGE *package ) +void msi_destroy_assembly_caches( void ) { UINT i;
- if (package->cache_sxs) + if (cache_sxs) { - IAssemblyCache_Release( package->cache_sxs ); - package->cache_sxs = NULL; + IAssemblyCache_Release( cache_sxs ); + cache_sxs = NULL; } for (i = 0; i < CLR_VERSION_MAX; i++) { - if (package->cache_net[i]) + if (cache_net[i]) { - IAssemblyCache_Release( package->cache_net[i] ); - package->cache_net[i] = NULL; + IAssemblyCache_Release( cache_net[i] ); + cache_net[i] = NULL; } } - package->pGetFileVersion = NULL; - package->pCreateAssemblyNameObject = NULL; - package->pCreateAssemblyEnum = NULL; - FreeLibrary( package->hfusion10 ); - FreeLibrary( package->hfusion11 ); - FreeLibrary( package->hfusion20 ); - FreeLibrary( package->hfusion40 ); - FreeLibrary( package->hmscoree ); - package->hfusion10 = NULL; - package->hfusion11 = NULL; - package->hfusion20 = NULL; - package->hfusion40 = NULL; - package->hmscoree = NULL; + pGetFileVersion = NULL; + pCreateAssemblyNameObject = NULL; + pCreateAssemblyEnum = NULL; + FreeLibrary( hfusion10 ); + FreeLibrary( hfusion11 ); + FreeLibrary( hfusion20 ); + FreeLibrary( hfusion40 ); + FreeLibrary( hmscoree ); + hfusion10 = NULL; + hfusion11 = NULL; + hfusion20 = NULL; + hfusion40 = NULL; + hmscoree = NULL; }
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp ) @@ -216,13 +225,13 @@ done: return display_name; }
-WCHAR *msi_get_assembly_path( MSIPACKAGE *package, const WCHAR *displayname ) +WCHAR *msi_get_assembly_path( const WCHAR *displayname ) { HRESULT hr; ASSEMBLY_INFO info; IAssemblyCache *cache;
- if (!init_assembly_caches( package ) || !(cache = package->cache_net[CLR_VERSION_V40])) return NULL; + if (!init_assembly_caches() || !(cache = cache_net[CLR_VERSION_V40])) return NULL;
memset( &info, 0, sizeof(info) ); info.cbAssemblyInfo = sizeof(info); @@ -241,7 +250,7 @@ WCHAR *msi_get_assembly_path( MSIPACKAGE *package, const WCHAR *displayname ) return info.pszCurrentAssemblyPathBuf; }
-IAssemblyEnum *msi_create_assembly_enum( MSIPACKAGE *package, const WCHAR *displayname ) +IAssemblyEnum *msi_create_assembly_enum( const WCHAR *displayname ) { HRESULT hr; IAssemblyName *name; @@ -249,10 +258,10 @@ IAssemblyEnum *msi_create_assembly_enum( MSIPACKAGE *package, const WCHAR *displ WCHAR *str; DWORD len = 0;
- if (!init_assembly_caches( package ) || !package->pCreateAssemblyNameObject || !package->pCreateAssemblyEnum) + if (!init_assembly_caches() || !pCreateAssemblyNameObject || !pCreateAssemblyEnum) return NULL;
- hr = package->pCreateAssemblyNameObject( &name, displayname, CANOF_PARSE_DISPLAY_NAME, NULL ); + hr = pCreateAssemblyNameObject( &name, displayname, CANOF_PARSE_DISPLAY_NAME, NULL ); if (FAILED( hr )) return NULL;
hr = IAssemblyName_GetName( name, &len, NULL ); @@ -270,11 +279,11 @@ IAssemblyEnum *msi_create_assembly_enum( MSIPACKAGE *package, const WCHAR *displ return NULL; }
- hr = package->pCreateAssemblyNameObject( &name, str, 0, NULL ); + hr = pCreateAssemblyNameObject( &name, str, 0, NULL ); free( str ); if (FAILED( hr )) return NULL;
- hr = package->pCreateAssemblyEnum( &ret, NULL, name, ASM_CACHE_GAC, NULL ); + hr = pCreateAssemblyEnum( &ret, NULL, name, ASM_CACHE_GAC, NULL ); IAssemblyName_Release( name ); if (FAILED( hr )) return NULL;
@@ -335,13 +344,13 @@ static enum clr_version get_clr_version( MSIPACKAGE *package, const WCHAR *filen enum clr_version version = CLR_VERSION_V11; WCHAR *strW;
- if (!package->pGetFileVersion) return CLR_VERSION_V10; + if (!pGetFileVersion) return CLR_VERSION_V10;
- hr = package->pGetFileVersion( filename, NULL, 0, &len ); + hr = pGetFileVersion( filename, NULL, 0, &len ); if (hr != E_NOT_SUFFICIENT_BUFFER) return CLR_VERSION_V11; if ((strW = malloc( len * sizeof(WCHAR) ))) { - hr = package->pGetFileVersion( filename, strW, len, &len ); + hr = pGetFileVersion( filename, strW, len, &len ); if (hr == S_OK) { UINT i; @@ -361,7 +370,7 @@ UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) MSIASSEMBLY *assembly = comp->assembly; MSIFEATURE *feature = NULL;
- if (!init_assembly_caches( package )) return ERROR_FUNCTION_FAILED; + if (!init_assembly_caches()) return ERROR_FUNCTION_FAILED;
if (comp->assembly->feature) feature = msi_get_loaded_feature( package, comp->assembly->feature ); @@ -379,12 +388,12 @@ UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) return ERROR_FUNCTION_FAILED; } manifest = msi_get_loaded_file( package, assembly->manifest )->TargetPath; - cache = package->cache_sxs; + cache = cache_sxs; } else { manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath; - cache = package->cache_net[get_clr_version( package, manifest )]; + cache = cache_net[get_clr_version( package, manifest )]; if (!cache) return ERROR_SUCCESS; } TRACE("installing assembly %s\n", debugstr_w(manifest)); @@ -406,7 +415,7 @@ UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) MSIASSEMBLY *assembly = comp->assembly; MSIFEATURE *feature = NULL;
- if (!init_assembly_caches( package )) return ERROR_FUNCTION_FAILED; + if (!init_assembly_caches()) return ERROR_FUNCTION_FAILED;
if (comp->assembly->feature) feature = msi_get_loaded_feature( package, comp->assembly->feature ); @@ -420,7 +429,7 @@ UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
if (assembly->attributes == msidbAssemblyAttributesWin32) { - cache = package->cache_sxs; + cache = cache_sxs; hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); if (FAILED( hr )) WARN( "failed to uninstall assembly %#lx\n", hr ); } @@ -430,7 +439,7 @@ UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp ) for (i = 0; i < CLR_VERSION_MAX; i++) { if (!assembly->clr_version[i]) continue; - cache = package->cache_net[i]; + cache = cache_net[i]; if (cache) { hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); diff --git a/dlls/msi/files.c b/dlls/msi/files.c index 1ffa918b4a9..e7686d07627 100644 --- a/dlls/msi/files.c +++ b/dlls/msi/files.c @@ -743,7 +743,7 @@ UINT msi_patch_assembly( MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEPATC IAssemblyName *name; IAssemblyEnum *iter;
- if (!(iter = msi_create_assembly_enum( package, assembly->display_name ))) + if (!(iter = msi_create_assembly_enum( assembly->display_name ))) return ERROR_FUNCTION_FAILED;
while ((IAssemblyEnum_GetNextAssembly( iter, NULL, &name, 0 ) == S_OK)) @@ -763,7 +763,7 @@ UINT msi_patch_assembly( MSIPACKAGE *package, MSIASSEMBLY *assembly, MSIFILEPATC break; }
- if ((path = msi_get_assembly_path( package, displayname ))) + if ((path = msi_get_assembly_path( displayname ))) { if (!msi_copy_file( package, path, patch->File->TargetPath, FALSE )) { diff --git a/dlls/msi/msi_main.c b/dlls/msi/msi_main.c index 32b4f9ad45d..860df7c8da0 100644 --- a/dlls/msi/msi_main.c +++ b/dlls/msi/msi_main.c @@ -82,6 +82,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_PROCESS_DETACH: if (lpvReserved) break; msi_dialog_unregister_class(); + msi_destroy_assembly_caches(); msi_free_handle_table(); free( gszLogFile ); release_typelib(); diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index bd8f6ec7a48..0efc367c76d 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -428,16 +428,6 @@ typedef struct tagMSIPACKAGE UINT LastActionResult; UINT action_progress_increment; HANDLE log_file; - HMODULE hfusion10; - HMODULE hfusion11; - HMODULE hfusion20; - HMODULE hfusion40; - HMODULE hmscoree; - HRESULT (WINAPI *pGetFileVersion)( const WCHAR *, WCHAR *, DWORD, DWORD * ); - HRESULT (WINAPI *pCreateAssemblyNameObject)( IAssemblyName **, const WCHAR *, DWORD, void * ); - HRESULT (WINAPI *pCreateAssemblyEnum)( IAssemblyEnum **, IUnknown *, IAssemblyName *, DWORD, void * ); - IAssemblyCache *cache_net[CLR_VERSION_MAX]; - IAssemblyCache *cache_sxs;
struct list classes; struct list extensions; @@ -1086,10 +1076,10 @@ extern UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace); extern MSIASSEMBLY *msi_load_assembly(MSIPACKAGE *, MSICOMPONENT *); extern UINT msi_install_assembly(MSIPACKAGE *, MSICOMPONENT *); extern UINT msi_uninstall_assembly(MSIPACKAGE *, MSICOMPONENT *); -extern void msi_destroy_assembly_caches(MSIPACKAGE *); +extern void msi_destroy_assembly_caches(void); extern BOOL msi_is_global_assembly(MSICOMPONENT *); -extern IAssemblyEnum *msi_create_assembly_enum(MSIPACKAGE *, const WCHAR *); -extern WCHAR *msi_get_assembly_path(MSIPACKAGE *, const WCHAR *) __WINE_DEALLOC(free) __WINE_MALLOC; +extern IAssemblyEnum *msi_create_assembly_enum(const WCHAR *); +extern WCHAR *msi_get_assembly_path(const WCHAR *) __WINE_DEALLOC(free) __WINE_MALLOC; extern WCHAR **msi_split_string(const WCHAR *, WCHAR); extern UINT msi_set_original_database_property(MSIDATABASE *, const WCHAR *); extern WCHAR *msi_get_error_message(MSIDATABASE *, int) __WINE_DEALLOC(free) __WINE_MALLOC; diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 969441f8827..feb50f232e7 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -332,8 +332,6 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg) { MSIPACKAGE *package = (MSIPACKAGE *)arg;
- msi_destroy_assembly_caches( package ); - if( package->dialog ) msi_dialog_destroy( package->dialog );
From: Hans Leidekker hans@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58577 --- dlls/msi/msi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 2c0f3aa50f5..6edee9c8185 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -2833,6 +2833,18 @@ static INSTALLSTATE MSI_GetComponentPath( const WCHAR *szProduct, const WCHAR *s if (state == INSTALLSTATE_LOCAL && !*path) state = INSTALLSTATE_NOTUSED;
+ if (wcslen(path) > 2 && !wcsncmp(path, L"<\", 2)) + { + WCHAR *assembly_path = msi_get_assembly_path(path + 2); + if (assembly_path) + { + free(path); + path = assembly_path; + if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES) + state = INSTALLSTATE_LOCAL; + } + } + if (msi_strcpy_to_awstring(path, -1, lpPathBuf, pcchBuf) == ERROR_MORE_DATA) state = INSTALLSTATE_MOREDATA;