Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mscoree/tests/Makefile.in | 2 +- dlls/mscoree/tests/comtest.c | 46 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/dlls/mscoree/tests/Makefile.in b/dlls/mscoree/tests/Makefile.in index f65e1bc6c25..7dcd5b64113 100644 --- a/dlls/mscoree/tests/Makefile.in +++ b/dlls/mscoree/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mscoree.dll -IMPORTS = ole32 shlwapi uuid shell32 +IMPORTS = ole32 shlwapi uuid shell32 advapi32
C_SRCS = \ comtest.c \ diff --git a/dlls/mscoree/tests/comtest.c b/dlls/mscoree/tests/comtest.c index 12b112417d5..8c2ae955cef 100644 --- a/dlls/mscoree/tests/comtest.c +++ b/dlls/mscoree/tests/comtest.c @@ -148,6 +148,51 @@ static void run_test(BOOL expect_success) } IClassFactory_Release(classFactory); } + +} + +static void run_registry_test(run_type run) +{ + char buffer[256]; + ITest *test = NULL; + HRESULT hr, result_expected; + HKEY hkey; + DWORD ret; + int i = 0; + + if (run == run_type_exe_directory) result_expected = S_OK; + else result_expected = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); + + sprintf(buffer, "CLSID\%s", wine_dbgstr_guid(&CLSID_Test), ""); + ret = RegCreateKeyA( HKEY_CLASSES_ROOT, buffer, &hkey ); + ok(ret == ERROR_SUCCESS, "RegCreateKeyA returned %x\n", ret); + + ret = RegSetKeyValueA(hkey, "InprocServer32", NULL, REG_SZ, "mscoree.dll", 11); + ok(ret == ERROR_SUCCESS, "RegSetKeyValueA returned %x\n", ret); + ret = RegSetKeyValueA(hkey, "InprocServer32", "Assembly", REG_SZ, "comtest, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", 74); + ok(ret == ERROR_SUCCESS, "RegSetKeyValueA returned %x\n", ret); + ret = RegSetKeyValueA(hkey, "InprocServer32", "Class", REG_SZ, "DLL.Test", 8); + ok(ret == ERROR_SUCCESS, "RegSetKeyValueA returned %x\n", ret); + ret = RegSetKeyValueA(hkey, "InprocServer32", "CodeBase", REG_SZ, "file:///U:/invalid/path/to/comtest.dll", 41); + 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); + + if (hr == S_OK) + { + hr = ITest_Func(test, &i); + ok(hr == S_OK, "Got %x\n", hr); + ok(i == 42, "Expected 42, got %d\n", i); + ITest_Release(test); + } + + RegDeleteKeyValueA(hkey, "InprocServer32", "CodeBase"); + RegDeleteKeyValueA(hkey, "InprocServer32", "Class"); + RegDeleteKeyValueA(hkey, "InprocServer32", "Assembly"); + RegDeleteKeyValueA(hkey, "InprocServer32", NULL); + RegDeleteKeyA(hkey, "InprocServer32"); + RegCloseKey(hkey); }
static void get_dll_path_for_run(char *path_dll, UINT path_dll_size, run_type run) @@ -247,6 +292,7 @@ static void prepare_and_run_test(const char *dll_source, run_type run) SetCurrentDirectoryA(path_tmp);
run_test(run == run_type_exe_directory); + run_registry_test(run);
cleanup: if (handle_context != NULL && handle_context != INVALID_HANDLE_VALUE)
Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mscoree/tests/comtest.c | 6 ++++++ dlls/mscoree/tests/comtest.cs | 12 +++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/mscoree/tests/comtest.c b/dlls/mscoree/tests/comtest.c index 8c2ae955cef..659eb9059a7 100644 --- a/dlls/mscoree/tests/comtest.c +++ b/dlls/mscoree/tests/comtest.c @@ -33,6 +33,8 @@
HMODULE hmscoree;
+DEFINE_GUID(IID_ITest2, 0x50adb433, 0xf6c5, 0x3b30, 0x92,0x0a, 0x55,0x57,0x11,0x86,0x75,0x09); + typedef enum _run_type { run_type_current_working_directory = 0, @@ -156,6 +158,7 @@ static void run_registry_test(run_type run) char buffer[256]; ITest *test = NULL; HRESULT hr, result_expected; + IUnknown *unk = NULL; HKEY hkey; DWORD ret; int i = 0; @@ -184,6 +187,9 @@ static void run_registry_test(run_type run) hr = ITest_Func(test, &i); ok(hr == S_OK, "Got %x\n", hr); ok(i == 42, "Expected 42, got %d\n", i); + hr = ITest_QueryInterface(test, &IID_ITest2, (void**)&unk); + todo_wine ok(hr == S_OK, "ITest_QueryInterface returned %x\n", hr); + if (hr == S_OK) IUnknown_Release(unk); ITest_Release(test); }
diff --git a/dlls/mscoree/tests/comtest.cs b/dlls/mscoree/tests/comtest.cs index f6461450331..536cd807691 100644 --- a/dlls/mscoree/tests/comtest.cs +++ b/dlls/mscoree/tests/comtest.cs @@ -30,12 +30,22 @@ namespace DLL void Func(ref int i); }
+ [ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface ITest2 + { + void Func2(ref int i); + } + [Guid("2e106e50-e7a4-4489-8538-83643f100fdc"), ComVisible(true), ClassInterface(ClassInterfaceType.None)] - public class Test : ITest + public class Test : ITest, ITest2 { public void Func(ref int i) { i = 42; } + public void Func2(ref int i) + { + i = 43; + } } }
Signed-off-by: Esme Povirk esme@codeweavers.com
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 rbernon@codeweavers.com --- 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 a5b378b9251..61839512bf6 100644 --- a/dlls/mscoree/corruntimehost.c +++ b/dlls/mscoree/corruntimehost.c @@ -1707,6 +1707,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]; @@ -1742,7 +1743,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]; @@ -1751,27 +1757,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) {
Signed-off-by: Esme Povirk esme@codeweavers.com