>From af406d48a1e447eafb9cb807472611f6dfb9d4cf Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 16 Dec 2011 09:15:11 +1100
Subject: [PATCH] Implement CLRRuntimeHost_ExecuteInDefaultAppDomain
To: wine-patches <wine-patches@winehq.org>

---
 dlls/mscoree/corruntimehost.c  |   83 +++++++++++++++++++++++++++++++++++++++-
 dlls/mscoree/metahost.c        |    1 +
 dlls/mscoree/mscoree_private.h |    2 +
 3 files changed, 84 insertions(+), 2 deletions(-)

diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c
index b7e4f5f..04482be 100644
--- a/dlls/mscoree/corruntimehost.c
+++ b/dlls/mscoree/corruntimehost.c
@@ -534,9 +534,88 @@ static HRESULT WINAPI CLRRuntimeHost_ExecuteInDefaultAppDomain(ICLRRuntimeHost*
     LPCWSTR pwzAssemblyPath, LPCWSTR pwzTypeName, LPCWSTR pwzMethodName,
     LPCWSTR pwzArgument, DWORD *pReturnValue)
 {
-    FIXME("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath),
+    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;
+
+    TRACE("(%p,%s,%s,%s,%s)\n", iface, debugstr_w(pwzAssemblyPath),
         debugstr_w(pwzTypeName), debugstr_w(pwzMethodName), debugstr_w(pwzArgument));
-    return E_NOTIMPL;
+
+    hr = RuntimeHost_GetDefaultDomain(This, &domain);
+    if(hr != S_OK)
+    {
+        ERR("Couldn't get Default Domain\n");
+        return hr;
+    }
+
+    hr = E_FAIL;
+
+    filenameA = WtoA(pwzAssemblyPath);
+    assembly = This->mono->mono_domain_assembly_open(domain, filenameA);
+    if (!assembly)
+    {
+        ERR("Cannot open assembly %s\n", filenameA);
+        goto cleanup;
+    }
+
+    image = This->mono->mono_assembly_get_image(assembly);
+    if (!image)
+    {
+        ERR("Couldn't get assembly image\n");
+        goto cleanup;
+    }
+
+    classA = WtoA(pwzTypeName);
+    ns = strrchr(classA, '.');
+    *ns = '\0';
+    klass = This->mono->mono_class_from_name(image, classA, ns+1);
+    if (!klass)
+    {
+        ERR("Couldn't get class from image\n");
+        goto cleanup;
+    }
+
+    methodA = WtoA(pwzMethodName);
+    method = This->mono->mono_class_get_method_from_name(klass, methodA, 1);
+    if (!method)
+    {
+        ERR("Couldn't get method from class\n");
+        goto cleanup;
+    }
+
+    argsA = WtoA(pwzArgument);
+    str = This->mono->mono_string_new(domain, argsA);
+    args[0] = &str;
+    args[1] = NULL;
+    result = This->mono->mono_runtime_invoke(method, NULL, args, NULL);
+    if (!result)
+        ERR("Couldn't get result pointer\n");
+    else
+    {
+        *pReturnValue = *(DWORD*)This->mono->mono_object_unbox(result);
+        hr = S_OK;
+    }
+
+cleanup:
+    if(filenameA)
+        HeapFree(GetProcessHeap(), 0, filenameA);
+    if(classA)
+        HeapFree(GetProcessHeap(), 0, classA);
+    if(argsA)
+        HeapFree(GetProcessHeap(), 0, argsA);
+    if(methodA)
+        HeapFree(GetProcessHeap(), 0, methodA);
+
+    return hr;
 }
 
 static const struct ICLRRuntimeHostVtbl CLRHostVtbl =
diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c
index d9e36a8..454a653 100644
--- a/dlls/mscoree/metahost.c
+++ b/dlls/mscoree/metahost.c
@@ -185,6 +185,7 @@ static HRESULT load_mono(CLRRuntimeInfo *This, loaded_mono **result)
         LOAD_MONO_FUNCTION(mono_runtime_quit);
         LOAD_MONO_FUNCTION(mono_set_dirs);
         LOAD_MONO_FUNCTION(mono_stringify_assembly_name);
+        LOAD_MONO_FUNCTION(mono_string_new);
 
         /* GLib imports obsoleted by the 2.0 ABI */
         if (This->mono_abi_version == 1)
diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h
index 71bf738..a45a405 100644
--- a/dlls/mscoree/mscoree_private.h
+++ b/dlls/mscoree/mscoree_private.h
@@ -41,6 +41,7 @@ typedef struct _MonoType MonoType;
 typedef struct _MonoImage MonoImage;
 typedef struct _MonoClass MonoClass;
 typedef struct _MonoObject MonoObject;
+typedef struct _MonoString MonoString;
 typedef struct _MonoMethod MonoMethod;
 typedef struct _MonoProfiler MonoProfiler;
 
@@ -161,6 +162,7 @@ struct loaded_mono
     void (CDECL *mono_thread_pool_cleanup)(void);
     void (CDECL *mono_thread_suspend_all_other_threads)(void);
     void (CDECL *mono_threads_set_shutting_down)(void);
+    MonoString* (CDECL *mono_string_new)(MonoDomain *domain, const char *str);
 };
 
 /* loaded runtime interfaces */
-- 
1.7.5.4

