[2/2] mscoree: search for COM classes by assembly name if CodeBase not found

Daniel Jeliński djelinski1 at gmail.com
Tue Jun 4 14:33:00 CDT 2013


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130604/29ad13b3/attachment.html>
-------------- next part --------------
From 544f2c30d45e743844872e2c83944148e7ef9842 Mon Sep 17 00:00:00 2001
From: Daniel Jelinski <djelinski1 at gmail.com>
Date: Tue, 4 Jun 2013 21:14:56 +0200
Subject: mscoree: search for COM classes by assembly name if CodeBase not
 found

Assembly name is stored in a subkey of InprocServer32 key. In all cases I've seen there was only one subkey.
Anecdotal evidence found on StackOverflow suggests that if there are multiple subkeys, the last one will be used.
This probably needs tests, but I'm not sure how to create these.
Fixes bug 33513.
---
 dlls/mscoree/corruntimehost.c |   45 +++++++++++++++++++++++++++++++----------
 1 files changed, 34 insertions(+), 11 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;
-- 
1.7.5.4


More information about the wine-patches mailing list