mscoree: Support loading assemblies from path specified in config file.
Signed-off-by: Gijs Vermeulen <gijsvrm@codeweavers.com> Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
79c5d8af22
commit
d7031be892
|
@ -347,8 +347,15 @@ static HRESULT parse_probing(ConfigFileHandler *This, ISAXAttributes *pAttr)
|
|||
|
||||
hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, privatePath, lstrlenW(privatePath), &value, &value_size);
|
||||
if (SUCCEEDED(hr))
|
||||
FIXME("privatePath=%s not implemented\n", debugstr_wn(value, value_size));
|
||||
hr = S_OK;
|
||||
{
|
||||
TRACE("%s\n", debugstr_wn(value, value_size));
|
||||
|
||||
This->result->private_path = HeapAlloc(GetProcessHeap(), 0, (value_size + 1) * sizeof(WCHAR));
|
||||
if (This->result->private_path)
|
||||
wcscpy(This->result->private_path, value);
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
@ -698,4 +705,6 @@ void free_parsed_config_file(parsed_config_file *file)
|
|||
list_remove(&cursor->entry);
|
||||
HeapFree(GetProcessHeap(), 0, cursor);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, file->private_path);
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ static HANDLE dll_fixup_heap; /* using a separate heap so we can have execute pe
|
|||
|
||||
static struct list dll_fixups;
|
||||
|
||||
WCHAR **private_path = NULL;
|
||||
|
||||
struct dll_fixup
|
||||
{
|
||||
struct list entry;
|
||||
|
@ -1436,6 +1438,8 @@ static void FixupVTable(HMODULE hmodule)
|
|||
|
||||
__int32 WINAPI _CorExeMain(void)
|
||||
{
|
||||
static const WCHAR dotconfig[] = {'.','c','o','n','f','i','g',0};
|
||||
static const WCHAR scW[] = {';',0};
|
||||
int exit_code;
|
||||
int argc;
|
||||
char **argv;
|
||||
|
@ -1443,12 +1447,14 @@ __int32 WINAPI _CorExeMain(void)
|
|||
MonoImage *image;
|
||||
MonoImageOpenStatus status;
|
||||
MonoAssembly *assembly=NULL;
|
||||
WCHAR filename[MAX_PATH];
|
||||
WCHAR filename[MAX_PATH], config_file[MAX_PATH], *temp, **priv_path;
|
||||
SIZE_T config_file_dir_size;
|
||||
char *filenameA;
|
||||
ICLRRuntimeInfo *info;
|
||||
RuntimeHost *host;
|
||||
parsed_config_file parsed_config;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
int i, number_of_private_paths = 0;
|
||||
|
||||
get_utf8_args(&argc, &argv);
|
||||
|
||||
|
@ -1468,6 +1474,33 @@ __int32 WINAPI _CorExeMain(void)
|
|||
|
||||
FixupVTable(GetModuleHandleW(NULL));
|
||||
|
||||
wcscpy(config_file, filename);
|
||||
wcscat(config_file, dotconfig);
|
||||
|
||||
hr = parse_config_file(config_file, &parsed_config);
|
||||
if (SUCCEEDED(hr) && parsed_config.private_path)
|
||||
{
|
||||
for(i = 0; parsed_config.private_path[i] != 0; i++)
|
||||
if (parsed_config.private_path[i] == ';') number_of_private_paths++;
|
||||
if (parsed_config.private_path[wcslen(parsed_config.private_path) - 1] != ';') number_of_private_paths++;
|
||||
config_file_dir_size = (wcsrchr(config_file, '\\') - config_file) + 1;
|
||||
priv_path = HeapAlloc(GetProcessHeap(), 0, (number_of_private_paths + 1) * sizeof(WCHAR *));
|
||||
/* wcstok ignores trailing semicolons */
|
||||
temp = wcstok(parsed_config.private_path, scW);
|
||||
for (i = 0; i < number_of_private_paths; i++)
|
||||
{
|
||||
priv_path[i] = HeapAlloc(GetProcessHeap(), 0, (config_file_dir_size + wcslen(temp) + 1) * sizeof(WCHAR));
|
||||
memcpy(priv_path[i], config_file, config_file_dir_size * sizeof(WCHAR));
|
||||
wcscpy(priv_path[i] + config_file_dir_size, temp);
|
||||
temp = wcstok(NULL, scW);
|
||||
}
|
||||
priv_path[number_of_private_paths] = NULL;
|
||||
if (InterlockedCompareExchangePointer((void **)&private_path, priv_path, NULL))
|
||||
ERR("private_path was already set\n");
|
||||
}
|
||||
|
||||
free_parsed_config_file(&parsed_config);
|
||||
|
||||
hr = get_runtime_info(filename, NULL, NULL, NULL, 0, 0, FALSE, &info);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
@ -1475,15 +1508,7 @@ __int32 WINAPI _CorExeMain(void)
|
|||
hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WCHAR config_file[MAX_PATH];
|
||||
static const WCHAR dotconfig[] = {'.','c','o','n','f','i','g',0};
|
||||
|
||||
lstrcpyW(config_file, filename);
|
||||
lstrcatW(config_file, dotconfig);
|
||||
|
||||
hr = RuntimeHost_GetDefaultDomain(host, config_file, &domain);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
|
@ -1610,20 +1610,56 @@ static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname
|
|||
HRESULT hr;
|
||||
MonoAssembly *result=NULL;
|
||||
char *stringname=NULL;
|
||||
const char *assemblyname;
|
||||
LPWSTR stringnameW;
|
||||
int stringnameW_size;
|
||||
WCHAR path[MAX_PATH];
|
||||
char *pathA;
|
||||
MonoImageOpenStatus stat;
|
||||
DWORD search_flags;
|
||||
int i;
|
||||
static const WCHAR dotdllW[] = {'.','d','l','l',0};
|
||||
static const WCHAR slashW[] = {'\\',0};
|
||||
|
||||
stringname = mono_stringify_assembly_name(aname);
|
||||
assemblyname = mono_assembly_name_get_name(aname);
|
||||
|
||||
TRACE("%s\n", debugstr_a(stringname));
|
||||
|
||||
if (!stringname) return NULL;
|
||||
if (!stringname || !assemblyname) return NULL;
|
||||
|
||||
search_flags = get_assembly_search_flags(aname);
|
||||
if (private_path)
|
||||
{
|
||||
stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, assemblyname, -1, NULL, 0);
|
||||
stringnameW = HeapAlloc(GetProcessHeap(), 0, stringnameW_size * sizeof(WCHAR));
|
||||
if (stringnameW)
|
||||
{
|
||||
MultiByteToWideChar(CP_UTF8, 0, assemblyname, -1, stringnameW, stringnameW_size);
|
||||
for (i = 0; private_path[i] != NULL; i++)
|
||||
{
|
||||
wcscpy(path, private_path[i]);
|
||||
wcscat(path, slashW);
|
||||
wcscat(path, stringnameW);
|
||||
wcscat(path, dotdllW);
|
||||
pathA = WtoA(path);
|
||||
if (pathA)
|
||||
{
|
||||
result = mono_assembly_open(pathA, &stat);
|
||||
if (result)
|
||||
{
|
||||
TRACE("found: %s\n", debugstr_w(path));
|
||||
HeapFree(GetProcessHeap(), 0, pathA);
|
||||
HeapFree(GetProcessHeap(), 0, stringnameW);
|
||||
mono_free(stringname);
|
||||
return result;
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, pathA);
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, stringnameW);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: We should search the given paths before the GAC. */
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ extern HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk) DECLSPEC_HIDDE
|
|||
typedef struct parsed_config_file
|
||||
{
|
||||
struct list supported_runtimes;
|
||||
LPWSTR private_path;
|
||||
} parsed_config_file;
|
||||
|
||||
typedef struct supported_runtime
|
||||
|
@ -125,6 +126,8 @@ typedef struct supported_runtime
|
|||
LPWSTR version;
|
||||
} supported_runtime;
|
||||
|
||||
extern WCHAR **private_path;
|
||||
|
||||
extern HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HRESULT parse_config_stream(IStream *stream, parsed_config_file *result) DECLSPEC_HIDDEN;
|
||||
|
|
Loading…
Reference in New Issue