Commit d7031be8 authored by Gijs Vermeulen's avatar Gijs Vermeulen Committed by Alexandre Julliard

mscoree: Support loading assemblies from path specified in config file.

parent 79c5d8af
...@@ -347,8 +347,15 @@ static HRESULT parse_probing(ConfigFileHandler *This, ISAXAttributes *pAttr) ...@@ -347,8 +347,15 @@ static HRESULT parse_probing(ConfigFileHandler *This, ISAXAttributes *pAttr)
hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, privatePath, lstrlenW(privatePath), &value, &value_size); hr = ISAXAttributes_getValueFromName(pAttr, empty, 0, privatePath, lstrlenW(privatePath), &value, &value_size);
if (SUCCEEDED(hr)) 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; return hr;
} }
...@@ -698,4 +705,6 @@ void free_parsed_config_file(parsed_config_file *file) ...@@ -698,4 +705,6 @@ void free_parsed_config_file(parsed_config_file *file)
list_remove(&cursor->entry); list_remove(&cursor->entry);
HeapFree(GetProcessHeap(), 0, cursor); 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 ...@@ -58,6 +58,8 @@ static HANDLE dll_fixup_heap; /* using a separate heap so we can have execute pe
static struct list dll_fixups; static struct list dll_fixups;
WCHAR **private_path = NULL;
struct dll_fixup struct dll_fixup
{ {
struct list entry; struct list entry;
...@@ -1436,6 +1438,8 @@ static void FixupVTable(HMODULE hmodule) ...@@ -1436,6 +1438,8 @@ static void FixupVTable(HMODULE hmodule)
__int32 WINAPI _CorExeMain(void) __int32 WINAPI _CorExeMain(void)
{ {
static const WCHAR dotconfig[] = {'.','c','o','n','f','i','g',0};
static const WCHAR scW[] = {';',0};
int exit_code; int exit_code;
int argc; int argc;
char **argv; char **argv;
...@@ -1443,12 +1447,14 @@ __int32 WINAPI _CorExeMain(void) ...@@ -1443,12 +1447,14 @@ __int32 WINAPI _CorExeMain(void)
MonoImage *image; MonoImage *image;
MonoImageOpenStatus status; MonoImageOpenStatus status;
MonoAssembly *assembly=NULL; 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; char *filenameA;
ICLRRuntimeInfo *info; ICLRRuntimeInfo *info;
RuntimeHost *host; RuntimeHost *host;
parsed_config_file parsed_config;
HRESULT hr; HRESULT hr;
int i; int i, number_of_private_paths = 0;
get_utf8_args(&argc, &argv); get_utf8_args(&argc, &argv);
...@@ -1468,6 +1474,33 @@ __int32 WINAPI _CorExeMain(void) ...@@ -1468,6 +1474,33 @@ __int32 WINAPI _CorExeMain(void)
FixupVTable(GetModuleHandleW(NULL)); 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); hr = get_runtime_info(filename, NULL, NULL, NULL, 0, 0, FALSE, &info);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
...@@ -1475,15 +1508,7 @@ __int32 WINAPI _CorExeMain(void) ...@@ -1475,15 +1508,7 @@ __int32 WINAPI _CorExeMain(void)
hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host); hr = ICLRRuntimeInfo_GetRuntimeHost(info, &host);
if (SUCCEEDED(hr)) 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); hr = RuntimeHost_GetDefaultDomain(host, config_file, &domain);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
......
...@@ -1610,20 +1610,56 @@ static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname ...@@ -1610,20 +1610,56 @@ static MonoAssembly* CDECL mono_assembly_preload_hook_fn(MonoAssemblyName *aname
HRESULT hr; HRESULT hr;
MonoAssembly *result=NULL; MonoAssembly *result=NULL;
char *stringname=NULL; char *stringname=NULL;
const char *assemblyname;
LPWSTR stringnameW; LPWSTR stringnameW;
int stringnameW_size; int stringnameW_size;
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
char *pathA; char *pathA;
MonoImageOpenStatus stat; MonoImageOpenStatus stat;
DWORD search_flags; DWORD search_flags;
int i;
static const WCHAR dotdllW[] = {'.','d','l','l',0};
static const WCHAR slashW[] = {'\\',0};
stringname = mono_stringify_assembly_name(aname); stringname = mono_stringify_assembly_name(aname);
assemblyname = mono_assembly_name_get_name(aname);
TRACE("%s\n", debugstr_a(stringname)); TRACE("%s\n", debugstr_a(stringname));
if (!stringname) return NULL; if (!stringname || !assemblyname) return NULL;
search_flags = get_assembly_search_flags(aname); 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. */ /* FIXME: We should search the given paths before the GAC. */
......
...@@ -117,6 +117,7 @@ extern HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk) DECLSPEC_HIDDE ...@@ -117,6 +117,7 @@ extern HRESULT MetaDataDispenser_CreateInstance(IUnknown **ppUnk) DECLSPEC_HIDDE
typedef struct parsed_config_file typedef struct parsed_config_file
{ {
struct list supported_runtimes; struct list supported_runtimes;
LPWSTR private_path;
} parsed_config_file; } parsed_config_file;
typedef struct supported_runtime typedef struct supported_runtime
...@@ -125,6 +126,8 @@ typedef struct supported_runtime ...@@ -125,6 +126,8 @@ typedef struct supported_runtime
LPWSTR version; LPWSTR version;
} supported_runtime; } supported_runtime;
extern WCHAR **private_path;
extern HRESULT parse_config_file(LPCWSTR filename, parsed_config_file *result) DECLSPEC_HIDDEN; 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; extern HRESULT parse_config_stream(IStream *stream, parsed_config_file *result) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment