Commit 613270d4 authored by Alexandre Julliard's avatar Alexandre Julliard

oleaut32: Fix loading a 64-bit typelib in 32-bit mode.

parent 4ffc313d
...@@ -73,6 +73,8 @@ ...@@ -73,6 +73,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(ole); WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(typelib); WINE_DECLARE_DEBUG_CHANNEL(typelib);
static const BOOL is_win64 = sizeof(void *) > sizeof(int);
typedef struct typedef struct
{ {
WORD offset; WORD offset;
...@@ -392,13 +394,11 @@ static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin, ...@@ -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 ) HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path )
{ {
BOOL redir = TRUE; BOOL redir = TRUE;
#ifdef _WIN64 HRESULT hres = query_typelib_path( guid, wMaj, wMin, is_win64 ? SYS_WIN64 : SYS_WIN32, lcid, path, TRUE );
HRESULT hres = query_typelib_path( guid, wMaj, wMin, SYS_WIN64, lcid, path, TRUE );
if(SUCCEEDED(hres)) if(SUCCEEDED(hres))
return hres; return hres;
redir = FALSE; redir = FALSE;
#endif return query_typelib_path( guid, wMaj, wMin, is_win64 ? SYS_WIN32 : SYS_WIN64, lcid, path, redir );
return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path, redir );
} }
/****************************************************************************** /******************************************************************************
...@@ -1978,10 +1978,8 @@ static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys, ...@@ -1978,10 +1978,8 @@ static HRESULT TLB_size_instance(ITypeInfoImpl *info, SYSKIND sys,
break; break;
case VT_VARIANT: case VT_VARIANT:
*size = sizeof(VARIANT); *size = sizeof(VARIANT);
#ifdef _WIN64 if(get_ptr_size(sys) != sizeof(void*))
if(sys == SYS_WIN32) *size += is_win64 ? -8 : 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */
*size -= 8; /* 32-bit VARIANT is 8 bytes smaller than 64-bit VARIANT */
#endif
break; break;
case VT_DECIMAL: case VT_DECIMAL:
*size = sizeof(DECIMAL); *size = sizeof(DECIMAL);
...@@ -2433,7 +2431,7 @@ MSFT_DoFuncs(TLBContext* pcx, ...@@ -2433,7 +2431,7 @@ MSFT_DoFuncs(TLBContext* pcx,
if (ptfd->funcdesc.funckind == FUNC_DISPATCH) if (ptfd->funcdesc.funckind == FUNC_DISPATCH)
ptfd->funcdesc.oVft = 0; ptfd->funcdesc.oVft = 0;
else 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) ; ptfd->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
/* nameoffset is sometimes -1 on the second half of a propget/propput /* 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, ...@@ -2611,10 +2609,9 @@ static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
} }
} }
#ifdef _WIN64 /* when a typelib is loaded in a different 32/64-bit mode, we need to resize pointers
/* when a 32-bit typelib is loaded in 64-bit mode, we need to resize pointers
* and some structures, and fix the alignment */ * 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){ if(info->typeattr.typekind == TKIND_ALIAS){
switch(info->tdescAlias->vt){ switch(info->tdescAlias->vt){
...@@ -2630,11 +2627,12 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) ...@@ -2630,11 +2627,12 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info)
break; break;
case VT_CARRAY: case VT_CARRAY:
case VT_USERDEFINED: 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; break;
case VT_VARIANT: case VT_VARIANT:
info->typeattr.cbSizeInstance = sizeof(VARIANT); info->typeattr.cbSizeInstance = sizeof(VARIANT);
info->typeattr.cbAlignment = 8; info->typeattr.cbAlignment = sizeof(void *);
default: default:
if(info->typeattr.cbSizeInstance < sizeof(void*)) if(info->typeattr.cbSizeInstance < sizeof(void*))
info->typeattr.cbAlignment = info->typeattr.cbSizeInstance; info->typeattr.cbAlignment = info->typeattr.cbSizeInstance;
...@@ -2649,7 +2647,6 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info) ...@@ -2649,7 +2647,6 @@ static void TLB_fix_32on64_typeinfo(ITypeInfoImpl *info)
info->typeattr.cbAlignment = sizeof(void*); info->typeattr.cbAlignment = sizeof(void*);
} }
} }
#endif
/* /*
* process a typeinfo record * process a typeinfo record
...@@ -3636,12 +3633,11 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength) ...@@ -3636,12 +3633,11 @@ static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
} }
} }
#ifdef _WIN64 if (pTypeLibImpl->ptr_size != sizeof(void *))
if(pTypeLibImpl->syskind == SYS_WIN32){ {
for(i = 0; i < pTypeLibImpl->TypeInfoCount; ++i) 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); TRACE("(%p)\n", pTypeLibImpl);
return &pTypeLibImpl->ITypeLib2_iface; return &pTypeLibImpl->ITypeLib2_iface;
...@@ -4151,7 +4147,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, ...@@ -4151,7 +4147,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI,
if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH) if (pFuncDesc->funcdesc.funckind == FUNC_DISPATCH)
pFuncDesc->funcdesc.oVft = 0; pFuncDesc->funcdesc.oVft = 0;
else 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) if(pFunc->magic & SLTG_FUNCTION_FLAGS_PRESENT)
pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags; pFuncDesc->funcdesc.wFuncFlags = pFunc->funcflags;
...@@ -10688,11 +10684,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface, ...@@ -10688,11 +10684,9 @@ static HRESULT WINAPI ICreateTypeInfo2_fnAddFuncDesc(ICreateTypeInfo2 *iface,
!funcDesc->cParams) !funcDesc->cParams)
return TYPE_E_INCONSISTENTPROPFUNCS; return TYPE_E_INCONSISTENTPROPFUNCS;
#ifdef _WIN64
if(This->pTypeLib->syskind == SYS_WIN64 && if(This->pTypeLib->syskind == SYS_WIN64 &&
funcDesc->oVft % 8 != 0) funcDesc->oVft % 8 != 0)
return E_INVALIDARG; return E_INVALIDARG;
#endif
memset(&tmp_func_desc, 0, sizeof(tmp_func_desc)); memset(&tmp_func_desc, 0, sizeof(tmp_func_desc));
TLBFuncDesc_Constructor(&tmp_func_desc); TLBFuncDesc_Constructor(&tmp_func_desc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment