Module: wine Branch: master Commit: 613270d49fd3c25a17bbce37277a8b9a5713b692 URL: https://gitlab.winehq.org/wine/wine/-/commit/613270d49fd3c25a17bbce37277a8b9...
Author: Alexandre Julliard julliard@winehq.org Date: Fri Dec 15 14:51:01 2023 +0100
oleaut32: Fix loading a 64-bit typelib in 32-bit mode.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55962
---
dlls/oleaut32/typelib.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c index 9fe4cb65f99..f412074bd21 100644 --- a/dlls/oleaut32/typelib.c +++ b/dlls/oleaut32/typelib.c @@ -73,6 +73,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DECLARE_DEBUG_CHANNEL(typelib);
+static const BOOL is_win64 = sizeof(void *) > sizeof(int); + typedef struct { WORD offset; @@ -392,13 +394,11 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path ) { BOOL redir = TRUE; -#ifdef _WIN64 - HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path, TRUE ); + HRESULT hres = query_typelib_path( guid, wMaj, wMin, is_win64 ? SYS_WIN64 : SYS_WIN32, lcid, path, TRUE ); if(SUCCEEDED(hres)) return hres; redir = FALSE; -#endif - return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path, redir ); + return query_typelib_path( guid, wMaj, wMin, is_win64 ? SYS_WIN32 : SYS_WIN64, lcid, path, redir ); }
/****************************************************************************** @@ -1978,10 +1978,8 @@ static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys, break; case VT_VARIANT: *size = sizeof(VARIANT); -#ifdef _WIN64 - if(sys == SYS_WIN32) - *size -= 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */ -#endif + if(get_ptr_size(sys) != sizeof(void*)) + *size += is_win64 ? -8 : 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */ break; case VT_DECIMAL: *size = sizeof(DECIMAL); @@ -2433,7 +2431,7 @@ MSFT_DoFuncs(TLBContext* pcx, if (ptfd->funcdesc.funckind == FUNC_DISPATCH) ptfd->funcdesc.oVft = 0; else - ptfd->funcdesc.oVft = (pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + ptfd->funcdesc.oVft = (unsigned short)(pFuncRec->VtableOffset & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
/* nameoffset is sometimes -1 on the second half of a propget/propput @@ -2611,10 +2609,9 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count, } }
-#ifdef _WIN64 -/* when a 32-bit typelib is loaded in 64-bit mode, we need to resize pointers +/* when a typelib is loaded in a different 32/64-bit mode, we need to resize pointers * and some structures, and fix the alignment */ -static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) +static void TLB_fix_typeinfo_ptr_size(ITypeInfoImpl *info) { if(info->typeattr.typekind == TKIND_ALIAS){ switch(info->tdescAlias->vt){ @@ -2630,11 +2627,12 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) break; case VT_CARRAY: case VT_USERDEFINED: - TLB_size_instance(info, SYS_WIN64, info->tdescAlias, &info->typeattr.cbSizeInstance, &info->typeattr.cbAlignment); + TLB_size_instance(info, is_win64 ? SYS_WIN64 : SYS_WIN32, info->tdescAlias, + &info->typeattr.cbSizeInstance, &info->typeattr.cbAlignment); break; case VT_VARIANT: info->typeattr.cbSizeInstance = sizeof(VARIANT); - info->typeattr.cbAlignment = 8; + info->typeattr.cbAlignment = sizeof(void *); default: if(info->typeattr.cbSizeInstance < sizeof(void*)) info->typeattr.cbAlignment = info->typeattr.cbSizeInstance; @@ -2649,7 +2647,6 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) info->typeattr.cbAlignment = sizeof(void*); } } -#endif
/* * process a typeinfo record @@ -3636,12 +3633,11 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) } }
-#ifdef _WIN64 - if(pTypeLibImpl->syskind == SYS_WIN32){ + if (pTypeLibImpl->ptr_size != sizeof(void *)) + { for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i) - TLB_fix_32on64_typeinfo(pTypeLibImpl->typeinfos[i]); + TLB_fix_typeinfo_ptr_size(pTypeLibImpl->typeinfos[i]); } -#endif
TRACE("(%p)\n", pTypeLibImpl); return &pTypeLibImpl->ITypeLib2_iface; @@ -4151,7 +4147,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH) pFuncDesc->funcdesc.oVft = 0; else - pFuncDesc->funcdesc.oVft = (pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size; + pFuncDesc->funcdesc.oVft = (unsigned short)(pFunc->vtblpos & ~1) * sizeof(void *) / pTI->pTypeLib->ptr_size;
if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT) pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; @@ -10688,11 +10684,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, !funcDesc->cParams) return TYPE_E_INCONSISTENTPROPFUNCS;
-#ifdef _WIN64 if(This->pTypeLib->syskind == SYS_WIN64 && funcDesc->oVft % 8 != 0) return E_INVALIDARG; -#endif
memset(&tmp_func_desc, 0, sizeof(tmp_func_desc)); TLBFuncDesc_Constructor(&tmp_func_desc);