mscoree/tests: Check if the runtime is usable before loading it.

Vincent Povirk madewokherd at gmail.com
Mon Feb 22 15:04:02 CST 2016


From: Vincent Povirk <vincent at codeweavers.com>

Unfortunately, Mono calls exit(1) if it can't load its class libraries,
which is the way Wine fails on x86_64, meaning we have to spawn another
process to check if the runtime works.

This should fix bug 40186 and also makes the failure on non-x86 a todo.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
---
 dlls/mscoree/tests/mscoree.c | 110 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 109 insertions(+), 1 deletion(-)

diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c
index 106577e..6923f2a 100644
--- a/dlls/mscoree/tests/mscoree.c
+++ b/dlls/mscoree/tests/mscoree.c
@@ -17,6 +17,8 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+#include <stdio.h>
+
 #define COBJMACROS
 
 #include "corerror.h"
@@ -72,6 +74,97 @@ static BOOL init_functionpointers(void)
     return TRUE;
 }
 
+static int check_runtime(void)
+{
+    ICLRMetaHost *metahost;
+    ICLRRuntimeInfo *runtimeinfo;
+    ICorRuntimeHost *runtimehost;
+    HRESULT hr;
+
+    if (!pCLRCreateInstance)
+    {
+        win_skip("Function CLRCreateInstance not found.\n");
+        return 1;
+    }
+
+    hr = pCLRCreateInstance(&CLSID_CLRMetaHost, &IID_ICLRMetaHost, (void **)&metahost);
+    if (hr == E_NOTIMPL)
+    {
+        win_skip("CLRCreateInstance not implemented\n");
+        return 1;
+    }
+    ok(SUCCEEDED(hr), "CLRCreateInstance failed, hr=%#.8x\n", hr);
+    if (FAILED(hr))
+        return 1;
+
+    hr = ICLRMetaHost_GetRuntime(metahost, v4_0, &IID_ICLRRuntimeInfo, (void **)&runtimeinfo);
+    ok(SUCCEEDED(hr), "ICLRMetaHost::GetRuntime failed, hr=%#.8x\n", hr);
+    if (FAILED(hr))
+        return 1;
+
+    hr = ICLRRuntimeInfo_GetInterface(runtimeinfo, &CLSID_CorRuntimeHost, &IID_ICorRuntimeHost,
+        (void **)&runtimehost);
+    ok(SUCCEEDED(hr), "ICLRRuntimeInfo::GetInterface failed, hr=%#.8x\n", hr);
+    if (FAILED(hr))
+        return 1;
+
+    hr = ICorRuntimeHost_Start(runtimehost);
+    ok(SUCCEEDED(hr), "ICorRuntimeHost::Start failed, hr=%#.8x\n", hr);
+    if (FAILED(hr))
+        return 1;
+
+    ICorRuntimeHost_Release(runtimehost);
+
+    ICLRRuntimeInfo_Release(runtimeinfo);
+
+    ICLRMetaHost_ExitProcess(metahost, 0);
+
+    ok(0, "ICLRMetaHost_ExitProcess is not supposed to return\n");
+    return 1;
+}
+
+static BOOL runtime_is_usable(void)
+{
+    static const char cmdline_format[] = "\"%s\" mscoree check_runtime";
+    char** argv;
+    char cmdline[MAX_PATH + sizeof(cmdline_format)];
+    STARTUPINFOA si = {0};
+    PROCESS_INFORMATION pi;
+    BOOL ret;
+    DWORD exitcode;
+
+    winetest_get_mainargs(&argv);
+
+    sprintf(cmdline, cmdline_format, argv[0]);
+
+    si.cb = sizeof(si);
+
+    ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
+    ok(ret, "CreateProcessA failed\n");
+    if (!ret)
+        return FALSE;
+
+    CloseHandle(pi.hThread);
+
+    WaitForSingleObject(pi.hProcess, INFINITE);
+
+    ret = GetExitCodeProcess(pi.hProcess, &exitcode);
+    CloseHandle(pi.hProcess);
+
+    ok(ret, "GetExitCodeProcess failed\n");
+
+    if (!ret || exitcode != 0)
+    {
+#ifndef __i386__
+        todo_wine
+#endif
+        win_skip(".NET 4.0 runtime is not usable\n");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 static void test_versioninfo(void)
 {
     const WCHAR v9_0[] = {'v','9','.','0','.','3','0','3','1','9',0};
@@ -520,14 +613,29 @@ static void test_createdomain(void)
 
 START_TEST(mscoree)
 {
+    int argc;
+    char** argv;
+
     if (!init_functionpointers())
         return;
 
+    argc = winetest_get_mainargs(&argv);
+    if (argc >= 3 && !strcmp(argv[2], "check_runtime"))
+    {
+        int result = check_runtime();
+        FreeLibrary(hmscoree);
+        exit(result);
+    }
+
     test_versioninfo();
     test_loadlibraryshim();
     test_createconfigstream();
     test_createinstance();
-    test_createdomain();
+
+    if (runtime_is_usable())
+    {
+        test_createdomain();
+    }
 
     FreeLibrary(hmscoree);
 }
-- 
2.5.0




More information about the wine-patches mailing list