From: Vincent Povirk Subject: [2/2] mscoree: Factor out common code for calling .NET methods. Message-Id: Date: Mon, 18 Aug 2014 11:33:30 -0500 From 0b97eb7dbf76ec8fed490316e1212765bf948347 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Wed, 13 Aug 2014 17:05:44 -0500 Subject: [PATCH 2/2] mscoree: Factor out common code for calling .NET methods. --- dlls/mscoree/corruntimehost.c | 235 ++++++++++++++++-------------------------- 1 file changed, 91 insertions(+), 144 deletions(-) diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c index b44fb6a..ce73134 100644 --- a/dlls/mscoree/corruntimehost.c +++ b/dlls/mscoree/corruntimehost.c @@ -153,23 +153,25 @@ static void RuntimeHost_DeleteDomain(RuntimeHost *This, MonoDomain *domain) LeaveCriticalSection(&This->lock); } -static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk) +static HRESULT RuntimeHost_Invoke(RuntimeHost *This, MonoDomain *domain, + const char *assemblyname, const char *namespace, const char *typename, const char *methodname, + MonoObject *obj, void **args, int arg_count, MonoObject **result) { - HRESULT hr; - void *args[1]; MonoAssembly *assembly; MonoImage *image; MonoClass *klass; MonoMethod *method; - MonoObject *appdomain_object; - IUnknown *unk; + MonoObject *exc; + static const char *get_hresult = "get_HResult"; + + *result = NULL; mono_thread_attach(domain); - assembly = mono_domain_assembly_open(domain, "mscorlib"); + assembly = mono_domain_assembly_open(domain, assemblyname); if (!assembly) { - ERR("Cannot load mscorlib\n"); + ERR("Cannot load assembly\n"); return E_FAIL; } @@ -180,29 +182,57 @@ static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *d return E_FAIL; } - klass = mono_class_from_name(image, "System", "AppDomain"); + klass = mono_class_from_name(image, namespace, typename); if (!klass) { ERR("Couldn't get class from image\n"); return E_FAIL; } - method = mono_class_get_method_from_name(klass, "get_CurrentDomain", 0); + method = mono_class_get_method_from_name(klass, methodname, arg_count); if (!method) { ERR("Couldn't get method from class\n"); return E_FAIL; } - args[0] = NULL; - appdomain_object = mono_runtime_invoke(method, NULL, args, NULL); - if (!appdomain_object) + *result = mono_runtime_invoke(method, obj, args, &exc); + if (exc) { - ERR("Couldn't get result pointer\n"); - return E_FAIL; + HRESULT hr; + MonoObject *hr_object; + + if (methodname != get_hresult) + { + /* Map the exception to an HRESULT. */ + hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System", "Exception", get_hresult, + exc, NULL, 0, &hr_object); + if (SUCCEEDED(hr)) + hr = *(HRESULT*)mono_object_unbox(hr_object); + if (SUCCEEDED(hr)) + hr = E_FAIL; + } + else + hr = E_FAIL; + ERR("Method %s.%s raised an exception, hr=%x\n", namespace, typename, hr); + *result = NULL; + return hr; } - hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk); + return S_OK; +} + +static HRESULT RuntimeHost_GetIUnknownForDomain(RuntimeHost *This, MonoDomain *domain, IUnknown **punk) +{ + HRESULT hr; + MonoObject *appdomain_object; + IUnknown *unk; + + hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System", "AppDomain", "get_CurrentDomain", + NULL, NULL, 0, &appdomain_object); + + if (SUCCEEDED(hr)) + hr = RuntimeHost_GetIUnknownForObject(This, appdomain_object, &unk); if (SUCCEEDED(hr)) { @@ -219,10 +249,7 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode) HRESULT hr; void *args[2]; MonoDomain *domain; - MonoAssembly *assembly; - MonoImage *image; - MonoClass *klass; - MonoMethod *method; + MonoObject *dummy; hr = RuntimeHost_GetDefaultDomain(This, &domain); if (FAILED(hr)) @@ -231,39 +258,10 @@ void RuntimeHost_ExitProcess(RuntimeHost *This, INT exitcode) return; } - mono_thread_attach(domain); - - assembly = mono_domain_assembly_open(domain, "mscorlib"); - if (!assembly) - { - ERR("Cannot load mscorlib\n"); - return; - } - - image = mono_assembly_get_image(assembly); - if (!image) - { - ERR("Couldn't get assembly image\n"); - return; - } - - klass = mono_class_from_name(image, "System", "Environment"); - if (!klass) - { - ERR("Couldn't get class from image\n"); - return; - } - - method = mono_class_get_method_from_name(klass, "Exit", 1); - if (!method) - { - ERR("Couldn't get method from class\n"); - return; - } - args[0] = &exitcode; args[1] = NULL; - mono_runtime_invoke(method, NULL, args, NULL); + RuntimeHost_Invoke(This, domain, "mscorlib", "System", "Environment", "Exit", + NULL, args, 1, &dummy); ERR("Process should have exited\n"); } @@ -629,13 +627,8 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* RuntimeHost *This = impl_from_ICLRRuntimeHost( iface ); HRESULT hr; MonoDomain *domain; - MonoAssembly *assembly; - MonoImage *image; - MonoClass *klass; - MonoMethod *method; MonoObject *result; MonoString *str; - void *args[2]; char *filenameA = NULL, *classA = NULL, *methodA = NULL; char *argsA = NULL, *ns; @@ -643,66 +636,60 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost* debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument)); hr = RuntimeHost_GetDefaultDomain(This, &domain); - if(hr != S_OK) - { - ERR("Couldn't get Default Domain\n"); - return hr; - } - hr = E_FAIL; - - mono_thread_attach(domain); - - filenameA = WtoA(pwzAssemblyPath); - assembly = mono_domain_assembly_open(domain, filenameA); - if (!assembly) + if (SUCCEEDED(hr)) { - ERR("Cannot open assembly %s\n", filenameA); - goto cleanup; + mono_thread_attach(domain); + + filenameA = WtoA(pwzAssemblyPath); + if (!filenameA) hr = E_OUTOFMEMORY; } - image = mono_assembly_get_image(assembly); - if (!image) + if (SUCCEEDED(hr)) { - ERR("Couldn't get assembly image\n"); - goto cleanup; + classA = WtoA(pwzTypeName); + if (!classA) hr = E_OUTOFMEMORY; } - classA = WtoA(pwzTypeName); - ns = strrchr(classA, '.'); - *ns = '\0'; - klass = mono_class_from_name(image, classA, ns+1); - if (!klass) + if (SUCCEEDED(hr)) { - ERR("Couldn't get class from image\n"); - goto cleanup; + ns = strrchr(classA, '.'); + if (ns) + *ns = '\0'; + else + hr = E_INVALIDARG; } - methodA = WtoA(pwzMethodName); - method = mono_class_get_method_from_name(klass, methodA, 1); - if (!method) + if (SUCCEEDED(hr)) { - ERR("Couldn't get method from class\n"); - goto cleanup; + methodA = WtoA(pwzMethodName); + if (!methodA) hr = E_OUTOFMEMORY; } /* The .NET function we are calling has the following declaration * public static int functionName(String param) */ - argsA = WtoA(pwzArgument); - str = mono_string_new(domain, argsA); - args[0] = str; - args[1] = NULL; - result = mono_runtime_invoke(method, NULL, args, NULL); - if (!result) - ERR("Couldn't get result pointer\n"); - else + if (SUCCEEDED(hr)) { - *pReturnValue = *(DWORD*)mono_object_unbox(result); - hr = S_OK; + argsA = WtoA(pwzArgument); + if (!argsA) hr = E_OUTOFMEMORY; } -cleanup: + if (SUCCEEDED(hr)) + { + str = mono_string_new(domain, argsA); + if (!str) hr = E_OUTOFMEMORY; + } + + if (SUCCEEDED(hr)) + { + hr = RuntimeHost_Invoke(This, domain, filenameA, classA, ns+1, methodA, + NULL, (void**)&str, 1, &result); + } + + if (SUCCEEDED(hr)) + *pReturnValue = *(DWORD*)mono_object_unbox(result); + HeapFree(GetProcessHeap(), 0, filenameA); HeapFree(GetProcessHeap(), 0, classA); HeapFree(GetProcessHeap(), 0, argsA); @@ -807,60 +794,20 @@ HRESULT RuntimeHost_GetIUnknownForObject(RuntimeHost *This, MonoObject *obj, IUnknown **ppUnk) { MonoDomain *domain; - MonoAssembly *assembly; - MonoImage *image; - MonoClass *klass; - MonoMethod *method; MonoObject *result; - void *args[2]; + HRESULT hr; domain = mono_object_get_domain(obj); - assembly = mono_domain_assembly_open(domain, "mscorlib"); - if (!assembly) - { - ERR("Cannot load mscorlib\n"); - return E_FAIL; - } - - image = mono_assembly_get_image(assembly); - if (!image) - { - ERR("Couldn't get assembly image\n"); - return E_FAIL; - } + hr = RuntimeHost_Invoke(This, domain, "mscorlib", "System.Runtime.InteropServices", "Marshal", "GetIUnknownForObject", + NULL, (void**)&obj, 1, &result); - klass = mono_class_from_name(image, "System.Runtime.InteropServices", "Marshal"); - if (!klass) - { - ERR("Couldn't get class from image\n"); - return E_FAIL; - } - - method = mono_class_get_method_from_name(klass, "GetIUnknownForObject", 1); - if (!method) - { - ERR("Couldn't get method from class\n"); - return E_FAIL; - } - - args[0] = obj; - args[1] = NULL; - result = mono_runtime_invoke(method, NULL, args, NULL); - if (!result) - { - ERR("Couldn't get result pointer\n"); - return E_FAIL; - } - - *ppUnk = *(IUnknown**)mono_object_unbox(result); - if (!*ppUnk) - { - ERR("GetIUnknownForObject returned 0\n"); - return E_FAIL; - } + if (SUCCEEDED(hr)) + *ppUnk = *(IUnknown**)mono_object_unbox(result); + else + *ppUnk = NULL; - return S_OK; + return hr; } static void get_utf8_args(int *argc, char ***argv) -- 1.8.3.2