mscoree: Search the Global Assembly Cache for required assemblies.
This commit is contained in:
parent
9d46ba417e
commit
d2d743efbb
|
@ -57,21 +57,6 @@ struct DomainEntry
|
||||||
MonoDomain *domain;
|
MonoDomain *domain;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *WtoA(LPCWSTR wstr)
|
|
||||||
{
|
|
||||||
int length;
|
|
||||||
char *result;
|
|
||||||
|
|
||||||
length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
|
|
||||||
|
|
||||||
result = HeapAlloc(GetProcessHeap(), 0, length);
|
|
||||||
|
|
||||||
if (result)
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, length, NULL, NULL);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT RuntimeHost_AddDomain(RuntimeHost *This, MonoDomain **result)
|
static HRESULT RuntimeHost_AddDomain(RuntimeHost *This, MonoDomain **result)
|
||||||
{
|
{
|
||||||
struct DomainEntry *entry;
|
struct DomainEntry *entry;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include "corerror.h"
|
#include "corerror.h"
|
||||||
#include "mscoree.h"
|
#include "mscoree.h"
|
||||||
|
#include "fusion.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
@ -73,6 +74,8 @@ static loaded_mono loaded_monos[NUM_ABI_VERSIONS];
|
||||||
|
|
||||||
static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path, int abi_version);
|
static BOOL find_mono_dll(LPCWSTR path, LPWSTR dll_path, int abi_version);
|
||||||
|
|
||||||
|
static MonoAssembly* mono_assembly_search_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data);
|
||||||
|
|
||||||
static void set_environment(LPCWSTR bin_path)
|
static void set_environment(LPCWSTR bin_path)
|
||||||
{
|
{
|
||||||
WCHAR path_env[MAX_PATH];
|
WCHAR path_env[MAX_PATH];
|
||||||
|
@ -93,6 +96,7 @@ static HRESULT load_mono(CLRRuntimeInfo *This, loaded_mono **result)
|
||||||
static const WCHAR bin[] = {'\\','b','i','n',0};
|
static const WCHAR bin[] = {'\\','b','i','n',0};
|
||||||
static const WCHAR lib[] = {'\\','l','i','b',0};
|
static const WCHAR lib[] = {'\\','l','i','b',0};
|
||||||
static const WCHAR etc[] = {'\\','e','t','c',0};
|
static const WCHAR etc[] = {'\\','e','t','c',0};
|
||||||
|
static const WCHAR glibdll[] = {'l','i','b','g','l','i','b','-','2','.','0','-','0','.','d','l','l',0};
|
||||||
WCHAR mono_dll_path[MAX_PATH+16], mono_bin_path[MAX_PATH+4];
|
WCHAR mono_dll_path[MAX_PATH+16], mono_bin_path[MAX_PATH+4];
|
||||||
WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
|
WCHAR mono_lib_path[MAX_PATH+4], mono_etc_path[MAX_PATH+4];
|
||||||
char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
|
char mono_lib_path_a[MAX_PATH], mono_etc_path_a[MAX_PATH];
|
||||||
|
@ -134,13 +138,30 @@ static HRESULT load_mono(CLRRuntimeInfo *This, loaded_mono **result)
|
||||||
} \
|
} \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
LOAD_MONO_FUNCTION(mono_assembly_open);
|
||||||
LOAD_MONO_FUNCTION(mono_config_parse);
|
LOAD_MONO_FUNCTION(mono_config_parse);
|
||||||
LOAD_MONO_FUNCTION(mono_domain_assembly_open);
|
LOAD_MONO_FUNCTION(mono_domain_assembly_open);
|
||||||
|
LOAD_MONO_FUNCTION(mono_install_assembly_preload_hook);
|
||||||
LOAD_MONO_FUNCTION(mono_jit_cleanup);
|
LOAD_MONO_FUNCTION(mono_jit_cleanup);
|
||||||
LOAD_MONO_FUNCTION(mono_jit_exec);
|
LOAD_MONO_FUNCTION(mono_jit_exec);
|
||||||
LOAD_MONO_FUNCTION(mono_jit_init);
|
LOAD_MONO_FUNCTION(mono_jit_init);
|
||||||
LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
|
LOAD_MONO_FUNCTION(mono_jit_set_trace_options);
|
||||||
LOAD_MONO_FUNCTION(mono_set_dirs);
|
LOAD_MONO_FUNCTION(mono_set_dirs);
|
||||||
|
LOAD_MONO_FUNCTION(mono_stringify_assembly_name);
|
||||||
|
|
||||||
|
/* GLib imports obsoleted by the 2.0 ABI */
|
||||||
|
if (This->mono_abi_version == 1)
|
||||||
|
{
|
||||||
|
(*result)->glib_handle = LoadLibraryW(glibdll);
|
||||||
|
if (!(*result)->glib_handle) goto fail;
|
||||||
|
|
||||||
|
(*result)->mono_free = (void*)GetProcAddress((*result)->glib_handle, "g_free");
|
||||||
|
if (!(*result)->mono_free) goto fail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOAD_MONO_FUNCTION(mono_free);
|
||||||
|
}
|
||||||
|
|
||||||
#undef LOAD_MONO_FUNCTION
|
#undef LOAD_MONO_FUNCTION
|
||||||
|
|
||||||
|
@ -148,6 +169,8 @@ static HRESULT load_mono(CLRRuntimeInfo *This, loaded_mono **result)
|
||||||
|
|
||||||
(*result)->mono_config_parse(NULL);
|
(*result)->mono_config_parse(NULL);
|
||||||
|
|
||||||
|
(*result)->mono_install_assembly_preload_hook(mono_assembly_search_hook_fn, *result);
|
||||||
|
|
||||||
trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
|
trace_size = GetEnvironmentVariableA("WINE_MONO_TRACE", trace_setting, sizeof(trace_setting));
|
||||||
|
|
||||||
if (trace_size)
|
if (trace_size)
|
||||||
|
@ -161,7 +184,9 @@ static HRESULT load_mono(CLRRuntimeInfo *This, loaded_mono **result)
|
||||||
fail:
|
fail:
|
||||||
ERR("Could not load Mono into this process\n");
|
ERR("Could not load Mono into this process\n");
|
||||||
FreeLibrary((*result)->mono_handle);
|
FreeLibrary((*result)->mono_handle);
|
||||||
|
FreeLibrary((*result)->glib_handle);
|
||||||
(*result)->mono_handle = NULL;
|
(*result)->mono_handle = NULL;
|
||||||
|
(*result)->glib_handle = NULL;
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1039,6 +1064,93 @@ extern HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj)
|
||||||
return ICLRMetaHost_QueryInterface((ICLRMetaHost*)&GlobalCLRMetaHost, riid, ppobj);
|
return ICLRMetaHost_QueryInterface((ICLRMetaHost*)&GlobalCLRMetaHost, riid, ppobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MonoAssembly* mono_assembly_search_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
|
||||||
|
{
|
||||||
|
loaded_mono *mono = user_data;
|
||||||
|
HRESULT hr=S_OK;
|
||||||
|
MonoAssembly *result=NULL;
|
||||||
|
char *stringname=NULL;
|
||||||
|
LPWSTR stringnameW;
|
||||||
|
int stringnameW_size;
|
||||||
|
IAssemblyCache *asmcache;
|
||||||
|
ASSEMBLY_INFO info;
|
||||||
|
WCHAR path[MAX_PATH];
|
||||||
|
char *pathA;
|
||||||
|
MonoImageOpenStatus stat;
|
||||||
|
static WCHAR fusiondll[] = {'f','u','s','i','o','n',0};
|
||||||
|
HMODULE hfusion=NULL;
|
||||||
|
static HRESULT WINAPI (*pCreateAssemblyCache)(IAssemblyCache**,DWORD);
|
||||||
|
|
||||||
|
stringname = mono->mono_stringify_assembly_name(aname);
|
||||||
|
|
||||||
|
TRACE("%s\n", debugstr_a(stringname));
|
||||||
|
|
||||||
|
if (!stringname) return NULL;
|
||||||
|
|
||||||
|
/* FIXME: We should search the given paths before the GAC. */
|
||||||
|
|
||||||
|
if (!pCreateAssemblyCache)
|
||||||
|
{
|
||||||
|
hr = LoadLibraryShim(fusiondll, NULL, NULL, &hfusion);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
pCreateAssemblyCache = (void*)GetProcAddress(hfusion, "CreateAssemblyCache");
|
||||||
|
if (!pCreateAssemblyCache)
|
||||||
|
hr = E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
hr = pCreateAssemblyCache(&asmcache, 0);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, stringname, -1, NULL, 0);
|
||||||
|
|
||||||
|
stringnameW = HeapAlloc(GetProcessHeap(), 0, stringnameW_size * sizeof(WCHAR));
|
||||||
|
if (stringnameW)
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, stringname, -1, stringnameW, stringnameW_size);
|
||||||
|
else
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
info.cbAssemblyInfo = sizeof(info);
|
||||||
|
info.pszCurrentAssemblyPathBuf = path;
|
||||||
|
info.cchBuf = MAX_PATH;
|
||||||
|
path[0] = 0;
|
||||||
|
|
||||||
|
hr = IAssemblyCache_QueryAssemblyInfo(asmcache, 0, stringnameW, &info);
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, stringnameW);
|
||||||
|
|
||||||
|
IAssemblyCache_Release(asmcache);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
TRACE("found: %s\n", debugstr_w(path));
|
||||||
|
|
||||||
|
pathA = WtoA(path);
|
||||||
|
|
||||||
|
if (pathA)
|
||||||
|
{
|
||||||
|
result = mono->mono_assembly_open(pathA, &stat);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
ERR("Failed to load %s, status=%u\n", debugstr_w(path), stat);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, pathA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mono->mono_free(stringname);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
|
HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file,
|
||||||
DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result)
|
DWORD startup_flags, DWORD runtimeinfo_flags, BOOL legacy, ICLRRuntimeInfo **result)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "cor.h"
|
#include "cor.h"
|
||||||
#include "corerror.h"
|
#include "corerror.h"
|
||||||
#include "mscoree.h"
|
#include "mscoree.h"
|
||||||
|
#include "fusion.h"
|
||||||
#include "metahost.h"
|
#include "metahost.h"
|
||||||
#include "wine/list.h"
|
#include "wine/list.h"
|
||||||
#include "mscoree_private.h"
|
#include "mscoree_private.h"
|
||||||
|
@ -50,6 +51,21 @@ WINE_DEFAULT_DEBUG_CHANNEL( mscoree );
|
||||||
|
|
||||||
LONG dll_refs = 0;
|
LONG dll_refs = 0;
|
||||||
|
|
||||||
|
char *WtoA(LPCWSTR wstr)
|
||||||
|
{
|
||||||
|
int length;
|
||||||
|
char *result;
|
||||||
|
|
||||||
|
length = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
|
||||||
|
|
||||||
|
result = HeapAlloc(GetProcessHeap(), 0, length);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, result, length, NULL, NULL);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL get_install_root(LPWSTR install_dir)
|
static BOOL get_install_root(LPWSTR install_dir)
|
||||||
{
|
{
|
||||||
const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0};
|
const WCHAR dotnet_key[] = {'S','O','F','T','W','A','R','E','\\','M','i','c','r','o','s','o','f','t','\\','.','N','E','T','F','r','a','m','e','w','o','r','k','\\',0};
|
||||||
|
|
|
@ -24,6 +24,8 @@ extern LONG dll_refs;
|
||||||
static inline void MSCOREE_LockModule(void) { InterlockedIncrement(&dll_refs); }
|
static inline void MSCOREE_LockModule(void) { InterlockedIncrement(&dll_refs); }
|
||||||
static inline void MSCOREE_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
|
static inline void MSCOREE_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
|
||||||
|
|
||||||
|
extern char *WtoA(LPCWSTR wstr);
|
||||||
|
|
||||||
extern HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj);
|
extern HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj);
|
||||||
|
|
||||||
typedef struct tagASSEMBLY ASSEMBLY;
|
typedef struct tagASSEMBLY ASSEMBLY;
|
||||||
|
@ -71,21 +73,36 @@ extern HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result);
|
||||||
|
|
||||||
extern void free_parsed_config_file(parsed_config_file *file);
|
extern void free_parsed_config_file(parsed_config_file *file);
|
||||||
|
|
||||||
/* Mono 2.6 embedding */
|
/* Mono embedding */
|
||||||
typedef struct _MonoDomain MonoDomain;
|
typedef struct _MonoDomain MonoDomain;
|
||||||
typedef struct _MonoAssembly MonoAssembly;
|
typedef struct _MonoAssembly MonoAssembly;
|
||||||
|
typedef struct _MonoAssemblyName MonoAssemblyName;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MONO_IMAGE_OK,
|
||||||
|
MONO_IMAGE_ERROR_ERRNO,
|
||||||
|
MONO_IMAGE_MISSING_ASSEMBLYREF,
|
||||||
|
MONO_IMAGE_IMAGE_INVALID
|
||||||
|
} MonoImageOpenStatus;
|
||||||
|
|
||||||
|
typedef MonoAssembly* (*MonoAssemblyPreLoadFunc)(MonoAssemblyName *aname, char **assemblies_path, void *user_data);
|
||||||
|
|
||||||
typedef struct loaded_mono
|
typedef struct loaded_mono
|
||||||
{
|
{
|
||||||
HMODULE mono_handle;
|
HMODULE mono_handle;
|
||||||
|
HMODULE glib_handle;
|
||||||
|
|
||||||
|
MonoAssembly* (*mono_assembly_open)(const char *filename, MonoImageOpenStatus *status);
|
||||||
void (*mono_config_parse)(const char *filename);
|
void (*mono_config_parse)(const char *filename);
|
||||||
MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name);
|
MonoAssembly* (*mono_domain_assembly_open) (MonoDomain *domain, const char *name);
|
||||||
|
void (*mono_free)(void *);
|
||||||
|
void (*mono_install_assembly_preload_hook)(MonoAssemblyPreLoadFunc func, void *user_data);
|
||||||
void (*mono_jit_cleanup)(MonoDomain *domain);
|
void (*mono_jit_cleanup)(MonoDomain *domain);
|
||||||
int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
|
int (*mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]);
|
||||||
MonoDomain* (*mono_jit_init)(const char *file);
|
MonoDomain* (*mono_jit_init)(const char *file);
|
||||||
int (*mono_jit_set_trace_options)(const char* options);
|
int (*mono_jit_set_trace_options)(const char* options);
|
||||||
void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir);
|
void (*mono_set_dirs)(const char *assembly_dir, const char *config_dir);
|
||||||
|
char* (*mono_stringify_assembly_name)(MonoAssemblyName *aname);
|
||||||
} loaded_mono;
|
} loaded_mono;
|
||||||
|
|
||||||
/* loaded runtime interfaces */
|
/* loaded runtime interfaces */
|
||||||
|
|
Loading…
Reference in New Issue