#include "winnls.h"
#include "winreg.h"
#include "winuser.h"
+#include "lzexpand.h"
#include "wine/unicode.h"
#include "objbase.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);
WINE_DECLARE_DEBUG_CHANNEL(typelib);
+typedef struct
+{
+ WORD offset;
+ WORD length;
+ WORD flags;
+ WORD id;
+ WORD handle;
+ WORD usage;
+} NE_NAMEINFO;
+
+typedef struct
+{
+ WORD type_id; /* Type identifier */
+ WORD count; /* Number of resources of this type */
+ DWORD resloader; /* SetResourceHandler() */
+ /*
+ * Name info array.
+ */
+} NE_TYPEINFO;
+
static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt);
static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
/*
* Find a typelib key which matches a requested maj.min version.
*/
-static BOOL find_typelib_key( REFGUID guid, WORD wMaj, WORD *wMin )
+static BOOL find_typelib_key( REFGUID guid, WORD *wMaj, WORD *wMin )
{
static const WCHAR typelibW[] = {'T','y','p','e','l','i','b','\\',0};
WCHAR buffer[60];
char key_name[16];
DWORD len, i;
- INT best_min = -1;
+ INT best_maj = -1, best_min = -1;
HKEY hkey;
memcpy( buffer, typelibW, sizeof(typelibW) );
{
TRACE("found %s: %x.%x\n", debugstr_w(buffer), v_maj, v_min);
- if (wMaj == v_maj)
+ if (*wMaj == 0xffff && *wMin == 0xffff)
+ {
+ if (v_maj > best_maj) best_maj = v_maj;
+ if (v_min > best_min) best_min = v_min;
+ }
+ else if (*wMaj == v_maj)
{
+ best_maj = v_maj;
+
if (*wMin == v_min)
{
best_min = v_min;
break; /* exact match */
}
- if (v_min > best_min) best_min = v_min;
+ if (*wMin != 0xffff && v_min > best_min) best_min = v_min;
}
}
len = sizeof(key_name);
}
RegCloseKey( hkey );
- if (best_min >= 0)
+
+ TRACE("found best_maj %d, best_min %d\n", best_maj, best_min);
+
+ if (*wMaj == 0xffff && *wMin == 0xffff)
+ {
+ if (best_maj >= 0 && best_min >= 0)
+ {
+ *wMaj = best_maj;
+ *wMin = best_min;
+ return TRUE;
+ }
+ }
+
+ if (*wMaj == best_maj && best_min >= 0)
{
*wMin = best_min;
return TRUE;
static const WCHAR LcidFormatW[] = {'%','l','x','\\',0};
static const WCHAR win16W[] = {'w','i','n','1','6',0};
static const WCHAR win32W[] = {'w','i','n','3','2',0};
+ static const WCHAR win64W[] = {'w','i','n','6','4',0};
sprintfW( buffer, LcidFormatW, lcid );
switch(syskind)
{
case SYS_WIN16: strcatW( buffer, win16W ); break;
case SYS_WIN32: strcatW( buffer, win32W ); break;
+ case SYS_WIN64: strcatW( buffer, win64W ); break;
default:
TRACE("Typelib is for unsupported syskind %i\n", syskind);
return NULL;
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;
TRACE_(typelib)("(%s, %x.%x, 0x%x, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path);
- if (!find_typelib_key( guid, wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED;
+ if (!find_typelib_key( guid, &wMaj, &wMin )) return TYPE_E_LIBNOTREGISTERED;
get_typelib_key( guid, wMaj, wMin, buffer );
res = RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey );
{
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
*
/* else fall-through */
case REGKIND_REGISTER:
- if (!SUCCEEDED(res = RegisterTypeLib(*pptLib, (LPOLESTR)szPath, NULL)))
+ if (FAILED(res = RegisterTypeLib(*pptLib, szPath, NULL)))
{
IUnknown_Release(*pptLib);
*pptLib = 0;
if (ptlib == NULL || szFullPath == NULL)
return E_INVALIDARG;
- if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr)))
+ if (FAILED(ITypeLib_GetLibAttr(ptlib, &attr)))
return E_FAIL;
+#ifdef _WIN64
+ if (attr->syskind != SYS_WIN64) return TYPE_E_BADMODULEKIND;
+#else
+ if (attr->syskind != SYS_WIN32 && attr->syskind != SYS_WIN16) return TYPE_E_BADMODULEKIND;
+#endif
+
get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
res = S_OK;
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 );
/* Create the path to the key */
get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
- if (syskind != SYS_WIN16 && syskind != SYS_WIN32)
+ if (syskind != SYS_WIN16 && syskind != SYS_WIN32 && syskind != SYS_WIN64)
{
TRACE("Unsupported syskind %i\n", syskind);
result = E_INVALIDARG;
}
/* 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);
}
end:
- if (tlibPath) SysFreeString(tlibPath);
+ SysFreeString(tlibPath);
if (typeLib) ITypeLib_Release(typeLib);
if (subKey) RegCloseKey(subKey);
if (key) RegCloseKey(key);
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
const ITypeCompVtbl *lpVtblTypeComp;
LONG ref;
TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
+ LCID lcid;
/* strings can be stored in tlb as multibyte strings BUT they are *always*
* exported to the application as a UNICODE string.
BSTR DocString;
BSTR HelpFile;
BSTR HelpStringDll;
- unsigned long dwHelpContext;
+ DWORD dwHelpContext;
int TypeInfoCount; /* nr of typeinfo's in librarry */
struct tagITypeInfoImpl *pTypeInfo; /* linked list of type info data */
int ctCustData; /* number of items in cust data list */
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; */
BSTR Name;
BSTR DocString;
BSTR DllName;
- unsigned long dwHelpContext;
- unsigned long dwHelpStringContext;
+ DWORD dwHelpContext;
+ DWORD dwHelpStringContext;
/* functions */
TLBFuncDesc * funclist; /* linked list with function descriptions */
static const ITypeInfo2Vtbl tinfvt;
static const ITypeCompVtbl tcompvt;
-static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void);
+static ITypeInfo2 * ITypeInfo_Constructor(void);
+static void ITypeInfo_fnDestroy(ITypeInfoImpl *This);
typedef struct tagTLBContext
{
static void dump_DispParms(const DISPPARAMS * pdp)
{
- int index;
+ unsigned int index;
TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
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
{
(*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
(*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
(*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
- (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
+ (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset;
(*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
MSFT_GetTdesc(pcx,
debugstr_w(ptiRet->Name),
debugstr_guid(&ptiRet->TypeAttr.guid),
typekind_desc[ptiRet->TypeAttr.typekind]);
+ if (TRACE_ON(typelib))
+ dump_TypeInfo(ptiRet);
return ptiRet;
}
return TYPE_E_CANTLOADLIBRARY;
}
+typedef struct TLB_NEFile
+{
+ const IUnknownVtbl *lpvtbl;
+ LONG refs;
+ LPVOID typelib_base;
+} TLB_NEFile;
+
+static HRESULT WINAPI TLB_NEFile_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
+{
+ if (IsEqualIID(riid, &IID_IUnknown))
+ {
+ *ppv = iface;
+ IUnknown_AddRef(iface);
+ return S_OK;
+ }
+ *ppv = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI TLB_NEFile_AddRef(IUnknown *iface)
+{
+ TLB_NEFile *This = (TLB_NEFile *)iface;
+ return InterlockedIncrement(&This->refs);
+}
+
+static ULONG WINAPI TLB_NEFile_Release(IUnknown *iface)
+{
+ TLB_NEFile *This = (TLB_NEFile *)iface;
+ ULONG refs = InterlockedDecrement(&This->refs);
+ if (!refs)
+ {
+ HeapFree(GetProcessHeap(), 0, This->typelib_base);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+ return refs;
+}
+
+static const IUnknownVtbl TLB_NEFile_Vtable =
+{
+ TLB_NEFile_QueryInterface,
+ TLB_NEFile_AddRef,
+ TLB_NEFile_Release
+};
+
+/***********************************************************************
+ * read_xx_header [internal]
+ */
+static int read_xx_header( HFILE lzfd )
+{
+ IMAGE_DOS_HEADER mzh;
+ char magic[3];
+
+ LZSeek( lzfd, 0, SEEK_SET );
+ if ( sizeof(mzh) != LZRead( lzfd, (LPSTR)&mzh, sizeof(mzh) ) )
+ return 0;
+ if ( mzh.e_magic != IMAGE_DOS_SIGNATURE )
+ return 0;
+
+ LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
+ if ( 2 != LZRead( lzfd, magic, 2 ) )
+ return 0;
+
+ LZSeek( lzfd, mzh.e_lfanew, SEEK_SET );
+
+ if ( magic[0] == 'N' && magic[1] == 'E' )
+ return IMAGE_OS2_SIGNATURE;
+ if ( magic[0] == 'P' && magic[1] == 'E' )
+ return IMAGE_NT_SIGNATURE;
+
+ magic[2] = '\0';
+ WARN("Can't handle %s files.\n", magic );
+ return 0;
+}
+
+
+/***********************************************************************
+ * find_ne_resource [internal]
+ */
+static BOOL find_ne_resource( HFILE lzfd, LPCSTR typeid, LPCSTR resid,
+ DWORD *resLen, DWORD *resOff )
+{
+ IMAGE_OS2_HEADER nehd;
+ NE_TYPEINFO *typeInfo;
+ NE_NAMEINFO *nameInfo;
+ DWORD nehdoffset;
+ LPBYTE resTab;
+ DWORD resTabSize;
+ int count;
+
+ /* Read in NE header */
+ nehdoffset = LZSeek( lzfd, 0, SEEK_CUR );
+ if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return 0;
+
+ resTabSize = nehd.ne_restab - nehd.ne_rsrctab;
+ if ( !resTabSize )
+ {
+ TRACE("No resources in NE dll\n" );
+ return FALSE;
+ }
+
+ /* Read in resource table */
+ resTab = HeapAlloc( GetProcessHeap(), 0, resTabSize );
+ if ( !resTab ) return FALSE;
+
+ LZSeek( lzfd, nehd.ne_rsrctab + nehdoffset, SEEK_SET );
+ if ( resTabSize != LZRead( lzfd, (char*)resTab, resTabSize ) )
+ {
+ HeapFree( GetProcessHeap(), 0, resTab );
+ return FALSE;
+ }
+
+ /* Find resource */
+ typeInfo = (NE_TYPEINFO *)(resTab + 2);
+
+ if (!IS_INTRESOURCE(typeid)) /* named type */
+ {
+ BYTE len = strlen( typeid );
+ while (typeInfo->type_id)
+ {
+ if (!(typeInfo->type_id & 0x8000))
+ {
+ BYTE *p = resTab + typeInfo->type_id;
+ if ((*p == len) && !strncasecmp( (char*)p+1, typeid, len )) goto found_type;
+ }
+ typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
+ typeInfo->count * sizeof(NE_NAMEINFO));
+ }
+ }
+ else /* numeric type id */
+ {
+ WORD id = LOWORD(typeid) | 0x8000;
+ while (typeInfo->type_id)
+ {
+ if (typeInfo->type_id == id) goto found_type;
+ typeInfo = (NE_TYPEINFO *)((char *)(typeInfo + 1) +
+ typeInfo->count * sizeof(NE_NAMEINFO));
+ }
+ }
+ TRACE("No typeid entry found for %p\n", typeid );
+ HeapFree( GetProcessHeap(), 0, resTab );
+ return FALSE;
+
+ found_type:
+ nameInfo = (NE_NAMEINFO *)(typeInfo + 1);
+
+ if (!IS_INTRESOURCE(resid)) /* named resource */
+ {
+ BYTE len = strlen( resid );
+ for (count = typeInfo->count; count > 0; count--, nameInfo++)
+ {
+ BYTE *p = resTab + nameInfo->id;
+ if (nameInfo->id & 0x8000) continue;
+ if ((*p == len) && !strncasecmp( (char*)p+1, resid, len )) goto found_name;
+ }
+ }
+ else /* numeric resource id */
+ {
+ WORD id = LOWORD(resid) | 0x8000;
+ for (count = typeInfo->count; count > 0; count--, nameInfo++)
+ if (nameInfo->id == id) goto found_name;
+ }
+ TRACE("No resid entry found for %p\n", typeid );
+ HeapFree( GetProcessHeap(), 0, resTab );
+ return FALSE;
+
+ found_name:
+ /* Return resource data */
+ if ( resLen ) *resLen = nameInfo->length << *(WORD *)resTab;
+ if ( resOff ) *resOff = nameInfo->offset << *(WORD *)resTab;
+
+ HeapFree( GetProcessHeap(), 0, resTab );
+ return TRUE;
+}
+
+static HRESULT TLB_NEFile_Open(LPCWSTR path, INT index, LPVOID *ppBase, DWORD *pdwTLBLength, IUnknown **ppFile){
+
+ HFILE lzfd = -1;
+ OFSTRUCT ofs;
+ HRESULT hr = TYPE_E_CANTLOADLIBRARY;
+ TLB_NEFile *This = NULL;
+
+ This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+ if (!This) return E_OUTOFMEMORY;
+
+ This->lpvtbl = &TLB_NEFile_Vtable;
+ This->refs = 1;
+ This->typelib_base = NULL;
+
+ lzfd = LZOpenFileW( (LPWSTR)path, &ofs, OF_READ );
+ if ( lzfd >= 0 && read_xx_header( lzfd ) == IMAGE_OS2_SIGNATURE )
+ {
+ DWORD reslen, offset;
+ if( find_ne_resource( lzfd, "TYPELIB", MAKEINTRESOURCEA(index), &reslen, &offset ) )
+ {
+ This->typelib_base = HeapAlloc(GetProcessHeap(), 0, reslen);
+ if( !This->typelib_base )
+ hr = E_OUTOFMEMORY;
+ else
+ {
+ LZSeek( lzfd, offset, SEEK_SET );
+ reslen = LZRead( lzfd, This->typelib_base, reslen );
+ LZClose( lzfd );
+ *ppBase = This->typelib_base;
+ *pdwTLBLength = reslen;
+ *ppFile = (IUnknown *)&This->lpvtbl;
+ return S_OK;
+ }
+ }
+ }
+
+ if( lzfd >= 0) LZClose( lzfd );
+ TLB_NEFile_Release((IUnknown *)&This->lpvtbl);
+ return hr;
+}
typedef struct TLB_Mapping
{
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;
/* now actually load and parse the typelib */
ret = TLB_PEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
+ if (ret == TYPE_E_CANTLOADLIBRARY)
+ ret = TLB_NEFile_Open(pszPath, index, &pBase, &dwTLBLength, &pFile);
if (ret == TYPE_E_CANTLOADLIBRARY)
ret = TLB_Mapping_Open(pszPath, &pBase, &dwTLBLength, &pFile);
if (SUCCEEDED(ret))
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;
}
/* TLIBATTR fields */
MSFT_ReadGuid(&pTypeLibImpl->LibAttr.guid, tlbHeader.posguid, &cx);
- /* pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid;*/
- /* Windows seems to have zero here, is this correct? */
- if(SUBLANGID(tlbHeader.lcid) == SUBLANG_NEUTRAL)
- pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(tlbHeader.lcid),0),0);
- else
- pTypeLibImpl->LibAttr.lcid = 0;
-
+ pTypeLibImpl->LibAttr.lcid = tlbHeader.lcid2;
pTypeLibImpl->LibAttr.syskind = tlbHeader.varflags & 0x0f; /* check the mask */
pTypeLibImpl->LibAttr.wMajorVerNum = LOWORD(tlbHeader.version);
pTypeLibImpl->LibAttr.wMinorVerNum = HIWORD(tlbHeader.version);
pTypeLibImpl->LibAttr.wLibFlags = (WORD) tlbHeader.flags & 0xffff;/* check mask */
+ pTypeLibImpl->lcid = tlbHeader.lcid;
+
/* name, eventually add to a hash table */
pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
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;
bytelen = *(const WORD*)ptr;
if(bytelen == 0xffff) return 2;
len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0);
- *pBstr = SysAllocStringLen(NULL, len - 1);
+ *pBstr = SysAllocStringLen(NULL, len);
if (*pBstr)
len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, *pBstr, len);
return bytelen + 2;
ptr += 2;
if(SUBLANGID(*(WORD*)ptr) == SUBLANG_NEUTRAL)
- pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
+ pTypeLibImpl->lcid = pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
else
- pTypeLibImpl->LibAttr.lcid = 0;
+ pTypeLibImpl->lcid = pTypeLibImpl->LibAttr.lcid = 0;
ptr += 2;
ptr += 4; /* skip res12 */
static HRESULT sltg_get_typelib_ref(const sltg_ref_lookup_t *table, DWORD typeinfo_ref,
HREFTYPE *typelib_ref)
{
- if(typeinfo_ref < table->num)
+ if(table && typeinfo_ref < table->num)
{
*typelib_ref = table->refs[typeinfo_ref];
return S_OK;
static sltg_ref_lookup_t *SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeLibImpl *pTL,
char *pNameTable)
{
- int ref;
+ unsigned int ref;
char *name;
TLBRefType *ref_type;
sltg_ref_lookup_t *table;
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 */
pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount);
- pFirstBlk = (LPVOID)(pPad9 + 1);
+ pFirstBlk = pPad9 + 1;
/* We'll set up a ptr to the main library block, which is the last one. */
(*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)
}
- if(pTITail) { /* could get cFuncs, cVars and cImplTypes from here
+ /* could get cFuncs, cVars and cImplTypes from here
but we've already set those */
#define X(x) TRACE_(typelib)("tt "#x": %x\n",pTITail->res##x);
- X(06);
- X(16);
- X(18);
- X(1a);
- X(1e);
- X(24);
- X(26);
- X(2a);
- X(2c);
- X(2e);
- X(30);
- X(32);
- X(34);
- }
+ X(06);
+ X(16);
+ X(18);
+ X(1a);
+ X(1e);
+ X(24);
+ X(26);
+ X(2a);
+ X(2c);
+ X(2e);
+ X(30);
+ X(32);
+ X(34);
+#undef X
ppTypeInfoImpl = &((*ppTypeInfoImpl)->next);
pBlk = (char*)pBlk + pBlkEntry[order].len;
}
TLBRefType *ref_type;
void *cursor2;
int i;
+ ITypeInfoImpl *pTI, *pTINext;
/* remove cache entry */
if(This->path)
}
TRACE(" destroying ITypeLib(%p)\n",This);
- if (This->Name)
- {
- SysFreeString(This->Name);
- This->Name = NULL;
- }
+ SysFreeString(This->Name);
+ This->Name = NULL;
- if (This->DocString)
- {
- SysFreeString(This->DocString);
- This->DocString = NULL;
- }
+ SysFreeString(This->DocString);
+ This->DocString = NULL;
- if (This->HelpFile)
- {
- SysFreeString(This->HelpFile);
- This->HelpFile = NULL;
- }
+ SysFreeString(This->HelpFile);
+ This->HelpFile = NULL;
- if (This->HelpStringDll)
- {
- SysFreeString(This->HelpStringDll);
- This->HelpStringDll = NULL;
- }
+ SysFreeString(This->HelpStringDll);
+ This->HelpStringDll = NULL;
for (pCustData = This->pCustData; pCustData; pCustData = pCustDataNext)
{
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;
}
UINT index,
ITypeInfo **ppTInfo)
{
- int i;
+ UINT i;
ITypeLibImpl *This = (ITypeLibImpl *)iface;
ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
TYPEKIND *pTKind)
{
ITypeLibImpl *This = (ITypeLibImpl *)iface;
- int i;
+ UINT i;
ITypeInfoImpl *pTInfo = This->pTypeInfo;
-
+
if (ITypeLib2_fnGetTypeInfoCount(iface) < index + 1)
return TYPE_E_ELEMENTNOTFOUND;
{
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 =
};
/*================== ITypeInfo(2) Methods ===================================*/
-static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
+static ITypeInfo2 * ITypeInfo_Constructor(void)
{
ITypeInfoImpl * pTypeInfoImpl;
{
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;
- if (This->Name)
- {
- SysFreeString(This->Name);
- This->Name = 0;
- }
+ SysFreeString(This->DllName);
+ This->DllName = NULL;
- if (This->DocString)
- {
- SysFreeString(This->DocString);
- This->DocString = 0;
- }
+ 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);
- if (This->DllName)
- {
- SysFreeString(This->DllName);
- This->DllName = 0;
- }
+ HeapFree(GetProcessHeap(), 0, This);
+}
- for (pFInfo = This->funclist; pFInfo; pFInfo = pFInfoNext)
- {
- UINT 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;
}
if (This->TypeAttr.typekind == TKIND_ALIAS)
TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias,
- &This->TypeAttr.tdescAlias, (void *)(*ppTypeAttr + 1));
+ &This->TypeAttr.tdescAlias, *ppTypeAttr + 1);
if((*ppTypeAttr)->typekind == TKIND_DISPATCH) {
- (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / 4; /* This should include all the inherited
- funcs */
- (*ppTypeAttr)->cbSizeVft = 28; /* This is always the size of IDispatch's vtbl */
+ /* This should include all the inherited funcs */
+ (*ppTypeAttr)->cFuncs = (*ppTypeAttr)->cbSizeVft / sizeof(void *);
+ (*ppTypeAttr)->cbSizeVft = 7 * sizeof(void *); /* This is always the size of IDispatch's vtbl */
(*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION;
}
return S_OK;
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
const TLBFuncDesc *pFDesc;
- int i;
+ UINT i;
for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
;
hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
if (FAILED(hr))
{
- SysFreeString((BSTR)dest_ptr);
+ SysFreeString((BSTR)dest);
return hr;
}
}
LPVARDESC *ppVarDesc)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
+ UINT i;
const TLBVarDesc *pVDesc;
TRACE("(%p) index %d\n", This, index);
HREFTYPE *pRefType)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
+ UINT i;
HRESULT hr = S_OK;
const TLBImplType *pImpl = This->impltypelist;
*/
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;
}
UINT index, INT *pImplTypeFlags)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
+ UINT i;
TLBImplType *pImpl;
TRACE("(%p) index %d\n", This, index);
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;
}
const TLBFuncDesc *pFDesc;
const TLBVarDesc *pVDesc;
HRESULT ret=S_OK;
- int i;
+ UINT i;
TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
cNames);
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);
/* The size of the argument on the stack in DWORD units (in all x86 call
* convetions the arguments on the stack are DWORD-aligned)
*/
-int _dispargsize(VARTYPE vt)
+static int _dispargsize(VARTYPE vt)
{
switch (vt) {
case VT_I8:
return 1;
}
}
+#endif /* __i386__ */
static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
{
*vt |= VT_ARRAY;
hr = typedescvt_to_variantvt(tinfo, tdesc->u.lptdesc, vt);
break;
+ case VT_INT:
+ *vt |= VT_I4;
+ break;
+ case VT_UINT:
+ *vt |= VT_UI4;
+ break;
default:
*vt |= tdesc->vt;
break;
void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
{
- int i, argsize, argspos;
+#ifdef __i386__
+ int argsize, argspos;
+ UINT i;
DWORD *args;
HRESULT hres;
for (i=0;i<cActuals;i++)
{
- TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_dispargsize(prgvt[i]));
+ TRACE("arg %u: type %d, size %d\n",i,prgvt[i],_dispargsize(prgvt[i]));
dump_Variant(prgpvarg[i]);
argsize += _dispargsize(prgvt[i]);
}
for (i=0;i<cActuals;i++)
{
VARIANT *arg = prgpvarg[i];
- TRACE("Storing arg %d (%d as %d)\n",i,V_VT(arg),prgvt[i]);
+ TRACE("Storing arg %u (%d as %d)\n",i,V_VT(arg),prgvt[i]);
if (prgvt[i] == VT_VARIANT)
memcpy(&args[argspos], arg, _dispargsize(prgvt[i]) * sizeof(DWORD));
else
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 \
(sizeof(VARIANTARG) + sizeof(VARIANTARG) + sizeof(VARIANTARG *) + sizeof(VARTYPE))
-#define INVBUF_GET_ARG_ARRAY(buffer, params) \
- ((VARIANTARG *)(buffer))
+#define INVBUF_GET_ARG_ARRAY(buffer, params) (buffer)
#define INVBUF_GET_MISSING_ARG_ARRAY(buffer, params) \
((VARIANTARG *)((char *)(buffer) + sizeof(VARIANTARG) * (params)))
#define INVBUF_GET_ARG_PTR_ARRAY(buffer, params) \
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) {
VARTYPE *rgvt = INVBUF_GET_ARG_TYPE_ARRAY(buffer, func_desc->cParams);
UINT cNamedArgs = pDispParams->cNamedArgs;
DISPID *rgdispidNamedArgs = pDispParams->rgdispidNamedArgs;
+ UINT vargs_converted=0;
hres = S_OK;
hres = DISP_E_PARAMNOTFOUND;
goto func_fail;
}
- /* ignore the DISPID_PROPERTYPUT named argument from now on */
- cNamedArgs--;
- rgdispidNamedArgs++;
}
if (func_desc->cParamsOpt < 0 && cNamedArgs)
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
VARIANTARG *src_arg;
+ if (wParamFlags & PARAMFLAG_FLCID)
+ {
+ VARIANTARG *arg;
+ arg = prgpvarg[i] = &rgvarg[i];
+ V_VT(arg) = VT_I4;
+ V_I4(arg) = This->pTypeLib->lcid;
+ 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
- src_arg = i < pDispParams->cArgs ? &pDispParams->rgvarg[pDispParams->cArgs - 1 - i] : NULL;
+
+ if (!src_arg && vargs_converted + cNamedArgs < pDispParams->cArgs)
+ {
+ src_arg = &pDispParams->rgvarg[pDispParams->cArgs - 1 - vargs_converted];
+ vargs_converted++;
+ }
if (wParamFlags & PARAMFLAG_FRETVAL)
{
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];
}
V_VT(&varresult), func_desc->cParams, rgvt,
prgpvarg, &varresult);
+ vargs_converted = 0;
+
for (i = 0; i < func_desc->cParams; i++)
{
USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
- if (wParamFlags & PARAMFLAG_FRETVAL)
+ VARIANTARG *missing_arg = INVBUF_GET_MISSING_ARG_ARRAY(buffer, func_desc->cParams);
+
+ if (wParamFlags & PARAMFLAG_FLCID)
+ continue;
+ else if (wParamFlags & PARAMFLAG_FRETVAL)
{
if (TRACE_ON(ole))
{
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 (i < pDispParams->cArgs)
+ 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 - i];
-
- 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 - i]));
- 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) &&
}
}
VariantClear(&rgvarg[i]);
+ vargs_converted++;
}
else if (wParamFlags & PARAMFLAG_FOPT)
{
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);
ref_type->pImpTLInfo->lcid,
&pTLib);
- if(!SUCCEEDED(result)) {
+ if(FAILED(result)) {
BSTR libnam=SysAllocString(ref_type->pImpTLInfo->name);
result=LoadTypeLib(libnam, &pTLib);
SysFreeString(libnam);
{
ERR("couldn't load %s\n", debugstr_w(dll));
SysFreeString(dll);
- if (entry) SysFreeString(entry);
+ SysFreeString(entry);
return STG_E_FILENOTFOUND;
}
/* FIXME: store library somewhere where we can free it */
}
SysFreeString(dll);
- if (entry) SysFreeString(entry);
+ SysFreeString(entry);
if (!*ppv)
return TYPE_E_DLLFUNCTIONNOTFOUND;
BSTR *pBstrMops)
{
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- FIXME("(%p) stub!\n", This);
+ FIXME("(%p %d) stub!\n", This, memid);
+ *pBstrMops = NULL;
return S_OK;
}
TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
- if(pCData)
- {
- VariantInit( pVarVal);
+ VariantInit( pVarVal);
+ if (pCData)
VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
+ else
+ VariantClear( pVarVal );
+ return S_OK;
}
/* ITypeInfo2::GetFuncCustData
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
- int i;
+ UINT i;
for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
pFDesc=pFDesc->next);
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
- int i;
+ UINT i;
for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBVarDesc * pVDesc;
- int i;
+ UINT i;
for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBImplType * pRDesc;
- int i;
+ UINT i;
for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBFuncDesc * pFDesc;
- int i;
+ UINT i;
TRACE("(%p) index %d\n", This, index);
for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
pFDesc=pFDesc->next)
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
- int i;
+ UINT i;
TRACE("(%p) index %d\n", This, indexFunc);
for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
pFDesc=pFDesc->next)
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBVarDesc * pVDesc;
- int i;
+ UINT i;
TRACE("(%p) index %d\n", This, index);
for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
pVDesc=pVDesc->next)
ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBImplType * pRDesc;
- int i;
+ UINT i;
TRACE("(%p) index %d\n", This, index);
for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
pRDesc=pRDesc->next)
{
ITypeInfoImpl *pTIClass, *pTIIface;
ITypeLibImpl *pTypeLibImpl;
- int param, func;
+ unsigned int param, func;
TLBFuncDesc **ppFuncDesc;
TLBRefType *ref;
(*ppFuncDesc)->funcdesc.callconv = md->cc;
(*ppFuncDesc)->funcdesc.cParams = md->cArgs;
(*ppFuncDesc)->funcdesc.cParamsOpt = 0;
- (*ppFuncDesc)->funcdesc.oVft = md->iMeth << 2;
+ (*ppFuncDesc)->funcdesc.oVft = md->iMeth * sizeof(void *);
(*ppFuncDesc)->funcdesc.cScodes = 0;
(*ppFuncDesc)->funcdesc.wFuncFlags = 0;
(*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
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;
}