diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c index 49fb0ee5460..e15a638c3b1 100644 --- a/dlls/mscoree/metahost.c +++ b/dlls/mscoree/metahost.c @@ -1310,11 +1310,21 @@ HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file, if (version) { - return CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)result); + hr = CLRMetaHost_GetRuntime(0, version, &IID_ICLRRuntimeInfo, (void**)result); + if(SUCCEEDED(hr)) + return hr; } if (runtimeinfo_flags & RUNTIME_INFO_UPGRADE_VERSION) { + DWORD major, minor, build; + + if (version && !parse_runtime_version(version, &major, &minor, &build)) + { + ERR("Cannot parse %s\n", debugstr_w(version)); + return CLR_E_SHIM_RUNTIME; + } + find_runtimes(); if (legacy) @@ -1325,8 +1335,16 @@ HRESULT get_runtime_info(LPCWSTR exefile, LPCWSTR version, LPCWSTR config_file, while (i--) { if (runtimes[i].mono_abi_version) - return ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface, - &IID_ICLRRuntimeInfo, (void **)result); + { + /* Must be greater or equal to the version passed in. */ + if (!version || ((runtimes[i].major >= major && runtimes[i].minor >= minor && runtimes[i].build >= build) || + (runtimes[i].major >= major && runtimes[i].minor > minor) || + (runtimes[i].major > major))) + { + return ICLRRuntimeInfo_QueryInterface(&runtimes[i].ICLRRuntimeInfo_iface, + &IID_ICLRRuntimeInfo, (void **)result); + } + } } if (legacy) diff --git a/dlls/mscoree/tests/mscoree.c b/dlls/mscoree/tests/mscoree.c index 56351c371d4..9b115c0979c 100644 --- a/dlls/mscoree/tests/mscoree.c +++ b/dlls/mscoree/tests/mscoree.c @@ -60,8 +60,11 @@ static BOOL init_functionpointers(void) static void test_versioninfo(void) { + const WCHAR v9_0[] = {'v','9','.','0','.','3','0','3','1','9',0}; const WCHAR v2_0[] = {'v','2','.','0','.','5','0','7','2','7',0}; + const WCHAR v2_0_0[] = {'v','2','.','0','.','0',0}; const WCHAR v1_1[] = {'v','1','.','1','.','4','3','2','2',0}; + const WCHAR v1_1_0[] = {'v','1','.','1','.','0',0}; WCHAR version[MAX_PATH]; WCHAR path[MAX_PATH]; @@ -143,6 +146,40 @@ static void test_versioninfo(void) hr = pGetRequestedRuntimeInfo( NULL, v2_0, NULL, 0, 0, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); ok(hr == S_OK, "GetRequestedRuntimeInfo returned %08x\n", hr); ok(!winetest_strcmpW(version, v2_0), "version is %s , expected %s\n", wine_dbgstr_w(version), wine_dbgstr_w(v2_0)); + + /* Invalid Version and RUNTIME_INFO_UPGRADE_VERSION flag*/ + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v1_1, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == S_OK || hr == CLR_E_SHIM_RUNTIME , "GetRequestedRuntimeInfo returned %08x\n", hr); + if(hr == S_OK) + { + /* .NET 1.1 may not be installed. */ + ok(!winetest_strcmpW(version, v1_1) || !winetest_strcmpW(version, v2_0), + "version is %s , expected %s or %s\n", wine_dbgstr_w(version), wine_dbgstr_w(v1_1), wine_dbgstr_w(v2_0)); + + } + + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v9_0, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == CLR_E_SHIM_RUNTIME, "GetRequestedRuntimeInfo returned %08x\n", hr); + + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v1_1_0, NULL, 0, 0, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == CLR_E_SHIM_RUNTIME, "GetRequestedRuntimeInfo returned %08x\n", hr); + + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v1_1_0, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == S_OK, "GetRequestedRuntimeInfo returned %08x\n", hr); + ok(!winetest_strcmpW(version, v2_0), "version is %s , expected %s\n", wine_dbgstr_w(version), wine_dbgstr_w(v2_0)); + + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v2_0_0, NULL, 0, 0, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == CLR_E_SHIM_RUNTIME, "GetRequestedRuntimeInfo returned %08x\n", hr); + + memset(version, 0, sizeof(version)); + hr = pGetRequestedRuntimeInfo( NULL, v2_0_0, NULL, 0, RUNTIME_INFO_UPGRADE_VERSION, path, MAX_PATH, &path_len, version, MAX_PATH, NULL); + ok(hr == S_OK, "GetRequestedRuntimeInfo returned %08x\n", hr); + ok(!winetest_strcmpW(version, v2_0), "version is %s , expected %s\n", wine_dbgstr_w(version), wine_dbgstr_w(v2_0)); } static void test_loadlibraryshim(void)