Commit cd3df383 authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

oleaut32: SLTG references are only unique at the typeinfo level, so convert them…

oleaut32: SLTG references are only unique at the typeinfo level, so convert them to be unique to the typelib.
parent 82a31d09
...@@ -2702,7 +2702,27 @@ static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl) ...@@ -2702,7 +2702,27 @@ static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
return ptr - (char*)pLibBlk; return ptr - (char*)pLibBlk;
} }
static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD) /* stores a mapping between the sltg typeinfo's references and the typelib's HREFTYPEs */
typedef struct
{
unsigned int num;
HREFTYPE refs[1];
} sltg_ref_lookup_t;
static HRESULT sltg_get_typelib_ref(sltg_ref_lookup_t *table, DWORD typeinfo_ref, HREFTYPE *typelib_ref)
{
if(typeinfo_ref < table->num)
{
*typelib_ref = table->refs[typeinfo_ref];
return S_OK;
}
ERR("Unable to find reference\n");
*typelib_ref = -1;
return E_FAIL;
}
static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD, sltg_ref_lookup_t *ref_lookup)
{ {
BOOL done = FALSE; BOOL done = FALSE;
...@@ -2723,7 +2743,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD) ...@@ -2723,7 +2743,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD)
case VT_USERDEFINED: case VT_USERDEFINED:
pTD->vt = VT_USERDEFINED; pTD->vt = VT_USERDEFINED;
pTD->u.hreftype = *(++pType) / 4; sltg_get_typelib_ref(ref_lookup, *(++pType) / 4, &pTD->u.hreftype);
done = TRUE; done = TRUE;
break; break;
...@@ -2768,7 +2788,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD) ...@@ -2768,7 +2788,7 @@ static WORD *SLTG_DoType(WORD *pType, char *pBlk, TYPEDESC *pTD)
return pType; return pType;
} }
static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem) static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem, sltg_ref_lookup_t *ref_lookup)
{ {
/* Handle [in/out] first */ /* Handle [in/out] first */
if((*pType & 0xc000) == 0xc000) if((*pType & 0xc000) == 0xc000)
...@@ -2786,23 +2806,33 @@ static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem) ...@@ -2786,23 +2806,33 @@ static WORD *SLTG_DoElem(WORD *pType, char *pBlk, ELEMDESC *pElem)
if(*pType & 0x80) if(*pType & 0x80)
pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL; pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;
return SLTG_DoType(pType, pBlk, &pElem->tdesc); return SLTG_DoType(pType, pBlk, &pElem->tdesc, ref_lookup);
} }
static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
char *pNameTable) char *pNameTable)
{ {
int ref; int ref;
char *name; char *name;
TLBRefType *ref_type; TLBRefType *ref_type;
sltg_ref_lookup_t *table;
HREFTYPE typelib_ref;
if(pRef->magic != SLTG_REF_MAGIC) { if(pRef->magic != SLTG_REF_MAGIC) {
FIXME("Ref magic = %x\n", pRef->magic); FIXME("Ref magic = %x\n", pRef->magic);
return; return NULL;
} }
name = ( (char*)(&pRef->names) + pRef->number); name = ( (char*)(&pRef->names) + pRef->number);
table = HeapAlloc(GetProcessHeap(), 0, sizeof(*table) + ((pRef->number >> 3) - 1) * sizeof(table->refs[0]));
table->num = pRef->number >> 3;
/* FIXME should scan the existing list and reuse matching refs added by previous typeinfos */
/* We don't want the first href to be 0 */
typelib_ref = (list_count(&pTL->ref_list) + 1) << 2;
for(ref = 0; ref < pRef->number >> 3; ref++) { for(ref = 0; ref < pRef->number >> 3; ref++) {
char *refname; char *refname;
unsigned int lib_offs, type_num; unsigned int lib_offs, type_num;
...@@ -2846,24 +2876,28 @@ static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL, ...@@ -2846,24 +2876,28 @@ static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
/* Store a reference to IDispatch */ /* Store a reference to IDispatch */
if(pTL->dispatch_href == -1 && IsEqualGUID(&(*import)->guid, &IID_StdOle) && type_num == 4) if(pTL->dispatch_href == -1 && IsEqualGUID(&(*import)->guid, &IID_StdOle) && type_num == 4)
pTL->dispatch_href = ref; pTL->dispatch_href = typelib_ref;
} else { /* internal ref */ } else { /* internal ref */
ref_type->pImpTLInfo = TLB_REF_INTERNAL; ref_type->pImpTLInfo = TLB_REF_INTERNAL;
} }
ref_type->reference = ref; ref_type->reference = typelib_ref;
ref_type->index = type_num; ref_type->index = type_num;
HeapFree(GetProcessHeap(), 0, refname); HeapFree(GetProcessHeap(), 0, refname);
list_add_tail(&pTL->ref_list, &ref_type->entry); list_add_tail(&pTL->ref_list, &ref_type->entry);
table->refs[ref] = typelib_ref;
typelib_ref += 4;
} }
if((BYTE)*name != SLTG_REF_MAGIC) if((BYTE)*name != SLTG_REF_MAGIC)
FIXME("End of ref block magic = %x\n", *name); FIXME("End of ref block magic = %x\n", *name);
dump_TLBRefType(pTL); dump_TLBRefType(pTL);
return table;
} }
static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
BOOL OneOnly) BOOL OneOnly, sltg_ref_lookup_t *ref_lookup)
{ {
SLTG_ImplInfo *info; SLTG_ImplInfo *info;
TLBImplType **ppImplType = &pTI->impltypelist; TLBImplType **ppImplType = &pTI->impltypelist;
...@@ -2878,7 +2912,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, ...@@ -2878,7 +2912,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
while(1) { while(1) {
*ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(**ppImplType)); sizeof(**ppImplType));
(*ppImplType)->hRef = info->ref; sltg_get_typelib_ref(ref_lookup, info->ref, &(*ppImplType)->hRef);
(*ppImplType)->implflags = info->impltypeflags; (*ppImplType)->implflags = info->impltypeflags;
pTI->TypeAttr.cImplTypes++; pTI->TypeAttr.cImplTypes++;
ppImplType = &(*ppImplType)->next; ppImplType = &(*ppImplType)->next;
...@@ -2893,7 +2927,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI, ...@@ -2893,7 +2927,7 @@ static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
return (char*)info; return (char*)info;
} }
static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, char *pNameTable) static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cVars, char *pNameTable, sltg_ref_lookup_t *ref_lookup)
{ {
TLBVarDesc **ppVarDesc = &pTI->varlist; TLBVarDesc **ppVarDesc = &pTI->varlist;
BSTR bstrPrevName = NULL; BSTR bstrPrevName = NULL;
...@@ -2957,7 +2991,7 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign ...@@ -2957,7 +2991,7 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xd2); FIXME_(typelib)("unhandled flags = %02x\n", pItem->flags & ~0xd2);
SLTG_DoElem(pType, pBlk, SLTG_DoElem(pType, pBlk,
&(*ppVarDesc)->vardesc.elemdescVar); &(*ppVarDesc)->vardesc.elemdescVar, ref_lookup);
dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf); dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf);
...@@ -2967,7 +3001,7 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign ...@@ -2967,7 +3001,7 @@ static void SLTG_DoVars(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsign
pTI->TypeAttr.cVars = cVars; pTI->TypeAttr.cVars = cVars;
} }
static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable) static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsigned short cFuncs, char *pNameTable, sltg_ref_lookup_t *ref_lookup)
{ {
SLTG_Function *pFunc; SLTG_Function *pFunc;
unsigned short i; unsigned short i;
...@@ -3015,7 +3049,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsig ...@@ -3015,7 +3049,7 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsig
else else
pType = (WORD*)(pBlk + pFunc->rettype); pType = (WORD*)(pBlk + pFunc->rettype);
SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc); SLTG_DoElem(pType, pBlk, &(*ppFuncDesc)->funcdesc.elemdescFunc, ref_lookup);
(*ppFuncDesc)->funcdesc.lprgelemdescParam = (*ppFuncDesc)->funcdesc.lprgelemdescParam =
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
...@@ -3053,13 +3087,13 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsig ...@@ -3053,13 +3087,13 @@ static void SLTG_DoFuncs(char *pBlk, char *pFirstItem, ITypeInfoImpl *pTI, unsig
if(HaveOffs) { /* the next word is an offset to type */ if(HaveOffs) { /* the next word is an offset to type */
pType = (WORD*)(pBlk + *pArg); pType = (WORD*)(pBlk + *pArg);
SLTG_DoElem(pType, pBlk, SLTG_DoElem(pType, pBlk,
&(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]); &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
pArg++; pArg++;
} else { } else {
if(paramName) if(paramName)
paramName--; paramName--;
pArg = SLTG_DoElem(pArg, pBlk, pArg = SLTG_DoElem(pArg, pBlk,
&(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]); &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param], ref_lookup);
} }
/* Are we an optional param ? */ /* Are we an optional param ? */
...@@ -3084,17 +3118,19 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3084,17 +3118,19 @@ static void SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
char *pFirstItem, *pNextItem; char *pFirstItem, *pNextItem;
sltg_ref_lookup_t *ref_lookup = NULL;
if(pTIHeader->href_table != 0xffffffff) { if(pTIHeader->href_table != 0xffffffff) {
SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib, ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
pNameTable); pNameTable);
} }
pFirstItem = pNextItem = pBlk; pFirstItem = pNextItem = pBlk;
if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) { if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE); pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE, ref_lookup);
} }
HeapFree(GetProcessHeap(), 0, ref_lookup);
} }
...@@ -3103,20 +3139,23 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3103,20 +3139,23 @@ static void SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
char *pFirstItem, *pNextItem; char *pFirstItem, *pNextItem;
sltg_ref_lookup_t *ref_lookup = NULL;
if(pTIHeader->href_table != 0xffffffff) { if(pTIHeader->href_table != 0xffffffff) {
SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib, ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
pNameTable); pNameTable);
} }
pFirstItem = pNextItem = pBlk; pFirstItem = pNextItem = pBlk;
if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) { if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE); pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE, ref_lookup);
} }
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
HeapFree(GetProcessHeap(), 0, ref_lookup);
if (TRACE_ON(typelib)) if (TRACE_ON(typelib))
dump_TLBFuncDesc(pTI->funclist); dump_TLBFuncDesc(pTI->funclist);
...@@ -3126,7 +3165,7 @@ static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3126,7 +3165,7 @@ static void SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
} }
static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
...@@ -3134,6 +3173,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3134,6 +3173,7 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
WORD *pType; WORD *pType;
sltg_ref_lookup_t *ref_lookup = NULL;
if (pTITail->simple_alias) { if (pTITail->simple_alias) {
/* if simple alias, no more processing required */ /* if simple alias, no more processing required */
...@@ -3142,35 +3182,39 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3142,35 +3182,39 @@ static void SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
} }
if(pTIHeader->href_table != 0xffffffff) { if(pTIHeader->href_table != 0xffffffff) {
SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib, ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
pNameTable); pNameTable);
} }
/* otherwise it is an offset to a type */ /* otherwise it is an offset to a type */
pType = (WORD *)(pBlk + pTITail->tdescalias_vt); pType = (WORD *)(pBlk + pTITail->tdescalias_vt);
SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias); SLTG_DoType(pType, pBlk, &pTI->TypeAttr.tdescAlias, ref_lookup);
HeapFree(GetProcessHeap(), 0, ref_lookup);
} }
static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib, ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) if (pTITail->vars_off != 0xffff)
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
/* this is necessary to cope with MSFT typelibs that set cFuncs to the number /* this is necessary to cope with MSFT typelibs that set cFuncs to the number
* of dispinterface functons including the IDispatch ones, so * of dispinterface functons including the IDispatch ones, so
* ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */ * ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *); pTI->TypeAttr.cbSizeVft = pTI->TypeAttr.cFuncs * sizeof(void *);
HeapFree(GetProcessHeap(), 0, ref_lookup);
if (TRACE_ON(typelib)) if (TRACE_ON(typelib))
dump_TLBFuncDesc(pTI->funclist); dump_TLBFuncDesc(pTI->funclist);
} }
...@@ -3179,22 +3223,24 @@ static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI, ...@@ -3179,22 +3223,24 @@ static void SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, NULL);
} }
static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI, static void SLTG_ProcessModule(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable, SLTG_TypeInfoHeader *pTIHeader, char *pNameTable, SLTG_TypeInfoHeader *pTIHeader,
SLTG_TypeInfoTail *pTITail) SLTG_TypeInfoTail *pTITail)
{ {
sltg_ref_lookup_t *ref_lookup = NULL;
if (pTIHeader->href_table != 0xffffffff) if (pTIHeader->href_table != 0xffffffff)
SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib, ref_lookup = SLTG_DoRefs((SLTG_RefInfo*)((char *)pTIHeader + pTIHeader->href_table), pTI->pTypeLib,
pNameTable); pNameTable);
if (pTITail->vars_off != 0xffff) if (pTITail->vars_off != 0xffff)
SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable); SLTG_DoVars(pBlk, pBlk + pTITail->vars_off, pTI, pTITail->cVars, pNameTable, ref_lookup);
if (pTITail->funcs_off != 0xffff) if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable); SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
HeapFree(GetProcessHeap(), 0, ref_lookup);
} }
/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more /* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
......
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