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