From 629d2d09a0323f8456d78be0cc08d8206ed722df Mon Sep 17 00:00:00 2001 From: Esme Povirk Date: Tue, 9 May 2023 13:20:21 -0500 Subject: [PATCH] mscoree: Search the Mono GAC before the appdomain paths. --- dlls/mscoree/metahost.c | 44 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index a9fb3be47d3..309ad639d42 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -130,6 +130,7 @@ MonoThread* (CDECL *mono_thread_attach)(MonoDomain *domain); void (CDECL *mono_thread_manage)(void); void (CDECL *mono_trace_set_print_handler)(MonoPrintCallback callback); void (CDECL *mono_trace_set_printerr_handler)(MonoPrintCallback callback); +static MonoAssembly* (CDECL *wine_mono_assembly_load_from_gac)(MonoAssemblyName *aname, MonoImageOpenStatus *status, int refonly); static void (CDECL *wine_mono_install_assembly_preload_hook)(WineMonoAssemblyPreLoadFunc func, void *user_data); static void (CDECL *wine_mono_install_assembly_preload_hook_v2)(WineMonoAssemblyPreLoadFunc func, void *user_data); @@ -253,6 +254,7 @@ static HRESULT load_mono(LPCWSTR mono_path) LOAD_OPT_MONO_FUNCTION(mono_set_crash_chaining, set_crash_chaining_dummy); LOAD_OPT_MONO_FUNCTION(mono_trace_set_print_handler, set_print_handler_dummy); LOAD_OPT_MONO_FUNCTION(mono_trace_set_printerr_handler, set_print_handler_dummy); + LOAD_OPT_MONO_FUNCTION(wine_mono_assembly_load_from_gac, NULL); LOAD_OPT_MONO_FUNCTION(wine_mono_install_assembly_preload_hook, NULL); LOAD_OPT_MONO_FUNCTION(wine_mono_install_assembly_preload_hook_v2, NULL); @@ -1375,16 +1377,19 @@ HRESULT CLRMetaHostPolicy_CreateInstance(REFIID riid, void **ppobj) * Assembly search override settings: * * WINE_MONO_OVERRIDES=*,Gac=n - * Never search the GAC for libraries. + * Never search the Windows GAC for libraries. + * + * WINE_MONO_OVERRIDES=*,MonoGac=n + * Never search the Mono GAC for libraries. * * WINE_MONO_OVERRIDES=*,PrivatePath=n * Never search the AppDomain search path for libraries. * * WINE_MONO_OVERRIDES=Microsoft.Xna.Framework,Gac=n - * Never search the GAC for Microsoft.Xna.Framework + * Never search the Windows GAC for Microsoft.Xna.Framework * * WINE_MONO_OVERRIDES=Microsoft.Xna.Framework.*,Gac=n;Microsoft.Xna.Framework.GamerServices,Gac=y - * Never search the GAC for Microsoft.Xna.Framework, or any library starting + * Never search the Windows GAC for Microsoft.Xna.Framework, or any library starting * with Microsoft.Xna.Framework, except for Microsoft.Xna.Framework.GamerServices */ @@ -1392,7 +1397,8 @@ HRESULT CLRMetaHostPolicy_CreateInstance(REFIID riid, void **ppobj) #define ASSEMBLY_SEARCH_GAC 1 #define ASSEMBLY_SEARCH_UNDEFINED 2 #define ASSEMBLY_SEARCH_PRIVATEPATH 4 -#define ASSEMBLY_SEARCH_DEFAULT (ASSEMBLY_SEARCH_GAC|ASSEMBLY_SEARCH_PRIVATEPATH) +#define ASSEMBLY_SEARCH_MONOGAC 8 +#define ASSEMBLY_SEARCH_DEFAULT (ASSEMBLY_SEARCH_GAC|ASSEMBLY_SEARCH_PRIVATEPATH|ASSEMBLY_SEARCH_MONOGAC) typedef struct override_entry { char *name; @@ -1441,6 +1447,14 @@ static void parse_override_entry(override_entry *entry, const char *string, int entry->flags &= ~ASSEMBLY_SEARCH_GAC; } break; + case 7: + if (!_strnicmp(string, "monogac", 7)) { + if (IS_OPTION_TRUE(*value)) + entry->flags |= ASSEMBLY_SEARCH_MONOGAC; + else if (IS_OPTION_FALSE(*value)) + entry->flags &= ~ASSEMBLY_SEARCH_MONOGAC; + } + break; case 11: if (!_strnicmp(string, "privatepath", 11)) { if (IS_OPTION_TRUE(*value)) @@ -1568,7 +1582,7 @@ static DWORD get_basename_search_flags(const char *basename, MonoAssemblyName *a if (strcmp(basename, "Microsoft.Xna.Framework.*") == 0 && mono_assembly_name_get_version(aname, NULL, NULL, NULL) == 4) /* Use FNA as a replacement for XNA4. */ - return 0; + return ASSEMBLY_SEARCH_MONOGAC; return ASSEMBLY_SEARCH_UNDEFINED; } @@ -1840,6 +1854,26 @@ static MonoAssembly* CDECL wine_mono_assembly_preload_hook_v2_fn(MonoAssemblyNam else TRACE("skipping Windows GAC search due to override setting\n"); + if (wine_mono_assembly_load_from_gac) + { + if (search_flags & ASSEMBLY_SEARCH_MONOGAC) + { + result = wine_mono_assembly_load_from_gac (aname, &stat, FALSE); + + if (result) + { + TRACE("found in Mono GAC\n"); + *flags |= WINE_PRELOAD_SET_GAC; + goto done; + } + } + else + { + *flags |= WINE_PRELOAD_SKIP_GAC; + TRACE("skipping Mono GAC search due to override setting\n"); + } + } + if ((search_flags & ASSEMBLY_SEARCH_PRIVATEPATH) == 0) { TRACE("skipping AppDomain search path due to override setting\n");