mscoree: search for COM classes in GAC if CodeBase value not found

Daniel Jeliński djelinski1 at gmail.com
Thu May 30 07:47:26 CDT 2013


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130530/5bf3f9c8/attachment-0001.html>
-------------- next part --------------
From e6a9b5ac116a3382a655d925c5c75ce9e8619806 Mon Sep 17 00:00:00 2001
From: Daniel Jelinski <djelinski1 at gmail.com>
Date: Thu, 30 May 2013 14:31:26 +0200
Subject: mscoree: search for COM classes in GAC if CodeBase value not found

fixes bug 33513 - with this patch SQL Server 2005 installer works with Mono almost as good as with native .NET.
---
 dlls/mscoree/corruntimehost.c  |   45 ++++++++++++++++++------
 dlls/mscoree/metahost.c        |   74 ++++++++++++++++++++++------------------
 dlls/mscoree/mscoree_private.h |    2 +
 3 files changed, 77 insertions(+), 44 deletions(-)

diff --git a/dlls/mscoree/corruntimehost.c b/dlls/mscoree/corruntimehost.c
index b4ee38b..76b7d65 100644
--- a/dlls/mscoree/corruntimehost.c
+++ b/dlls/mscoree/corruntimehost.c
@@ -1235,6 +1235,7 @@ HRESULT RuntimeHost_Destroy(RuntimeHost *This)
 
 HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
 {
+    static const WCHAR wszAssembly[] = {'A','s','s','e','m','b','l','y',0};
     static const WCHAR wszCodebase[] = {'C','o','d','e','B','a','s','e',0};
     static const WCHAR wszClass[] = {'C','l','a','s','s',0};
     static const WCHAR wszFileSlash[] = {'f','i','l','e',':','/','/','/',0};
@@ -1246,11 +1247,12 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
     ICLRRuntimeInfo *info = NULL;
     RuntimeHost *host;
     HRESULT hr;
-    HKEY key;
+    HKEY key, subkey;
     LONG res;
     int offset = 0;
+    DWORD numKeys, keyLength;
     WCHAR codebase[MAX_PATH + 8];
-    WCHAR classname[350];
+    WCHAR classname[350], subkeyName[256];
     WCHAR filename[MAX_PATH];
 
     DWORD dwBufLen = 350;
@@ -1277,19 +1279,40 @@ HRESULT create_monodata(REFIID riid, LPVOID *ppObj )
 
     dwBufLen = MAX_PATH + 8;
     res = RegGetValueW( key, NULL, wszCodebase, RRF_RT_REG_SZ, NULL, codebase, &dwBufLen);
-    if(res != ERROR_SUCCESS)
+    if(res == ERROR_SUCCESS)
+    {
+        /* Strip file:/// */
+        if(strncmpW(codebase, wszFileSlash, strlenW(wszFileSlash)) == 0)
+            offset = strlenW(wszFileSlash);
+
+        strcpyW(filename, codebase + offset);
+    }
+    else
     {
-        WARN("CodeBase value cannot be found.\n");
         hr = CLASS_E_CLASSNOTAVAILABLE;
-        goto cleanup;
+        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 = sizeof(subkeyName) / sizeof(WCHAR);
+        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, codebase, &dwBufLen);
+        RegCloseKey(subkey);
+        if (res != ERROR_SUCCESS)
+            goto cleanup;
+        hr = get_file_from_strongname(codebase, filename, MAX_PATH);
+        if (!SUCCEEDED(hr))
+            goto cleanup;
     }
 
-    /* Strip file:/// */
-    if(strncmpW(codebase, wszFileSlash, strlenW(wszFileSlash)) == 0)
-        offset = strlenW(wszFileSlash);
-
-    strcpyW(filename, codebase + offset);
-
     TRACE("codebase (%s)\n", debugstr_w(filename));
 
     *ppObj = NULL;
diff --git a/dlls/mscoree/metahost.c b/dlls/mscoree/metahost.c
index fe529fd..eabdcf5 100644
--- a/dlls/mscoree/metahost.c
+++ b/dlls/mscoree/metahost.c
@@ -1210,31 +1210,15 @@ HRESULT CLRMetaHost_CreateInstance(REFIID riid, void **ppobj)
     return ICLRMetaHost_QueryInterface(&GlobalCLRMetaHost.ICLRMetaHost_iface, riid, ppobj);
 }
 
