PATCH: typelib things
Marcus Meissner
marcus at jet.franken.de
Sat Dec 28 14:49:58 CST 2002
Hi,
This obsoletes parts of the VB6 rollup patch I posted some days ago.
Ciao, Marcus
Changelog:
Process TKIND_ALIAS in SLTG typelibs, 0x14 in the tail
is the tdescAlias.vt entry.
Added a small handler for TKIND_DISPATCH in SLTG.
ITypeLib_Release can have a NULL pointer as ITypeInfo*.
Split out _copy_arg function for both DispCall and
ITypeInfo_fnInvoke, added some more functionality.
ITypeInfo_fnInvoke can handle VT_USERDEFINED variants.
Index: typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.84
diff -u -r1.84 typelib.c
--- typelib.c 12 Dec 2002 22:59:25 -0000 1.84
+++ typelib.c 28 Dec 2002 20:48:02 -0000
@@ -573,9 +573,6 @@
return S_OK; /* FIXME: pretend everything is OK */
}
-/* for better debugging info leave the static out for the time being */
-#define static
-
/*======================= ITypeLib implementation =======================*/
typedef struct tagTLBCustData
@@ -1030,7 +1025,13 @@
TRACE("%d\n", *(short*)ref);
break;
+ case VT_UI4:
+ case VT_UINT:
+ TRACE("%u\n", *(UINT*)ref);
+ break;
+
case VT_I4:
+ case VT_INT:
TRACE("%d\n", *(INT*)ref);
break;
@@ -2727,6 +2734,58 @@
return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
}
+static SLTG_TypeInfoTail *SLTG_ProcessAlias(char *pBlk, ITypeInfoImpl *pTI,
+ char *pNameTable)
+{
+ SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
+ SLTG_MemberHeader *pMemHeader;
+ SLTG_AliasItem *pItem;
+ int i, mustbelast;
+
+ pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
+ pItem = (SLTG_AliasItem*)(pMemHeader + 1);
+
+ mustbelast = 0;
+ /* This is used for creating a TYPEDESC chain in case of VT_USERDEFINED */
+ for (i = 0 ; i<pMemHeader->cbExtra/4 ; i++) {
+ if (pItem->vt == 0xffff) {
+ if (i<(pMemHeader->cbExtra/4-1))
+ FIXME("Endmarker too early in process alias data!\n");
+ break;
+ }
+ if (mustbelast) {
+ FIXME("Chain extends over last entry?\n");
+ break;
+ }
+ if (pItem->vt == VT_USERDEFINED) {
+ pTI->TypeAttr.tdescAlias.vt = pItem->vt;
+ /* guessing here ... */
+ FIXME("Guessing TKIND_ALIAS of VT_USERDEFINED with hreftype 0x%x\n",pItem->res02);
+ pTI->TypeAttr.tdescAlias.u.hreftype = pItem->res02;
+ mustbelast = 1;
+ } else {
+ FIXME("alias %d: 0x%x\n",i,pItem->vt);
+ FIXME("alias %d: 0x%x\n",i,pItem->res02);
+ }
+ pItem++;
+ }
+ return (SLTG_TypeInfoTail*)((char*)(pMemHeader + 1)+pMemHeader->cbExtra);
+}
+
+static SLTG_TypeInfoTail *SLTG_ProcessDispatch(char *pBlk, ITypeInfoImpl *pTI,
+ char *pNameTable)
+{
+ SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
+ SLTG_MemberHeader *pMemHeader;
+ SLTG_AliasItem *pItem;
+
+ pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
+ pItem = (SLTG_AliasItem*)(pMemHeader + 1);
+ FIXME("memh.cbExtra is %ld\n",pMemHeader->cbExtra);
+ FIXME("offset 0 0x%x\n",*(WORD*)pItem);
+ return (SLTG_TypeInfoTail*)((char*)(pMemHeader + 1)+pMemHeader->cbExtra);
+}
+
static SLTG_TypeInfoTail *SLTG_ProcessEnum(char *pBlk, ITypeInfoImpl *pTI,
char *pNameTable)
{
@@ -3016,6 +3075,16 @@
pTITail = SLTG_ProcessCoClass(pBlk, *ppTypeInfoImpl, pNameTable);
break;
+ case TKIND_ALIAS:
+ pTITail = SLTG_ProcessAlias(pBlk, *ppTypeInfoImpl, pNameTable);
+ if (pTITail->tdescalias_vt)
+ (*ppTypeInfoImpl)->TypeAttr.tdescAlias.vt = pTITail->tdescalias_vt;
+ break;
+
+ case TKIND_DISPATCH:
+ pTITail = SLTG_ProcessDispatch(pBlk, *ppTypeInfoImpl, pNameTable);
+ break;
+
default:
FIXME("Not processing typekind %d\n", pTIHeader->typekind);
pTITail = NULL;
@@ -3028,6 +3097,28 @@
(*ppTypeInfoImpl)->TypeAttr.cbAlignment = pTITail->cbAlignment;
(*ppTypeInfoImpl)->TypeAttr.cbSizeInstance = pTITail->cbSizeInstance;
(*ppTypeInfoImpl)->TypeAttr.cbSizeVft = pTITail->cbSizeVft;
+
+#define X(x) TRACE("tt "#x": %x\n",pTITail->res##x);
+ X(06);
+ X(08);
+ X(0a);
+ X(0c);
+ X(0e);
+ X(10);
+ X(12);
+ X(16);
+ X(18);
+ X(1a);
+ X(1c);
+ X(1e);
+ X(24);
+ X(26);
+ X(2a);
+ X(2c);
+ X(2e);
+ X(30);
+ X(32);
+ X(34);
}
ppTypeInfoImpl = &((*ppTypeInfoImpl)->next);
pBlk = (char*)pBlk + pBlkEntry[order].len;
@@ -3122,7 +3213,8 @@
This->HelpStringDll = NULL;
}
- ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
+ if (This->pTypeInfo) /* can be NULL */
+ ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
HeapFree(GetProcessHeap(),0,This);
return 0;
}
@@ -3885,7 +3977,7 @@
TLBImplType *pImpl = This->impltypelist;
TRACE("(%p) index %d\n", This, index);
- dump_TypeInfo(This);
+ if (TRACE_ON(ole)) dump_TypeInfo(This);
if(index==(UINT)-1)
{
@@ -4089,6 +4181,89 @@
extern int const _argsize(DWORD vt);
+/****************************************************************************
+ * Helper functions for Dispcall / Invoke, which copies one variant
+ * with target type onto the argument stack.
+ */
+static HRESULT
+_copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
+ DWORD *argpos, VARIANT *arg, VARTYPE vt
+) {
+ UINT arglen = _argsize(vt)*sizeof(DWORD);
+ VARTYPE oldvt;
+
+ if (V_VT(arg) == vt) {
+ memcpy(argpos, &V_UNION(arg,lVal), arglen);
+ return S_OK;
+ }
+
+ if (vt == VT_VARIANT) {
+ memcpy(argpos, arg, arglen);
+ return S_OK;
+ }
+ /* Deref BYREF vars if there is need */
+ if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==vt)) {
+ memcpy(argpos,(void*)V_UNION(arg,lVal), arglen);
+ return S_OK;
+ }
+ if (vt==VT_UNKNOWN && V_VT(arg)==VT_DISPATCH) {
+ /* in this context, if the type lib specifies IUnknown*, giving an IDispatch* is correct; so, don't invoke VariantChangeType */
+ memcpy(argpos,&V_UNION(arg,lVal), arglen);
+ return S_OK;
+ }
+ if ((vt == VT_PTR) && tdesc)
+ return _copy_arg(tinfo, tdesc->u.lptdesc, argpos, arg, tdesc->u.lptdesc->vt);
+ if ((vt == VT_USERDEFINED) && tdesc && tinfo) {
+ ITypeInfo *tinfo2;
+ TYPEATTR *tattr;
+ HRESULT hres;
+
+ hres = ITypeInfo_GetRefTypeInfo(tinfo,tdesc->u.hreftype,&tinfo2);
+ if (hres) {
+ FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing from vt 0x%x. Copying 4 byte.\n",tdesc->u.hreftype,V_VT(arg));
+ memcpy(argpos, &V_UNION(arg,lVal), 4);
+ return S_OK;
+ }
+ ITypeInfo_GetTypeAttr(tinfo2,&tattr);
+ switch (tattr->typekind) {
+ case TKIND_ENUM:
+ if (V_VT(arg) == VT_I4) {
+ memcpy(argpos, &V_UNION(arg,iVal), 4);
+ return S_OK;
+ }
+ FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
+ break;
+ case TKIND_ALIAS:
+ tdesc = &(tattr->tdescAlias);
+ hres = _copy_arg((ITypeInfo2*)tinfo2, tdesc, argpos, arg, tdesc->vt);
+ ITypeInfo_Release(tinfo2);
+ return hres;
+
+ case TKIND_INTERFACE:
+ FIXME("TKIND_INTERFACE unhandled.\n");
+ break;
+ case TKIND_DISPATCH:
+ FIXME("TKIND_DISPATCH unhandled.\n");
+ break;
+ case TKIND_RECORD:
+ FIXME("TKIND_RECORD unhandled.\n");
+ break;
+ default:
+ FIXME("TKIND %d unhandled.\n",tattr->typekind);
+ break;
+ }
+ return E_FAIL;
+ }
+ oldvt = V_VT(arg);
+ if (VariantChangeType(arg,arg,0,vt)==S_OK) {
+ FIXME("argument was coerced in-place (0x%x -> 0x%x); source data has been modified!!!\n", oldvt, vt);
+ memcpy(argpos,&V_UNION(arg,lVal), arglen);
+ return S_OK;
+ }
+ ERR("Set arg to disparg type 0x%x vs 0x%x\n",V_VT(arg),vt);
+ return E_FAIL;
+}
+
/***********************************************************************
* DispCallFunc (OLEAUT32.@)
*/
@@ -4108,33 +4283,18 @@
So we need to add a first parameter to the list of arguments, to supply the interface pointer */
argsize = 1;
for (i=0;i<cActuals;i++) {
- TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_argsize(prgvt[i]));
+ TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_argsize(prgvt[i]));
dump_Variant(prgpvarg[i]);
- argsize += _argsize(prgvt[i]);
+ argsize += _argsize(prgvt[i]);
}
args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
- args[0]=0; /* this is the fake IDispatch interface pointer */
+ args[0] = (DWORD)pvInstance; /* this is the fake IDispatch interface pointer */
argspos = 1;
for (i=0;i<cActuals;i++) {
- int arglen;
- VARIANT *arg = prgpvarg[i];
- TRACE("Storing arg %d (%d as %d)\n",i,V_VT(arg),prgvt[i]);
- arglen = _argsize(prgvt[i]);
- if (V_VT(arg) == prgvt[i]) {
- memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
- } else if (prgvt[i] == VT_VARIANT) {
- memcpy(&args[argspos],arg, arglen*sizeof(DWORD));
- } else if (prgvt[i]==VT_UNKNOWN && V_VT(arg)==VT_DISPATCH) {
- /* in this context, if the type lib specifies IUnknown*, giving an IDispatch* is correct;
- so, don't invoke VariantChangeType */
- memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
- } else if (VariantChangeType(arg,arg,0,prgvt[i])==S_OK) {
- FIXME("argument was coerced in-place; source data has been modified!!!\n");
- memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
- } else {
- ERR("Set arg %d to disparg type %d vs %d\n",i,V_VT(arg),prgvt[i]);
- }
- argspos += arglen;
+ VARIANT *arg = prgpvarg[i];
+ TRACE("Storing arg %d (%d as %d)\n",i,V_VT(arg),prgvt[i]);
+ _copy_arg(NULL, NULL, &args[argspos], arg, prgvt[i]);
+ argspos += _argsize(prgvt[i]);
}
if(pvargResult!=NULL && V_VT(pvargResult)==VT_EMPTY)
@@ -4166,6 +4326,7 @@
TLBFuncDesc * pFDesc;
TLBVarDesc * pVDesc;
int i;
+ HRESULT hres;
TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p) partial stub!\n",
This,pIUnk,memid,dwFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
@@ -4178,7 +4339,7 @@
break;
}
if (pFDesc) {
- dump_TLBFuncDescOne(pFDesc);
+ if (TRACE_ON(typelib)) dump_TLBFuncDescOne(pFDesc);
/* dump_FUNCDESC(&pFDesc->funcdesc);*/
switch (pFDesc->funcdesc.funckind) {
case FUNC_PUREVIRTUAL:
@@ -4208,18 +4369,8 @@
if (i<pDispParams->cArgs) {
VARIANT *arg = &pDispParams->rgvarg[pDispParams->cArgs-i-1];
TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
-
- if (V_VT(arg) == tdesc->vt) {
- memcpy(&args[argspos],&V_UNION(arg,lVal), arglen*sizeof(DWORD));
- } else if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==tdesc->vt)) {
- memcpy(&args[argspos],(void*)V_UNION(arg,lVal), arglen*sizeof(DWORD));
- } else if (tdesc->vt == VT_VARIANT) {
- memcpy(&args[argspos],arg, arglen*sizeof(DWORD));
- } else {
- ERR("Set arg %d to disparg type %d vs %d\n",i,
- V_VT(arg),tdesc->vt
- );
- }
+ hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
+ if (FAILED(hres)) return hres;
argspos += arglen;
} else {
TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
@@ -4262,6 +4413,40 @@
if (tdesc->vt == VT_PTR)
tdesc = tdesc->u.lptdesc;
+ if (tdesc->vt == VT_USERDEFINED) {
+ ITypeInfo *tinfo2;
+ TYPEATTR *tattr;
+
+ hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2);
+ if (hres) {
+ FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype);
+ return E_FAIL;
+ }
+ ITypeInfo_GetTypeAttr(tinfo2,&tattr);
+ switch (tattr->typekind) {
+ case TKIND_ENUM:
+ FIXME("TKIND_ENUM unhandled.\n");
+ break;
+ case TKIND_ALIAS:
+ TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt);
+ tdesc = &(tattr->tdescAlias);
+ break;
+
+ case TKIND_INTERFACE:
+ FIXME("TKIND_INTERFACE unhandled.\n");
+ break;
+ case TKIND_DISPATCH:
+ FIXME("TKIND_DISPATCH unhandled.\n");
+ break;
+ case TKIND_RECORD:
+ FIXME("TKIND_RECORD unhandled.\n");
+ break;
+ default:
+ FIXME("TKIND %d unhandled.\n",tattr->typekind);
+ break;
+ }
+ ITypeInfo_Release(tinfo2);
+ }
V_VT(pVarResult) = tdesc->vt;
/* HACK: VB5 likes this.
Index: dlls/oleaut32/typelib.h
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.h,v
retrieving revision 1.13
diff -u -r1.13 typelib.h
--- dlls/oleaut32/typelib.h 10 Jul 2002 23:07:59 -0000 1.13
+++ dlls/oleaut32/typelib.h 28 Dec 2002 20:26:10 -0000
@@ -417,7 +417,7 @@
/*0e*/ WORD res0e;
/*10*/ WORD res10;
/*12*/ WORD res12;
-/*14*/ WORD res14;
+/*14*/ WORD tdescalias_vt; /* for TKIND_ALIAS */
/*16*/ WORD res16;
/*18*/ WORD res18;
/*1a*/ WORD res1a;
@@ -457,6 +457,13 @@
} SLTG_EnumItem;
#define SLTG_ENUMITEM_MAGIC 0x120a
+
+typedef struct {
+/*00*/ WORD vt; /* vartype, 0xffff marks end. */
+/*02*/ WORD res02; /* ?, 0xffff marks end */
+} SLTG_AliasItem;
+
+#define SLTG_ALIASITEM_MAGIC 0x001d
typedef struct {
More information about the wine-patches
mailing list