From 57cdf8bfa8a312ce9a8b7c6c80b0570d3be05b11 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 1 Aug 2017 11:51:22 -0500 Subject: [PATCH] mscoree: Implement RequestRuntimeLoadedNotification. Signed-off-by: Vincent Povirk Signed-off-by: Alexandre Julliard --- dlls/mscoree/metahost.c | 44 +++++++++++++++++++------ dlls/mscoree/tests/metahost.c | 62 ++++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index 4108f55b96e..6edd30f21f9 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -66,6 +66,15 @@ static CRITICAL_SECTION_DEBUG runtime_list_cs_debug = }; static CRITICAL_SECTION runtime_list_cs = { &runtime_list_cs_debug, -1, 0, 0, 0, 0 }; +struct CLRMetaHost +{ + ICLRMetaHost ICLRMetaHost_iface; + + RuntimeLoadedCallbackFnPtr callback; +}; + +static struct CLRMetaHost GlobalCLRMetaHost; + static HMODULE mono_handle; BOOL is_mono_started; @@ -299,6 +308,18 @@ static void CDECL mono_print_handler_fn(const char *string, INT is_stdout) } } +static HRESULT WINAPI thread_set_fn(void) +{ + WARN("stub\n"); + return S_OK; +} + +static HRESULT WINAPI thread_unset_fn(void) +{ + WARN("stub\n"); + return S_OK; +} + static HRESULT CLRRuntimeInfo_GetRuntimeHost(CLRRuntimeInfo *This, RuntimeHost **result) { HRESULT hr = S_OK; @@ -318,6 +339,17 @@ static HRESULT CLRRuntimeInfo_GetRuntimeHost(CLRRuntimeInfo *This, RuntimeHost * EnterCriticalSection(&runtime_list_cs); + if (This->loaded_runtime) + { + *result = This->loaded_runtime; + return hr; + } + + if (GlobalCLRMetaHost.callback) + { + GlobalCLRMetaHost.callback(&This->ICLRRuntimeInfo_iface, thread_set_fn, thread_unset_fn); + } + hr = load_mono(mono_path); if (SUCCEEDED(hr)) @@ -795,15 +827,6 @@ static const struct IEnumUnknownVtbl InstalledRuntimeEnum_Vtbl = { InstalledRuntimeEnum_Clone }; -struct CLRMetaHost -{ - ICLRMetaHost ICLRMetaHost_iface; - - RuntimeLoadedCallbackFnPtr callback; -}; - -static struct CLRMetaHost GlobalCLRMetaHost; - static HRESULT WINAPI CLRMetaHost_QueryInterface(ICLRMetaHost* iface, REFIID riid, void **ppvObject) @@ -988,7 +1011,8 @@ static HRESULT WINAPI CLRMetaHost_RequestRuntimeLoadedNotification(ICLRMetaHost* if(!pCallbackFunction) return E_POINTER; - WARN("Callback currently will not be called.\n"); + if (GlobalCLRMetaHost.callback) + return HOST_E_INVALIDOPERATION; GlobalCLRMetaHost.callback = pCallbackFunction; diff --git a/dlls/mscoree/tests/metahost.c b/dlls/mscoree/tests/metahost.c index 5a8b3e09272..fd97361a010 100644 --- a/dlls/mscoree/tests/metahost.c +++ b/dlls/mscoree/tests/metahost.c @@ -35,6 +35,10 @@ static HRESULT (WINAPI *pCLRCreateInstance)(REFCLSID clsid, REFIID riid, LPVOID static ICLRMetaHost *metahost; +static const WCHAR v4_0[] = {'v','4','.','0','.','3','0','3','1','9',0}; + +static DWORD expect_runtime_tid; + static BOOL init_pointers(void) { HRESULT hr = E_FAIL; @@ -148,10 +152,37 @@ static void test_enumruntimes(void) IEnumUnknown_Release(runtime_enum); } +static void WINAPI notification_dummy_callback(ICLRRuntimeInfo *pRuntimeInfo, CallbackThreadSetFnPtr pfnCallbackThreadSet, + CallbackThreadUnsetFnPtr pfnCallbackThreadUnset) +{ + ok(0, "unexpected call\n"); +} + static void WINAPI notification_callback(ICLRRuntimeInfo *pRuntimeInfo, CallbackThreadSetFnPtr pfnCallbackThreadSet, CallbackThreadUnsetFnPtr pfnCallbackThreadUnset) { - ok(0, "Unexpected call\n"); + HRESULT hr; + WCHAR buf[20]; + DWORD buf_size = 20; + + ok(expect_runtime_tid != 0, "unexpected call\n"); + + if (expect_runtime_tid != 0) + { + ok(GetCurrentThreadId() == expect_runtime_tid, + "expected call on thread %04x, got thread %04x\n", expect_runtime_tid, GetCurrentThreadId()); + expect_runtime_tid = 0; + } + + hr = ICLRRuntimeInfo_GetVersionString(pRuntimeInfo, buf, &buf_size); + ok(hr == S_OK, "GetVersion returned %x\n", hr); + ok(lstrcmpW(buf, v4_0) == 0, "GetVersion returned %s\n", wine_dbgstr_w(buf)); + + hr = pfnCallbackThreadSet(); + ok(hr == S_OK, "pfnCallbackThreadSet returned %x\n", hr); + + hr = pfnCallbackThreadUnset(); + ok(hr == S_OK, "pfnCallbackThreadUnset returned %x\n", hr); } static void test_notification(void) @@ -159,10 +190,32 @@ static void test_notification(void) HRESULT hr; hr = ICLRMetaHost_RequestRuntimeLoadedNotification(metahost, NULL); - ok(hr == E_POINTER, "GetVersion failed, hr=%x\n", hr); + ok(hr == E_POINTER, "RequestRuntimeLoadedNotification returned %x\n", hr); hr = ICLRMetaHost_RequestRuntimeLoadedNotification(metahost,notification_callback); - ok(hr == S_OK, "GetVersion failed, hr=%x\n", hr); + ok(hr == S_OK, "RequestRuntimeLoadedNotification failed, hr=%x\n", hr); + + hr = ICLRMetaHost_RequestRuntimeLoadedNotification(metahost,notification_dummy_callback); + ok(hr == HOST_E_INVALIDOPERATION, "RequestRuntimeLoadedNotification returned %x\n", hr); +} + +static void test_notification_cb(void) +{ + HRESULT hr; + ICLRRuntimeInfo *info; + ICLRRuntimeHost *host; + + hr = ICLRMetaHost_GetRuntime(metahost, v4_0, &IID_ICLRRuntimeInfo, (void**)&info); + ok(hr == S_OK, "GetRuntime returned %x\n", hr); + + expect_runtime_tid = GetCurrentThreadId(); + hr = ICLRRuntimeInfo_GetInterface(info, &CLSID_CLRRuntimeHost, &IID_ICLRRuntimeHost, (void**)&host); + ok(hr == S_OK, "GetInterface returned %x\n", hr); + ok(expect_runtime_tid == 0, "notification_callback was not called\n"); + + ICLRRuntimeHost_Release(host); + + ICLRRuntimeInfo_Release(info); } START_TEST(metahost) @@ -170,8 +223,9 @@ START_TEST(metahost) if (!init_pointers()) return; - test_enumruntimes(); test_notification(); + test_enumruntimes(); + test_notification_cb(); cleanup(); }