-static MonoAssembly* mono_assembly_search_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
+HRESULT get_file_from_strongname(WCHAR* stringnameW, WCHAR* assemblies_path, int path_length)
 {
-    loaded_mono *mono = user_data;
     HRESULT hr=S_OK;
-    MonoAssembly *result=NULL;
-    char *stringname=NULL;
-    LPWSTR stringnameW;
-    int stringnameW_size;
     IAssemblyCache *asmcache;
     ASSEMBLY_INFO info;
-    WCHAR path[MAX_PATH];
-    char *pathA;
-    MonoImageOpenStatus stat;
     static WCHAR fusiondll[] = {'f','u','s','i','o','n',0};
     HMODULE hfusion=NULL;
     static HRESULT (WINAPI *pCreateAssemblyCache)(IAssemblyCache**,DWORD);
 
-    stringname = mono->mono_stringify_assembly_name(aname);
-
-    TRACE("%s\n", debugstr_a(stringname));
-
-    if (!stringname) return NULL;
-
-    /* FIXME: We should search the given paths before the GAC. */
-
     if (!pCreateAssemblyCache)
     {
         hr = LoadLibraryShim(fusiondll, NULL, NULL, &hfusion);
@@ -1252,28 +1236,52 @@ static MonoAssembly* mono_assembly_search_hook_fn(MonoAssemblyName *aname, char
 
     if (SUCCEEDED(hr))
     {
-        stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, stringname, -1, NULL, 0);
+        info.cbAssemblyInfo = sizeof(info);
+        info.pszCurrentAssemblyPathBuf = assemblies_path;
+        info.cchBuf = path_length;
+        assemblies_path[0] = 0;
 
-        stringnameW = HeapAlloc(GetProcessHeap(), 0, stringnameW_size * sizeof(WCHAR));
-        if (stringnameW)
-            MultiByteToWideChar(CP_UTF8, 0, stringname, -1, stringnameW, stringnameW_size);
-        else
-            hr = E_OUTOFMEMORY;
+        hr = IAssemblyCache_QueryAssemblyInfo(asmcache, 0, stringnameW, &info);
 
-        if (SUCCEEDED(hr))
-        {
-            info.cbAssemblyInfo = sizeof(info);
-            info.pszCurrentAssemblyPathBuf = path;
-            info.cchBuf = MAX_PATH;
-            path[0] = 0;
+        IAssemblyCache_Release(asmcache);
+    }
 
-            hr = IAssemblyCache_QueryAssemblyInfo(asmcache, 0, stringnameW, &info);
-        }
+    return hr;
+}
 
-        HeapFree(GetProcessHeap(), 0, stringnameW);
+static MonoAssembly* mono_assembly_search_hook_fn(MonoAssemblyName *aname, char **assemblies_path, void *user_data)
+{
+    loaded_mono *mono = user_data;
+    HRESULT hr;
+    MonoAssembly *result=NULL;
+    char *stringname=NULL;
+    LPWSTR stringnameW;
+    int stringnameW_size;
+    WCHAR path[MAX_PATH];
+    char *pathA;
+    MonoImageOpenStatus stat;
 
-        IAssemblyCache_Release(asmcache);
+    stringname = mono->mono_stringify_assembly_name(aname);
+
+    TRACE("%s\n", debugstr_a(stringname));
+
+    if (!stringname) return NULL;
+
+    /* FIXME: We should search the given paths before the GAC. */
+
+    stringnameW_size = MultiByteToWideChar(CP_UTF8, 0, stringname, -1, NULL, 0);
+
+    stringnameW = HeapAlloc(GetProcessHeap(), 0, stringnameW_size * sizeof(WCHAR));
+    if (stringnameW)
+    {
+        MultiByteToWideChar(CP_UTF8, 0, stringname, -1, stringnameW, stringnameW_size);
+
+        hr = get_file_from_strongname(stringnameW, path, MAX_PATH);
+
+        HeapFree(GetProcessHeap(), 0, stringnameW);
     }
+    else
+        hr = E_OUTOFMEMORY;
 
     if (SUCCEEDED(hr))
     {
diff --git a/dlls/mscoree/mscoree_private.h b/dlls/mscoree/mscoree_private.h
index 4677921..b66669c 100644
--- a/dlls/mscoree/mscoree_private.h
+++ b/dlls/mscoree/mscoree_private.h
@@ -204,6 +204,8 @@ extern HRESULT CorDebug_Create(ICLRRuntimeHost *runtimehost, IUnknown** ppUnk) D
 
 extern HRESULT create_monodata(REFIID riid, LPVOID *ppObj) DECLSPEC_HIDDEN;
 
+extern HRESULT get_file_from_strongname(WCHAR* stringnameW, WCHAR* assemblies_path, int path_length) DECLSPEC_HIDDEN;
+
 extern void runtimehost_init(void);
 extern void runtimehost_uninit(void);
 
-- 
1.7.5.4


More information about the wine-patches mailing list