mscoree/tests: Check if the runtime is usable before loading it.
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. Signed-off-by: Vincent Povirk <vincent@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c8e87bd878
commit
b99c35c0e8
|
@ -17,6 +17,8 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define COBJMACROS
|
#define COBJMACROS
|
||||||
|
|
||||||
#include "corerror.h"
|
#include "corerror.h"
|
||||||
|
@ -72,6 +74,97 @@ static BOOL init_functionpointers(void)
|
||||||
return TRUE;
|
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)
|
static void test_versioninfo(void)
|
||||||
{
|
{
|
||||||
const WCHAR v9_0[] = {'v','9','.','0','.','3','0','3','1','9',0};
|
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)
|
START_TEST(mscoree)
|
||||||
{
|
{
|
||||||
|
int argc;
|
||||||
|
char** argv;
|
||||||
|
|
||||||
if (!init_functionpointers())
|
if (!init_functionpointers())
|
||||||
return;
|
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_versioninfo();
|
||||||
test_loadlibraryshim();
|
test_loadlibraryshim();
|
||||||
test_createconfigstream();
|
test_createconfigstream();
|
||||||
test_createinstance();
|
test_createinstance();
|
||||||
test_createdomain();
|
|
||||||
|
if (runtime_is_usable())
|
||||||
|
{
|
||||||
|
test_createdomain();
|
||||||
|
}
|
||||||
|
|
||||||
FreeLibrary(hmscoree);
|
FreeLibrary(hmscoree);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue