static HRESULT TLB_ReadTypeLib(LPCWSTR pszFileName, LPWSTR pszPath, UINT cchPath, ITypeLib2 **ppTypeLib);
-/****************************************************************************
- * QueryPathOfRegTypeLib [OLEAUT32.164]
- *
- * Gets the path to a registered type library.
- *
- * PARAMS
- * guid [I] referenced guid
- * wMaj [I] major version
- * wMin [I] minor version
- * lcid [I] locale id
- * path [O] path of typelib
- *
- * RETURNS
- * Success: S_OK.
- * Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
- * or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
- * opened.
- */
-HRESULT WINAPI QueryPathOfRegTypeLib(
- REFGUID guid,
- WORD wMaj,
- WORD wMin,
- LCID lcid,
- LPBSTR path )
+/* Get the path to a registered type library. Helper for QueryPathOfRegTypeLib. */
+static HRESULT query_typelib_path( REFGUID guid, WORD wMaj, WORD wMin,
+ SYSKIND syskind, LCID lcid, LPBSTR path )
{
HRESULT hr = TYPE_E_LIBNOTREGISTERED;
LCID myLCID = lcid;
{
LONG dwPathLen = sizeof(Path);
- get_lcid_subkey( myLCID, SYS_WIN32, buffer );
+ get_lcid_subkey( myLCID, syskind, buffer );
if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
{
return hr;
}
+/****************************************************************************
+ * QueryPathOfRegTypeLib [OLEAUT32.164]
+ *
+ * Gets the path to a registered type library.
+ *
+ * PARAMS
+ * guid [I] referenced guid
+ * wMaj [I] major version
+ * wMin [I] minor version
+ * lcid [I] locale id
+ * path [O] path of typelib
+ *
+ * RETURNS
+ * Success: S_OK.
+ * Failure: If the type library is not registered then TYPE_E_LIBNOTREGISTERED
+ * or TYPE_E_REGISTRYACCESS if the type library registration key couldn't be
+ * opened.
+ */
+HRESULT WINAPI QueryPathOfRegTypeLib( REFGUID guid, WORD wMaj, WORD wMin, LCID lcid, LPBSTR path )
+{
+ return query_typelib_path( guid, wMaj, wMin, SYS_WIN32, lcid, path );
+}
+
/******************************************************************************
* CreateTypeLib [OLEAUT32.160] creates a typelib
*
LPOLESTR doc;
/* Set the human-readable name of the typelib */
- if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+ if (FAILED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
+ res = E_FAIL;
+ else if (doc)
{
if (RegSetValueExW(key, NULL, 0, REG_SZ,
(BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
SysFreeString(doc);
}
- else
- res = E_FAIL;
/* Make up the name of the typelib path subkey */
if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
MESSAGE("\n");
}
- if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL|TYPEFLAG_FDISPATCHABLE))
+ /* Register all dispinterfaces (which includes dual interfaces) and
+ oleautomation interfaces */
+ if ((kind == TKIND_INTERFACE && (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
+ kind == TKIND_DISPATCH)
{
/* register interface<->typelib coupling */
get_interface_key( &tattr->guid, keyName );
}
/* get the path to the typelib on disk */
- if (QueryPathOfRegTypeLib(libid, wVerMajor, wVerMinor, lcid, &tlibPath) != S_OK) {
+ if (query_typelib_path(libid, wVerMajor, wVerMinor, syskind, lcid, &tlibPath) != S_OK) {
result = E_INVALIDARG;
goto end;
}
goto enddeleteloop;
}
- /* the path to the type */
- get_interface_key( &typeAttr->guid, subKeyName );
+ if ((kind == TKIND_INTERFACE && (typeAttr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) ||
+ kind == TKIND_DISPATCH)
+ {
+ /* the path to the type */
+ get_interface_key( &typeAttr->guid, subKeyName );
- /* Delete its bits */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != ERROR_SUCCESS) {
- goto enddeleteloop;
+ /* Delete its bits */
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != ERROR_SUCCESS)
+ goto enddeleteloop;
+
+ RegDeleteKeyW(subKey, ProxyStubClsidW);
+ RegDeleteKeyW(subKey, ProxyStubClsid32W);
+ RegDeleteKeyW(subKey, TypeLibW);
+ RegCloseKey(subKey);
+ subKey = NULL;
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
}
- RegDeleteKeyW(subKey, ProxyStubClsidW);
- RegDeleteKeyW(subKey, ProxyStubClsid32W);
- RegDeleteKeyW(subKey, TypeLibW);
- RegCloseKey(subKey);
- subKey = NULL;
- RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
enddeleteloop:
if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
return result;
}
+/******************************************************************************
+ * RegisterTypeLibForUser [OLEAUT32.442]
+ * Adds information about a type library to the user registry
+ * NOTES
+ * Docs: ITypeLib FAR * ptlib
+ * Docs: OLECHAR FAR* szFullPath
+ * Docs: OLECHAR FAR* szHelpDir
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: Status
+ */
+HRESULT WINAPI RegisterTypeLibForUser(
+ ITypeLib * ptlib, /* [in] Pointer to the library*/
+ OLECHAR * szFullPath, /* [in] full Path of the library*/
+ OLECHAR * szHelpDir) /* [in] dir to the helpfile for the library,
+ may be NULL*/
+{
+ FIXME("(%p, %s, %s) registering the typelib system-wide\n", ptlib,
+ debugstr_w(szFullPath), debugstr_w(szHelpDir));
+ return RegisterTypeLib(ptlib, szFullPath, szHelpDir);
+}
+
+/******************************************************************************
+ * UnRegisterTypeLibForUser [OLEAUT32.443]
+ * Removes information about a type library from the user registry
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: Status
+ */
+HRESULT WINAPI UnRegisterTypeLibForUser(
+ REFGUID libid, /* [in] GUID of the library */
+ WORD wVerMajor, /* [in] major version */
+ WORD wVerMinor, /* [in] minor version */
+ LCID lcid, /* [in] locale id */
+ SYSKIND syskind)
+{
+ FIXME("(%s, %u, %u, %u, %u) unregistering the typelib system-wide\n",
+ debugstr_guid(libid), wVerMajor, wVerMinor, lcid, syskind);
+ return UnRegisterTypeLib(libid, wVerMajor, wVerMinor, lcid, syskind);
+}
+
/*======================= ITypeLib implementation =======================*/
typedef struct tagTLBCustData
int helpcontext;
int HelpStringContext;
BSTR HelpString;
- BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
+ BSTR Entry; /* if IS_INTRESOURCE true, it's numeric; if -1 it isn't present */
int ctCustData;
TLBCustData * pCustData; /* linked list to cust data; */
struct tagTLBFuncDesc * next;
const ITypeInfo2Vtbl *lpVtbl;
const ITypeCompVtbl *lpVtblTypeComp;
LONG ref;
- BOOL no_free_data; /* don't free data structures */
+ BOOL not_attached_to_typelib;
TYPEATTR TypeAttr ; /* _lots_ of type information. */
ITypeLibImpl * pTypeLib; /* back pointer to typelib */
int index; /* index in this typelib; */
static const ITypeCompVtbl tcompvt;
static ITypeInfo2 * ITypeInfo_Constructor(void);
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
typedef struct tagTLBContext
{
return pcx->pos;
}
-static inline void MSFT_Seek(TLBContext *pcx, long where)
+static inline void MSFT_Seek(TLBContext *pcx, LONG where)
{
if (where != DO_NOT_SEEK)
{
if (where > pcx->length)
{
/* FIXME */
- ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
+ ERR("seek beyond end (%d/%d)\n", where, pcx->length );
TLB_abort();
}
pcx->pos = where;
}
/* read function */
-static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
+static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, LONG where )
{
- TRACE_(typelib)("pos=0x%08x len=0x%08x 0x%08x 0x%08x 0x%08lx\n",
+ TRACE_(typelib)("pos=0x%08x len=0x%08x 0x%08x 0x%08x 0x%08x\n",
pcx->pos, count, pcx->oStart, pcx->length, where);
MSFT_Seek(pcx, where);
}
static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx,
- long where )
+ LONG where )
{
DWORD ret;
}
static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx,
- long where )
+ LONG where )
{
DWORD ret;
{
if ( pFuncRec->FKCCIC & 0x2000 )
{
- if (HIWORD(pFuncRec->OptAttr[2]) != 0)
- ERR("ordinal 0x%08x invalid, HIWORD != 0\n", pFuncRec->OptAttr[2]);
- (*pptfd)->Entry = (BSTR)pFuncRec->OptAttr[2];
+ if (!IS_INTRESOURCE(pFuncRec->OptAttr[2]))
+ ERR("ordinal 0x%08x invalid, IS_INTRESOURCE is false\n", pFuncRec->OptAttr[2]);
+ (*pptfd)->Entry = (BSTR)(DWORD_PTR)LOWORD(pFuncRec->OptAttr[2]);
}
else
{
/* Find resource */
typeInfo = (NE_TYPEINFO *)(resTab + 2);
- if (HIWORD(typeid) != 0) /* named type */
+ if (!IS_INTRESOURCE(typeid)) /* named type */
{
BYTE len = strlen( typeid );
while (typeInfo->type_id)
found_type:
nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
- if (HIWORD(resid) != 0) /* named resource */
+ if (!IS_INTRESOURCE(resid)) /* named resource */
{
BYTE len = strlen( resid );
for (count = typeInfo->count; count > 0; count--, nameInfo++)
if(index_str && *++index_str != '\0')
{
LPWSTR end_ptr;
- long idx = strtolW(index_str, &end_ptr, 10);
+ LONG idx = strtolW(index_str, &end_ptr, 10);
if(*end_ptr == '\0')
{
int str_len = index_str - pszFileName - 1;
static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
{
TLBContext cx;
- long lPSegDir;
+ LONG lPSegDir;
MSFT_Header tlbHeader;
MSFT_SegDir tlbSegDir;
ITypeLibImpl * pTypeLibImpl;
lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
/* now read the segment directory */
- TRACE("read segment directory (at %ld)\n",lPSegDir);
+ TRACE("read segment directory (at %d)\n",lPSegDir);
MSFT_ReadLEDWords(&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
cx.pTblDir = &tlbSegDir;
/* just check two entries */
if ( tlbSegDir.pTypeInfoTab.res0c != 0x0F || tlbSegDir.pImpInfo.res0c != 0x0F)
{
- ERR("cannot find the table directory, ptr=0x%lx\n",lPSegDir);
+ ERR("cannot find the table directory, ptr=0x%x\n",lPSegDir);
HeapFree(GetProcessHeap(),0,pTypeLibImpl);
return NULL;
}
else if(td[0] == VT_CARRAY)
{
/* array descr table here */
- pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)((int) td[2]); /* temp store offset in*/
+ pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)(INT_PTR)td[2]; /* temp store offset in*/
}
else if(td[0] == VT_USERDEFINED)
{
if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
if(tlbSegDir.pArrayDescriptions.offset>0)
{
- MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
+ MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (INT_PTR)pTypeLibImpl->pTypeDesc[i].u.lpadesc);
pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
if(td[1]<0)
pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem.vt = td[0] & VT_TYPEMASK;
else
- pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = stndTypeDesc[td[0]/8];
+ pTypeLibImpl->pTypeDesc[i].u.lpadesc->tdescElem = cx.pLibInfo->pTypeDesc[td[0]/(2*sizeof(INT))];
pTypeLibImpl->pTypeDesc[i].u.lpadesc->cDims = td[2];
name = TLB_Alloc(size+1);
MSFT_Read(name, size, &cx, DO_NOT_SEEK);
(*ppImpLib)->name = TLB_MultiByteToBSTR(name);
+ TLB_Free(name);
MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
if (pTITail->funcs_off != 0xffff)
SLTG_DoFuncs(pBlk, pBlk + pTITail->funcs_off, pTI, pTITail->cFuncs, pNameTable, ref_lookup);
+ if (pTITail->impls_off != 0xffff)
+ SLTG_DoImpls(pBlk + pTITail->impls_off, pTI, FALSE, ref_lookup);
+
/* this is necessary to cope with MSFT typelibs that set cFuncs to the number
* of dispinterface functions including the IDispatch ones, so
* ITypeInfo::GetFuncDesc takes the real value for cFuncs from cbSizeVft */
(*ppTypeInfoImpl)->TypeAttr.wTypeFlags =
(pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
+ if((*ppTypeInfoImpl)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
+ (*ppTypeInfoImpl)->TypeAttr.typekind = TKIND_DISPATCH;
+
if((pTIHeader->typeflags1 & 7) != 2)
FIXME_(typelib)("typeflags1 = %02x\n", pTIHeader->typeflags1);
if(pTIHeader->typeflags3 != 2)
TLBRefType *ref_type;
void *cursor2;
int i;
+ ITypeInfoImpl *pTI, *pTINext;
/* remove cache entry */
if(This->path)
TLB_Free(ref_type);
}
- if (This->pTypeInfo) /* can be NULL */
- ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
+ for (pTI = This->pTypeInfo; pTI; pTI = pTINext)
+ {
+ pTINext = pTI->next;
+ ITypeInfo_fnDestroy(pTI);
+ }
HeapFree(GetProcessHeap(),0,This);
return 0;
}
{
ITypeLibImpl *This = impl_from_ITypeComp(iface);
ITypeInfoImpl *pTypeInfo;
+ int typemismatch=0;
TRACE("(%s, 0x%x, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
TRACE("found in module or in enum: %s\n", debugstr_w(szName));
return S_OK;
}
+ else if (hr == TYPE_E_TYPEMISMATCH)
+ typemismatch = 1;
}
if ((pTypeInfo->TypeAttr.typekind == TKIND_COCLASS) &&
&subtypeinfo, &subdesckind, &subbindptr);
if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
{
- TYPEDESC tdesc_appobject =
- {
- {
- (TYPEDESC *)pTypeInfo->hreftype
- },
- VT_USERDEFINED
- };
+ TYPEDESC tdesc_appobject;
const VARDESC vardesc_appobject =
{
-2, /* memid */
VAR_STATIC /* varkind */
};
+ tdesc_appobject.u.hreftype = pTypeInfo->hreftype;
+ tdesc_appobject.vt = VT_USERDEFINED;
+
TRACE("found in implicit app object: %s\n", debugstr_w(szName));
/* cleanup things filled in by Bind call so we can put our
ITypeInfo_AddRef(*ppTInfo);
return S_OK;
}
+ else if (hr == TYPE_E_TYPEMISMATCH)
+ typemismatch = 1;
}
}
- TRACE("name not found %s\n", debugstr_w(szName));
- return S_OK;
+ if (typemismatch)
+ {
+ TRACE("type mismatch %s\n", debugstr_w(szName));
+ return TYPE_E_TYPEMISMATCH;
+ }
+ else
+ {
+ TRACE("name not found %s\n", debugstr_w(szName));
+ return S_OK;
+ }
}
static HRESULT WINAPI ITypeLibComp_fnBindType(
ITypeInfo ** ppTInfo,
ITypeComp ** ppTComp)
{
- FIXME("(%s, %x, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
- return E_NOTIMPL;
+ ITypeLibImpl *This = impl_from_ITypeComp(iface);
+ ITypeInfoImpl *pTypeInfo;
+
+ TRACE("(%s, %x, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
+
+ for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next)
+ {
+ /* FIXME: should use lHash to do the search */
+ if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName))
+ {
+ TRACE("returning %p\n", pTypeInfo);
+ *ppTInfo = (ITypeInfo *)&pTypeInfo->lpVtbl;
+ ITypeInfo_AddRef(*ppTInfo);
+ *ppTComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
+ ITypeComp_AddRef(*ppTComp);
+ return S_OK;
+ }
+ }
+
+ TRACE("not found\n");
+ *ppTInfo = NULL;
+ *ppTComp = NULL;
+ return S_OK;
}
static const ITypeCompVtbl tlbtcvt =
{
pTypeInfoImpl->lpVtbl = &tinfvt;
pTypeInfoImpl->lpVtblTypeComp = &tcompvt;
- pTypeInfoImpl->ref=1;
+ pTypeInfoImpl->ref = 0;
pTypeInfoImpl->hreftype = -1;
pTypeInfoImpl->TypeAttr.memidConstructor = MEMBERID_NIL;
pTypeInfoImpl->TypeAttr.memidDestructor = MEMBERID_NIL;
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
ULONG ref = InterlockedIncrement(&This->ref);
- ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
-
TRACE("(%p)->ref is %u\n",This, ref);
+
+ if (ref == 1 /* incremented from 0 */)
+ ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
+
return ref;
}
-/* ITypeInfo::Release
- */
-static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This)
{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(%u)\n",This, ref);
+ TLBFuncDesc *pFInfo, *pFInfoNext;
+ TLBVarDesc *pVInfo, *pVInfoNext;
+ TLBImplType *pImpl, *pImplNext;
- if (ref) {
- /* We don't release ITypeLib when ref=0 because
- it means that function is called by ITypeLib2_Release */
- ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
- } else {
- TLBFuncDesc *pFInfo, *pFInfoNext;
- TLBVarDesc *pVInfo, *pVInfoNext;
- TLBImplType *pImpl, *pImplNext;
+ TRACE("destroying ITypeInfo(%p)\n",This);
- TRACE("destroying ITypeInfo(%p)\n",This);
+ SysFreeString(This->Name);
+ This->Name = NULL;
- if (This->no_free_data)
- goto finish_free;
+ SysFreeString(This->DocString);
+ This->DocString = NULL;
- SysFreeString(This->Name);
- This->Name = NULL;
+ SysFreeString(This->DllName);
+ This->DllName = NULL;
- SysFreeString(This->DocString);
- This->DocString = NULL;
+ for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
+ {
+ INT i;
+ for(i = 0;i < pFInfo->funcdesc.cParams; i++)
+ {
+ ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
+ if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
+ {
+ VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
+ TLB_Free(elemdesc->u.paramdesc.pparamdescex);
+ }
+ SysFreeString(pFInfo->pParamDesc[i].Name);
+ }
+ TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
+ TLB_Free(pFInfo->pParamDesc);
+ TLB_FreeCustData(pFInfo->pCustData);
+ if (!IS_INTRESOURCE(pFInfo->Entry) && pFInfo->Entry != (BSTR)-1)
+ SysFreeString(pFInfo->Entry);
+ SysFreeString(pFInfo->HelpString);
+ SysFreeString(pFInfo->Name);
+
+ pFInfoNext = pFInfo->next;
+ TLB_Free(pFInfo);
+ }
+ for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
+ {
+ if (pVInfo->vardesc.varkind == VAR_CONST)
+ {
+ VariantClear(pVInfo->vardesc.u.lpvarValue);
+ TLB_Free(pVInfo->vardesc.u.lpvarValue);
+ }
+ TLB_FreeCustData(pVInfo->pCustData);
+ SysFreeString(pVInfo->Name);
+ pVInfoNext = pVInfo->next;
+ TLB_Free(pVInfo);
+ }
+ for (pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
+ {
+ TLB_FreeCustData(pImpl->pCustData);
+ pImplNext = pImpl->next;
+ TLB_Free(pImpl);
+ }
+ TLB_FreeCustData(This->pCustData);
- SysFreeString(This->DllName);
- This->DllName = NULL;
+ HeapFree(GetProcessHeap(), 0, This);
+}
- for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
- {
- INT i;
- for(i = 0;i < pFInfo->funcdesc.cParams; i++)
- {
- ELEMDESC *elemdesc = &pFInfo->funcdesc.lprgelemdescParam[i];
- if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
- {
- VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
- TLB_Free(elemdesc->u.paramdesc.pparamdescex);
- }
- SysFreeString(pFInfo->pParamDesc[i].Name);
- }
- TLB_Free(pFInfo->funcdesc.lprgelemdescParam);
- TLB_Free(pFInfo->pParamDesc);
- TLB_FreeCustData(pFInfo->pCustData);
- if (HIWORD(pFInfo->Entry) != 0 && pFInfo->Entry != (BSTR)-1)
- SysFreeString(pFInfo->Entry);
- SysFreeString(pFInfo->HelpString);
- SysFreeString(pFInfo->Name);
-
- pFInfoNext = pFInfo->next;
- TLB_Free(pFInfo);
- }
- for (pVInfo = This->varlist; pVInfo; pVInfo = pVInfoNext)
- {
- if (pVInfo->vardesc.varkind == VAR_CONST)
- {
- VariantClear(pVInfo->vardesc.u.lpvarValue);
- TLB_Free(pVInfo->vardesc.u.lpvarValue);
- }
- TLB_FreeCustData(pVInfo->pCustData);
- SysFreeString(pVInfo->Name);
- pVInfoNext = pVInfo->next;
- TLB_Free(pVInfo);
- }
- for(pImpl = This->impltypelist; pImpl; pImpl = pImplNext)
- {
- TLB_FreeCustData(pImpl->pCustData);
- pImplNext = pImpl->next;
- TLB_Free(pImpl);
- }
- TLB_FreeCustData(This->pCustData);
+/* ITypeInfo::Release
+ */
+static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
+{
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ ULONG ref = InterlockedDecrement(&This->ref);
-finish_free:
- if (This->next)
- {
- ITypeInfo_Release((ITypeInfo*)This->next);
- }
+ TRACE("(%p)->(%u)\n",This, ref);
- HeapFree(GetProcessHeap(),0,This);
- return 0;
+ if (!ref)
+ {
+ BOOL not_attached_to_typelib = This->not_attached_to_typelib;
+ ITypeLib2_Release((ITypeLib2*)This->pTypeLib);
+ if (not_attached_to_typelib)
+ HeapFree(GetProcessHeap(), 0, This);
+ /* otherwise This will be freed when typelib is freed */
}
+
return ref;
}
hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
if (FAILED(hr))
{
- SysFreeString((BSTR)dest_ptr);
+ SysFreeString((BSTR)dest);
return hr;
}
}
*/
if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
- if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
- This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
+ if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL)
{
*pRefType = -1;
}
return S_OK;
}
*pImplTypeFlags=0;
+
+ if(This->TypeAttr.typekind==TKIND_DISPATCH && !index)
+ return S_OK;
+
+ WARN("ImplType %d not found\n", index);
return TYPE_E_ELEMENTNOTFOUND;
}
return DISP_E_UNKNOWNNAME;
}
+
+#ifdef __i386__
+
+extern DWORD CDECL call_method( void *func, int nb_args, const DWORD *args );
+__ASM_GLOBAL_FUNC( call_method,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "pushl %esi\n\t"
+ __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
+ "pushl %edi\n\t"
+ __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
+ "movl 12(%ebp),%edx\n\t"
+ "shll $2,%edx\n\t"
+ "jz 1f\n\t"
+ "subl %edx,%esp\n\t"
+ "andl $~15,%esp\n\t"
+ "movl 12(%ebp),%ecx\n\t"
+ "movl 16(%ebp),%esi\n\t"
+ "movl %esp,%edi\n\t"
+ "cld\n\t"
+ "rep; movsl\n"
+ "1:\tcall *8(%ebp)\n\t"
+ "leal -8(%ebp),%esp\n\t"
+ "popl %edi\n\t"
+ __ASM_CFI(".cfi_same_value %edi\n\t")
+ "popl %esi\n\t"
+ __ASM_CFI(".cfi_same_value %esi\n\t")
+ "popl %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret" )
+
/* ITypeInfo::Invoke
*
* Invokes a method, or accesses a property of an object, that implements the
if (TRACE_ON(ole)) {
int i;
TRACE("Calling %p(",func);
- for (i=0;i<nrargs;i++) TRACE("%08x,",args[i]);
+ for (i=0;i<min(nrargs,30);i++) TRACE("%08x,",args[i]);
+ if (nrargs > 30) TRACE("...");
TRACE(")\n");
}
switch (callconv) {
case CC_STDCALL:
-
- switch (nrargs) {
- case 0:
- res = func();
- break;
- case 1:
- res = func(args[0]);
- break;
- case 2:
- res = func(args[0],args[1]);
- break;
- case 3:
- res = func(args[0],args[1],args[2]);
- break;
- case 4:
- res = func(args[0],args[1],args[2],args[3]);
- break;
- case 5:
- res = func(args[0],args[1],args[2],args[3],args[4]);
- break;
- case 6:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5]);
- break;
- case 7:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6]);
- break;
- case 8:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]);
- break;
- case 9:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]);
- break;
- case 10:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]);
- break;
- case 11:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]);
- break;
- case 12:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]);
- break;
- case 13:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]);
- break;
- case 14:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]);
- break;
- case 15:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14]);
- break;
- case 16:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15]);
- break;
- case 17:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16]);
- break;
- case 18:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17]);
- break;
- case 19:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18]);
- break;
- case 20:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19]);
- break;
- case 21:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20]);
- break;
- case 22:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21]);
- break;
- case 23:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22]);
- break;
- case 24:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23]);
- break;
- case 25:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24]);
- break;
- case 26:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25]);
- break;
- case 27:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26]);
- break;
- case 28:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27]);
- break;
- case 29:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28]);
- break;
- case 30:
- res = func(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14],args[15],args[16],args[17],args[18],args[19],args[20],args[21],args[22],args[23],args[24],args[25],args[26],args[27],args[28],args[29]);
- break;
- default:
- FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
- res = -1;
- break;
- }
+ case CC_CDECL:
+ res = call_method( func, nrargs, args );
break;
default:
FIXME("unsupported calling convention %d\n",callconv);
return 1;
}
}
+#endif /* __i386__ */
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
{
+#ifdef __i386__
int argsize, argspos;
UINT i;
DWORD *args;
V_VT(pvargResult) = vtReturn;
V_UI4(pvargResult) = hres;
}
-
HeapFree(GetProcessHeap(),0,args);
return S_OK;
+#else
+ FIXME( "(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d)): not implemented for this CPU\n",
+ pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg, pvargResult, V_VT(pvargResult));
+ return E_NOTIMPL;
+#endif
}
#define INVBUF_ELEMENT_SIZE \
This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
);
+ if( This->TypeAttr.wTypeFlags & TYPEFLAG_FRESTRICTED )
+ return DISP_E_MEMBERNOTFOUND;
+
if (!pDispParams)
{
ERR("NULL pDispParams not allowed\n");
* FUNCDESC for dispinterfaces and we want the real function description */
for (pFuncInfo = This->funclist; pFuncInfo; pFuncInfo=pFuncInfo->next)
if ((memid == pFuncInfo->funcdesc.memid) &&
- (wFlags & pFuncInfo->funcdesc.invkind))
+ (wFlags & pFuncInfo->funcdesc.invkind) &&
+ (pFuncInfo->funcdesc.wFuncFlags & FUNCFLAG_FRESTRICTED) == 0)
break;
if (pFuncInfo) {
hres = DISP_E_PARAMNOTFOUND;
goto func_fail;
}
- /* ignore the DISPID_PROPERTYPUT named argument from now on */
- cNamedArgs--;
- rgdispidNamedArgs++;
}
if (func_desc->cParamsOpt < 0 && cNamedArgs)
continue;
}
+ src_arg = NULL;
+
if (cNamedArgs)
{
USHORT j;
- src_arg = NULL;
for (j = 0; j < cNamedArgs; j++)
- if (rgdispidNamedArgs[j] == i)
+ if (rgdispidNamedArgs[j] == i || (i == func_desc->cParams-1 && rgdispidNamedArgs[j] == DISPID_PROPERTYPUT))
{
src_arg = &pDispParams->rgvarg[j];
break;
}
}
- else
+
+ if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
{
- src_arg = vargs_converted < pDispParams->cArgs ? &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted] : NULL;
+ src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
vargs_converted++;
}
else
{
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
- hres = VariantCopy(&missing_arg[i], src_arg);
+ if (wParamFlags & PARAMFLAG_FIN)
+ hres = VariantCopy(&missing_arg[i], src_arg);
V_VARIANTREF(&rgvarg[i]) = &missing_arg[i];
}
V_VT(&rgvarg[i]) = rgvt[i];
else if ((rgvt[i] & VT_BYREF) && !V_ISBYREF(src_arg))
{
VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
- V_VT(&missing_arg[i]) = V_VT(src_arg);
- hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+ if (wParamFlags & PARAMFLAG_FIN)
+ hres = VariantChangeType(&missing_arg[i], src_arg, 0, rgvt[i] & ~VT_BYREF);
+ else
+ V_VT(&missing_arg[i]) = rgvt[i] & ~VT_BYREF;
V_BYREF(&rgvarg[i]) = &V_NONE(&missing_arg[i]);
V_VT(&rgvarg[i]) = rgvt[i];
}
for (i = 0; i < func_desc->cParams; i++)
{
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
+ VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
if (wParamFlags & PARAMFLAG_FLCID)
continue;
hres = VariantCopyInd(pVarResult, prgpvarg[i]);
}
- /* free data stored in varresult. Note that
- * VariantClear doesn't do what we want because we are
- * working with byref types. */
- /* FIXME: clear safearrays, bstrs, records and
- * variants here too */
- if ((V_VT(prgpvarg[i]) == (VT_UNKNOWN | VT_BYREF)) ||
- (V_VT(prgpvarg[i]) == (VT_DISPATCH | VT_BYREF)))
- {
- if(*V_UNKNOWNREF(prgpvarg[i]))
- IUnknown_Release(*V_UNKNOWNREF(prgpvarg[i]));
- }
- break;
+ VARIANT_ClearInd(prgpvarg[i]);
}
else if (vargs_converted < pDispParams->cArgs)
{
+ VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
if (wParamFlags & PARAMFLAG_FOUT)
{
- VARIANTARG *arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
-
- if ((rgvt[i] == VT_BYREF) && (V_VT(arg) != VT_BYREF))
+ if ((rgvt[i] & VT_BYREF) && !(V_VT(arg) & VT_BYREF))
+ {
hres = VariantChangeType(arg, &rgvarg[i], 0, V_VT(arg));
- if (FAILED(hres))
- {
- ERR("failed to convert param %d to vt %d\n", i,
- V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
- break;
+ if (FAILED(hres))
+ {
+ ERR("failed to convert param %d to vt %d\n", i,
+ V_VT(&pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted]));
+ break;
+ }
}
}
else if (V_VT(prgpvarg[i]) == (VT_VARIANT | VT_ARRAY) &&
if (wParamFlags & PARAMFLAG_FHASDEFAULT)
VariantClear(&rgvarg[i]);
}
+
+ VariantClear(&missing_arg[i]);
}
if ((V_VT(&varresult) == VT_ERROR) && FAILED(V_ERROR(&varresult)))
WARN("Could not search inherited interface!\n");
}
}
- ERR("did not find member id %d, flags 0x%x!\n", memid, wFlags);
+ WARN("did not find member id %d, flags 0x%x!\n", memid, wFlags);
return DISP_E_MEMBERNOTFOUND;
}
if (pBstrDllName)
*pBstrDllName = SysAllocString(This->DllName);
- if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
+ if (!IS_INTRESOURCE(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
if (pBstrName)
*pBstrName = SysAllocString(pFDesc->Entry);
if (pwOrdinal)
if (pBstrName)
*pBstrName = NULL;
if (pwOrdinal)
- *pwOrdinal = (DWORD)pFDesc->Entry;
+ *pwOrdinal = LOWORD(pFDesc->Entry);
return S_OK;
}
return TYPE_E_ELEMENTNOTFOUND;
*ppTInfo = (ITypeInfo*) pTypeInfoImpl;
- /* we use data structures from This, so we need to keep a reference
- * to it to stop it being destroyed and signal to the new instance to
+ /* the AddRef implicitly adds a reference to the parent typelib, which
+ * stops the copied data from being destroyed until the new typeinfo's
+ * refcount goes to zero, but we need to signal to the new instance to
* not free its data structures when it is destroyed */
- pTypeInfoImpl->no_free_data = TRUE;
- pTypeInfoImpl->next = This;
- ITypeInfo_AddRef((ITypeInfo*) This);
+ pTypeInfoImpl->not_attached_to_typelib = TRUE;
ITypeInfo_AddRef(*ppTInfo);
result = S_OK;
} else if ((hRefType != -1) && (hRefType & DISPATCH_HREF_MASK) &&
- (This->TypeAttr.typekind == TKIND_DISPATCH) &&
- (This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
+ (This->TypeAttr.typekind == TKIND_DISPATCH))
{
HREFTYPE href_dispatch = hRefType;
result = ITypeInfoImpl_GetDispatchRefTypeInfo((ITypeInfo *)iface, &href_dispatch, ppTInfo);
BSTR *pBstrMops)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- FIXME("(%p) stub!\n", This);
+ FIXME("(%p %d) stub!\n", This, memid);
+ *pBstrMops = NULL;
return S_OK;
}
ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
const TLBFuncDesc *pFDesc;
const TLBVarDesc *pVDesc;
- HRESULT hr = DISP_E_MEMBERNOTFOUND;
+ HRESULT hr = S_OK;
- TRACE("(%s, %x, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
+ TRACE("(%p)->(%s, %x, 0x%x, %p, %p, %p)\n", This, debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
*pDescKind = DESCKIND_NONE;
pBindPtr->lpfuncdesc = NULL;
}
WARN("Could not search inherited interface!\n");
}
- WARN("did not find member with name %s, flags 0x%x!\n", debugstr_w(szName), wFlags);
+ TRACE("did not find member with name %s, flags 0x%x\n", debugstr_w(szName), wFlags);
return hr;
}