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