From 7b0a939a1fb9f0acc7b450cd849fb4e1d93eb499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Fri, 23 Oct 2020 08:51:46 +0200 Subject: [PATCH] mscoree: Fallback to assembly name if codebase path is invalid. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also use the InprocServer32 key values if there's no subkeys, as shown by the test results. L.A.Noire game crashes on startup after failing to load its ErrorHandler assembly, that has an invalid CodeBase path in the registry. Signed-off-by: RĂ©mi Bernon Signed-off-by: Esme Povirk Signed-off-by: Alexandre Julliard --- dlls/mscoree/corruntimehost.c | 44 ++++++++++++++++++++++++----------- dlls/mscoree/tests/comtest.c | 3 ++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c index f50eb5a0cd7..cf8acae09e0 100644 --- a/dlls/mscoree/corruntimehost.c +++ b/dlls/mscoree/corruntimehost.c @@ -1747,6 +1747,7 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) HKEY key, subkey; LONG res; int offset = 0; + HANDLE file = INVALID_HANDLE_VALUE; DWORD numKeys, keyLength; WCHAR codebase[MAX_PATH + 8]; WCHAR classname[350], subkeyName[256]; @@ -1782,7 +1783,12 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) offset = lstrlenW(wszFileSlash); lstrcpyW(filename, codebase + offset); + + file = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); } + + if (file != INVALID_HANDLE_VALUE) + CloseHandle(file); else { WCHAR assemblyname[MAX_PATH + 8]; @@ -1791,27 +1797,37 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj ) WARN("CodeBase value cannot be found, trying Assembly.\n"); /* get the last subkey of InprocServer32 */ res = RegQueryInfoKeyW(key, 0, 0, 0, &numKeys, 0, 0, 0, 0, 0, 0, 0); - if (res != ERROR_SUCCESS || numKeys == 0) - goto cleanup; - numKeys--; - keyLength = ARRAY_SIZE(subkeyName); - res = RegEnumKeyExW(key, numKeys, subkeyName, &keyLength, 0, 0, 0, 0); - if (res != ERROR_SUCCESS) - goto cleanup; - res = RegOpenKeyExW(key, subkeyName, 0, KEY_READ, &subkey); - if (res != ERROR_SUCCESS) - goto cleanup; - dwBufLen = MAX_PATH + 8; - res = RegGetValueW(subkey, NULL, wszAssembly, RRF_RT_REG_SZ, NULL, assemblyname, &dwBufLen); - RegCloseKey(subkey); if (res != ERROR_SUCCESS) goto cleanup; + if (numKeys > 0) + { + numKeys--; + keyLength = ARRAY_SIZE(subkeyName); + res = RegEnumKeyExW(key, numKeys, subkeyName, &keyLength, 0, 0, 0, 0); + if (res != ERROR_SUCCESS) + goto cleanup; + res = RegOpenKeyExW(key, subkeyName, 0, KEY_READ, &subkey); + if (res != ERROR_SUCCESS) + goto cleanup; + dwBufLen = MAX_PATH + 8; + res = RegGetValueW(subkey, NULL, wszAssembly, RRF_RT_REG_SZ, NULL, assemblyname, &dwBufLen); + RegCloseKey(subkey); + if (res != ERROR_SUCCESS) + goto cleanup; + } + else + { + dwBufLen = MAX_PATH + 8; + res = RegGetValueW(key, NULL, wszAssembly, RRF_RT_REG_SZ, NULL, assemblyname, &dwBufLen); + if (res != ERROR_SUCCESS) + goto cleanup; + } hr = get_file_from_strongname(assemblyname, filename, MAX_PATH); if (FAILED(hr)) { /* - * The registry doesn't have a CodeBase entry and it's not in the GAC. + * The registry doesn't have a CodeBase entry or the file isn't there, and it's not in the GAC. * * Use the Assembly Key to retrieve the filename. * Assembly : REG_SZ : AssemblyName, Version=X.X.X.X, Culture=neutral, PublicKeyToken=null diff --git a/dlls/mscoree/tests/comtest.c b/dlls/mscoree/tests/comtest.c index 659eb9059a7..b62d527bb95 100644 --- a/dlls/mscoree/tests/comtest.c +++ b/dlls/mscoree/tests/comtest.c @@ -180,7 +180,8 @@ static void run_registry_test(run_type run) ok(ret == ERROR_SUCCESS, "RegSetKeyValueA returned %x\n", ret); hr = CoCreateInstance(&CLSID_Test, NULL, CLSCTX_INPROC_SERVER, &IID_ITest, (void**)&test); - todo_wine ok(hr == result_expected, "Expected %x, got %x\n", result_expected, hr); + todo_wine_if(result_expected != S_OK) + ok(hr == result_expected, "Expected %x, got %x\n", result_expected, hr); if (hr == S_OK) {