Commit 4dec065e authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

mscoree: Restore previous domain whenever we set it.

Unmanaged APIs could be called directly or indirectly by managed code in any domain, and we could create problems by not restoring the old one. Signed-off-by: 's avatarVincent Povirk <vincent@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 6ff1f38b
......@@ -68,6 +68,25 @@ struct dll_fixup
void *tokens; /* pointer into process heap */
};
static MonoDomain* domain_attach(MonoDomain *domain)
{
MonoDomain *prev_domain = mono_domain_get();
if (prev_domain == domain)
/* Do not set or restore domain. */
return NULL;
mono_thread_attach(domain);
return prev_domain;
}
static void domain_restore(MonoDomain *prev_domain)
{
if (prev_domain != NULL)
mono_domain_set(prev_domain, FALSE);
}
static HRESULT RuntimeHost_AddDefaultDomain(RuntimeHost *This, MonoDomain **result)
{
struct DomainEntry *entry;
......@@ -267,15 +286,17 @@ static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain,
MonoObject *obj, void **args, int arg_count, MonoObject **result)
{
MonoMethod *method;
MonoDomain *prev_domain;
HRESULT hr;
*result = NULL;
mono_thread_attach(domain);
prev_domain = domain_attach(domain);
if (!RuntimeHost_GetMethod(domain, assemblyname, namespace, typename, methodname,
arg_count, &method))
{
domain_restore(prev_domain);
return E_FAIL;
}
......@@ -285,6 +306,8 @@ static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain,
ERR("Method %s.%s:%s raised an exception, hr=%x\n", namespace, typename, methodname, hr);
}
domain_restore(prev_domain);
return hr;
}
......@@ -293,6 +316,7 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain,
MonoObject *obj, void **args, int arg_count, MonoObject **result)
{
MonoMethod *method;
MonoDomain *prev_domain;
HRESULT hr;
*result = NULL;
......@@ -303,11 +327,12 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain,
return E_POINTER;
}
mono_thread_attach(domain);
prev_domain = domain_attach(domain);
if (!RuntimeHost_GetMethod(domain, assemblyname, namespace, typename, methodname,
arg_count, &method))
{
domain_restore(prev_domain);
return E_FAIL;
}
......@@ -315,6 +340,7 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain,
if (!method)
{
ERR("Object %p does not support method %s.%s:%s\n", obj, namespace, typename, methodname);
domain_restore(prev_domain);
return E_FAIL;
}
......@@ -324,6 +350,8 @@ static HRESULT RuntimeHost_VirtualInvoke(RuntimeHost *This, MonoDomain *domain,
ERR("Method %s.%s:%s raised an exception, hr=%x\n", namespace, typename, methodname, hr);
}
domain_restore(prev_domain);
return hr;
}
......@@ -853,7 +881,7 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
{
RuntimeHost *This = impl_from_ICLRRuntimeHost( iface );
HRESULT hr;
MonoDomain *domain;
MonoDomain *domain, *prev_domain;
MonoObject *result;
MonoString *str;
char *filenameA = NULL, *classA = NULL, *methodA = NULL;
......@@ -864,10 +892,13 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain);
if (FAILED(hr))
return hr;
prev_domain = domain_attach(domain);
if (SUCCEEDED(hr))
{
mono_thread_attach(domain);
filenameA = WtoA(pwzAssemblyPath);
if (!filenameA) hr = E_OUTOFMEMORY;
}
......@@ -917,6 +948,8 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
if (SUCCEEDED(hr))
*pReturnValue = *(DWORD*)mono_object_unbox(result);
domain_restore(prev_domain);
HeapFree(GetProcessHeap(), 0, filenameA);
HeapFree(GetProcessHeap(), 0, classA);
HeapFree(GetProcessHeap(), 0, argsA);
......@@ -952,10 +985,16 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
MonoType *type;
MonoClass *klass;
MonoObject *obj;
MonoDomain *prev_domain;
if (!domain)
hr = RuntimeHost_GetDefaultDomain(This, NULL, &domain);
if (FAILED(hr))
return hr;
prev_domain = domain_attach(domain);
if (SUCCEEDED(hr))
{
nameA = WtoA(name);
......@@ -965,8 +1004,6 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
if (SUCCEEDED(hr))
{
mono_thread_attach(domain);
type = mono_reflection_type_from_name(nameA, NULL);
if (!type)
{
......@@ -1002,6 +1039,8 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
*result = obj;
}
domain_restore(prev_domain);
HeapFree(GetProcessHeap(), 0, nameA);
return hr;
......@@ -1014,9 +1053,7 @@ HRESULT RuntimeHost_CreateManagedInstance(RuntimeHost *This, LPCWSTR name,
*
* NOTE: The IUnknown* is created with a reference to the object.
* Until they have a reference, objects must be in the stack to prevent the
* garbage collector from freeing them.
*
* mono_thread_attach must have already been called for this thread. */
* garbage collector from freeing them. */
HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj,
IUnknown **ppUnk)
{
......@@ -1230,35 +1267,39 @@ static void CDECL ReallyFixupVTable(struct dll_fixup *fixup)
if (SUCCEEDED(hr))
{
mono_thread_attach(domain);
MonoDomain *prev_domain;
prev_domain = domain_attach(domain);
assembly = mono_assembly_open(filenameA, &status);
}
if (assembly)
{
int i;
if (assembly)
{
int i;
/* Mono needs an image that belongs to an assembly. */
image = mono_assembly_get_image(assembly);
/* Mono needs an image that belongs to an assembly. */
image = mono_assembly_get_image(assembly);
#if __x86_64__
if (fixup->fixup->type & COR_VTABLE_64BIT)
if (fixup->fixup->type & COR_VTABLE_64BIT)
#else
if (fixup->fixup->type & COR_VTABLE_32BIT)
if (fixup->fixup->type & COR_VTABLE_32BIT)
#endif
{
void **vtable = fixup->vtable;
ULONG_PTR *tokens = fixup->tokens;
for (i=0; i<fixup->fixup->count; i++)
{
TRACE("%#lx\n", tokens[i]);
vtable[i] = mono_marshal_get_vtfixup_ftnptr(
image, tokens[i], fixup->fixup->type);
void **vtable = fixup->vtable;
ULONG_PTR *tokens = fixup->tokens;
for (i=0; i<fixup->fixup->count; i++)
{
TRACE("%#lx\n", tokens[i]);
vtable[i] = mono_marshal_get_vtfixup_ftnptr(
image, tokens[i], fixup->fixup->type);
}
}
fixup->done = TRUE;
}
fixup->done = TRUE;
domain_restore(prev_domain);
}
if (info != NULL)
......@@ -1686,13 +1727,14 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
MonoImage *image;
MonoClass *klass;
MonoObject *result;
MonoDomain *prev_domain;
IUnknown *unk = NULL;
char *filenameA, *ns;
char *classA;
hr = CLASS_E_CLASSNOTAVAILABLE;
mono_thread_attach(domain);
prev_domain = domain_attach(domain);
filenameA = WtoA(filename);
assembly = mono_domain_assembly_open(domain, filenameA);
......@@ -1700,6 +1742,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
if (!assembly)
{
ERR("Cannot open assembly %s\n", filenameA);
domain_restore(prev_domain);
goto cleanup;
}
......@@ -1707,6 +1750,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
if (!image)
{
ERR("Couldn't get assembly image\n");
domain_restore(prev_domain);
goto cleanup;
}
......@@ -1719,6 +1763,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
if (!klass)
{
ERR("Couldn't get class from image\n");
domain_restore(prev_domain);
goto cleanup;
}
......@@ -1737,6 +1782,8 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
}
else
hr = CLASS_E_CLASSNOTAVAILABLE;
domain_restore(prev_domain);
}
else
hr = CLASS_E_CLASSNOTAVAILABLE;
......
......@@ -79,7 +79,9 @@ MonoClass* (CDECL *mono_class_from_name)(MonoImage *image, const char* name_spac
MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count);
static void (CDECL *mono_config_parse)(const char *filename);
MonoAssembly* (CDECL *mono_domain_assembly_open)(MonoDomain *domain, const char *name);
MonoDomain* (CDECL *mono_domain_get)(void);
MonoDomain* (CDECL *mono_domain_get_by_id)(int id);
BOOL (CDECL *mono_domain_set)(MonoDomain *domain,BOOL force);
void (CDECL *mono_domain_set_config)(MonoDomain *domain,const char *base_dir,const char *config_file_name);
static void (CDECL *mono_free)(void *);
static MonoImage* (CDECL *mono_image_open)(const char *fname, MonoImageOpenStatus *status);
......@@ -177,7 +179,9 @@ static HRESULT load_mono(LPCWSTR mono_path)
LOAD_MONO_FUNCTION(mono_class_from_name);
LOAD_MONO_FUNCTION(mono_class_get_method_from_name);
LOAD_MONO_FUNCTION(mono_domain_assembly_open);
LOAD_MONO_FUNCTION(mono_domain_get);
LOAD_MONO_FUNCTION(mono_domain_get_by_id);
LOAD_MONO_FUNCTION(mono_domain_set);
LOAD_MONO_FUNCTION(mono_domain_set_config);
LOAD_MONO_FUNCTION(mono_free);
LOAD_MONO_FUNCTION(mono_image_open);
......
......@@ -146,7 +146,9 @@ extern MonoClass* (CDECL *mono_class_from_mono_type)(MonoType *type) DECLSPEC_HI
extern MonoClass* (CDECL *mono_class_from_name)(MonoImage *image, const char* name_space, const char *name) DECLSPEC_HIDDEN;
extern MonoMethod* (CDECL *mono_class_get_method_from_name)(MonoClass *klass, const char *name, int param_count) DECLSPEC_HIDDEN;
extern MonoAssembly* (CDECL *mono_domain_assembly_open)(MonoDomain *domain, const char *name) DECLSPEC_HIDDEN;
extern MonoDomain* (CDECL *mono_domain_get_by_id)(int id);
extern MonoDomain* (CDECL *mono_domain_get)(void) DECLSPEC_HIDDEN;
extern MonoDomain* (CDECL *mono_domain_get_by_id)(int id) DECLSPEC_HIDDEN;
extern BOOL (CDECL *mono_domain_set)(MonoDomain *domain, BOOL force) DECLSPEC_HIDDEN;
extern void (CDECL *mono_domain_set_config)(MonoDomain *domain,const char *base_dir,const char *config_file_name) DECLSPEC_HIDDEN;
extern int (CDECL *mono_jit_exec)(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]) DECLSPEC_HIDDEN;
extern MonoDomain* (CDECL *mono_jit_init_version)(const char *domain_name, const char *runtime_version) 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