Added patch to extend a vtable offset before calling 64-bit DispCallFunc() for a 32-bit typelib.

This commit is contained in:
Sebastian Lackner
2016-05-06 04:16:30 +02:00
parent cecff04cad
commit ece39ae33d
3 changed files with 89 additions and 1 deletions

View File

@@ -0,0 +1,71 @@
From f650db00efa6e175b314f7e926bd92d0eb1f56b8 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Mon, 2 May 2016 15:49:53 +0800
Subject: oleaut32: Extend a vtable offset before calling 64-bit DispCallFunc()
for a 32-bit typelib.
DispCallFunc() divides a passed in offset by sizeof(void*) to calculate
the actual function offset in the vtable, so in order to make this work
under win64 for a 32-bit typelib ITypeInfo::Invoke() needs to compensate
the logic by multiplying the offset by 2.
---
dlls/oleaut32/typelib.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 517e515..971f746 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -3547,6 +3547,10 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
/* name, eventually add to a hash table */
pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
+ TRACE("%s, syskind %d, version %d.%d, flags %04x\n",
+ debugstr_w(pTypeLibImpl->Name->str), pTypeLibImpl->syskind,
+ pTypeLibImpl->ver_major, pTypeLibImpl->ver_minor, pTypeLibImpl->libflags);
+
/* help info */
pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
@@ -6960,6 +6964,7 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
UINT cNamedArgs = pDispParams->cNamedArgs;
DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
UINT vargs_converted=0;
+ ULONG_PTR offset;
hres = S_OK;
@@ -7204,7 +7209,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
break;
}
}
- if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
+ if (FAILED(hres))
+ {
+ ERR("failed: %08x\n", hres);
+ goto func_fail; /* FIXME: we don't free changed types here */
+ }
/* VT_VOID is a special case for return types, so it is not
* handled in the general function */
@@ -7217,7 +7226,16 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
if (FAILED(hres)) goto func_fail; /* FIXME: we don't free changed types here */
}
- hres = DispCallFunc(pIUnk, func_desc->oVft & 0xFFFC, func_desc->callconv,
+ offset = func_desc->oVft & 0xFFFC;
+#ifdef _WIN64
+ if (This->pTypeLib->syskind == SYS_WIN32)
+ {
+ offset *= 2;
+ TRACE("extended offset to %#lx for SYS_WIN32\n", offset);
+ }
+#endif
+ TRACE("func_desc->oVft %#x, offset %#lx\n", func_desc->oVft, offset);
+ hres = DispCallFunc(pIUnk, offset, func_desc->callconv,
V_VT(&varresult), func_desc->cParams, rgvt,
prgpvarg, &varresult);
--
2.8.0

View File

@@ -0,0 +1 @@
Fixes: Extend a vtable offset before calling 64-bit DispCallFunc() for a 32-bit typelib