From: Francis De Brabandere <francisdb@gmail.com> ITypeInfoImpl_GetInternalDispatchFuncDesc walked impltypes whenever any impl type was registered, surfacing inherited IDispatch slots ahead of own funcs in the index space. That matches MIDL-built TKIND_DISPATCH typelibs (where cbSizeVft includes inherited slots and cFuncs is inflated to match) but mismatches ICreateTypeLib2-built ones where cbSizeVft only spans own funcs and GetFuncDesc should expose only those. Skip the walk when the stored cbSizeVft has no room beyond own_count * ptr_size, so GetFuncDesc on ICreateTypeLib2 typelibs hits own funcs at indices 0..cFuncs-1 and returns TYPE_E_ELEMENTNOTFOUND past the end, matching native. --- dlls/oleaut32/tests/typelib.c | 3 --- dlls/oleaut32/typelib.c | 8 +++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dlls/oleaut32/tests/typelib.c b/dlls/oleaut32/tests/typelib.c index d1fc449dd52..21be6d97fb1 100644 --- a/dlls/oleaut32/tests/typelib.c +++ b/dlls/oleaut32/tests/typelib.c @@ -8923,18 +8923,15 @@ static void test_dispatch_funcdesc_bound(void) hr = ITypeInfo_GetFuncDesc(ti, 0, &got); ok(hr == S_OK, "GetFuncDesc(0) got %#lx\n", hr); if (SUCCEEDED(hr)) { - todo_wine ok(got->memid == 0x100, "GetFuncDesc(0) memid %#lx\n", got->memid); ITypeInfo_ReleaseFuncDesc(ti, got); } hr = ITypeInfo_GetFuncDesc(ti, 1, &got); ok(hr == S_OK, "GetFuncDesc(1) got %#lx\n", hr); if (SUCCEEDED(hr)) { - todo_wine ok(got->memid == 0x101, "GetFuncDesc(1) memid %#lx\n", got->memid); ITypeInfo_ReleaseFuncDesc(ti, got); } - todo_wine ok(ITypeInfo_GetFuncDesc(ti, 2, &got) == TYPE_E_ELEMENTNOTFOUND, "GetFuncDesc(2) should return TYPE_E_ELEMENTNOTFOUND\n"); diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index d604ccc0fd8..07aeac53350 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -5954,7 +5954,13 @@ static HRESULT ITypeInfoImpl_GetInternalDispatchFuncDesc( ITypeInfo *iface, else *hrefoffset = DISPATCH_HREF_OFFSET; - if(This->impltypes) + /* Only walk impltypes when the stored cbSizeVft has room for inherited + * slots beyond our own funcs. Typelibs built via ICreateTypeLib2 store + * cbSizeVft = own_count * ptr_size and expose only own funcs through + * GetFuncDesc; MIDL-built typelibs store cbSizeVft = (own+inh)*ptr_size + * and rely on impltypes traversal to surface inherited slots. */ + if(This->impltypes + && This->typeattr.cbSizeVft > This->typeattr.cFuncs * This->pTypeLib->ptr_size) { ITypeInfo *pSubTypeInfo; UINT sub_funcs; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10857