oleaut32: Use context redirects when creating typelib marshaler proxy/stub

Nikolay Sivov nsivov at codeweavers.com
Sun Jun 28 03:18:05 CDT 2015


https://bugs.winehq.org/show_bug.cgi?id=38510
-------------- next part --------------
From 03b3552bcc29a14f0de83c3cf01bcbc13a7cb201 Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov at codeweavers.com>
Date: Sun, 28 Jun 2015 11:16:23 +0300
Subject: [PATCH] oleaut32: Use context redirects when creating typelib
 marshaler proxy/stub

---
 dlls/oleaut32/tmarshal.c | 101 ++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 86 insertions(+), 15 deletions(-)

diff --git a/dlls/oleaut32/tmarshal.c b/dlls/oleaut32/tmarshal.c
index 7bf62b7..9039815 100644
--- a/dlls/oleaut32/tmarshal.c
+++ b/dlls/oleaut32/tmarshal.c
@@ -263,18 +263,71 @@ PSFacBuf_QueryInterface(LPPSFACTORYBUFFER iface, REFIID iid, LPVOID *ppv) {
 static ULONG WINAPI PSFacBuf_AddRef(LPPSFACTORYBUFFER iface) { return 2; }
 static ULONG WINAPI PSFacBuf_Release(LPPSFACTORYBUFFER iface) { return 1; }
 
-static HRESULT
-_get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
-    HRESULT	hres;
+struct ifacepsredirect_data
+{
+    ULONG size;
+    DWORD mask;
+    GUID  iid;
+    ULONG nummethods;
+    GUID  tlbid;
+    GUID  base;
+    ULONG name_len;
+    ULONG name_offset;
+};
+
+struct tlibredirect_data
+{
+    ULONG  size;
+    DWORD  res;
+    ULONG  name_len;
+    ULONG  name_offset;
+    LANGID langid;
+    WORD   flags;
+    ULONG  help_len;
+    ULONG  help_offset;
+    WORD   major_version;
+    WORD   minor_version;
+};
+
+static BOOL actctx_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
+{
+    struct ifacepsredirect_data *iface;
+    struct tlibredirect_data *tlib;
+    ACTCTX_SECTION_KEYED_DATA data;
+    WCHAR *ptrW;
+
+    data.cbSize = sizeof(data);
+    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION,
+            riid, &data))
+        return FALSE;
+
+    iface = (struct ifacepsredirect_data*)data.lpData;
+    if (!FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION,
+            &iface->tlbid, &data))
+        return FALSE;
+
+    tlib = (struct tlibredirect_data*)data.lpData;
+    ptrW = (WCHAR*)((BYTE*)data.lpSectionBase + tlib->name_offset);
+
+    if (tlib->name_len/sizeof(WCHAR) >= len) {
+        ERR("need larger module buffer, %u\n", tlib->name_len/sizeof(WCHAR));
+        return FALSE;
+    }
+
+    memcpy(module, ptrW, tlib->name_len);
+    module[tlib->name_len/sizeof(WCHAR)] = 0;
+    return TRUE;
+}
+
+static HRESULT reg_get_typelib_module(REFIID riid, WCHAR *module, DWORD len)
+{
     HKEY	ikey;
     REGSAM	opposite = (sizeof(void*) == 8) ? KEY_WOW64_32KEY : KEY_WOW64_64KEY;
     BOOL	is_wow64;
     char	tlguid[200],typelibkey[300],interfacekey[300],ver[100];
     char	tlfn[260];
-    OLECHAR	tlfnW[260];
     DWORD	tlguidlen, verlen, type;
     LONG	tlfnlen, err;
-    ITypeLib	*tl;
 
     sprintf( interfacekey, "Interface\\{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\Typelib",
 	riid->Data1, riid->Data2, riid->Data3,
@@ -318,19 +371,37 @@ _get_typeinfo_for_iid(REFIID riid, ITypeInfo**ti) {
         }
 #endif
     }
-    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, tlfnW, sizeof(tlfnW) / sizeof(tlfnW[0]));
-    hres = LoadTypeLib(tlfnW,&tl);
-    if (hres) {
-	ERR("Failed to load typelib for %s, but it should be there.\n",debugstr_guid(riid));
-	return hres;
+    MultiByteToWideChar(CP_ACP, 0, tlfn, -1, module, len);
+    return S_OK;
+}
+
+static HRESULT
+_get_typeinfo_for_iid(REFIID riid, ITypeInfo **typeinfo)
+{
+    OLECHAR   moduleW[260];
+    ITypeLib *typelib;
+    HRESULT   hres;
+
+    *typeinfo = NULL;
+
+    moduleW[0] = 0;
+    if (!actctx_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]))) {
+        hres = reg_get_typelib_module(riid, moduleW, sizeof(moduleW)/sizeof(moduleW[0]));
+        if (FAILED(hres))
+            return hres;
     }
-    hres = ITypeLib_GetTypeInfoOfGuid(tl,riid,ti);
-    if (hres) {
-	ERR("typelib does not contain info for %s?\n",debugstr_guid(riid));
-	ITypeLib_Release(tl);
+
+    hres = LoadTypeLib(moduleW, &typelib);
+    if (hres != S_OK) {
+	ERR("Failed to load typelib for %s, but it should be there.\n",debugstr_guid(riid));
 	return hres;
     }
-    ITypeLib_Release(tl);
+
+    hres = ITypeLib_GetTypeInfoOfGuid(typelib, riid, typeinfo);
+    ITypeLib_Release(typelib);
+    if (hres != S_OK)
+	ERR("typelib does not contain info for %s\n", debugstr_guid(riid));
+
     return hres;
 }
 
-- 
2.1.4



More information about the wine-patches mailing list