+++ /dev/null
-/*
- * TYPELIB
- *
- * Copyright 1997 Marcus Meissner
- * 1999 Rein Klazes
- * 2000 Francois Jacques
- * 2001 Huw D M Davies for CodeWeavers
- * 2005 Robert Shearman, for CodeWeavers
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * --------------------------------------------------------------------------------------
- * Known problems (2000, Francois Jacques)
- *
- * - Tested using OLEVIEW (Platform SDK tool) only.
- *
- * - dual interface dispinterfaces. vtable-interface ITypeInfo instances are
- * creating by doing a straight copy of the dispinterface instance and just changing
- * its typekind. Pointed structures aren't copied - only the address of the pointers.
- * So when you release the dispinterface, you delete the vtable-interface structures
- * as well... fortunately, clean up of structures is not implemented.
- *
- * - locale stuff is partially implemented but hasn't been tested.
- *
- * - typelib file is still read in its entirety, but it is released now.
- * - some garbage is read from function names on some very rare occasions.
- *
- * --------------------------------------------------------------------------------------
- * Known problems left from previous implementation (1999, Rein Klazes) :
- *
- * -. Data structures are straightforward, but slow for look-ups.
- * -. (related) nothing is hashed
- * -. there are a number of stubs in ITypeLib and ITypeInfo interfaces. Most
- * of them I don't know yet how to implement them.
- * -. Most error return values are just guessed not checked with windows
- * behaviour.
- * -. didn't bother with a c++ interface
- * -. lousy fatal error handling
- * -. some methods just return pointers to internal data structures, this is
- * partly laziness, partly I want to check how windows does it.
- *
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <ctype.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winnls.h"
-#include "winreg.h"
-#include "winuser.h"
-
-#include "wine/unicode.h"
-#include "objbase.h"
-#include "typelib.h"
-#include "wine/debug.h"
-#include "variant.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(ole);
-WINE_DECLARE_DEBUG_CHANNEL(typelib);
-
-/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
-const GUID CLSID_PSOAInterface = { 0x00020424, 0, 0, { 0xC0, 0, 0, 0, 0, 0, 0, 0x46 } };
-
-static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt);
-static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
-
-/****************************************************************************
- * FromLExxx
- *
- * Takes p_iVal (which is in little endian) and returns it
- * in the host machine's byte order.
- */
-#ifdef WORDS_BIGENDIAN
-static WORD FromLEWord(WORD p_iVal)
-{
- return (((p_iVal & 0x00FF) << 8) |
- ((p_iVal & 0xFF00) >> 8));
-}
-
-
-static DWORD FromLEDWord(DWORD p_iVal)
-{
- return (((p_iVal & 0x000000FF) << 24) |
- ((p_iVal & 0x0000FF00) << 8) |
- ((p_iVal & 0x00FF0000) >> 8) |
- ((p_iVal & 0xFF000000) >> 24));
-}
-#else
-#define FromLEWord(X) (X)
-#define FromLEDWord(X) (X)
-#endif
-
-
-/****************************************************************************
- * FromLExxx
- *
- * Fix byte order in any structure if necessary
- */
-#ifdef WORDS_BIGENDIAN
-static void FromLEWords(void *p_Val, int p_iSize)
-{
- WORD *Val = p_Val;
-
- p_iSize /= sizeof(WORD);
-
- while (p_iSize) {
- *Val = FromLEWord(*Val);
- Val++;
- p_iSize--;
- }
-}
-
-
-static void FromLEDWords(void *p_Val, int p_iSize)
-{
- DWORD *Val = p_Val;
-
- p_iSize /= sizeof(DWORD);
-
- while (p_iSize) {
- *Val = FromLEDWord(*Val);
- Val++;
- p_iSize--;
- }
-}
-#else
-#define FromLEWords(X,Y) /*nothing*/
-#define FromLEDWords(X,Y) /*nothing*/
-#endif
-
-/* get the path of a typelib key, in the form "Typelib\\<guid>\\<maj>.<min>" */
-/* buffer must be at least 60 characters long */
-static WCHAR *get_typelib_key( REFGUID guid, WORD wMaj, WORD wMin, WCHAR *buffer )
-{
- static const WCHAR TypelibW[] = {'T','y','p','e','l','i','b','\\',0};
- static const WCHAR VersionFormatW[] = {'\\','%','u','.','%','u',0};
-
- memcpy( buffer, TypelibW, sizeof(TypelibW) );
- StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
- sprintfW( buffer + strlenW(buffer), VersionFormatW, wMaj, wMin );
- return buffer;
-}
-
-/* get the path of an interface key, in the form "Interface\\<guid>" */
-/* buffer must be at least 50 characters long */
-static WCHAR *get_interface_key( REFGUID guid, WCHAR *buffer )
-{
- static const WCHAR InterfaceW[] = {'I','n','t','e','r','f','a','c','e','\\',0};
-
- memcpy( buffer, InterfaceW, sizeof(InterfaceW) );
- StringFromGUID2( guid, buffer + strlenW(buffer), 40 );
- return buffer;
-}
-
-/* get the lcid subkey for a typelib, in the form "<lcid>\\<syskind>" */
-/* buffer must be at least 16 characters long */
-static WCHAR *get_lcid_subkey( LCID lcid, SYSKIND syskind, WCHAR *buffer )
-{
- 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};
-
- sprintfW( buffer, LcidFormatW, lcid );
- switch(syskind)
- {
- case SYS_WIN16: strcatW( buffer, win16W ); break;
- case SYS_WIN32: strcatW( buffer, win32W ); break;
- default:
- TRACE("Typelib is for unsupported syskind %i\n", syskind);
- return NULL;
- }
- return buffer;
-}
-
-int TLB_ReadTypeLib(LPCWSTR file, INT index, 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 )
-{
- HRESULT hr = TYPE_E_LIBNOTREGISTERED;
- LCID myLCID = lcid;
- HKEY hkey;
- WCHAR buffer[60];
- WCHAR Path[MAX_PATH];
- LONG res;
-
- TRACE_(typelib)("(%s, %x.%x, 0x%lx, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path);
-
- get_typelib_key( guid, wMaj, wMin, buffer );
-
- res = RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey );
- if (res == ERROR_FILE_NOT_FOUND)
- {
- TRACE_(typelib)("%s not found\n", debugstr_w(buffer));
- return TYPE_E_LIBNOTREGISTERED;
- }
- else if (res != ERROR_SUCCESS)
- {
- TRACE_(typelib)("failed to open %s for read access\n", debugstr_w(buffer));
- return TYPE_E_REGISTRYACCESS;
- }
-
- while (hr != S_OK)
- {
- LONG dwPathLen = sizeof(Path);
-
- get_lcid_subkey( myLCID, SYS_WIN32, buffer );
-
- if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
- {
- if (!lcid)
- break;
- else if (myLCID == lcid)
- {
- /* try with sub-langid */
- myLCID = SUBLANGID(lcid);
- }
- else if ((myLCID == SUBLANGID(lcid)) && myLCID)
- {
- /* try with system langid */
- myLCID = 0;
- }
- else
- {
- break;
- }
- }
- else
- {
- *path = SysAllocString( Path );
- hr = S_OK;
- }
- }
- RegCloseKey( hkey );
- TRACE_(typelib)("-- 0x%08lx\n", hr);
- return hr;
-}
-
-/******************************************************************************
- * CreateTypeLib [OLEAUT32.160] creates a typelib
- *
- * RETURNS
- * Success: S_OK
- * Failure: Status
- */
-HRESULT WINAPI CreateTypeLib(
- SYSKIND syskind, LPCOLESTR szFile, ICreateTypeLib** ppctlib
-) {
- FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
- return E_FAIL;
-}
-
-/******************************************************************************
- * LoadTypeLib [OLEAUT32.161]
- *
- * Loads a type library
- *
- * PARAMS
- * szFile [I] Name of file to load from.
- * pptLib [O] Pointer that receives ITypeLib object on success.
- *
- * RETURNS
- * Success: S_OK
- * Failure: Status
- *
- * SEE
- * LoadTypeLibEx, LoadRegTypeLib, CreateTypeLib.
- */
-HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib * *pptLib)
-{
- TRACE("(%s,%p)\n",debugstr_w(szFile), pptLib);
- return LoadTypeLibEx(szFile, REGKIND_DEFAULT, pptLib);
-}
-
-/******************************************************************************
- * LoadTypeLibEx [OLEAUT32.183]
- *
- * Loads and optionally registers a type library
- *
- * RETURNS
- * Success: S_OK
- * Failure: Status
- */
-HRESULT WINAPI LoadTypeLibEx(
- LPCOLESTR szFile, /* [in] Name of file to load from */
- REGKIND regkind, /* [in] Specify kind of registration */
- ITypeLib **pptLib) /* [out] Pointer to pointer to loaded type library */
-{
- WCHAR szPath[MAX_PATH+1], szFileCopy[MAX_PATH+1];
- WCHAR *pIndexStr;
- HRESULT res;
- INT index = 1;
-
- TRACE("(%s,%d,%p)\n",debugstr_w(szFile), regkind, pptLib);
-
- /* by default try and load using LoadLibrary (for builtin stdole32.tlb) */
- memcpy(szPath, szFile, (strlenW(szFile)+1)*sizeof(WCHAR));
-
- *pptLib = NULL;
- if(!SearchPathW(NULL,szFile,NULL,sizeof(szPath)/sizeof(WCHAR),szPath,
- NULL)) {
-
- /* Look for a trailing '\\' followed by an index */
- pIndexStr = strrchrW(szFile, '\\');
- if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
- index = atoiW(pIndexStr);
- memcpy(szFileCopy, szFile,
- (pIndexStr - szFile - 1) * sizeof(WCHAR));
- szFileCopy[pIndexStr - szFile - 1] = '\0';
- if(!SearchPathW(NULL,szFileCopy,NULL,sizeof(szPath)/sizeof(WCHAR),
- szPath,NULL))
- return TYPE_E_CANTLOADLIBRARY;
- if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY)
- return TYPE_E_CANTLOADLIBRARY;
- }
- }
-
- TRACE("File %s index %d\n", debugstr_w(szPath), index);
-
- res = TLB_ReadTypeLib(szPath, index, (ITypeLib2**)pptLib);
-
- if (SUCCEEDED(res))
- switch(regkind)
- {
- case REGKIND_DEFAULT:
- /* don't register typelibs supplied with full path. Experimentation confirms the following */
- if ((!szFile) ||
- ((szFile[0] == '\\') && (szFile[1] == '\\')) ||
- (szFile[0] && (szFile[1] == ':'))) break;
- /* else fall-through */
-
- case REGKIND_REGISTER:
- if (!SUCCEEDED(res = RegisterTypeLib(*pptLib, (LPOLESTR)szPath, NULL)))
- {
- IUnknown_Release(*pptLib);
- *pptLib = 0;
- }
- break;
- case REGKIND_NONE:
- break;
- }
-
- TRACE(" returns %08lx\n",res);
- return res;
-}
-
-/******************************************************************************
- * LoadRegTypeLib [OLEAUT32.162]
- *
- * Loads a registered type library.
- *
- * PARAMS
- * rguid [I] GUID of the registered type library.
- * wVerMajor [I] major version.
- * wVerMinor [I] minor version.
- * lcid [I] locale ID.
- * ppTLib [O] pointer that receives an ITypeLib object on success.
- *
- * RETURNS
- * Success: S_OK.
- * Failure: Any HRESULT code returned from QueryPathOfRegTypeLib or
- * LoadTypeLib.
- */
-HRESULT WINAPI LoadRegTypeLib(
- REFGUID rguid,
- WORD wVerMajor,
- WORD wVerMinor,
- LCID lcid,
- ITypeLib **ppTLib)
-{
- BSTR bstr=NULL;
- HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
-
- if(SUCCEEDED(res))
- {
- res= LoadTypeLib(bstr, ppTLib);
- SysFreeString(bstr);
- }
-
- TRACE("(IID: %s) load %s (%p)\n",debugstr_guid(rguid), SUCCEEDED(res)? "SUCCESS":"FAILED", *ppTLib);
-
- return res;
-}
-
-
-/* some string constants shared between RegisterTypeLib and UnRegisterTypeLib */
-static const WCHAR TypeLibW[] = {'T','y','p','e','L','i','b',0};
-static const WCHAR FLAGSW[] = {'F','L','A','G','S',0};
-static const WCHAR HELPDIRW[] = {'H','E','L','P','D','I','R',0};
-static const WCHAR ProxyStubClsidW[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d',0};
-static const WCHAR ProxyStubClsid32W[] = {'P','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
-
-/******************************************************************************
- * RegisterTypeLib [OLEAUT32.163]
- * Adds information about a type library to the System Registry
- * NOTES
- * Docs: ITypeLib FAR * ptlib
- * Docs: OLECHAR FAR* szFullPath
- * Docs: OLECHAR FAR* szHelpDir
- *
- * RETURNS
- * Success: S_OK
- * Failure: Status
- */
-HRESULT WINAPI RegisterTypeLib(
- 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*/
-{
- static const WCHAR PSOA[] = {'{','0','0','0','2','0','4','2','4','-',
- '0','0','0','0','-','0','0','0','0','-','C','0','0','0','-',
- '0','0','0','0','0','0','0','0','0','0','4','6','}',0};
- HRESULT res;
- TLIBATTR *attr;
- WCHAR keyName[60];
- WCHAR tmp[16];
- HKEY key, subKey;
- UINT types, tidx;
- TYPEKIND kind;
- DWORD disposition;
-
- if (ptlib == NULL || szFullPath == NULL)
- return E_INVALIDARG;
-
- if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr)))
- return E_FAIL;
-
- get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
-
- res = S_OK;
- if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
- KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
- {
- LPOLESTR doc;
-
- /* Set the human-readable name of the typelib */
- if (SUCCEEDED(ITypeLib_GetDocumentation(ptlib, -1, NULL, &doc, NULL, NULL)))
- {
- if (RegSetValueExW(key, NULL, 0, REG_SZ,
- (BYTE *)doc, (lstrlenW(doc)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
- res = E_FAIL;
-
- 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;
-
- /* Create the typelib path subkey */
- if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
- {
- if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE *)szFullPath, (lstrlenW(szFullPath)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS)
- res = E_FAIL;
-
- RegCloseKey(subKey);
- }
- else
- res = E_FAIL;
-
- /* Create the flags subkey */
- if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
- {
- /* FIXME: is %u correct? */
- static const WCHAR formatW[] = {'%','u',0};
- WCHAR buf[20];
- sprintfW(buf, formatW, attr->wLibFlags);
- if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE *)buf, (strlenW(buf) + 1)*sizeof(WCHAR) ) != ERROR_SUCCESS)
- res = E_FAIL;
-
- RegCloseKey(subKey);
- }
- else
- res = E_FAIL;
-
- /* create the helpdir subkey */
- if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
- {
- BOOL freeHelpDir = FALSE;
- OLECHAR* pIndexStr;
-
- /* if we created a new key, and helpDir was null, set the helpdir
- to the directory which contains the typelib. However,
- if we just opened an existing key, we leave the helpdir alone */
- if ((disposition == REG_CREATED_NEW_KEY) && (szHelpDir == NULL)) {
- szHelpDir = SysAllocString(szFullPath);
- pIndexStr = strrchrW(szHelpDir, '\\');
- if (pIndexStr) {
- *pIndexStr = 0;
- }
- freeHelpDir = TRUE;
- }
-
- /* if we have an szHelpDir, set it! */
- if (szHelpDir != NULL) {
- if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE *)szHelpDir, (lstrlenW(szHelpDir)+1) * sizeof(OLECHAR)) != ERROR_SUCCESS) {
- res = E_FAIL;
- }
- }
-
- /* tidy up */
- if (freeHelpDir) SysFreeString(szHelpDir);
- RegCloseKey(subKey);
-
- } else {
- res = E_FAIL;
- }
-
- RegCloseKey(key);
- }
- else
- res = E_FAIL;
-
- /* register OLE Automation-compatible interfaces for this typelib */
- types = ITypeLib_GetTypeInfoCount(ptlib);
- for (tidx=0; tidx<types; tidx++) {
- if (SUCCEEDED(ITypeLib_GetTypeInfoType(ptlib, tidx, &kind))) {
- LPOLESTR name = NULL;
- ITypeInfo *tinfo = NULL;
-
- ITypeLib_GetDocumentation(ptlib, tidx, &name, NULL, NULL, NULL);
-
- switch (kind) {
- case TKIND_INTERFACE:
- TRACE_(typelib)("%d: interface %s\n", tidx, debugstr_w(name));
- ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
- break;
-
- case TKIND_DISPATCH:
- TRACE_(typelib)("%d: dispinterface %s\n", tidx, debugstr_w(name));
- ITypeLib_GetTypeInfo(ptlib, tidx, &tinfo);
- break;
-
- default:
- TRACE_(typelib)("%d: %s\n", tidx, debugstr_w(name));
- break;
- }
-
- if (tinfo) {
- TYPEATTR *tattr = NULL;
- ITypeInfo_GetTypeAttr(tinfo, &tattr);
-
- if (tattr) {
- TRACE_(typelib)("guid=%s, flags=%04x (",
- debugstr_guid(&tattr->guid),
- tattr->wTypeFlags);
-
- if (TRACE_ON(typelib)) {
-#define XX(x) if (TYPEFLAG_##x & tattr->wTypeFlags) MESSAGE(#x"|");
- XX(FAPPOBJECT);
- XX(FCANCREATE);
- XX(FLICENSED);
- XX(FPREDECLID);
- XX(FHIDDEN);
- XX(FCONTROL);
- XX(FDUAL);
- XX(FNONEXTENSIBLE);
- XX(FOLEAUTOMATION);
- XX(FRESTRICTED);
- XX(FAGGREGATABLE);
- XX(FREPLACEABLE);
- XX(FDISPATCHABLE);
- XX(FREVERSEBIND);
- XX(FPROXY);
-#undef XX
- MESSAGE("\n");
- }
-
- if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL))
- {
- /* register interface<->typelib coupling */
- get_interface_key( &tattr->guid, keyName );
- if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
- KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
- {
- if (name)
- RegSetValueExW(key, NULL, 0, REG_SZ,
- (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR));
-
- if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
- RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE*)PSOA, sizeof PSOA);
- RegCloseKey(subKey);
- }
-
- if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
- RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE*)PSOA, sizeof PSOA);
- RegCloseKey(subKey);
- }
-
- if (RegCreateKeyExW(key, TypeLibW, 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
- {
- WCHAR buffer[40];
- static const WCHAR fmtver[] = {'%','u','.','%','u',0 };
- static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0};
-
- StringFromGUID2(&attr->guid, buffer, 40);
- RegSetValueExW(subKey, NULL, 0, REG_SZ,
- (BYTE *)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
- sprintfW(buffer, fmtver, attr->wMajorVerNum, attr->wMinorVerNum);
- RegSetValueExW(subKey, VersionW, 0, REG_SZ,
- (BYTE*)buffer, (strlenW(buffer)+1) * sizeof(WCHAR));
- RegCloseKey(subKey);
- }
-
- RegCloseKey(key);
- }
- }
-
- ITypeInfo_ReleaseTypeAttr(tinfo, tattr);
- }
-
- ITypeInfo_Release(tinfo);
- }
-
- SysFreeString(name);
- }
- }
-
- ITypeLib_ReleaseTLibAttr(ptlib, attr);
-
- return res;
-}
-
-
-/******************************************************************************
- * UnRegisterTypeLib [OLEAUT32.186]
- * Removes information about a type library from the System Registry
- * NOTES
- *
- * RETURNS
- * Success: S_OK
- * Failure: Status
- */
-HRESULT WINAPI UnRegisterTypeLib(
- REFGUID libid, /* [in] Guid of the library */
- WORD wVerMajor, /* [in] major version */
- WORD wVerMinor, /* [in] minor version */
- LCID lcid, /* [in] locale id */
- SYSKIND syskind)
-{
- BSTR tlibPath = NULL;
- DWORD tmpLength;
- WCHAR keyName[60];
- WCHAR subKeyName[50];
- int result = S_OK;
- DWORD i = 0;
- BOOL deleteOtherStuff;
- HKEY key = NULL;
- HKEY subKey = NULL;
- TYPEATTR* typeAttr = NULL;
- TYPEKIND kind;
- ITypeInfo* typeInfo = NULL;
- ITypeLib* typeLib = NULL;
- int numTypes;
-
- TRACE("(IID: %s): stub\n",debugstr_guid(libid));
-
- /* Create the path to the key */
- get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
-
- if (syskind != SYS_WIN16 && syskind != SYS_WIN32)
- {
- TRACE("Unsupported syskind %i\n", syskind);
- result = E_INVALIDARG;
- goto end;
- }
-
- /* get the path to the typelib on disk */
- if (QueryPathOfRegTypeLib(libid, wVerMajor, wVerMinor, lcid, &tlibPath) != S_OK) {
- result = E_INVALIDARG;
- goto end;
- }
-
- /* Try and open the key to the type library. */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) {
- result = E_INVALIDARG;
- goto end;
- }
-
- /* Try and load the type library */
- if (LoadTypeLibEx(tlibPath, REGKIND_NONE, &typeLib)) {
- result = TYPE_E_INVALIDSTATE;
- goto end;
- }
-
- /* remove any types registered with this typelib */
- numTypes = ITypeLib_GetTypeInfoCount(typeLib);
- for (i=0; i<numTypes; i++) {
- /* get the kind of type */
- if (ITypeLib_GetTypeInfoType(typeLib, i, &kind) != S_OK) {
- goto enddeleteloop;
- }
-
- /* skip non-interfaces, and get type info for the type */
- if ((kind != TKIND_INTERFACE) && (kind != TKIND_DISPATCH)) {
- goto enddeleteloop;
- }
- if (ITypeLib_GetTypeInfo(typeLib, i, &typeInfo) != S_OK) {
- goto enddeleteloop;
- }
- if (ITypeInfo_GetTypeAttr(typeInfo, &typeAttr) != S_OK) {
- goto enddeleteloop;
- }
-
- /* the path to the type */
- get_interface_key( &typeAttr->guid, subKeyName );
-
- /* Delete its bits */
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) {
- goto enddeleteloop;
- }
- 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);
- typeAttr = NULL;
- if (typeInfo) ITypeInfo_Release(typeInfo);
- typeInfo = NULL;
- }
-
- /* Now, delete the type library path subkey */
- get_lcid_subkey( lcid, syskind, subKeyName );
- RegDeleteKeyW(key, subKeyName);
- *strrchrW( subKeyName, '\\' ) = 0; /* remove last path component */
- RegDeleteKeyW(key, subKeyName);
-
- /* check if there is anything besides the FLAGS/HELPDIR keys.
- If there is, we don't delete them */
- tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
- deleteOtherStuff = TRUE;
- i = 0;
- while(RegEnumKeyExW(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == S_OK) {
- tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
-
- /* if its not FLAGS or HELPDIR, then we must keep the rest of the key */
- if (!strcmpW(subKeyName, FLAGSW)) continue;
- if (!strcmpW(subKeyName, HELPDIRW)) continue;
- deleteOtherStuff = FALSE;
- break;
- }
-
- /* only delete the other parts of the key if we're absolutely sure */
- if (deleteOtherStuff) {
- RegDeleteKeyW(key, FLAGSW);
- RegDeleteKeyW(key, HELPDIRW);
- RegCloseKey(key);
- key = NULL;
-
- RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
- *strrchrW( keyName, '\\' ) = 0; /* remove last path component */
- RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
- }
-
-end:
- if (tlibPath) SysFreeString(tlibPath);
- if (typeLib) ITypeLib_Release(typeLib);
- if (subKey) RegCloseKey(subKey);
- if (key) RegCloseKey(key);
- return result;
-}
-
-/*======================= ITypeLib implementation =======================*/
-
-typedef struct tagTLBCustData
-{
- GUID guid;
- VARIANT data;
- struct tagTLBCustData* next;
-} TLBCustData;
-
-/* data structure for import typelibs */
-typedef struct tagTLBImpLib
-{
- int offset; /* offset in the file (MSFT)
- offset in nametable (SLTG)
- just used to identify library while reading
- data from file */
- GUID guid; /* libid */
- BSTR name; /* name */
-
- LCID lcid; /* lcid of imported typelib */
-
- WORD wVersionMajor; /* major version number */
- WORD wVersionMinor; /* minor version number */
-
- struct tagITypeLibImpl *pImpTypeLib; /* pointer to loaded typelib, or
- NULL if not yet loaded */
- struct tagTLBImpLib * next;
-} TLBImpLib;
-
-/* internal ITypeLib data */
-typedef struct tagITypeLibImpl
-{
- const ITypeLib2Vtbl *lpVtbl;
- const ITypeCompVtbl *lpVtblTypeComp;
- LONG ref;
- TLIBATTR LibAttr; /* guid,lcid,syskind,version,flags */
-
- /* strings can be stored in tlb as multibyte strings BUT they are *always*
- * exported to the application as a UNICODE string.
- */
- BSTR Name;
- BSTR DocString;
- BSTR HelpFile;
- BSTR HelpStringDll;
- unsigned long 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 */
- TLBCustData * pCustData; /* linked list to cust data */
- TLBImpLib * pImpLibs; /* linked list to all imported typelibs */
- TYPEDESC * pTypeDesc; /* array of TypeDescriptions found in the
- libary. Only used while read MSFT
- typelibs */
-
- /* typelibs are cached, keyed by path and index, so store the linked list info within them */
- struct tagITypeLibImpl *next, *prev;
- WCHAR *path;
- INT index;
-} ITypeLibImpl;
-
-static const ITypeLib2Vtbl tlbvt;
-static const ITypeCompVtbl tlbtcvt;
-
-static inline ITypeLibImpl *impl_from_ITypeComp( ITypeComp *iface )
-{
- return (ITypeLibImpl *)((char*)iface - FIELD_OFFSET(ITypeLibImpl, lpVtblTypeComp));
-}
-
-/* ITypeLib methods */
-static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength);
-static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength);
-
-/*======================= ITypeInfo implementation =======================*/
-
-/* data for referenced types */
-typedef struct tagTLBRefType
-{
- INT index; /* Type index for internal ref or for external ref
- it the format is SLTG. -2 indicates to
- use guid */
-
- GUID guid; /* guid of the referenced type */
- /* if index == TLB_REF_USE_GUID */
-
- HREFTYPE reference; /* The href of this ref */
- TLBImpLib *pImpTLInfo; /* If ref is external ptr to library data
- TLB_REF_INTERNAL for internal refs
- TLB_REF_NOT_FOUND for broken refs */
-
- struct tagTLBRefType * next;
-} TLBRefType;
-
-#define TLB_REF_USE_GUID -2
-
-#define TLB_REF_INTERNAL (void*)-2
-#define TLB_REF_NOT_FOUND (void*)-1
-
-/* internal Parameter data */
-typedef struct tagTLBParDesc
-{
- BSTR Name;
- int ctCustData;
- TLBCustData * pCustData; /* linked list to cust data */
-} TLBParDesc;
-
-/* internal Function data */
-typedef struct tagTLBFuncDesc
-{
- FUNCDESC funcdesc; /* lots of info on the function and its attributes. */
- BSTR Name; /* the name of this function */
- TLBParDesc *pParamDesc; /* array with param names and custom data */
- int helpcontext;
- int HelpStringContext;
- BSTR HelpString;
- BSTR Entry; /* if its Hiword==0, it numeric; -1 is not present*/
- int ctCustData;
- TLBCustData * pCustData; /* linked list to cust data; */
- struct tagTLBFuncDesc * next;
-} TLBFuncDesc;
-
-/* internal Variable data */
-typedef struct tagTLBVarDesc
-{
- VARDESC vardesc; /* lots of info on the variable and its attributes. */
- BSTR Name; /* the name of this variable */
- int HelpContext;
- int HelpStringContext; /* FIXME: where? */
- BSTR HelpString;
- int ctCustData;
- TLBCustData * pCustData;/* linked list to cust data; */
- struct tagTLBVarDesc * next;
-} TLBVarDesc;
-
-/* internal implemented interface data */
-typedef struct tagTLBImplType
-{
- HREFTYPE hRef; /* hRef of interface */
- int implflags; /* IMPLFLAG_*s */
- int ctCustData;
- TLBCustData * pCustData;/* linked list to custom data; */
- struct tagTLBImplType *next;
-} TLBImplType;
-
-/* internal TypeInfo data */
-typedef struct tagITypeInfoImpl
-{
- const ITypeInfo2Vtbl *lpVtbl;
- const ITypeCompVtbl *lpVtblTypeComp;
- LONG ref;
- TYPEATTR TypeAttr ; /* _lots_ of type information. */
- ITypeLibImpl * pTypeLib; /* back pointer to typelib */
- int index; /* index in this typelib; */
- HREFTYPE hreftype; /* hreftype for app object binding */
- /* type libs seem to store the doc strings in ascii
- * so why should we do it in unicode?
- */
- BSTR Name;
- BSTR DocString;
- BSTR DllName;
- unsigned long dwHelpContext;
- unsigned long dwHelpStringContext;
-
- /* functions */
- TLBFuncDesc * funclist; /* linked list with function descriptions */
-
- /* variables */
- TLBVarDesc * varlist; /* linked list with variable descriptions */
-
- /* Implemented Interfaces */
- TLBImplType * impltypelist;
-
- TLBRefType * reflist;
- int ctCustData;
- TLBCustData * pCustData; /* linked list to cust data; */
- struct tagITypeInfoImpl * next;
-} ITypeInfoImpl;
-
-static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface )
-{
- return (ITypeInfoImpl *)((char*)iface - FIELD_OFFSET(ITypeInfoImpl, lpVtblTypeComp));
-}
-
-static const ITypeInfo2Vtbl tinfvt;
-static const ITypeCompVtbl tcompvt;
-
-static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void);
-
-typedef struct tagTLBContext
-{
- unsigned int oStart; /* start of TLB in file */
- unsigned int pos; /* current pos */
- unsigned int length; /* total length */
- void *mapping; /* memory mapping */
- MSFT_SegDir * pTblDir;
- ITypeLibImpl* pLibInfo;
-} TLBContext;
-
-
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI, int offset);
-
-/*
- debug
-*/
-static void dump_TypeDesc(const TYPEDESC *pTD,char *szVarType) {
- if (pTD->vt & VT_RESERVED)
- szVarType += strlen(strcpy(szVarType, "reserved | "));
- if (pTD->vt & VT_BYREF)
- szVarType += strlen(strcpy(szVarType, "ref to "));
- if (pTD->vt & VT_ARRAY)
- szVarType += strlen(strcpy(szVarType, "array of "));
- if (pTD->vt & VT_VECTOR)
- szVarType += strlen(strcpy(szVarType, "vector of "));
- switch(pTD->vt & VT_TYPEMASK) {
- case VT_UI1: sprintf(szVarType, "VT_UI1"); break;
- case VT_I2: sprintf(szVarType, "VT_I2"); break;
- case VT_I4: sprintf(szVarType, "VT_I4"); break;
- case VT_R4: sprintf(szVarType, "VT_R4"); break;
- case VT_R8: sprintf(szVarType, "VT_R8"); break;
- case VT_BOOL: sprintf(szVarType, "VT_BOOL"); break;
- case VT_ERROR: sprintf(szVarType, "VT_ERROR"); break;
- case VT_CY: sprintf(szVarType, "VT_CY"); break;
- case VT_DATE: sprintf(szVarType, "VT_DATE"); break;
- case VT_BSTR: sprintf(szVarType, "VT_BSTR"); break;
- case VT_UNKNOWN: sprintf(szVarType, "VT_UNKNOWN"); break;
- case VT_DISPATCH: sprintf(szVarType, "VT_DISPATCH"); break;
- case VT_I1: sprintf(szVarType, "VT_I1"); break;
- case VT_UI2: sprintf(szVarType, "VT_UI2"); break;
- case VT_UI4: sprintf(szVarType, "VT_UI4"); break;
- case VT_INT: sprintf(szVarType, "VT_INT"); break;
- case VT_UINT: sprintf(szVarType, "VT_UINT"); break;
- case VT_VARIANT: sprintf(szVarType, "VT_VARIANT"); break;
- case VT_VOID: sprintf(szVarType, "VT_VOID"); break;
- case VT_HRESULT: sprintf(szVarType, "VT_HRESULT"); break;
- case VT_USERDEFINED: sprintf(szVarType, "VT_USERDEFINED ref = %lx",
- pTD->u.hreftype); break;
- case VT_PTR: sprintf(szVarType, "ptr to ");
- dump_TypeDesc(pTD->u.lptdesc, szVarType + 7);
- break;
- case VT_SAFEARRAY: sprintf(szVarType, "safearray of ");
- dump_TypeDesc(pTD->u.lptdesc, szVarType + 13);
- break;
- case VT_CARRAY: sprintf(szVarType, "%d dim array of ",
- pTD->u.lpadesc->cDims); /* FIXME print out sizes */
- dump_TypeDesc(&pTD->u.lpadesc->tdescElem, szVarType + strlen(szVarType));
- break;
-
- default: sprintf(szVarType, "unknown(%d)", pTD->vt & VT_TYPEMASK); break;
- }
-}
-
-static void dump_ELEMDESC(const ELEMDESC *edesc) {
- char buf[200];
- USHORT flags = edesc->u.paramdesc.wParamFlags;
- dump_TypeDesc(&edesc->tdesc,buf);
- MESSAGE("\t\ttdesc.vartype %d (%s)\n",edesc->tdesc.vt,buf);
- MESSAGE("\t\tu.paramdesc.wParamFlags");
- if (!flags) MESSAGE(" PARAMFLAGS_NONE");
- if (flags & PARAMFLAG_FIN) MESSAGE(" PARAMFLAG_FIN");
- if (flags & PARAMFLAG_FOUT) MESSAGE(" PARAMFLAG_FOUT");
- if (flags & PARAMFLAG_FLCID) MESSAGE(" PARAMFLAG_FLCID");
- if (flags & PARAMFLAG_FRETVAL) MESSAGE(" PARAMFLAG_FRETVAL");
- if (flags & PARAMFLAG_FOPT) MESSAGE(" PARAMFLAG_FOPT");
- if (flags & PARAMFLAG_FHASDEFAULT) MESSAGE(" PARAMFLAG_FHASDEFAULT");
- if (flags & PARAMFLAG_FHASCUSTDATA) MESSAGE(" PARAMFLAG_FHASCUSTDATA");
- MESSAGE("\n\t\tu.paramdesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
-}
-static void dump_FUNCDESC(const FUNCDESC *funcdesc) {
- int i;
- MESSAGE("memid is %08lx\n",funcdesc->memid);
- for (i=0;i<funcdesc->cParams;i++) {
- MESSAGE("Param %d:\n",i);
- dump_ELEMDESC(funcdesc->lprgelemdescParam+i);
- }
- MESSAGE("\tfunckind: %d (",funcdesc->funckind);
- switch (funcdesc->funckind) {
- case FUNC_VIRTUAL: MESSAGE("virtual");break;
- case FUNC_PUREVIRTUAL: MESSAGE("pure virtual");break;
- case FUNC_NONVIRTUAL: MESSAGE("nonvirtual");break;
- case FUNC_STATIC: MESSAGE("static");break;
- case FUNC_DISPATCH: MESSAGE("dispatch");break;
- default: MESSAGE("unknown");break;
- }
- MESSAGE(")\n\tinvkind: %d (",funcdesc->invkind);
- switch (funcdesc->invkind) {
- case INVOKE_FUNC: MESSAGE("func");break;
- case INVOKE_PROPERTYGET: MESSAGE("property get");break;
- case INVOKE_PROPERTYPUT: MESSAGE("property put");break;
- case INVOKE_PROPERTYPUTREF: MESSAGE("property put ref");break;
- }
- MESSAGE(")\n\tcallconv: %d (",funcdesc->callconv);
- switch (funcdesc->callconv) {
- case CC_CDECL: MESSAGE("cdecl");break;
- case CC_PASCAL: MESSAGE("pascal");break;
- case CC_STDCALL: MESSAGE("stdcall");break;
- case CC_SYSCALL: MESSAGE("syscall");break;
- default:break;
- }
- MESSAGE(")\n\toVft: %d\n", funcdesc->oVft);
- MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
- MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
-
- MESSAGE("\telemdescFunc (return value type):\n");
- dump_ELEMDESC(&funcdesc->elemdescFunc);
-}
-
-static const char * typekind_desc[] =
-{
- "TKIND_ENUM",
- "TKIND_RECORD",
- "TKIND_MODULE",
- "TKIND_INTERFACE",
- "TKIND_DISPATCH",
- "TKIND_COCLASS",
- "TKIND_ALIAS",
- "TKIND_UNION",
- "TKIND_MAX"
-};
-
-static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd)
-{
- int i;
- MESSAGE("%s(%u)\n", debugstr_w(pfd->Name), pfd->funcdesc.cParams);
- for (i=0;i<pfd->funcdesc.cParams;i++)
- MESSAGE("\tparm%d: %s\n",i,debugstr_w(pfd->pParamDesc[i].Name));
-
-
- dump_FUNCDESC(&(pfd->funcdesc));
-
- MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
- MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry));
-}
-static void dump_TLBFuncDesc(const TLBFuncDesc * pfd)
-{
- while (pfd)
- {
- dump_TLBFuncDescOne(pfd);
- pfd = pfd->next;
- };
-}
-static void dump_TLBVarDesc(const TLBVarDesc * pvd)
-{
- while (pvd)
- {
- TRACE_(typelib)("%s\n", debugstr_w(pvd->Name));
- pvd = pvd->next;
- };
-}
-
-static void dump_TLBImpLib(const TLBImpLib *import)
-{
- TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)),
- debugstr_w(import->name));
- TRACE_(typelib)("v%d.%d lcid=%lx offset=%x\n", import->wVersionMajor,
- import->wVersionMinor, import->lcid, import->offset);
-}
-
-static void dump_TLBRefType(const TLBRefType * prt)
-{
- while (prt)
- {
- TRACE_(typelib)("href:0x%08lx\n", prt->reference);
- if(prt->index == -1)
- TRACE_(typelib)("%s\n", debugstr_guid(&(prt->guid)));
- else
- TRACE_(typelib)("type no: %d\n", prt->index);
-
- if(prt->pImpTLInfo != TLB_REF_INTERNAL &&
- prt->pImpTLInfo != TLB_REF_NOT_FOUND) {
- TRACE_(typelib)("in lib\n");
- dump_TLBImpLib(prt->pImpTLInfo);
- }
- prt = prt->next;
- };
-}
-
-static void dump_TLBImplType(const TLBImplType * impl)
-{
- while (impl) {
- TRACE_(typelib)(
- "implementing/inheriting interface hRef = %lx implflags %x\n",
- impl->hRef, impl->implflags);
- impl = impl->next;
- }
-}
-
-void dump_Variant(const VARIANT * pvar)
-{
- SYSTEMTIME st;
-
- TRACE("%p->{%s%s", pvar, debugstr_VT(pvar), debugstr_VF(pvar));
-
- if (pvar)
- {
- if (V_ISBYREF(pvar) || V_TYPE(pvar) == VT_UNKNOWN ||
- V_TYPE(pvar) == VT_DISPATCH || V_TYPE(pvar) == VT_RECORD)
- {
- TRACE(",%p", V_BYREF(pvar));
- }
- else if (V_ISARRAY(pvar) || V_ISVECTOR(pvar))
- {
- TRACE(",FIXME");
- }
- else switch (V_TYPE(pvar))
- {
- case VT_I1: TRACE(",%d", V_I1(pvar)); break;
- case VT_UI1: TRACE(",%d", V_UI1(pvar)); break;
- case VT_I2: TRACE(",%d", V_I2(pvar)); break;
- case VT_UI2: TRACE(",%d", V_UI2(pvar)); break;
- case VT_INT:
- case VT_I4: TRACE(",%ld", V_I4(pvar)); break;
- case VT_UINT:
- case VT_UI4: TRACE(",%ld", V_UI4(pvar)); break;
- case VT_I8: TRACE(",0x%08lx,0x%08lx", (ULONG)(V_I8(pvar) >> 32),
- (ULONG)(V_I8(pvar) & 0xffffffff)); break;
- case VT_UI8: TRACE(",0x%08lx,0x%08lx", (ULONG)(V_UI8(pvar) >> 32),
- (ULONG)(V_UI8(pvar) & 0xffffffff)); break;
- case VT_R4: TRACE(",%3.3e", V_R4(pvar)); break;
- case VT_R8: TRACE(",%3.3e", V_R8(pvar)); break;
- case VT_BOOL: TRACE(",%s", V_BOOL(pvar) ? "TRUE" : "FALSE"); break;
- case VT_BSTR: TRACE(",%s", debugstr_w(V_BSTR(pvar))); break;
- case VT_CY: TRACE(",0x%08lx,0x%08lx", V_CY(pvar).s.Hi,
- V_CY(pvar).s.Lo); break;
- case VT_DATE:
- if(!VariantTimeToSystemTime(V_DATE(pvar), &st))
- TRACE(",<invalid>");
- else
- TRACE(",%04d/%02d/%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay,
- st.wHour, st.wMinute, st.wSecond);
- break;
- case VT_ERROR:
- case VT_VOID:
- case VT_USERDEFINED:
- case VT_EMPTY:
- case VT_NULL: break;
- default: TRACE(",?"); break;
- }
- }
- TRACE("}\n");
-}
-
-static void dump_DispParms(const DISPPARAMS * pdp)
-{
- int index = 0;
-
- TRACE("args=%u named args=%u\n", pdp->cArgs, pdp->cNamedArgs);
-
- while (index < pdp->cArgs)
- {
- dump_Variant( &pdp->rgvarg[index] );
- ++index;
- }
-}
-
-static void dump_TypeInfo(const ITypeInfoImpl * pty)
-{
- TRACE("%p ref=%lu\n", pty, pty->ref);
- TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString));
- TRACE("attr:%s\n", debugstr_guid(&(pty->TypeAttr.guid)));
- TRACE("kind:%s\n", typekind_desc[pty->TypeAttr.typekind]);
- TRACE("fct:%u var:%u impl:%u\n",
- pty->TypeAttr.cFuncs, pty->TypeAttr.cVars, pty->TypeAttr.cImplTypes);
- TRACE("wTypeFlags: 0x%04x\n", pty->TypeAttr.wTypeFlags);
- TRACE("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
- if (pty->TypeAttr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(pty->DllName));
- if (TRACE_ON(ole))
- dump_TLBFuncDesc(pty->funclist);
- dump_TLBVarDesc(pty->varlist);
- dump_TLBImplType(pty->impltypelist);
-}
-
-static void dump_VARDESC(const VARDESC *v)
-{
- MESSAGE("memid %ld\n",v->memid);
- MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
- MESSAGE("oInst %ld\n",v->u.oInst);
- dump_ELEMDESC(&(v->elemdescVar));
- MESSAGE("wVarFlags %x\n",v->wVarFlags);
- MESSAGE("varkind %d\n",v->varkind);
-}
-
-static TYPEDESC stndTypeDesc[VT_LPWSTR+1]=
-{
- /* VT_LPWSTR is largest type that */
- /* may appear in type description*/
- {{0}, 0},{{0}, 1},{{0}, 2},{{0}, 3},{{0}, 4},
- {{0}, 5},{{0}, 6},{{0}, 7},{{0}, 8},{{0}, 9},
- {{0},10},{{0},11},{{0},12},{{0},13},{{0},14},
- {{0},15},{{0},16},{{0},17},{{0},18},{{0},19},
- {{0},20},{{0},21},{{0},22},{{0},23},{{0},24},
- {{0},25},{{0},26},{{0},27},{{0},28},{{0},29},
- {{0},30},{{0},31}
-};
-
-static void TLB_abort(void)
-{
- DebugBreak();
-}
-static void * TLB_Alloc(unsigned size)
-{
- void * ret;
- if((ret=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size))==NULL){
- /* FIXME */
- ERR("cannot allocate memory\n");
- }
- return ret;
-}
-
-static void TLB_Free(void * ptr)
-{
- HeapFree(GetProcessHeap(), 0, ptr);
-}
-
-/* returns the size required for a deep copy of a typedesc into a
- * flat buffer */
-static SIZE_T TLB_SizeTypeDesc( const TYPEDESC *tdesc, BOOL alloc_initial_space )
-{
- SIZE_T size = 0;
-
- if (alloc_initial_space)
- size += sizeof(TYPEDESC);
-
- switch (tdesc->vt)
- {
- case VT_PTR:
- case VT_SAFEARRAY:
- size += TLB_SizeTypeDesc(tdesc->u.lptdesc, TRUE);
- break;
- case VT_CARRAY:
- size += FIELD_OFFSET(ARRAYDESC, rgbounds[tdesc->u.lpadesc->cDims]);
- size += TLB_SizeTypeDesc(&tdesc->u.lpadesc->tdescElem, FALSE);
- break;
- }
- return size;
-}
-
-/* deep copy a typedesc into a flat buffer */
-static void *TLB_CopyTypeDesc( TYPEDESC *dest, const TYPEDESC *src, void *buffer )
-{
- if (!dest)
- {
- dest = buffer;
- buffer = (char *)buffer + sizeof(TYPEDESC);
- }
-
- *dest = *src;
-
- switch (src->vt)
- {
- case VT_PTR:
- case VT_SAFEARRAY:
- dest->u.lptdesc = buffer;
- buffer = TLB_CopyTypeDesc(NULL, src->u.lptdesc, buffer);
- break;
- case VT_CARRAY:
- dest->u.lpadesc = buffer;
- memcpy(dest->u.lpadesc, src->u.lpadesc, FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]));
- buffer = (char *)buffer + FIELD_OFFSET(ARRAYDESC, rgbounds[src->u.lpadesc->cDims]);
- buffer = TLB_CopyTypeDesc(&dest->u.lpadesc->tdescElem, &src->u.lpadesc->tdescElem, buffer);
- break;
- }
- return buffer;
-}
-
-/**********************************************************************
- *
- * Functions for reading MSFT typelibs (those created by CreateTypeLib2)
- */
-/* read function */
-static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
-{
- TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
- pcx->pos, count, pcx->oStart, pcx->length, where);
-
- if (where != DO_NOT_SEEK)
- {
- where += pcx->oStart;
- if (where > pcx->length)
- {
- /* FIXME */
- ERR("seek beyond end (%ld/%d)\n", where, pcx->length );
- TLB_abort();
- }
- pcx->pos = where;
- }
- if (pcx->pos + count > pcx->length) count = pcx->length - pcx->pos;
- memcpy( buffer, (char *)pcx->mapping + pcx->pos, count );
- pcx->pos += count;
- return count;
-}
-
-static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx,
- long where )
-{
- DWORD ret;
-
- ret = MSFT_Read(buffer, count, pcx, where);
- FromLEDWords(buffer, ret);
-
- return ret;
-}
-
-static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx,
- long where )
-{
- DWORD ret;
-
- ret = MSFT_Read(buffer, count, pcx, where);
- FromLEWords(buffer, ret);
-
- return ret;
-}
-
-static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
-{
- if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
- memset(pGuid,0, sizeof(GUID));
- return;
- }
- MSFT_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
- pGuid->Data1 = FromLEDWord(pGuid->Data1);
- pGuid->Data2 = FromLEWord(pGuid->Data2);
- pGuid->Data3 = FromLEWord(pGuid->Data3);
- TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
-}
-
-static HREFTYPE MSFT_ReadHreftype( TLBContext *pcx, int offset )
-{
- MSFT_NameIntro niName;
-
- if (offset < 0)
- {
- ERR_(typelib)("bad offset %d\n", offset);
- return -1;
- }
-
- MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
- pcx->pTblDir->pNametab.offset+offset);
-
- return niName.hreftype;
-}
-
-static BSTR MSFT_ReadName( TLBContext *pcx, int offset)
-{
- char * name;
- MSFT_NameIntro niName;
- int lengthInChars;
- WCHAR* pwstring = NULL;
- BSTR bstrName = NULL;
-
- if (offset < 0)
- {
- ERR_(typelib)("bad offset %d\n", offset);
- return NULL;
- }
- MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
- pcx->pTblDir->pNametab.offset+offset);
- niName.namelen &= 0xFF; /* FIXME: correct ? */
- name=TLB_Alloc((niName.namelen & 0xff) +1);
- MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
- name[niName.namelen & 0xff]='\0';
-
- lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
- name, -1, NULL, 0);
-
- /* no invalid characters in string */
- if (lengthInChars)
- {
- pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
-
- /* don't check for invalid character since this has been done previously */
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, pwstring, lengthInChars);
-
- bstrName = SysAllocStringLen(pwstring, lengthInChars);
- lengthInChars = SysStringLen(bstrName);
- HeapFree(GetProcessHeap(), 0, pwstring);
- }
-
- TRACE_(typelib)("%s %d\n", debugstr_w(bstrName), lengthInChars);
- return bstrName;
-}
-
-static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
-{
- char * string;
- INT16 length;
- int lengthInChars;
- BSTR bstr = NULL;
-
- if(offset<0) return NULL;
- MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
- if(length <= 0) return 0;
- string=TLB_Alloc(length +1);
- MSFT_Read(string, length, pcx, DO_NOT_SEEK);
- string[length]='\0';
-
- lengthInChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS,
- string, -1, NULL, 0);
-
- /* no invalid characters in string */
- if (lengthInChars)
- {
- WCHAR* pwstring = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*lengthInChars);
-
- /* don't check for invalid character since this has been done previously */
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, string, -1, pwstring, lengthInChars);
-
- bstr = SysAllocStringLen(pwstring, lengthInChars);
- lengthInChars = SysStringLen(bstr);
- HeapFree(GetProcessHeap(), 0, pwstring);
- }
-
- TRACE_(typelib)("%s %d\n", debugstr_w(bstr), lengthInChars);
- return bstr;
-}
-/*
- * read a value and fill a VARIANT structure
- */
-static void MSFT_ReadValue( VARIANT * pVar, int offset, TLBContext *pcx )
-{
- int size;
-
- TRACE_(typelib)("\n");
-
- if(offset <0) { /* data are packed in here */
- V_VT(pVar) = (offset & 0x7c000000 )>> 26;
- V_I4(pVar) = offset & 0x3ffffff;
- return;
- }
- MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
- pcx->pTblDir->pCustData.offset + offset );
- TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
- switch (V_VT(pVar)){
- case VT_EMPTY: /* FIXME: is this right? */
- case VT_NULL: /* FIXME: is this right? */
- case VT_I2 : /* this should not happen */
- case VT_I4 :
- case VT_R4 :
- case VT_ERROR :
- case VT_BOOL :
- case VT_I1 :
- case VT_UI1 :
- case VT_UI2 :
- case VT_UI4 :
- case VT_INT :
- case VT_UINT :
- case VT_VOID : /* FIXME: is this right? */
- case VT_HRESULT :
- size=4; break;
- case VT_R8 :
- case VT_CY :
- case VT_DATE :
- case VT_I8 :
- case VT_UI8 :
- case VT_DECIMAL : /* FIXME: is this right? */
- case VT_FILETIME :
- size=8;break;
- /* pointer types with known behaviour */
- case VT_BSTR :{
- char * ptr;
- MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
- if(size < 0) {
- FIXME("BSTR length = %d?\n", size);
- } else {
- ptr=TLB_Alloc(size);/* allocate temp buffer */
- MSFT_Read(ptr, size, pcx, DO_NOT_SEEK);/* read string (ANSI) */
- V_BSTR(pVar)=SysAllocStringLen(NULL,size);
- /* FIXME: do we need a AtoW conversion here? */
- V_UNION(pVar, bstrVal[size])=L'\0';
- while(size--) V_UNION(pVar, bstrVal[size])=ptr[size];
- TLB_Free(ptr);
- }
- }
- size=-4; break;
- /* FIXME: this will not work AT ALL when the variant contains a pointer */
- case VT_DISPATCH :
- case VT_VARIANT :
- case VT_UNKNOWN :
- case VT_PTR :
- case VT_SAFEARRAY :
- case VT_CARRAY :
- case VT_USERDEFINED :
- case VT_LPSTR :
- case VT_LPWSTR :
- case VT_BLOB :
- case VT_STREAM :
- case VT_STORAGE :
- case VT_STREAMED_OBJECT :
- case VT_STORED_OBJECT :
- case VT_BLOB_OBJECT :
- case VT_CF :
- case VT_CLSID :
- default:
- size=0;
- FIXME("VARTYPE %d is not supported, setting pointer to NULL\n",
- V_VT(pVar));
- }
-
- if(size>0) /* (big|small) endian correct? */
- MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
- return;
-}
-/*
- * create a linked list with custom data
- */
-static int MSFT_CustData( TLBContext *pcx, int offset, TLBCustData** ppCustData )
-{
- MSFT_CDGuid entry;
- TLBCustData* pNew;
- int count=0;
-
- TRACE_(typelib)("\n");
-
- while(offset >=0){
- count++;
- pNew=TLB_Alloc(sizeof(TLBCustData));
- MSFT_ReadLEDWords(&entry, sizeof(entry), pcx, pcx->pTblDir->pCDGuids.offset+offset);
- MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
- MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
- /* add new custom data at head of the list */
- pNew->next=*ppCustData;
- *ppCustData=pNew;
- offset = entry.next;
- }
- return count;
-}
-
-static void MSFT_GetTdesc(TLBContext *pcx, INT type, TYPEDESC *pTd,
- ITypeInfoImpl *pTI)
-{
- if(type <0)
- pTd->vt=type & VT_TYPEMASK;
- else
- *pTd=pcx->pLibInfo->pTypeDesc[type/(2*sizeof(INT))];
-
- if(pTd->vt == VT_USERDEFINED)
- MSFT_DoRefType(pcx, pTI, pTd->u.hreftype);
-
- TRACE_(typelib)("vt type = %X\n", pTd->vt);
-}
-
-static void
-MSFT_DoFuncs(TLBContext* pcx,
- ITypeInfoImpl* pTI,
- int cFuncs,
- int cVars,
- int offset,
- TLBFuncDesc** pptfd)
-{
- /*
- * member information is stored in a data structure at offset
- * indicated by the memoffset field of the typeinfo structure
- * There are several distinctive parts.
- * The first part starts with a field that holds the total length
- * of this (first) part excluding this field. Then follow the records,
- * for each member there is one record.
- *
- * The first entry is always the length of the record (including this
- * length word).
- * The rest of the record depends on the type of the member. If there is
- * a field indicating the member type (function, variable, interface, etc)
- * I have not found it yet. At this time we depend on the information
- * in the type info and the usual order how things are stored.
- *
- * Second follows an array sized nrMEM*sizeof(INT) with a member id
- * for each member;
- *
- * Third is an equal sized array with file offsets to the name entry
- * of each member.
- *
- * The fourth and last (?) part is an array with offsets to the records
- * in the first part of this file segment.
- */
-
- int infolen, nameoffset, reclength, nrattributes, i;
- int recoffset = offset + sizeof(INT);
-
- char recbuf[512];
- MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf;
- TLBFuncDesc *ptfd_prev = NULL;
-
- TRACE_(typelib)("\n");
-
- MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
-
- for ( i = 0; i < cFuncs ; i++ )
- {
- *pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
-
- /* name, eventually add to a hash table */
- MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
- offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
-
- /* nameoffset is sometimes -1 on the second half of a propget/propput
- * pair of functions */
- if ((nameoffset == -1) && (i > 0))
- (*pptfd)->Name = SysAllocString(ptfd_prev->Name);
- else
- (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
-
- /* read the function information record */
- MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
-
- reclength &= 0x1ff;
-
- MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
-
- /* do the attributes */
- nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
- / sizeof(int);
-
- if ( nrattributes > 0 )
- {
- (*pptfd)->helpcontext = pFuncRec->OptAttr[0] ;
-
- if ( nrattributes > 1 )
- {
- (*pptfd)->HelpString = MSFT_ReadString(pcx,
- pFuncRec->OptAttr[1]) ;
-
- if ( nrattributes > 2 )
- {
- if ( pFuncRec->FKCCIC & 0x2000 )
- {
- (*pptfd)->Entry = (WCHAR*) pFuncRec->OptAttr[2] ;
- }
- else
- {
- (*pptfd)->Entry = MSFT_ReadString(pcx,
- pFuncRec->OptAttr[2]);
- }
- if( nrattributes > 5 )
- {
- (*pptfd)->HelpStringContext = pFuncRec->OptAttr[5] ;
-
- if ( nrattributes > 6 && pFuncRec->FKCCIC & 0x80 )
- {
- MSFT_CustData(pcx,
- pFuncRec->OptAttr[6],
- &(*pptfd)->pCustData);
- }
- }
- }
- }
- }
-
- /* fill the FuncDesc Structure */
- MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid, sizeof(INT), pcx,
- offset + infolen + ( i + 1) * sizeof(INT));
-
- (*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
- (*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
- (*pptfd)->funcdesc.callconv = (pFuncRec->FKCCIC) >> 8 & 0xF;
- (*pptfd)->funcdesc.cParams = pFuncRec->nrargs ;
- (*pptfd)->funcdesc.cParamsOpt = pFuncRec->nroargs ;
- (*pptfd)->funcdesc.oVft = pFuncRec->VtableOffset ;
- (*pptfd)->funcdesc.wFuncFlags = LOWORD(pFuncRec->Flags) ;
-
- MSFT_GetTdesc(pcx,
- pFuncRec->DataType,
- &(*pptfd)->funcdesc.elemdescFunc.tdesc,
- pTI);
-
- /* do the parameters/arguments */
- if(pFuncRec->nrargs)
- {
- int j = 0;
- MSFT_ParameterInfo paraminfo;
-
- (*pptfd)->funcdesc.lprgelemdescParam =
- TLB_Alloc(pFuncRec->nrargs * sizeof(ELEMDESC));
-
- (*pptfd)->pParamDesc =
- TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
-
- MSFT_ReadLEDWords(¶minfo, sizeof(paraminfo), pcx,
- recoffset + reclength - pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
-
- for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
- {
- TYPEDESC *lpArgTypeDesc;
- ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j];
-
- MSFT_GetTdesc(pcx,
- paraminfo.DataType,
- &elemdesc->tdesc,
- pTI);
-
- elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;
-
- /* name */
- if (paraminfo.oName == -1)
- /* this occurs for [propput] or [propget] methods, so
- * we should just set the name of the parameter to the
- * name of the method. */
- (*pptfd)->pParamDesc[j].Name = SysAllocString((*pptfd)->Name);
- else
- (*pptfd)->pParamDesc[j].Name =
- MSFT_ReadName( pcx, paraminfo.oName );
- TRACE_(typelib)("param[%d] = %s\n", j, debugstr_w((*pptfd)->pParamDesc[j].Name));
-
- lpArgTypeDesc = &elemdesc->tdesc;
-
- /* resolve referenced type if any */
- while ( lpArgTypeDesc != NULL )
- {
- switch ( lpArgTypeDesc->vt )
- {
- case VT_PTR:
- lpArgTypeDesc = lpArgTypeDesc->u.lptdesc;
- break;
-
- case VT_CARRAY:
- lpArgTypeDesc = & (lpArgTypeDesc->u.lpadesc->tdescElem);
- break;
-
- case VT_USERDEFINED:
- MSFT_DoRefType(pcx, pTI,
- lpArgTypeDesc->u.hreftype);
-
- lpArgTypeDesc = NULL;
- break;
-
- default:
- lpArgTypeDesc = NULL;
- }
- }
-
- /* default value */
- if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
- (pFuncRec->FKCCIC & 0x1000) )
- {
- INT* pInt = (INT *)((char *)pFuncRec +
- reclength -
- (pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
-
- PARAMDESC* pParamDesc = &elemdesc->u.paramdesc;
-
- pParamDesc->pparamdescex = TLB_Alloc(sizeof(PARAMDESCEX));
- pParamDesc->pparamdescex->cBytes = sizeof(PARAMDESCEX);
-
- MSFT_ReadValue(&(pParamDesc->pparamdescex->varDefaultValue),
- pInt[j], pcx);
- }
- else
- elemdesc->u.paramdesc.pparamdescex = NULL;
- /* custom info */
- if ( nrattributes > 7 + j && pFuncRec->FKCCIC & 0x80 )
- {
- MSFT_CustData(pcx,
- pFuncRec->OptAttr[7+j],
- &(*pptfd)->pParamDesc[j].pCustData);
- }
-
- /* SEEK value = jump to offset,
- * from there jump to the end of record,
- * go back by (j-1) arguments
- */
- MSFT_ReadLEDWords( ¶minfo ,
- sizeof(MSFT_ParameterInfo), pcx,
- recoffset + reclength - ((pFuncRec->nrargs - j - 1)
- * sizeof(MSFT_ParameterInfo)));
- }
- }
-
- /* scode is not used: archaic win16 stuff FIXME: right? */
- (*pptfd)->funcdesc.cScodes = 0 ;
- (*pptfd)->funcdesc.lprgscode = NULL ;
-
- ptfd_prev = *pptfd;
- pptfd = & ((*pptfd)->next);
- recoffset += reclength;
- }
-}
-
-static void MSFT_DoVars(TLBContext *pcx, ITypeInfoImpl *pTI, int cFuncs,
- int cVars, int offset, TLBVarDesc ** pptvd)
-{
- int infolen, nameoffset, reclength;
- char recbuf[256];
- MSFT_VarRecord * pVarRec=(MSFT_VarRecord *) recbuf;
- int i;
- int recoffset;
-
- TRACE_(typelib)("\n");
-
- MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
- MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
- ((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
- recoffset += offset+sizeof(INT);
- for(i=0;i<cVars;i++){
- *pptvd=TLB_Alloc(sizeof(TLBVarDesc));
- /* name, eventually add to a hash table */
- MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
- offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
- (*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
- /* read the variable information record */
- MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
- reclength &=0xff;
- MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
- /* Optional data */
- if(reclength >(6*sizeof(INT)) )
- (*pptvd)->HelpContext=pVarRec->HelpContext;
- if(reclength >(7*sizeof(INT)) )
- (*pptvd)->HelpString = MSFT_ReadString(pcx, pVarRec->oHelpString) ;
- if(reclength >(8*sizeof(INT)) )
- if(reclength >(9*sizeof(INT)) )
- (*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
- /* fill the VarDesc Structure */
- MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
- offset + infolen + ( i + 1) * sizeof(INT));
- (*pptvd)->vardesc.varkind = pVarRec->VarKind;
- (*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
- MSFT_GetTdesc(pcx, pVarRec->DataType,
- &(*pptvd)->vardesc.elemdescVar.tdesc, pTI);
-/* (*pptvd)->vardesc.lpstrSchema; is reserved (SDK) FIXME?? */
- if(pVarRec->VarKind == VAR_CONST ){
- (*pptvd)->vardesc.u.lpvarValue=TLB_Alloc(sizeof(VARIANT));
- MSFT_ReadValue((*pptvd)->vardesc.u.lpvarValue,
- pVarRec->OffsValue, pcx);
- } else
- (*pptvd)->vardesc.u.oInst=pVarRec->OffsValue;
- pptvd=&((*pptvd)->next);
- recoffset += reclength;
- }
-}
-/* fill in data for a hreftype (offset). When the referenced type is contained
- * in the typelib, it's just an (file) offset in the type info base dir.
- * If comes from import, it's an offset+1 in the ImpInfo table
- * */
-static void MSFT_DoRefType(TLBContext *pcx, ITypeInfoImpl *pTI,
- int offset)
-{
- int j;
- TLBRefType **ppRefType = &pTI->reflist;
-
- TRACE_(typelib)("TLB context %p, TLB offset %x\n", pcx, offset);
-
- while(*ppRefType) {
- if((*ppRefType)->reference == offset)
- return;
- ppRefType = &(*ppRefType)->next;
- }
-
- *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppRefType));
-
- if(!MSFT_HREFTYPE_INTHISFILE( offset)) {
- /* external typelib */
- MSFT_ImpInfo impinfo;
- TLBImpLib *pImpLib=(pcx->pLibInfo->pImpLibs);
-
- TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
-
- MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
- pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
- for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
- if(pImpLib->offset==impinfo.oImpFile) break;
- pImpLib=pImpLib->next;
- }
- if(pImpLib){
- (*ppRefType)->reference=offset;
- (*ppRefType)->pImpTLInfo = pImpLib;
- if(impinfo.flags & MSFT_IMPINFO_OFFSET_IS_GUID) {
- MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
- (*ppRefType)->index = TLB_REF_USE_GUID;
- } else
- (*ppRefType)->index = impinfo.oGuid;
- }else{
- ERR("Cannot find a reference\n");
- (*ppRefType)->reference=-1;
- (*ppRefType)->pImpTLInfo=TLB_REF_NOT_FOUND;
- }
- }else{
- /* in this typelib */
- (*ppRefType)->index = MSFT_HREFTYPE_INDEX(offset);
- (*ppRefType)->reference=offset;
- (*ppRefType)->pImpTLInfo=TLB_REF_INTERNAL;
- }
-}
-
-/* process Implemented Interfaces of a com class */
-static void MSFT_DoImplTypes(TLBContext *pcx, ITypeInfoImpl *pTI, int count,
- int offset)
-{
- int i;
- MSFT_RefRecord refrec;
- TLBImplType **ppImpl = &pTI->impltypelist;
-
- TRACE_(typelib)("\n");
-
- for(i=0;i<count;i++){
- if(offset<0) break; /* paranoia */
- *ppImpl=TLB_Alloc(sizeof(**ppImpl));
- MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
- MSFT_DoRefType(pcx, pTI, refrec.reftype);
- (*ppImpl)->hRef = refrec.reftype;
- (*ppImpl)->implflags=refrec.flags;
- (*ppImpl)->ctCustData=
- MSFT_CustData(pcx, refrec.oCustData, &(*ppImpl)->pCustData);
- offset=refrec.onext;
- ppImpl=&((*ppImpl)->next);
- }
-}
-/*
- * process a typeinfo record
- */
-static ITypeInfoImpl * MSFT_DoTypeInfo(
- TLBContext *pcx,
- int count,
- ITypeLibImpl * pLibInfo)
-{
- MSFT_TypeInfoBase tiBase;
- ITypeInfoImpl *ptiRet;
-
- TRACE_(typelib)("count=%u\n", count);
-
- ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
- MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
- pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
-
-/* this is where we are coming from */
- ptiRet->pTypeLib = pLibInfo;
- ptiRet->index=count;
-/* fill in the typeattr fields */
- WARN("Assign constructor/destructor memid\n");
-
- MSFT_ReadGuid(&ptiRet->TypeAttr.guid, tiBase.posguid, pcx);
- ptiRet->TypeAttr.lcid=pLibInfo->LibAttr.lcid; /* FIXME: correct? */
- ptiRet->TypeAttr.memidConstructor=MEMBERID_NIL ;/* FIXME */
- ptiRet->TypeAttr.memidDestructor=MEMBERID_NIL ; /* FIXME */
- ptiRet->TypeAttr.lpstrSchema=NULL; /* reserved */
- ptiRet->TypeAttr.cbSizeInstance=tiBase.size;
- ptiRet->TypeAttr.typekind=tiBase.typekind & 0xF;
- ptiRet->TypeAttr.cFuncs=LOWORD(tiBase.cElement);
- ptiRet->TypeAttr.cVars=HIWORD(tiBase.cElement);
- ptiRet->TypeAttr.cbAlignment=(tiBase.typekind >> 11 )& 0x1F; /* there are more flags there */
- ptiRet->TypeAttr.wTypeFlags=tiBase.flags;
- ptiRet->TypeAttr.wMajorVerNum=LOWORD(tiBase.version);
- ptiRet->TypeAttr.wMinorVerNum=HIWORD(tiBase.version);
- ptiRet->TypeAttr.cImplTypes=tiBase.cImplTypes;
- ptiRet->TypeAttr.cbSizeVft=tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
- if(ptiRet->TypeAttr.typekind == TKIND_ALIAS)
- MSFT_GetTdesc(pcx, tiBase.datatype1,
- &ptiRet->TypeAttr.tdescAlias, ptiRet);
-
-/* FIXME: */
-/* IDLDESC idldescType; *//* never saw this one != zero */
-
-/* name, eventually add to a hash table */
- ptiRet->Name=MSFT_ReadName(pcx, tiBase.NameOffset);
- ptiRet->hreftype = MSFT_ReadHreftype(pcx, tiBase.NameOffset);
- TRACE_(typelib)("reading %s\n", debugstr_w(ptiRet->Name));
- /* help info */
- ptiRet->DocString=MSFT_ReadString(pcx, tiBase.docstringoffs);
- ptiRet->dwHelpStringContext=tiBase.helpstringcontext;
- ptiRet->dwHelpContext=tiBase.helpcontext;
-
- if (ptiRet->TypeAttr.typekind == TKIND_MODULE)
- ptiRet->DllName = MSFT_ReadString(pcx, tiBase.datatype1);
-
-/* note: InfoType's Help file and HelpStringDll come from the containing
- * library. Further HelpString and Docstring appear to be the same thing :(
- */
- /* functions */
- if(ptiRet->TypeAttr.cFuncs >0 )
- MSFT_DoFuncs(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
- ptiRet->TypeAttr.cVars,
- tiBase.memoffset, & ptiRet->funclist);
- /* variables */
- if(ptiRet->TypeAttr.cVars >0 )
- MSFT_DoVars(pcx, ptiRet, ptiRet->TypeAttr.cFuncs,
- ptiRet->TypeAttr.cVars,
- tiBase.memoffset, & ptiRet->varlist);
- if(ptiRet->TypeAttr.cImplTypes >0 ) {
- switch(ptiRet->TypeAttr.typekind)
- {
- case TKIND_COCLASS:
- MSFT_DoImplTypes(pcx, ptiRet, ptiRet->TypeAttr.cImplTypes ,
- tiBase.datatype1);
- break;
- case TKIND_DISPATCH:
- ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
-
- if (tiBase.datatype1 != -1)
- {
- MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
- ptiRet->impltypelist->hRef = tiBase.datatype1;
- }
- else
- { /* FIXME: This is a really bad hack to add IDispatch */
- const char* szStdOle = "stdole2.tlb\0";
- int nStdOleLen = strlen(szStdOle);
- TLBRefType **ppRef = &ptiRet->reflist;
-
- while(*ppRef) {
- if((*ppRef)->reference == -1)
- break;
- ppRef = &(*ppRef)->next;
- }
- if(!*ppRef) {
- *ppRef = TLB_Alloc(sizeof(**ppRef));
- (*ppRef)->guid = IID_IDispatch;
- (*ppRef)->reference = -1;
- (*ppRef)->index = TLB_REF_USE_GUID;
- (*ppRef)->pImpTLInfo = TLB_Alloc(sizeof(TLBImpLib));
- (*ppRef)->pImpTLInfo->guid = IID_StdOle;
- (*ppRef)->pImpTLInfo->name = SysAllocStringLen(NULL,
- nStdOleLen + 1);
-
- MultiByteToWideChar(CP_ACP,
- MB_PRECOMPOSED,
- szStdOle,
- -1,
- (*ppRef)->pImpTLInfo->name,
- SysStringLen((*ppRef)->pImpTLInfo->name));
-
- (*ppRef)->pImpTLInfo->lcid = 0;
- (*ppRef)->pImpTLInfo->wVersionMajor = 2;
- (*ppRef)->pImpTLInfo->wVersionMinor = 0;
- }
- }
- break;
- default:
- ptiRet->impltypelist=TLB_Alloc(sizeof(TLBImplType));
- MSFT_DoRefType(pcx, ptiRet, tiBase.datatype1);
- ptiRet->impltypelist->hRef = tiBase.datatype1;
- break;
- }
- }
- ptiRet->ctCustData=
- MSFT_CustData(pcx, tiBase.oCustData, &ptiRet->pCustData);
-
- TRACE_(typelib)("%s guid: %s kind:%s\n",
- debugstr_w(ptiRet->Name),
- debugstr_guid(&ptiRet->TypeAttr.guid),
- typekind_desc[ptiRet->TypeAttr.typekind]);
-
- return ptiRet;
-}
-
-/* Because type library parsing has some degree of overhead, and some apps repeatedly load the same
- * typelibs over and over, we cache them here. According to MSDN Microsoft have a similar scheme in
- * place. This will cause a deliberate memory leak, but generally losing RAM for cycles is an acceptable
- * tradeoff here.
- */
-static ITypeLibImpl *tlb_cache_first;
-static CRITICAL_SECTION cache_section;
-static CRITICAL_SECTION_DEBUG cache_section_debug =
-{
- 0, 0, &cache_section,
- { &cache_section_debug.ProcessLocksList, &cache_section_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": typelib loader cache") }
-};
-static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };
-
-
-/****************************************************************************
- * TLB_ReadTypeLib
- *
- * find the type of the typelib file and map the typelib resource into
- * the memory
- */
-#define MSFT_SIGNATURE 0x5446534D /* "MSFT" */
-#define SLTG_SIGNATURE 0x47544c53 /* "SLTG" */
-int TLB_ReadTypeLib(LPCWSTR pszFileName, INT index, ITypeLib2 **ppTypeLib)
-{
- ITypeLibImpl *entry;
- int ret = TYPE_E_CANTLOADLIBRARY;
- DWORD dwSignature = 0;
- HANDLE hFile;
-
- TRACE_(typelib)("%s:%d\n", debugstr_w(pszFileName), index);
-
- *ppTypeLib = NULL;
-
- /* We look the path up in the typelib cache. If found, we just addref it, and return the pointer. */
- EnterCriticalSection(&cache_section);
- for (entry = tlb_cache_first; entry != NULL; entry = entry->next)
- {
- if (!strcmpiW(entry->path, pszFileName) && entry->index == index)
- {
- TRACE("cache hit\n");
- *ppTypeLib = (ITypeLib2*)entry;
- ITypeLib_AddRef(*ppTypeLib);
- LeaveCriticalSection(&cache_section);
- return S_OK;
- }
- }
- LeaveCriticalSection(&cache_section);
-
- /* check the signature of the file */
- hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
- if (INVALID_HANDLE_VALUE != hFile)
- {
- HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
- if (hMapping)
- {
- LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
- if(pBase)
- {
- /* retrieve file size */
- DWORD dwTLBLength = GetFileSize(hFile, NULL);
-
- /* first try to load as *.tlb */
- dwSignature = FromLEDWord(*((DWORD*) pBase));
- if ( dwSignature == MSFT_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
- }
- else if ( dwSignature == SLTG_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
- }
- UnmapViewOfFile(pBase);
- }
- CloseHandle(hMapping);
- }
- CloseHandle(hFile);
- }
- else
- {
- TRACE("not found, trying to load %s as library\n", debugstr_w(pszFileName));
- }
-
- /* if the file is a DLL or not found, try loading it with LoadLibrary */
- if (((WORD)dwSignature == IMAGE_DOS_SIGNATURE) || (dwSignature == 0))
- {
- /* find the typelibrary resource*/
- HINSTANCE hinstDLL = LoadLibraryExW(pszFileName, 0, DONT_RESOLVE_DLL_REFERENCES|
- LOAD_LIBRARY_AS_DATAFILE|LOAD_WITH_ALTERED_SEARCH_PATH);
- if (hinstDLL)
- {
- static const WCHAR TYPELIBW[] = {'T','Y','P','E','L','I','B',0};
- HRSRC hrsrc = FindResourceW(hinstDLL, MAKEINTRESOURCEW(index), TYPELIBW);
- if (hrsrc)
- {
- HGLOBAL hGlobal = LoadResource(hinstDLL, hrsrc);
- if (hGlobal)
- {
- LPVOID pBase = LockResource(hGlobal);
- DWORD dwTLBLength = SizeofResource(hinstDLL, hrsrc);
-
- if (pBase)
- {
- /* try to load as incore resource */
- dwSignature = FromLEDWord(*((DWORD*) pBase));
- if ( dwSignature == MSFT_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
- }
- else if ( dwSignature == SLTG_SIGNATURE)
- {
- *ppTypeLib = ITypeLib2_Constructor_SLTG(pBase, dwTLBLength);
- }
- else
- {
- FIXME("Header type magic 0x%08lx not supported.\n",dwSignature);
- }
- }
- FreeResource( hGlobal );
- }
- }
- FreeLibrary(hinstDLL);
- }
- }
-
- if(*ppTypeLib) {
- ITypeLibImpl *impl = (ITypeLibImpl*)*ppTypeLib;
-
- TRACE("adding to cache\n");
- impl->path = HeapAlloc(GetProcessHeap(), 0, (strlenW(pszFileName)+1) * sizeof(WCHAR));
- lstrcpyW(impl->path, pszFileName);
- /* We should really canonicalise the path here. */
- impl->index = index;
-
- /* FIXME: check if it has added already in the meantime */
- EnterCriticalSection(&cache_section);
- if ((impl->next = tlb_cache_first) != NULL) impl->next->prev = impl;
- impl->prev = NULL;
- tlb_cache_first = impl;
- LeaveCriticalSection(&cache_section);
- ret = S_OK;
- } else
- ERR("Loading of typelib %s failed with error %ld\n", debugstr_w(pszFileName), GetLastError());
-
- return ret;
-}
-
-/*================== ITypeLib(2) Methods ===================================*/
-
-/****************************************************************************
- * ITypeLib2_Constructor_MSFT
- *
- * loading an MSFT typelib from an in-memory image
- */
-static ITypeLib2* ITypeLib2_Constructor_MSFT(LPVOID pLib, DWORD dwTLBLength)
-{
- TLBContext cx;
- long lPSegDir;
- MSFT_Header tlbHeader;
- MSFT_SegDir tlbSegDir;
- ITypeLibImpl * pTypeLibImpl;
-
- TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
-
- pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
- if (!pTypeLibImpl) return NULL;
-
- pTypeLibImpl->lpVtbl = &tlbvt;
- pTypeLibImpl->lpVtblTypeComp = &tlbtcvt;
- pTypeLibImpl->ref = 1;
-
- /* get pointer to beginning of typelib data */
- cx.pos = 0;
- cx.oStart=0;
- cx.mapping = pLib;
- cx.pLibInfo = pTypeLibImpl;
- cx.length = dwTLBLength;
-
- /* read header */
- MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
- TRACE("header:\n");
- TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
- if (tlbHeader.magic1 != MSFT_SIGNATURE) {
- FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
- return NULL;
- }
- /* there is a small amount of information here until the next important
- * part:
- * the segment directory . Try to calculate the amount of data */
- lPSegDir = sizeof(tlbHeader) + (tlbHeader.nrtypeinfos)*4 + ((tlbHeader.varflags & HELPDLLFLAG)? 4 :0);
-
- /* now read the segment directory */
- TRACE("read segment directory (at %ld)\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);
- HeapFree(GetProcessHeap(),0,pTypeLibImpl);
- return NULL;
- }
-
- /* now fill our internal data */
- /* 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.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 */
-
- /* name, eventually add to a hash table */
- pTypeLibImpl->Name = MSFT_ReadName(&cx, tlbHeader.NameOffset);
-
- /* help info */
- pTypeLibImpl->DocString = MSFT_ReadString(&cx, tlbHeader.helpstring);
- pTypeLibImpl->HelpFile = MSFT_ReadString(&cx, tlbHeader.helpfile);
-
- if( tlbHeader.varflags & HELPDLLFLAG)
- {
- int offset;
- MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
- pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
- }
-
- pTypeLibImpl->dwHelpContext = tlbHeader.helpstringcontext;
-
- /* custom data */
- if(tlbHeader.CustomDataOffset >= 0)
- {
- pTypeLibImpl->ctCustData = MSFT_CustData(&cx, tlbHeader.CustomDataOffset, &pTypeLibImpl->pCustData);
- }
-
- /* fill in typedescriptions */
- if(tlbSegDir.pTypdescTab.length > 0)
- {
- int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
- INT16 td[4];
- pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
- MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
- for(i=0; i<cTD; )
- {
- /* FIXME: add several sanity checks here */
- pTypeLibImpl->pTypeDesc[i].vt = td[0] & VT_TYPEMASK;
- if(td[0] == VT_PTR || td[0] == VT_SAFEARRAY)
- {
- /* FIXME: check safearray */
- if(td[3] < 0)
- pTypeLibImpl->pTypeDesc[i].u.lptdesc= & stndTypeDesc[td[2]];
- else
- pTypeLibImpl->pTypeDesc[i].u.lptdesc= & pTypeLibImpl->pTypeDesc[td[2]/8];
- }
- else if(td[0] == VT_CARRAY)
- {
- /* array descr table here */
- pTypeLibImpl->pTypeDesc[i].u.lpadesc = (void *)((int) td[2]); /* temp store offset in*/
- }
- else if(td[0] == VT_USERDEFINED)
- {
- pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]);
- }
- if(++i<cTD) MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
- }
-
- /* second time around to fill the array subscript info */
- for(i=0;i<cTD;i++)
- {
- 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);
- 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->cDims = td[2];
-
- for(j = 0; j<td[2]; j++)
- {
- MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
- sizeof(INT), &cx, DO_NOT_SEEK);
- MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
- sizeof(INT), &cx, DO_NOT_SEEK);
- }
- }
- else
- {
- pTypeLibImpl->pTypeDesc[i].u.lpadesc = NULL;
- ERR("didn't find array description data\n");
- }
- }
- }
-
- /* imported type libs */
- if(tlbSegDir.pImpFiles.offset>0)
- {
- TLBImpLib **ppImpLib = &(pTypeLibImpl->pImpLibs);
- int oGuid, offset = tlbSegDir.pImpFiles.offset;
- UINT16 size;
-
- while(offset < tlbSegDir.pImpFiles.offset +tlbSegDir.pImpFiles.length)
- {
- char *name;
- DWORD len;
-
- *ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
- (*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
- MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
-
- MSFT_ReadLEDWords(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
- MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
- MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
- MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
-
- size >>= 2;
- name = TLB_Alloc(size+1);
- MSFT_Read(name, size, &cx, DO_NOT_SEEK);
- len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0 );
- (*ppImpLib)->name = TLB_Alloc(len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, name, -1, (*ppImpLib)->name, len );
- TLB_Free(name);
-
- MSFT_ReadGuid(&(*ppImpLib)->guid, oGuid, &cx);
- offset = (offset + sizeof(INT) + sizeof(DWORD) + sizeof(LCID) + sizeof(UINT16) + size + 3) & ~3;
-
- ppImpLib = &(*ppImpLib)->next;
- }
- }
-
- /* type info's */
- if(tlbHeader.nrtypeinfos >= 0 )
- {
- /*pTypeLibImpl->TypeInfoCount=tlbHeader.nrtypeinfos; */
- ITypeInfoImpl **ppTI = &(pTypeLibImpl->pTypeInfo);
- int i;
-
- for(i = 0; i<(int)tlbHeader.nrtypeinfos; i++)
- {
- *ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
-
- ppTI = &((*ppTI)->next);
- (pTypeLibImpl->TypeInfoCount)++;
- }
- }
-
- TRACE("(%p)\n", pTypeLibImpl);
- return (ITypeLib2*) pTypeLibImpl;
-}
-
-
-static BSTR TLB_MultiByteToBSTR(char *ptr)
-{
- DWORD len;
- WCHAR *nameW;
- BSTR ret;
-
- len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0);
- nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- MultiByteToWideChar(CP_ACP, 0, ptr, -1, nameW, len);
- ret = SysAllocString(nameW);
- HeapFree(GetProcessHeap(), 0, nameW);
- return ret;
-}
-
-static BOOL TLB_GUIDFromString(char *str, GUID *guid)
-{
- char b[3];
- int i;
- short s;
-
- if(sscanf(str, "%lx-%hx-%hx-%hx", &guid->Data1, &guid->Data2, &guid->Data3, &s) != 4) {
- FIXME("Can't parse guid %s\n", debugstr_guid(guid));
- return FALSE;
- }
-
- guid->Data4[0] = s >> 8;
- guid->Data4[1] = s & 0xff;
-
- b[2] = '\0';
- for(i = 0; i < 6; i++) {
- memcpy(b, str + 24 + 2 * i, 2);
- guid->Data4[i + 2] = strtol(b, NULL, 16);
- }
- return TRUE;
-}
-
-static WORD SLTG_ReadString(char *ptr, BSTR *pBstr)
-{
- WORD bytelen;
- DWORD len;
- WCHAR *nameW;
-
- *pBstr = NULL;
- bytelen = *(WORD*)ptr;
- if(bytelen == 0xffff) return 2;
- len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, NULL, 0);
- nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- len = MultiByteToWideChar(CP_ACP, 0, ptr + 2, bytelen, nameW, len);
- *pBstr = SysAllocStringLen(nameW, len);
- HeapFree(GetProcessHeap(), 0, nameW);
- return bytelen + 2;
-}
-
-static WORD SLTG_ReadStringA(char *ptr, char **str)
-{
- WORD bytelen;
-
- *str = NULL;
- bytelen = *(WORD*)ptr;
- if(bytelen == 0xffff) return 2;
- *str = HeapAlloc(GetProcessHeap(), 0, bytelen + 1);
- memcpy(*str, ptr + 2, bytelen);
- (*str)[bytelen] = '\0';
- return bytelen + 2;
-}
-
-static DWORD SLTG_ReadLibBlk(LPVOID pLibBlk, ITypeLibImpl *pTypeLibImpl)
-{
- char *ptr = pLibBlk;
- WORD w;
-
- if((w = *(WORD*)ptr) != SLTG_LIBBLK_MAGIC) {
- FIXME("libblk magic = %04x\n", w);
- return 0;
- }
-
- ptr += 6;
- if((w = *(WORD*)ptr) != 0xffff) {
- FIXME("LibBlk.res06 = %04x. Assumung string and skipping\n", w);
- ptr += w;
- }
- ptr += 2;
-
- ptr += SLTG_ReadString(ptr, &pTypeLibImpl->DocString);
-
- ptr += SLTG_ReadString(ptr, &pTypeLibImpl->HelpFile);
-
- pTypeLibImpl->dwHelpContext = *(DWORD*)ptr;
- ptr += 4;
-
- pTypeLibImpl->LibAttr.syskind = *(WORD*)ptr;
- ptr += 2;
-
- if(SUBLANGID(*(WORD*)ptr) == SUBLANG_NEUTRAL)
- pTypeLibImpl->LibAttr.lcid = MAKELCID(MAKELANGID(PRIMARYLANGID(*(WORD*)ptr),0),0);
- else
- pTypeLibImpl->LibAttr.lcid = 0;
- ptr += 2;
-
- ptr += 4; /* skip res12 */
-
- pTypeLibImpl->LibAttr.wLibFlags = *(WORD*)ptr;
- ptr += 2;
-
- pTypeLibImpl->LibAttr.wMajorVerNum = *(WORD*)ptr;
- ptr += 2;
-
- pTypeLibImpl->LibAttr.wMinorVerNum = *(WORD*)ptr;
- ptr += 2;
-
- memcpy(&pTypeLibImpl->LibAttr.guid, ptr, sizeof(GUID));
- ptr += sizeof(GUID);
-
- return ptr - (char*)pLibBlk;
-}
-
-static WORD *SLTG_DoType(WORD *pType, char *pBlk, ELEMDESC *pElem)
-{
- BOOL done = FALSE;
- TYPEDESC *pTD = &pElem->tdesc;
-
- /* Handle [in/out] first */
- if((*pType & 0xc000) == 0xc000)
- pElem->u.paramdesc.wParamFlags = PARAMFLAG_NONE;
- else if(*pType & 0x8000)
- pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN | PARAMFLAG_FOUT;
- else if(*pType & 0x4000)
- pElem->u.paramdesc.wParamFlags = PARAMFLAG_FOUT;
- else
- pElem->u.paramdesc.wParamFlags = PARAMFLAG_FIN;
-
- if(*pType & 0x2000)
- pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FLCID;
-
- if(*pType & 0x80)
- pElem->u.paramdesc.wParamFlags |= PARAMFLAG_FRETVAL;
-
- while(!done) {
- if((*pType & 0xe00) == 0xe00) {
- pTD->vt = VT_PTR;
- pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(TYPEDESC));
- pTD = pTD->u.lptdesc;
- }
- switch(*pType & 0x7f) {
- case VT_PTR:
- pTD->vt = VT_PTR;
- pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(TYPEDESC));
- pTD = pTD->u.lptdesc;
- break;
-
- case VT_USERDEFINED:
- pTD->vt = VT_USERDEFINED;
- pTD->u.hreftype = *(++pType) / 4;
- done = TRUE;
- break;
-
- case VT_CARRAY:
- {
- /* *(pType+1) is offset to a SAFEARRAY, *(pType+2) is type of
- array */
-
- SAFEARRAY *pSA = (SAFEARRAY *)(pBlk + *(++pType));
-
- pTD->vt = VT_CARRAY;
- pTD->u.lpadesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(ARRAYDESC) +
- (pSA->cDims - 1) * sizeof(SAFEARRAYBOUND));
- pTD->u.lpadesc->cDims = pSA->cDims;
- memcpy(pTD->u.lpadesc->rgbounds, pSA->rgsabound,
- pSA->cDims * sizeof(SAFEARRAYBOUND));
-
- pTD = &pTD->u.lpadesc->tdescElem;
- break;
- }
-
- case VT_SAFEARRAY:
- {
- /* FIXME: *(pType+1) gives an offset to SAFEARRAY, is this
- useful? */
-
- pType++;
- pTD->vt = VT_SAFEARRAY;
- pTD->u.lptdesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(TYPEDESC));
- pTD = pTD->u.lptdesc;
- break;
- }
- default:
- pTD->vt = *pType & 0x7f;
- done = TRUE;
- break;
- }
- pType++;
- }
- return pType;
-}
-
-
-static void SLTG_DoRefs(SLTG_RefInfo *pRef, ITypeInfoImpl *pTI,
- char *pNameTable)
-{
- int ref;
- char *name;
- TLBRefType **ppRefType;
-
- if(pRef->magic != SLTG_REF_MAGIC) {
- FIXME("Ref magic = %x\n", pRef->magic);
- return;
- }
- name = ( (char*)(&pRef->names) + pRef->number);
-
- ppRefType = &pTI->reflist;
- for(ref = 0; ref < pRef->number >> 3; ref++) {
- char *refname;
- unsigned int lib_offs, type_num;
-
- *ppRefType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppRefType));
-
- name += SLTG_ReadStringA(name, &refname);
- if(sscanf(refname, "*\\R%x*#%x", &lib_offs, &type_num) != 2)
- FIXME("Can't sscanf ref\n");
- if(lib_offs != 0xffff) {
- TLBImpLib **import = &pTI->pTypeLib->pImpLibs;
-
- while(*import) {
- if((*import)->offset == lib_offs)
- break;
- import = &(*import)->next;
- }
- if(!*import) {
- char fname[MAX_PATH+1];
- int len;
-
- *import = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**import));
- (*import)->offset = lib_offs;
- TLB_GUIDFromString( pNameTable + lib_offs + 4,
- &(*import)->guid);
- if(sscanf(pNameTable + lib_offs + 40, "}#%hd.%hd#%lx#%s",
- &(*import)->wVersionMajor,
- &(*import)->wVersionMinor,
- &(*import)->lcid, fname) != 4) {
- FIXME("can't sscanf ref %s\n",
- pNameTable + lib_offs + 40);
- }
- len = strlen(fname);
- if(fname[len-1] != '#')
- FIXME("fname = %s\n", fname);
- fname[len-1] = '\0';
- (*import)->name = TLB_MultiByteToBSTR(fname);
- }
- (*ppRefType)->pImpTLInfo = *import;
- } else { /* internal ref */
- (*ppRefType)->pImpTLInfo = TLB_REF_INTERNAL;
- }
- (*ppRefType)->reference = ref;
- (*ppRefType)->index = type_num;
-
- HeapFree(GetProcessHeap(), 0, refname);
- ppRefType = &(*ppRefType)->next;
- }
- if((BYTE)*name != SLTG_REF_MAGIC)
- FIXME("End of ref block magic = %x\n", *name);
- dump_TLBRefType(pTI->reflist);
-}
-
-static char *SLTG_DoImpls(char *pBlk, ITypeInfoImpl *pTI,
- BOOL OneOnly)
-{
- SLTG_ImplInfo *info;
- TLBImplType **ppImplType = &pTI->impltypelist;
- /* I don't really get this structure, usually it's 0x16 bytes
- long, but iuser.tlb contains some that are 0x18 bytes long.
- That's ok because we can use the next ptr to jump to the next
- one. But how do we know the length of the last one? The WORD
- at offs 0x8 might be the clue. For now I'm just assuming that
- the last one is the regular 0x16 bytes. */
-
- info = (SLTG_ImplInfo*)pBlk;
- while(1) {
- *ppImplType = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppImplType));
- (*ppImplType)->hRef = info->ref;
- (*ppImplType)->implflags = info->impltypeflags;
- pTI->TypeAttr.cImplTypes++;
- ppImplType = &(*ppImplType)->next;
-
- if(info->next == 0xffff)
- break;
- if(OneOnly)
- FIXME("Interface inheriting more than one interface\n");
- info = (SLTG_ImplInfo*)(pBlk + info->next);
- }
- info++; /* see comment at top of function */
- return (char*)info;
-}
-
-static SLTG_TypeInfoTail *SLTG_ProcessCoClass(char *pBlk, ITypeInfoImpl *pTI,
- char *pNameTable)
-{
- SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
- SLTG_MemberHeader *pMemHeader;
- char *pFirstItem, *pNextItem;
-
- if(pTIHeader->href_table != 0xffffffff) {
- SLTG_DoRefs((SLTG_RefInfo*)(pBlk + pTIHeader->href_table), pTI,
- pNameTable);
- }
-
-
- pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
-
- pFirstItem = pNextItem = (char*)(pMemHeader + 1);
-
- if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
- pNextItem = SLTG_DoImpls(pFirstItem, pTI, FALSE);
- }
-
- return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
-}
-
-
-static SLTG_TypeInfoTail *SLTG_ProcessInterface(char *pBlk, ITypeInfoImpl *pTI,
- char *pNameTable)
-{
- SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
- SLTG_MemberHeader *pMemHeader;
- SLTG_Function *pFunc;
- char *pFirstItem, *pNextItem;
- TLBFuncDesc **ppFuncDesc = &pTI->funclist;
- int num = 0;
-
- if(pTIHeader->href_table != 0xffffffff) {
- SLTG_DoRefs((SLTG_RefInfo*)(pBlk + pTIHeader->href_table), pTI,
- pNameTable);
- }
-
- pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
-
- pFirstItem = pNextItem = (char*)(pMemHeader + 1);
-
- if(*(WORD*)pFirstItem == SLTG_IMPL_MAGIC) {
- pNextItem = SLTG_DoImpls(pFirstItem, pTI, TRUE);
- }
-
- for(pFunc = (SLTG_Function*)pNextItem, num = 1; 1;
- pFunc = (SLTG_Function*)(pFirstItem + pFunc->next), num++) {
-
- int param;
- WORD *pType, *pArg;
-
- if(pFunc->magic != SLTG_FUNCTION_MAGIC &&
- pFunc->magic != SLTG_FUNCTION_WITH_FLAGS_MAGIC) {
- FIXME("func magic = %02x\n", pFunc->magic);
- return NULL;
- }
- *ppFuncDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppFuncDesc));
- (*ppFuncDesc)->Name = TLB_MultiByteToBSTR(pFunc->name + pNameTable);
-
- (*ppFuncDesc)->funcdesc.memid = pFunc->dispid;
- (*ppFuncDesc)->funcdesc.invkind = pFunc->inv >> 4;
- (*ppFuncDesc)->funcdesc.callconv = pFunc->nacc & 0x7;
- (*ppFuncDesc)->funcdesc.cParams = pFunc->nacc >> 3;
- (*ppFuncDesc)->funcdesc.cParamsOpt = (pFunc->retnextopt & 0x7e) >> 1;
- (*ppFuncDesc)->funcdesc.oVft = pFunc->vtblpos;
-
- if(pFunc->magic == SLTG_FUNCTION_WITH_FLAGS_MAGIC)
- (*ppFuncDesc)->funcdesc.wFuncFlags = pFunc->funcflags;
-
- if(pFunc->retnextopt & 0x80)
- pType = &pFunc->rettype;
- else
- pType = (WORD*)(pFirstItem + pFunc->rettype);
-
-
- SLTG_DoType(pType, pFirstItem, &(*ppFuncDesc)->funcdesc.elemdescFunc);
-
- (*ppFuncDesc)->funcdesc.lprgelemdescParam =
- HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- (*ppFuncDesc)->funcdesc.cParams * sizeof(ELEMDESC));
- (*ppFuncDesc)->pParamDesc =
- HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- (*ppFuncDesc)->funcdesc.cParams * sizeof(TLBParDesc));
-
- pArg = (WORD*)(pFirstItem + pFunc->arg_off);
-
- for(param = 0; param < (*ppFuncDesc)->funcdesc.cParams; param++) {
- char *paramName = pNameTable + *pArg;
- BOOL HaveOffs;
- /* If arg type follows then paramName points to the 2nd
- letter of the name, else the next WORD is an offset to
- the arg type and paramName points to the first letter.
- So let's take one char off paramName and see if we're
- pointing at an alpha-numeric char. However if *pArg is
- 0xffff or 0xfffe then the param has no name, the former
- meaning that the next WORD is the type, the latter
- meaning the the next WORD is an offset to the type. */
-
- HaveOffs = FALSE;
- if(*pArg == 0xffff)
- paramName = NULL;
- else if(*pArg == 0xfffe) {
- paramName = NULL;
- HaveOffs = TRUE;
- }
- else if(paramName[-1] && !isalnum(paramName[-1]))
- HaveOffs = TRUE;
-
- pArg++;
-
- if(HaveOffs) { /* the next word is an offset to type */
- pType = (WORD*)(pFirstItem + *pArg);
- SLTG_DoType(pType, pFirstItem,
- &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]);
- pArg++;
- } else {
- if(paramName)
- paramName--;
- pArg = SLTG_DoType(pArg, pFirstItem,
- &(*ppFuncDesc)->funcdesc.lprgelemdescParam[param]);
- }
-
- /* Are we an optional param ? */
- if((*ppFuncDesc)->funcdesc.cParams - param <=
- (*ppFuncDesc)->funcdesc.cParamsOpt)
- (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].u.paramdesc.wParamFlags |= PARAMFLAG_FOPT;
-
- if(paramName) {
- (*ppFuncDesc)->pParamDesc[param].Name =
- TLB_MultiByteToBSTR(paramName);
- }
- }
-
- ppFuncDesc = &((*ppFuncDesc)->next);
- if(pFunc->next == 0xffff) break;
- }
- pTI->TypeAttr.cFuncs = num;
- if (TRACE_ON(typelib))
- dump_TLBFuncDesc(pTI->funclist);
- return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
-}
-
-static SLTG_TypeInfoTail *SLTG_ProcessRecord(char *pBlk, ITypeInfoImpl *pTI,
- char *pNameTable)
-{
- SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
- SLTG_MemberHeader *pMemHeader;
- SLTG_RecordItem *pItem;
- char *pFirstItem;
- TLBVarDesc **ppVarDesc = &pTI->varlist;
- int num = 0;
- WORD *pType;
- char buf[300];
-
- pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
-
- pFirstItem = (char*)(pMemHeader + 1);
- for(pItem = (SLTG_RecordItem *)pFirstItem, num = 1; 1;
- pItem = (SLTG_RecordItem *)(pFirstItem + pItem->next), num++) {
- if(pItem->magic != SLTG_RECORD_MAGIC) {
- FIXME("record magic = %02x\n", pItem->magic);
- return NULL;
- }
- *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppVarDesc));
- (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable);
- (*ppVarDesc)->vardesc.memid = pItem->memid;
- (*ppVarDesc)->vardesc.u.oInst = pItem->byte_offs;
- (*ppVarDesc)->vardesc.varkind = VAR_PERINSTANCE;
-
- if(pItem->typepos == 0x02)
- pType = &pItem->type;
- else if(pItem->typepos == 0x00)
- pType = (WORD*)(pFirstItem + pItem->type);
- else {
- FIXME("typepos = %02x\n", pItem->typepos);
- break;
- }
-
- SLTG_DoType(pType, pFirstItem,
- &(*ppVarDesc)->vardesc.elemdescVar);
-
- /* FIXME("helpcontext, helpstring\n"); */
-
- dump_TypeDesc(&(*ppVarDesc)->vardesc.elemdescVar.tdesc, buf);
-
- ppVarDesc = &((*ppVarDesc)->next);
- if(pItem->next == 0xffff) break;
- }
- pTI->TypeAttr.cVars = num;
- 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)
-{
- SLTG_TypeInfoHeader *pTIHeader = (SLTG_TypeInfoHeader*)pBlk;
- SLTG_MemberHeader *pMemHeader;
- SLTG_EnumItem *pItem;
- char *pFirstItem;
- TLBVarDesc **ppVarDesc = &pTI->varlist;
- int num = 0;
-
- pMemHeader = (SLTG_MemberHeader*)(pBlk + pTIHeader->elem_table);
-
- pFirstItem = (char*)(pMemHeader + 1);
- for(pItem = (SLTG_EnumItem *)pFirstItem, num = 1; 1;
- pItem = (SLTG_EnumItem *)(pFirstItem + pItem->next), num++) {
- if(pItem->magic != SLTG_ENUMITEM_MAGIC) {
- FIXME("enumitem magic = %04x\n", pItem->magic);
- return NULL;
- }
- *ppVarDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(**ppVarDesc));
- (*ppVarDesc)->Name = TLB_MultiByteToBSTR(pItem->name + pNameTable);
- (*ppVarDesc)->vardesc.memid = pItem->memid;
- (*ppVarDesc)->vardesc.u.lpvarValue = HeapAlloc(GetProcessHeap(), 0,
- sizeof(VARIANT));
- V_VT((*ppVarDesc)->vardesc.u.lpvarValue) = VT_INT;
- V_UNION((*ppVarDesc)->vardesc.u.lpvarValue, intVal) =
- *(INT*)(pItem->value + pFirstItem);
- (*ppVarDesc)->vardesc.elemdescVar.tdesc.vt = VT_I4;
- (*ppVarDesc)->vardesc.varkind = VAR_CONST;
- /* FIXME("helpcontext, helpstring\n"); */
-
- ppVarDesc = &((*ppVarDesc)->next);
- if(pItem->next == 0xffff) break;
- }
- pTI->TypeAttr.cVars = num;
- return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
-}
-
-/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
- managable copy of it into this */
-typedef struct {
- WORD small_no;
- char *index_name;
- char *other_name;
- WORD res1a;
- WORD name_offs;
- WORD more_bytes;
- char *extra;
- WORD res20;
- DWORD helpcontext;
- WORD res26;
- GUID uuid;
-} SLTG_InternalOtherTypeInfo;
-
-/****************************************************************************
- * ITypeLib2_Constructor_SLTG
- *
- * loading a SLTG typelib from an in-memory image
- */
-static ITypeLib2* ITypeLib2_Constructor_SLTG(LPVOID pLib, DWORD dwTLBLength)
-{
- ITypeLibImpl *pTypeLibImpl;
- SLTG_Header *pHeader;
- SLTG_BlkEntry *pBlkEntry;
- SLTG_Magic *pMagic;
- SLTG_Index *pIndex;
- SLTG_Pad9 *pPad9;
- LPVOID pBlk, pFirstBlk;
- SLTG_LibBlk *pLibBlk;
- SLTG_InternalOtherTypeInfo *pOtherTypeInfoBlks;
- char *pAfterOTIBlks = NULL;
- char *pNameTable, *ptr;
- int i;
- DWORD len, order;
- ITypeInfoImpl **ppTypeInfoImpl;
-
- TRACE_(typelib)("%p, TLB length = %ld\n", pLib, dwTLBLength);
-
- pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
- if (!pTypeLibImpl) return NULL;
-
- pTypeLibImpl->lpVtbl = &tlbvt;
- pTypeLibImpl->ref = 1;
-
- pHeader = pLib;
-
- TRACE_(typelib)("header:\n");
- TRACE_(typelib)("\tmagic=0x%08lx, file blocks = %d\n", pHeader->SLTG_magic,
- pHeader->nrOfFileBlks );
- if (pHeader->SLTG_magic != SLTG_SIGNATURE) {
- FIXME("Header type magic 0x%08lx not supported.\n",
- pHeader->SLTG_magic);
- return NULL;
- }
-
- /* There are pHeader->nrOfFileBlks - 2 TypeInfo records in this typelib */
- pTypeLibImpl->TypeInfoCount = pHeader->nrOfFileBlks - 2;
-
- /* This points to pHeader->nrOfFileBlks - 1 of SLTG_BlkEntry */
- pBlkEntry = (SLTG_BlkEntry*)(pHeader + 1);
-
- /* Next we have a magic block */
- pMagic = (SLTG_Magic*)(pBlkEntry + pHeader->nrOfFileBlks - 1);
-
- /* Let's see if we're still in sync */
- if(memcmp(pMagic->CompObj_magic, SLTG_COMPOBJ_MAGIC,
- sizeof(SLTG_COMPOBJ_MAGIC))) {
- FIXME("CompObj magic = %s\n", pMagic->CompObj_magic);
- return NULL;
- }
- if(memcmp(pMagic->dir_magic, SLTG_DIR_MAGIC,
- sizeof(SLTG_DIR_MAGIC))) {
- FIXME("dir magic = %s\n", pMagic->dir_magic);
- return NULL;
- }
-
- pIndex = (SLTG_Index*)(pMagic+1);
-
- pPad9 = (SLTG_Pad9*)(pIndex + pTypeLibImpl->TypeInfoCount);
-
- pFirstBlk = (LPVOID)(pPad9 + 1);
-
- /* We'll set up a ptr to the main library block, which is the last one. */
-
- for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
- pBlkEntry[order].next != 0;
- order = pBlkEntry[order].next - 1, i++) {
- pBlk = (char*)pBlk + pBlkEntry[order].len;
- }
- pLibBlk = pBlk;
-
- len = SLTG_ReadLibBlk(pLibBlk, pTypeLibImpl);
-
- /* Now there's 0x40 bytes of 0xffff with the numbers 0 to TypeInfoCount
- interspersed */
-
- len += 0x40;
-
- /* And now TypeInfoCount of SLTG_OtherTypeInfo */
-
- pOtherTypeInfoBlks = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- sizeof(*pOtherTypeInfoBlks) *
- pTypeLibImpl->TypeInfoCount);
-
-
- ptr = (char*)pLibBlk + len;
-
- for(i = 0; i < pTypeLibImpl->TypeInfoCount; i++) {
- WORD w, extra;
- len = 0;
-
- pOtherTypeInfoBlks[i].small_no = *(WORD*)ptr;
-
- w = *(WORD*)(ptr + 2);
- if(w != 0xffff) {
- len += w;
- pOtherTypeInfoBlks[i].index_name = HeapAlloc(GetProcessHeap(),0,
- w+1);
- memcpy(pOtherTypeInfoBlks[i].index_name, ptr + 4, w);
- pOtherTypeInfoBlks[i].index_name[w] = '\0';
- }
- w = *(WORD*)(ptr + 4 + len);
- if(w != 0xffff) {
- TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
- len += w;
- pOtherTypeInfoBlks[i].other_name = HeapAlloc(GetProcessHeap(),0,
- w+1);
- memcpy(pOtherTypeInfoBlks[i].other_name, ptr + 6 + len, w);
- pOtherTypeInfoBlks[i].other_name[w] = '\0';
- }
- pOtherTypeInfoBlks[i].res1a = *(WORD*)(ptr + len + 6);
- pOtherTypeInfoBlks[i].name_offs = *(WORD*)(ptr + len + 8);
- extra = pOtherTypeInfoBlks[i].more_bytes = *(WORD*)(ptr + 10 + len);
- if(extra) {
- pOtherTypeInfoBlks[i].extra = HeapAlloc(GetProcessHeap(),0,
- extra);
- memcpy(pOtherTypeInfoBlks[i].extra, ptr + 12, extra);
- len += extra;
- }
- pOtherTypeInfoBlks[i].res20 = *(WORD*)(ptr + 12 + len);
- pOtherTypeInfoBlks[i].helpcontext = *(DWORD*)(ptr + 14 + len);
- pOtherTypeInfoBlks[i].res26 = *(WORD*)(ptr + 18 + len);
- memcpy(&pOtherTypeInfoBlks[i].uuid, ptr + 20 + len, sizeof(GUID));
- len += sizeof(SLTG_OtherTypeInfo);
- ptr += len;
- }
-
- pAfterOTIBlks = ptr;
-
- /* Skip this WORD and get the next DWORD */
- len = *(DWORD*)(pAfterOTIBlks + 2);
-
- /* Now add this to pLibBLk look at what we're pointing at and
- possibly add 0x20, then add 0x216, sprinkle a bit a magic
- dust and we should be pointing at the beginning of the name
- table */
-
- pNameTable = (char*)pLibBlk + len;
-
- switch(*(WORD*)pNameTable) {
- case 0xffff:
- break;
- case 0x0200:
- pNameTable += 0x20;
- break;
- default:
- FIXME("pNameTable jump = %x\n", *(WORD*)pNameTable);
- break;
- }
-
- pNameTable += 0x216;
-
- pNameTable += 2;
-
- TRACE("Library name is %s\n", pNameTable + pLibBlk->name);
-
- pTypeLibImpl->Name = TLB_MultiByteToBSTR(pNameTable + pLibBlk->name);
-
-
- /* Hopefully we now have enough ptrs set up to actually read in
- some TypeInfos. It's not clear which order to do them in, so
- I'll just follow the links along the BlkEntry chain and read
- them in in the order in which they're in the file */
-
- ppTypeInfoImpl = &(pTypeLibImpl->pTypeInfo);
-
- for(pBlk = pFirstBlk, order = pHeader->first_blk - 1, i = 0;
- pBlkEntry[order].next != 0;
- order = pBlkEntry[order].next - 1, i++) {
-
- SLTG_TypeInfoHeader *pTIHeader;
- SLTG_TypeInfoTail *pTITail;
-
- if(strcmp(pBlkEntry[order].index_string + (char*)pMagic,
- pOtherTypeInfoBlks[i].index_name)) {
- FIXME("Index strings don't match\n");
- return NULL;
- }
-
- pTIHeader = pBlk;
- if(pTIHeader->magic != SLTG_TIHEADER_MAGIC) {
- FIXME("TypeInfoHeader magic = %04x\n", pTIHeader->magic);
- return NULL;
- }
- *ppTypeInfoImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
- (*ppTypeInfoImpl)->pTypeLib = pTypeLibImpl;
- (*ppTypeInfoImpl)->index = i;
- (*ppTypeInfoImpl)->Name = TLB_MultiByteToBSTR(
- pOtherTypeInfoBlks[i].name_offs +
- pNameTable);
- (*ppTypeInfoImpl)->dwHelpContext = pOtherTypeInfoBlks[i].helpcontext;
- memcpy(&((*ppTypeInfoImpl)->TypeAttr.guid), &pOtherTypeInfoBlks[i].uuid,
- sizeof(GUID));
- (*ppTypeInfoImpl)->TypeAttr.typekind = pTIHeader->typekind;
- (*ppTypeInfoImpl)->TypeAttr.wMajorVerNum = pTIHeader->major_version;
- (*ppTypeInfoImpl)->TypeAttr.wMinorVerNum = pTIHeader->minor_version;
- (*ppTypeInfoImpl)->TypeAttr.wTypeFlags =
- (pTIHeader->typeflags1 >> 3) | (pTIHeader->typeflags2 << 5);
-
- if((pTIHeader->typeflags1 & 7) != 2)
- FIXME("typeflags1 = %02x\n", pTIHeader->typeflags1);
- if(pTIHeader->typeflags3 != 2)
- FIXME("typeflags3 = %02x\n", pTIHeader->typeflags3);
-
- TRACE("TypeInfo %s of kind %s guid %s typeflags %04x\n",
- debugstr_w((*ppTypeInfoImpl)->Name),
- typekind_desc[pTIHeader->typekind],
- debugstr_guid(&(*ppTypeInfoImpl)->TypeAttr.guid),
- (*ppTypeInfoImpl)->TypeAttr.wTypeFlags);
-
- switch(pTIHeader->typekind) {
- case TKIND_ENUM:
- pTITail = SLTG_ProcessEnum(pBlk, *ppTypeInfoImpl, pNameTable);
- break;
-
- case TKIND_RECORD:
- pTITail = SLTG_ProcessRecord(pBlk, *ppTypeInfoImpl, pNameTable);
- break;
-
- case TKIND_INTERFACE:
- pTITail = SLTG_ProcessInterface(pBlk, *ppTypeInfoImpl, pNameTable);
- break;
-
- case TKIND_COCLASS:
- 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;
- break;
-
- }
-
- if(pTITail) { /* could get cFuncs, cVars and cImplTypes from here
- but we've already set those */
- (*ppTypeInfoImpl)->TypeAttr.cbAlignment = pTITail->cbAlignment;
- (*ppTypeInfoImpl)->TypeAttr.cbSizeInstance = pTITail->cbSizeInstance;
- (*ppTypeInfoImpl)->TypeAttr.cbSizeVft = pTITail->cbSizeVft;
-
-#define X(x) TRACE_(typelib)("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;
- }
-
- if(i != pTypeLibImpl->TypeInfoCount) {
- FIXME("Somehow processed %d TypeInfos\n", i);
- return NULL;
- }
-
- HeapFree(GetProcessHeap(), 0, pOtherTypeInfoBlks);
- return (ITypeLib2*)pTypeLibImpl;
-}
-
-/* ITypeLib::QueryInterface
- */
-static HRESULT WINAPI ITypeLib2_fnQueryInterface(
- ITypeLib2 * iface,
- REFIID riid,
- VOID **ppvObject)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
-
- TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
-
- *ppvObject=NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid,&IID_ITypeLib)||
- IsEqualIID(riid,&IID_ITypeLib2))
- {
- *ppvObject = This;
- }
-
- if(*ppvObject)
- {
- ITypeLib2_AddRef(iface);
- TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
- return S_OK;
- }
- TRACE("-- Interface: E_NOINTERFACE\n");
- return E_NOINTERFACE;
-}
-
-/* ITypeLib::AddRef
- */
-static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
-
- TRACE("(%p)->ref was %lu\n",This, ref - 1);
-
- return ref;
-}
-
-/* ITypeLib::Release
- */
-static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(%lu)\n",This, ref);
-
- if (!ref)
- {
- /* remove cache entry */
- TRACE("removing from cache list\n");
- EnterCriticalSection(&cache_section);
- if (This->next) This->next->prev = This->prev;
- if (This->prev) This->prev->next = This->next;
- else tlb_cache_first = This->next;
- LeaveCriticalSection(&cache_section);
-
- /* FIXME destroy child objects */
- TRACE(" destroying ITypeLib(%p)\n",This);
-
- if (This->Name)
- {
- SysFreeString(This->Name);
- This->Name = NULL;
- }
-
- if (This->DocString)
- {
- SysFreeString(This->DocString);
- This->DocString = NULL;
- }
-
- if (This->HelpFile)
- {
- SysFreeString(This->HelpFile);
- This->HelpFile = NULL;
- }
-
- if (This->HelpStringDll)
- {
- SysFreeString(This->HelpStringDll);
- This->HelpStringDll = NULL;
- }
-
- if (This->pTypeInfo) /* can be NULL */
- ITypeInfo_Release((ITypeInfo*) This->pTypeInfo);
- HeapFree(GetProcessHeap(),0,This);
- return 0;
- }
-
- return ref;
-}
-
-/* ITypeLib::GetTypeInfoCount
- *
- * Returns the number of type descriptions in the type library
- */
-static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
- return This->TypeInfoCount;
-}
-
-/* ITypeLib::GetTypeInfo
- *
- * retrieves the specified type description in the library.
- */
-static HRESULT WINAPI ITypeLib2_fnGetTypeInfo(
- ITypeLib2 *iface,
- UINT index,
- ITypeInfo **ppTInfo)
-{
- int i;
-
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
-
- TRACE("(%p)->(index=%d)\n", This, index);
-
- if (!ppTInfo) return E_INVALIDARG;
-
- /* search element n in list */
- for(i=0; i < index; i++)
- {
- pTypeInfo = pTypeInfo->next;
- if (!pTypeInfo)
- {
- TRACE("-- element not found\n");
- return TYPE_E_ELEMENTNOTFOUND;
- }
- }
-
- *ppTInfo = (ITypeInfo *) pTypeInfo;
-
- ITypeInfo_AddRef(*ppTInfo);
- TRACE("-- found (%p)\n",*ppTInfo);
- return S_OK;
-}
-
-
-/* ITypeLibs::GetTypeInfoType
- *
- * Retrieves the type of a type description.
- */
-static HRESULT WINAPI ITypeLib2_fnGetTypeInfoType(
- ITypeLib2 *iface,
- UINT index,
- TYPEKIND *pTKind)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- int i;
- ITypeInfoImpl *pTInfo = This->pTypeInfo;
-
- TRACE("(%p) index %d\n", This, index);
-
- if(!pTKind) return E_INVALIDARG;
-
- /* search element n in list */
- for(i=0; i < index; i++)
- {
- if(!pTInfo)
- {
- TRACE("-- element not found\n");
- return TYPE_E_ELEMENTNOTFOUND;
- }
- pTInfo = pTInfo->next;
- }
-
- *pTKind = pTInfo->TypeAttr.typekind;
- TRACE("-- found Type (%d)\n", *pTKind);
- return S_OK;
-}
-
-/* ITypeLib::GetTypeInfoOfGuid
- *
- * Retrieves the type description that corresponds to the specified GUID.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetTypeInfoOfGuid(
- ITypeLib2 *iface,
- REFGUID guid,
- ITypeInfo **ppTInfo)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */
-
- TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
-
- if (!pTypeInfo)
- {
- WARN("-- element not found\n");
- return TYPE_E_ELEMENTNOTFOUND;
- }
-
- /* search linked list for guid */
- while( !IsEqualIID(guid,&pTypeInfo->TypeAttr.guid) )
- {
- pTypeInfo = pTypeInfo->next;
-
- if (!pTypeInfo)
- {
- /* end of list reached */
- WARN("-- element not found\n");
- return TYPE_E_ELEMENTNOTFOUND;
- }
- }
-
- TRACE("-- found (%p, %s)\n",
- pTypeInfo,
- debugstr_w(pTypeInfo->Name));
-
- *ppTInfo = (ITypeInfo*)pTypeInfo;
- ITypeInfo_AddRef(*ppTInfo);
- return S_OK;
-}
-
-/* ITypeLib::GetLibAttr
- *
- * Retrieves the structure that contains the library's attributes.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetLibAttr(
- ITypeLib2 *iface,
- LPTLIBATTR *ppTLibAttr)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- TRACE("(%p)\n",This);
- *ppTLibAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppTLibAttr));
- memcpy(*ppTLibAttr, &This->LibAttr, sizeof(**ppTLibAttr));
- return S_OK;
-}
-
-/* ITypeLib::GetTypeComp
- *
- * Enables a client compiler to bind to a library's types, variables,
- * constants, and global functions.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetTypeComp(
- ITypeLib2 *iface,
- ITypeComp **ppTComp)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
-
- TRACE("(%p)->(%p)\n",This,ppTComp);
- *ppTComp = (ITypeComp *)&This->lpVtblTypeComp;
- ITypeComp_AddRef(*ppTComp);
-
- return S_OK;
-}
-
-/* ITypeLib::GetDocumentation
- *
- * Retrieves the library's documentation string, the complete Help file name
- * and path, and the context identifier for the library Help topic in the Help
- * file.
- *
- * On a successful return all non-null BSTR pointers will have been set,
- * possibly to NULL.
- */
-static HRESULT WINAPI ITypeLib2_fnGetDocumentation(
- ITypeLib2 *iface,
- INT index,
- BSTR *pBstrName,
- BSTR *pBstrDocString,
- DWORD *pdwHelpContext,
- BSTR *pBstrHelpFile)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
-
- HRESULT result = E_INVALIDARG;
-
- ITypeInfo *pTInfo;
-
-
- TRACE("(%p) index %d Name(%p) DocString(%p) HelpContext(%p) HelpFile(%p)\n",
- This, index,
- pBstrName, pBstrDocString,
- pdwHelpContext, pBstrHelpFile);
-
- if(index<0)
- {
- /* documentation for the typelib */
- if(pBstrName)
- {
- if (This->Name)
- {
- if(!(*pBstrName = SysAllocString(This->Name)))
- goto memerr1;
- }
- else
- *pBstrName = NULL;
- }
- if(pBstrDocString)
- {
- if (This->DocString)
- {
- if(!(*pBstrDocString = SysAllocString(This->DocString)))
- goto memerr2;
- }
- else if (This->Name)
- {
- if(!(*pBstrDocString = SysAllocString(This->Name)))
- goto memerr2;
- }
- else
- *pBstrDocString = NULL;
- }
- if(pdwHelpContext)
- {
- *pdwHelpContext = This->dwHelpContext;
- }
- if(pBstrHelpFile)
- {
- if (This->HelpFile)
- {
- if(!(*pBstrHelpFile = SysAllocString(This->HelpFile)))
- goto memerr3;
- }
- else
- *pBstrHelpFile = NULL;
- }
-
- result = S_OK;
- }
- else
- {
- /* for a typeinfo */
- result = ITypeLib2_fnGetTypeInfo(iface, index, &pTInfo);
-
- if(SUCCEEDED(result))
- {
- result = ITypeInfo_GetDocumentation(pTInfo,
- MEMBERID_NIL,
- pBstrName,
- pBstrDocString,
- pdwHelpContext, pBstrHelpFile);
-
- ITypeInfo_Release(pTInfo);
- }
- }
- return result;
-memerr3:
- if (pBstrDocString) SysFreeString (*pBstrDocString);
-memerr2:
- if (pBstrName) SysFreeString (*pBstrName);
-memerr1:
- return STG_E_INSUFFICIENTMEMORY;
-}
-
-/* ITypeLib::IsName
- *
- * Indicates whether a passed-in string contains the name of a type or member
- * described in the library.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnIsName(
- ITypeLib2 *iface,
- LPOLESTR szNameBuf,
- ULONG lHashVal,
- BOOL *pfName)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ITypeInfoImpl *pTInfo;
- TLBFuncDesc *pFInfo;
- TLBVarDesc *pVInfo;
- int i;
- UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR);
-
- TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
- pfName);
-
- *pfName=TRUE;
- for(pTInfo=This->pTypeInfo;pTInfo;pTInfo=pTInfo->next){
- if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
- for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
- if(!memcmp(szNameBuf,pFInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
- for(i=0;i<pFInfo->funcdesc.cParams;i++)
- if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name, nNameBufLen))
- goto ITypeLib2_fnIsName_exit;
- }
- for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
- if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnIsName_exit;
-
- }
- *pfName=FALSE;
-
-ITypeLib2_fnIsName_exit:
- TRACE("(%p)slow! search for %s: %s found!\n", This,
- debugstr_w(szNameBuf), *pfName?"NOT":"");
-
- return S_OK;
-}
-
-/* ITypeLib::FindName
- *
- * Finds occurrences of a type description in a type library. This may be used
- * to quickly verify that a name exists in a type library.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnFindName(
- ITypeLib2 *iface,
- LPOLESTR szNameBuf,
- ULONG lHashVal,
- ITypeInfo **ppTInfo,
- MEMBERID *rgMemId,
- UINT16 *pcFound)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- ITypeInfoImpl *pTInfo;
- TLBFuncDesc *pFInfo;
- TLBVarDesc *pVInfo;
- int i,j = 0;
- UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR);
-
- for(pTInfo=This->pTypeInfo;pTInfo && j<*pcFound; pTInfo=pTInfo->next){
- if(!memcmp(szNameBuf,pTInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
- for(pFInfo=pTInfo->funclist;pFInfo;pFInfo=pFInfo->next) {
- if(!memcmp(szNameBuf,pFInfo->Name,nNameBufLen)) goto ITypeLib2_fnFindName_exit;
- for(i=0;i<pFInfo->funcdesc.cParams;i++) {
- if(!memcmp(szNameBuf,pFInfo->pParamDesc[i].Name,nNameBufLen))
- goto ITypeLib2_fnFindName_exit;
- }
- }
- for(pVInfo=pTInfo->varlist;pVInfo;pVInfo=pVInfo->next)
- if(!memcmp(szNameBuf,pVInfo->Name, nNameBufLen)) goto ITypeLib2_fnFindName_exit;
- continue;
-ITypeLib2_fnFindName_exit:
- ITypeInfo_AddRef((ITypeInfo*)pTInfo);
- ppTInfo[j]=(LPTYPEINFO)pTInfo;
- j++;
- }
- TRACE("(%p)slow! search for %d with %s: found %d TypeInfo's!\n",
- This, *pcFound, debugstr_w(szNameBuf), j);
-
- *pcFound=j;
-
- return S_OK;
-}
-
-/* ITypeLib::ReleaseTLibAttr
- *
- * Releases the TLIBATTR originally obtained from ITypeLib::GetLibAttr.
- *
- */
-static VOID WINAPI ITypeLib2_fnReleaseTLibAttr(
- ITypeLib2 *iface,
- TLIBATTR *pTLibAttr)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- TRACE("freeing (%p)\n",This);
- HeapFree(GetProcessHeap(),0,pTLibAttr);
-
-}
-
-/* ITypeLib2::GetCustData
- *
- * gets the custom data
- */
-static HRESULT WINAPI ITypeLib2_fnGetCustData(
- ITypeLib2 * iface,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- TLBCustData *pCData;
-
- for(pCData=This->pCustData; pCData; pCData = pCData->next)
- {
- if( IsEqualIID(guid, &pCData->guid)) break;
- }
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData)
- {
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeLib2::GetLibStatistics
- *
- * Returns statistics about a type library that are required for efficient
- * sizing of hash tables.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetLibStatistics(
- ITypeLib2 * iface,
- ULONG *pcUniqueNames,
- ULONG *pcchUniqueNames)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
-
- FIXME("(%p): stub!\n", This);
-
- if(pcUniqueNames) *pcUniqueNames=1;
- if(pcchUniqueNames) *pcchUniqueNames=1;
- return S_OK;
-}
-
-/* ITypeLib2::GetDocumentation2
- *
- * Retrieves the library's documentation string, the complete Help file name
- * and path, the localization context to use, and the context ID for the
- * library Help topic in the Help file.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetDocumentation2(
- ITypeLib2 * iface,
- INT index,
- LCID lcid,
- BSTR *pbstrHelpString,
- DWORD *pdwHelpStringContext,
- BSTR *pbstrHelpStringDll)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- HRESULT result;
- ITypeInfo *pTInfo;
-
- FIXME("(%p) index %d lcid %ld half implemented stub!\n", This, index, lcid);
-
- /* the help string should be obtained from the helpstringdll,
- * using the _DLLGetDocumentation function, based on the supplied
- * lcid. Nice to do sometime...
- */
- if(index<0)
- {
- /* documentation for the typelib */
- if(pbstrHelpString)
- *pbstrHelpString=SysAllocString(This->DocString);
- if(pdwHelpStringContext)
- *pdwHelpStringContext=This->dwHelpContext;
- if(pbstrHelpStringDll)
- *pbstrHelpStringDll=SysAllocString(This->HelpStringDll);
-
- result = S_OK;
- }
- else
- {
- /* for a typeinfo */
- result=ITypeLib2_GetTypeInfo(iface, index, &pTInfo);
-
- if(SUCCEEDED(result))
- {
- ITypeInfo2 * pTInfo2;
- result = ITypeInfo_QueryInterface(pTInfo,
- &IID_ITypeInfo2,
- (LPVOID*) &pTInfo2);
-
- if(SUCCEEDED(result))
- {
- result = ITypeInfo2_GetDocumentation2(pTInfo2,
- MEMBERID_NIL,
- lcid,
- pbstrHelpString,
- pdwHelpStringContext,
- pbstrHelpStringDll);
-
- ITypeInfo2_Release(pTInfo2);
- }
-
- ITypeInfo_Release(pTInfo);
- }
- }
- return result;
-}
-
-/* ITypeLib2::GetAllCustData
- *
- * Gets all custom data items for the library.
- *
- */
-static HRESULT WINAPI ITypeLib2_fnGetAllCustData(
- ITypeLib2 * iface,
- CUSTDATA *pCustData)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
- TLBCustData *pCData;
- int i;
- TRACE("(%p) returning %d items\n", This, This->ctCustData);
- pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=This->ctCustData;
- for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
-}
-
-static const ITypeLib2Vtbl tlbvt = {
- ITypeLib2_fnQueryInterface,
- ITypeLib2_fnAddRef,
- ITypeLib2_fnRelease,
- ITypeLib2_fnGetTypeInfoCount,
- ITypeLib2_fnGetTypeInfo,
- ITypeLib2_fnGetTypeInfoType,
- ITypeLib2_fnGetTypeInfoOfGuid,
- ITypeLib2_fnGetLibAttr,
- ITypeLib2_fnGetTypeComp,
- ITypeLib2_fnGetDocumentation,
- ITypeLib2_fnIsName,
- ITypeLib2_fnFindName,
- ITypeLib2_fnReleaseTLibAttr,
-
- ITypeLib2_fnGetCustData,
- ITypeLib2_fnGetLibStatistics,
- ITypeLib2_fnGetDocumentation2,
- ITypeLib2_fnGetAllCustData
- };
-
-
-static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
-{
- ITypeLibImpl *This = impl_from_ITypeComp(iface);
-
- return ITypeLib2_QueryInterface((ITypeLib *)This, riid, ppv);
-}
-
-static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp * iface)
-{
- ITypeLibImpl *This = impl_from_ITypeComp(iface);
-
- return ITypeLib2_AddRef((ITypeLib2 *)This);
-}
-
-static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp * iface)
-{
- ITypeLibImpl *This = impl_from_ITypeComp(iface);
-
- return ITypeLib2_Release((ITypeLib2 *)This);
-}
-
-static HRESULT WINAPI ITypeLibComp_fnBind(
- ITypeComp * iface,
- OLECHAR * szName,
- ULONG lHash,
- WORD wFlags,
- ITypeInfo ** ppTInfo,
- DESCKIND * pDescKind,
- BINDPTR * pBindPtr)
-{
- ITypeLibImpl *This = impl_from_ITypeComp(iface);
- ITypeInfoImpl *pTypeInfo;
-
- TRACE("(%s, 0x%lx, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
-
- *pDescKind = DESCKIND_NONE;
- pBindPtr->lptcomp = NULL;
- *ppTInfo = NULL;
-
- for (pTypeInfo = This->pTypeInfo; pTypeInfo; pTypeInfo = pTypeInfo->next)
- {
- TRACE("testing %s\n", debugstr_w(pTypeInfo->Name));
-
- /* FIXME: check wFlags here? */
- /* FIXME: we should use a hash table to look this info up using lHash
- * instead of an O(n) search */
- if ((pTypeInfo->TypeAttr.typekind == TKIND_ENUM) ||
- (pTypeInfo->TypeAttr.typekind == TKIND_MODULE))
- {
- if (pTypeInfo->Name && !strcmpW(pTypeInfo->Name, szName))
- {
- *pDescKind = DESCKIND_TYPECOMP;
- pBindPtr->lptcomp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
- ITypeComp_AddRef(pBindPtr->lptcomp);
- TRACE("module or enum: %s\n", debugstr_w(szName));
- return S_OK;
- }
- }
-
- if ((pTypeInfo->TypeAttr.typekind == TKIND_MODULE) ||
- (pTypeInfo->TypeAttr.typekind == TKIND_ENUM))
- {
- ITypeComp *pSubTypeComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
- HRESULT hr;
-
- hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
- if (SUCCEEDED(hr) && (*pDescKind != DESCKIND_NONE))
- {
- TRACE("found in module or in enum: %s\n", debugstr_w(szName));
- return S_OK;
- }
- }
-
- if ((pTypeInfo->TypeAttr.typekind == TKIND_COCLASS) &&
- (pTypeInfo->TypeAttr.wTypeFlags & TYPEFLAG_FAPPOBJECT))
- {
- ITypeComp *pSubTypeComp = (ITypeComp *)&pTypeInfo->lpVtblTypeComp;
- HRESULT hr;
- ITypeInfo *subtypeinfo;
- BINDPTR subbindptr;
- DESCKIND subdesckind;
-
- hr = ITypeComp_Bind(pSubTypeComp, szName, lHash, wFlags,
- &subtypeinfo, &subdesckind, &subbindptr);
- if (SUCCEEDED(hr) && (subdesckind != DESCKIND_NONE))
- {
- TYPEDESC tdesc_appobject =
- {
- {
- (TYPEDESC *)pTypeInfo->hreftype
- },
- VT_USERDEFINED
- };
- const VARDESC vardesc_appobject =
- {
- -2, /* memid */
- NULL, /* lpstrSchema */
- {
- 0 /* oInst */
- },
- {
- /* ELEMDESC */
- {
- /* TYPEDESC */
- {
- &tdesc_appobject
- },
- VT_PTR
- },
- },
- 0, /* wVarFlags */
- VAR_STATIC /* varkind */
- };
-
- TRACE("found in implicit app object: %s\n", debugstr_w(szName));
-
- /* cleanup things filled in by Bind call so we can put our
- * application object data in there instead */
- switch (subdesckind)
- {
- case DESCKIND_FUNCDESC:
- ITypeInfo_ReleaseFuncDesc(subtypeinfo, subbindptr.lpfuncdesc);
- break;
- case DESCKIND_VARDESC:
- ITypeInfo_ReleaseVarDesc(subtypeinfo, subbindptr.lpvardesc);
- break;
- default:
- break;
- }
- if (subtypeinfo) ITypeInfo_Release(subtypeinfo);
-
- if (pTypeInfo->hreftype == -1)
- FIXME("no hreftype for interface %p\n", pTypeInfo);
-
- hr = TLB_AllocAndInitVarDesc(&vardesc_appobject, &pBindPtr->lpvardesc);
- if (FAILED(hr))
- return hr;
-
- *pDescKind = DESCKIND_IMPLICITAPPOBJ;
- *ppTInfo = (ITypeInfo *)pTypeInfo;
- ITypeInfo_AddRef(*ppTInfo);
- return S_OK;
- }
- }
- }
-
- TRACE("name not found %s\n", debugstr_w(szName));
- return S_OK;
-}
-
-static HRESULT WINAPI ITypeLibComp_fnBindType(
- ITypeComp * iface,
- OLECHAR * szName,
- ULONG lHash,
- ITypeInfo ** ppTInfo,
- ITypeComp ** ppTComp)
-{
- FIXME("(%s, %lx, %p, %p): stub\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
- return E_NOTIMPL;
-}
-
-static const ITypeCompVtbl tlbtcvt =
-{
-
- ITypeLibComp_fnQueryInterface,
- ITypeLibComp_fnAddRef,
- ITypeLibComp_fnRelease,
-
- ITypeLibComp_fnBind,
- ITypeLibComp_fnBindType
-};
-
-/*================== ITypeInfo(2) Methods ===================================*/
-static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void)
-{
- ITypeInfoImpl * pTypeInfoImpl;
-
- pTypeInfoImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeInfoImpl));
- if (pTypeInfoImpl)
- {
- pTypeInfoImpl->lpVtbl = &tinfvt;
- pTypeInfoImpl->lpVtblTypeComp = &tcompvt;
- pTypeInfoImpl->ref=1;
- pTypeInfoImpl->hreftype = -1;
- }
- TRACE("(%p)\n", pTypeInfoImpl);
- return (ITypeInfo2*) pTypeInfoImpl;
-}
-
-/* ITypeInfo::QueryInterface
- */
-static HRESULT WINAPI ITypeInfo_fnQueryInterface(
- ITypeInfo2 *iface,
- REFIID riid,
- VOID **ppvObject)
-{
- ITypeLibImpl *This = (ITypeLibImpl *)iface;
-
- TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
-
- *ppvObject=NULL;
- if(IsEqualIID(riid, &IID_IUnknown) ||
- IsEqualIID(riid,&IID_ITypeInfo)||
- IsEqualIID(riid,&IID_ITypeInfo2))
- *ppvObject = This;
-
- if(*ppvObject){
- ITypeInfo_AddRef(iface);
- TRACE("-- Interface: (%p)->(%p)\n",ppvObject,*ppvObject);
- return S_OK;
- }
- TRACE("-- Interface: E_NOINTERFACE\n");
- return E_NOINTERFACE;
-}
-
-/* ITypeInfo::AddRef
- */
-static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- ULONG ref = InterlockedIncrement(&This->ref);
-
- ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
-
- TRACE("(%p)->ref is %lu\n",This, ref);
- return ref;
-}
-
-/* ITypeInfo::Release
- */
-static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- ULONG ref = InterlockedDecrement(&This->ref);
-
- TRACE("(%p)->(%lu)\n",This, ref);
-
- 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 {
- FIXME("destroy child objects\n");
-
- TRACE("destroying ITypeInfo(%p)\n",This);
- if (This->Name)
- {
- SysFreeString(This->Name);
- This->Name = 0;
- }
-
- if (This->DocString)
- {
- SysFreeString(This->DocString);
- This->DocString = 0;
- }
-
- if (This->DllName)
- {
- SysFreeString(This->DllName);
- This->DllName = 0;
- }
-
- if (This->next)
- {
- ITypeInfo_Release((ITypeInfo*)This->next);
- }
-
- HeapFree(GetProcessHeap(),0,This);
- return 0;
- }
- return ref;
-}
-
-/* ITypeInfo::GetTypeAttr
- *
- * Retrieves a TYPEATTR structure that contains the attributes of the type
- * description.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
- LPTYPEATTR *ppTypeAttr)
-{
- const ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- SIZE_T size;
-
- TRACE("(%p)\n",This);
-
- size = sizeof(**ppTypeAttr);
- if (This->TypeAttr.typekind == TKIND_ALIAS)
- size += TLB_SizeTypeDesc(&This->TypeAttr.tdescAlias, FALSE);
-
- *ppTypeAttr = HeapAlloc(GetProcessHeap(), 0, size);
- if (!*ppTypeAttr)
- return E_OUTOFMEMORY;
-
- memcpy(*ppTypeAttr, &This->TypeAttr, sizeof(**ppTypeAttr));
-
- if (This->TypeAttr.typekind == TKIND_ALIAS)
- TLB_CopyTypeDesc(&(*ppTypeAttr)->tdescAlias,
- &This->TypeAttr.tdescAlias, (void *)(*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 */
- (*ppTypeAttr)->wTypeFlags &= ~TYPEFLAG_FOLEAUTOMATION;
- }
- return S_OK;
-}
-
-/* ITypeInfo::GetTypeComp
- *
- * Retrieves the ITypeComp interface for the type description, which enables a
- * client compiler to bind to the type description's members.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
- ITypeComp * *ppTComp)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
-
- TRACE("(%p)->(%p) stub!\n", This, ppTComp);
-
- *ppTComp = (ITypeComp *)&This->lpVtblTypeComp;
- ITypeComp_AddRef(*ppTComp);
- return S_OK;
-}
-
-static SIZE_T TLB_SizeElemDesc( const ELEMDESC *elemdesc )
-{
- SIZE_T size = TLB_SizeTypeDesc(&elemdesc->tdesc, FALSE);
- if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
- size += sizeof(*elemdesc->u.paramdesc.pparamdescex);
- return size;
-}
-
-static HRESULT TLB_CopyElemDesc( const ELEMDESC *src, ELEMDESC *dest, char **buffer )
-{
- memcpy(dest, src, sizeof(ELEMDESC));
- *buffer = TLB_CopyTypeDesc(&dest->tdesc, &src->tdesc, *buffer);
- if (src->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
- {
- const PARAMDESCEX *pparamdescex_src = src->u.paramdesc.pparamdescex;
- PARAMDESCEX *pparamdescex_dest = dest->u.paramdesc.pparamdescex = (PARAMDESCEX *)*buffer;
- *buffer += sizeof(PARAMDESCEX);
- memcpy(pparamdescex_dest, pparamdescex_src, sizeof(PARAMDESCEX));
- VariantInit(&pparamdescex_dest->varDefaultValue);
- return VariantCopy(&pparamdescex_dest->varDefaultValue,
- (VARIANTARG *)&pparamdescex_src->varDefaultValue);
- }
- else
- dest->u.paramdesc.pparamdescex = NULL;
- return S_OK;
-}
-
-static void TLB_FreeElemDesc( ELEMDESC *elemdesc )
-{
- if (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT)
- VariantClear(&elemdesc->u.paramdesc.pparamdescex->varDefaultValue);
-}
-
-static HRESULT TLB_AllocAndInitFuncDesc( const FUNCDESC *src, FUNCDESC **dest_ptr, BOOL dispinterface )
-{
- FUNCDESC *dest;
- char *buffer;
- SIZE_T size = sizeof(*src);
- SHORT i;
- HRESULT hr;
-
- size += sizeof(*src->lprgscode) * src->cScodes;
- size += TLB_SizeElemDesc(&src->elemdescFunc);
- for (i = 0; i < src->cParams; i++)
- {
- size += sizeof(ELEMDESC);
- size += TLB_SizeElemDesc(&src->lprgelemdescParam[i]);
- }
-
- dest = (FUNCDESC *)SysAllocStringByteLen(NULL, size);
- if (!dest) return E_OUTOFMEMORY;
-
- memcpy(dest, src, sizeof(FUNCDESC));
- buffer = (char *)(dest + 1);
-
- dest->lprgscode = (SCODE *)buffer;
- memcpy(dest->lprgscode, src->lprgscode, sizeof(*src->lprgscode) * src->cScodes);
- buffer += sizeof(*src->lprgscode) * src->cScodes;
-
- hr = TLB_CopyElemDesc(&src->elemdescFunc, &dest->elemdescFunc, &buffer);
- if (FAILED(hr))
- {
- SysFreeString((BSTR)dest);
- return hr;
- }
-
- dest->lprgelemdescParam = (ELEMDESC *)buffer;
- buffer += sizeof(ELEMDESC) * src->cParams;
- for (i = 0; i < src->cParams; i++)
- {
- hr = TLB_CopyElemDesc(&src->lprgelemdescParam[i], &dest->lprgelemdescParam[i], &buffer);
- if (FAILED(hr))
- break;
- }
- if (FAILED(hr))
- {
- /* undo the above actions */
- for (i = i - 1; i >= 0; i--)
- TLB_FreeElemDesc(&dest->lprgelemdescParam[i]);
- TLB_FreeElemDesc(&dest->elemdescFunc);
- SysFreeString((BSTR)dest);
- return hr;
- }
-
- /* special treatment for dispinterfaces: this makes functions appear
- * to return their [retval] value when it is really returning an
- * HRESULT */
- if (dispinterface && dest->elemdescFunc.tdesc.vt == VT_HRESULT)
- {
- if (dest->cParams &&
- (dest->lprgelemdescParam[dest->cParams - 1].u.paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
- {
- ELEMDESC *elemdesc = &dest->lprgelemdescParam[dest->cParams - 1];
- if (elemdesc->tdesc.vt != VT_PTR)
- {
- ERR("elemdesc should have started with VT_PTR instead of:\n");
- if (ERR_ON(ole))
- dump_ELEMDESC(elemdesc);
- return E_UNEXPECTED;
- }
-
- /* copy last parameter to the return value. we are using a flat
- * buffer so there is no danger of leaking memory in
- * elemdescFunc */
- dest->elemdescFunc.tdesc = *elemdesc->tdesc.u.lptdesc;
-
- /* remove the last parameter */
- dest->cParams--;
- }
- else
- /* otherwise this function is made to appear to have no return
- * value */
- dest->elemdescFunc.tdesc.vt = VT_VOID;
-
- }
-
- *dest_ptr = dest;
- return S_OK;
-}
-
-HRESULT ITypeInfoImpl_GetInternalFuncDesc( ITypeInfo *iface, UINT index, const FUNCDESC **ppFuncDesc )
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- const TLBFuncDesc *pFDesc;
- int i;
-
- for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
- ;
-
- if (pFDesc)
- {
- *ppFuncDesc = &pFDesc->funcdesc;
- return S_OK;
- }
-
- return E_INVALIDARG;
-}
-
-/* ITypeInfo::GetFuncDesc
- *
- * Retrieves the FUNCDESC structure that contains information about a
- * specified function.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
- LPFUNCDESC *ppFuncDesc)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- const FUNCDESC *internal_funcdesc;
- HRESULT hr;
-
- TRACE("(%p) index %d\n", This, index);
-
- hr = ITypeInfoImpl_GetInternalFuncDesc((ITypeInfo *)iface, index, &internal_funcdesc);
- if (FAILED(hr))
- return hr;
-
- return TLB_AllocAndInitFuncDesc(
- internal_funcdesc,
- ppFuncDesc,
- This->TypeAttr.typekind == TKIND_DISPATCH);
-}
-
-static HRESULT TLB_AllocAndInitVarDesc( const VARDESC *src, VARDESC **dest_ptr )
-{
- VARDESC *dest;
- char *buffer;
- SIZE_T size = sizeof(*src);
- HRESULT hr;
-
- if (src->lpstrSchema) size += (strlenW(src->lpstrSchema) + 1) * sizeof(WCHAR);
- if (src->varkind == VAR_CONST)
- size += sizeof(VARIANT);
- size += TLB_SizeElemDesc(&src->elemdescVar);
-
- dest = (VARDESC *)SysAllocStringByteLen(NULL, size);
- if (!dest) return E_OUTOFMEMORY;
-
- *dest = *src;
- buffer = (char *)(dest + 1);
- if (src->lpstrSchema)
- {
- int len;
- dest->lpstrSchema = (LPOLESTR)buffer;
- len = strlenW(src->lpstrSchema);
- memcpy(dest->lpstrSchema, src->lpstrSchema, (len + 1) * sizeof(WCHAR));
- buffer += (len + 1) * sizeof(WCHAR);
- }
-
- if (src->varkind == VAR_CONST)
- {
- HRESULT hr;
-
- dest->u.lpvarValue = (VARIANT *)buffer;
- *dest->u.lpvarValue = *src->u.lpvarValue;
- buffer += sizeof(VARIANT);
- VariantInit(dest->u.lpvarValue);
- hr = VariantCopy(dest->u.lpvarValue, src->u.lpvarValue);
- if (FAILED(hr))
- {
- SysFreeString((BSTR)dest_ptr);
- return hr;
- }
- }
- hr = TLB_CopyElemDesc(&src->elemdescVar, &dest->elemdescVar, &buffer);
- if (FAILED(hr))
- {
- if (src->varkind == VAR_CONST)
- VariantClear(dest->u.lpvarValue);
- SysFreeString((BSTR)dest);
- return hr;
- }
- *dest_ptr = dest;
- return S_OK;
-}
-
-/* ITypeInfo::GetVarDesc
- *
- * Retrieves a VARDESC structure that describes the specified variable.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetVarDesc( ITypeInfo2 *iface, UINT index,
- LPVARDESC *ppVarDesc)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
- const TLBVarDesc *pVDesc;
-
- TRACE("(%p) index %d\n", This, index);
-
- for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next)
- ;
-
- if (pVDesc)
- return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
-
- return E_INVALIDARG;
-}
-
-/* ITypeInfo_GetNames
- *
- * Retrieves the variable with the specified member ID (or the name of the
- * property or method and its parameters) that correspond to the specified
- * function ID.
- */
-static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
- BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
- int i;
- TRACE("(%p) memid=0x%08lx Maxname=%d\n", This, memid, cMaxNames);
- for(pFDesc=This->funclist; pFDesc && pFDesc->funcdesc.memid != memid; pFDesc=pFDesc->next);
- if(pFDesc)
- {
- /* function found, now return function and parameter names */
- for(i=0; i<cMaxNames && i <= pFDesc->funcdesc.cParams; i++)
- {
- if(!i)
- *rgBstrNames=SysAllocString(pFDesc->Name);
- else
- rgBstrNames[i]=SysAllocString(pFDesc->pParamDesc[i-1].Name);
- }
- *pcNames=i;
- }
- else
- {
- for(pVDesc=This->varlist; pVDesc && pVDesc->vardesc.memid != memid; pVDesc=pVDesc->next);
- if(pVDesc)
- {
- *rgBstrNames=SysAllocString(pVDesc->Name);
- *pcNames=1;
- }
- else
- {
- if(This->TypeAttr.cImplTypes &&
- (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) {
- /* recursive search */
- ITypeInfo *pTInfo;
- HRESULT result;
- result=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef,
- &pTInfo);
- if(SUCCEEDED(result))
- {
- result=ITypeInfo_GetNames(pTInfo, memid, rgBstrNames, cMaxNames, pcNames);
- ITypeInfo_Release(pTInfo);
- return result;
- }
- WARN("Could not search inherited interface!\n");
- }
- else
- {
- WARN("no names found\n");
- }
- *pcNames=0;
- return TYPE_E_ELEMENTNOTFOUND;
- }
- }
- return S_OK;
-}
-
-
-/* ITypeInfo::GetRefTypeOfImplType
- *
- * If a type description describes a COM class, it retrieves the type
- * description of the implemented interface types. For an interface,
- * GetRefTypeOfImplType returns the type information for inherited interfaces,
- * if any exist.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetRefTypeOfImplType(
- ITypeInfo2 *iface,
- UINT index,
- HREFTYPE *pRefType)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
- HRESULT hr = S_OK;
- TLBImplType *pImpl = This->impltypelist;
-
- TRACE("(%p) index %d\n", This, index);
- if (TRACE_ON(ole)) dump_TypeInfo(This);
-
- if(index==(UINT)-1)
- {
- /* only valid on dual interfaces;
- retrieve the associated TKIND_INTERFACE handle for the current TKIND_DISPATCH
- */
- if( This->TypeAttr.typekind != TKIND_DISPATCH) return E_INVALIDARG;
-
- if (This->TypeAttr.wTypeFlags & TYPEFLAG_FDISPATCHABLE &&
- This->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL )
- {
- *pRefType = -1;
- }
- else
- {
- hr = TYPE_E_ELEMENTNOTFOUND;
- }
- }
- else
- {
- /* get element n from linked list */
- for(i=0; pImpl && i<index; i++)
- {
- pImpl = pImpl->next;
- }
-
- if (pImpl)
- *pRefType = pImpl->hRef;
- else
- hr = TYPE_E_ELEMENTNOTFOUND;
- }
-
- if(TRACE_ON(ole))
- {
- if(SUCCEEDED(hr))
- TRACE("SUCCESS -- hRef = 0x%08lx\n", *pRefType );
- else
- TRACE("FAILURE -- hresult = 0x%08lx\n", hr);
- }
-
- return hr;
-}
-
-/* ITypeInfo::GetImplTypeFlags
- *
- * Retrieves the IMPLTYPEFLAGS enumeration for one implemented interface
- * or base interface in a type description.
- */
-static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
- UINT index, INT *pImplTypeFlags)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
- TLBImplType *pImpl;
-
- TRACE("(%p) index %d\n", This, index);
- for(i=0, pImpl=This->impltypelist; i<index && pImpl;
- i++, pImpl=pImpl->next)
- ;
- if(i==index && pImpl){
- *pImplTypeFlags=pImpl->implflags;
- return S_OK;
- }
- *pImplTypeFlags=0;
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* GetIDsOfNames
- * Maps between member names and member IDs, and parameter names and
- * parameter IDs.
- */
-static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
- LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
- HRESULT ret=S_OK;
- int i;
-
- TRACE("(%p) Name %s cNames %d\n", This, debugstr_w(*rgszNames),
- cNames);
-
- /* init out parameters in case of failure */
- for (i = 0; i < cNames; i++)
- pMemId[i] = MEMBERID_NIL;
-
- for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next) {
- int j;
- if(!lstrcmpiW(*rgszNames, pFDesc->Name)) {
- if(cNames) *pMemId=pFDesc->funcdesc.memid;
- for(i=1; i < cNames; i++){
- for(j=0; j<pFDesc->funcdesc.cParams; j++)
- if(!lstrcmpiW(rgszNames[i],pFDesc->pParamDesc[j].Name))
- break;
- if( j<pFDesc->funcdesc.cParams)
- pMemId[i]=j;
- else
- ret=DISP_E_UNKNOWNNAME;
- };
- TRACE("-- 0x%08lx\n", ret);
- return ret;
- }
- }
- for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
- if(!lstrcmpiW(*rgszNames, pVDesc->Name)) {
- if(cNames) *pMemId=pVDesc->vardesc.memid;
- return ret;
- }
- }
- /* not found, see if this is and interface with an inheritance */
- if(This->TypeAttr.cImplTypes &&
- (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) {
- /* recursive search */
- ITypeInfo *pTInfo;
- ret=ITypeInfo_GetRefTypeInfo(iface,
- This->impltypelist->hRef, &pTInfo);
- if(SUCCEEDED(ret)){
- ret=ITypeInfo_GetIDsOfNames(pTInfo, rgszNames, cNames, pMemId );
- ITypeInfo_Release(pTInfo);
- return ret;
- }
- WARN("Could not search inherited interface!\n");
- } else
- WARN("no names found\n");
- return DISP_E_UNKNOWNNAME;
-}
-
-/* ITypeInfo::Invoke
- *
- * Invokes a method, or accesses a property of an object, that implements the
- * interface described by the type description.
- */
-DWORD
-_invoke(FARPROC func,CALLCONV callconv, int nrargs, DWORD *args) {
- DWORD res;
-
- if (TRACE_ON(ole)) {
- int i;
- TRACE("Calling %p(",func);
- for (i=0;i<nrargs;i++) TRACE("%08lx,",args[i]);
- 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;
- default:
- FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
- res = -1;
- break;
- }
- break;
- default:
- FIXME("unsupported calling convention %d\n",callconv);
- res = -1;
- break;
- }
- TRACE("returns %08lx\n",res);
- return res;
-}
-
-extern int _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);
- VARIANT va;
-
- if ((vt==VT_PTR) && tdesc && (tdesc->u.lptdesc->vt == VT_VARIANT)) {
- memcpy(argpos,&arg,sizeof(void*));
- return S_OK;
- }
-
- if (V_VT(arg) == vt) {
- memcpy(argpos, &V_I4(arg), arglen);
- return S_OK;
- }
-
- if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) {
- memcpy(argpos, &V_ARRAY(arg), sizeof(SAFEARRAY*));
- 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_I4(arg), 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_I4(arg), 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 = NULL;
- TYPEATTR *tattr = NULL;
- 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_I4(arg), 4);
- return S_OK;
- }
- hres = ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- if( hres )
- {
- ERR("GetTypeAttr failed\n");
- ITypeInfo_Release(tinfo2);
- return hres;
- }
- switch (tattr->typekind) {
- case TKIND_ENUM:
- switch ( V_VT( arg ) ) {
- case VT_I2:
- *argpos = V_I2(arg);
- hres = S_OK;
- break;
- case VT_I4:
- memcpy(argpos, &V_I4(arg), 4);
- hres = S_OK;
- break;
- case VT_BYREF|VT_I4:
- memcpy(argpos, V_I4REF(arg), 4);
- hres = S_OK;
- break;
- default:
- FIXME("vt 0x%x -> TKIND_ENUM unhandled.\n",V_VT(arg));
- hres = E_FAIL;
- break;
- }
- break;
-
- case TKIND_ALIAS:
- tdesc = &(tattr->tdescAlias);
- hres = _copy_arg((ITypeInfo2*)tinfo2, tdesc, argpos, arg, tdesc->vt);
- break;
-
- case TKIND_INTERFACE:
- if (V_VT(arg) == VT_DISPATCH) {
- IDispatch *disp;
- if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) {
- memcpy(argpos, &V_DISPATCH(arg), 4);
- hres = S_OK;
- break;
- }
- hres=IUnknown_QueryInterface(V_DISPATCH(arg),
- &IID_IDispatch,(LPVOID*)&disp);
- if (SUCCEEDED(hres)) {
- memcpy(argpos,&disp,4);
- IUnknown_Release(V_DISPATCH(arg));
- hres = S_OK;
- break;
- }
- FIXME("Failed to query IDispatch interface from %s while "
- "converting to VT_DISPATCH!\n",debugstr_guid(&(tattr->guid)));
- hres = E_FAIL;
- break;
- }
- if (V_VT(arg) == VT_UNKNOWN) {
- memcpy(argpos, &V_UNKNOWN(arg), 4);
- hres = S_OK;
- break;
- }
- FIXME("vt 0x%x -> TKIND_INTERFACE(%s) unhandled\n",
- V_VT(arg),debugstr_guid(&(tattr->guid)));
- hres = E_FAIL;
- break;
-
- case TKIND_DISPATCH:
- if (V_VT(arg) == VT_DISPATCH) {
- memcpy(argpos, &V_DISPATCH(arg), 4);
- hres = S_OK;
- }
- else {
- hres = E_FAIL;
- FIXME("TKIND_DISPATCH unhandled for target vt 0x%x.\n",V_VT(arg));
- }
- break;
- case TKIND_RECORD:
- FIXME("TKIND_RECORD unhandled.\n");
- hres = E_FAIL;
- break;
- default:
- FIXME("TKIND %d unhandled.\n",tattr->typekind);
- hres = E_FAIL;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return hres;
- }
-
- VariantInit(&va);
- if (VariantChangeType(&va,arg,0,vt)==S_OK) {
- memcpy(argpos,&V_I4(&va), arglen);
- FIXME("Should not use VariantChangeType here."
- " (conversion from 0x%x -> 0x%x) %08lx\n",
- V_VT(arg), vt, *argpos
- );
- return S_OK;
- }
- ERR("Set arg to disparg type 0x%x vs 0x%x\n",V_VT(arg),vt);
- return E_FAIL;
-}
-
-static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
-{
- HRESULT hr = S_OK;
- ITypeInfo *tinfo2 = NULL;
- TYPEATTR *tattr = NULL;
-
- hr = ITypeInfo_GetRefTypeInfo(tinfo, tdesc->u.hreftype, &tinfo2);
- if (hr)
- {
- ERR("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "
- "hr = 0x%08lx\n",
- tdesc->u.hreftype, hr);
- return hr;
- }
- hr = ITypeInfo_GetTypeAttr(tinfo2, &tattr);
- if (hr)
- {
- ERR("ITypeInfo_GetTypeAttr failed, hr = 0x%08lx\n", hr);
- ITypeInfo_Release(tinfo2);
- return hr;
- }
-
- switch (tattr->typekind)
- {
- case TKIND_ENUM:
- *vt |= VT_I4;
- break;
-
- case TKIND_ALIAS:
- tdesc = &tattr->tdescAlias;
- hr = typedescvt_to_variantvt(tinfo2, &tattr->tdescAlias, vt);
- break;
-
- case TKIND_INTERFACE:
- if (IsEqualIID(&IID_IDispatch, &tattr->guid))
- *vt |= VT_DISPATCH;
- else
- *vt |= VT_UNKNOWN;
- break;
-
- case TKIND_DISPATCH:
- *vt |= VT_DISPATCH;
- break;
-
- case TKIND_RECORD:
- FIXME("TKIND_RECORD unhandled.\n");
- hr = E_NOTIMPL;
- break;
-
- case TKIND_UNION:
- FIXME("TKIND_RECORD unhandled.\n");
- hr = E_NOTIMPL;
- break;
-
- default:
- FIXME("TKIND %d unhandled.\n",tattr->typekind);
- hr = E_NOTIMPL;
- break;
- }
- ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
- ITypeInfo_Release(tinfo2);
- return hr;
-}
-
-static HRESULT typedescvt_to_variantvt(ITypeInfo *tinfo, const TYPEDESC *tdesc, VARTYPE *vt)
-{
- HRESULT hr = S_OK;
-
- /* enforce only one level of pointer indirection */
- if (!(*vt & VT_BYREF) && (tdesc->vt == VT_PTR))
- {
- tdesc = tdesc->u.lptdesc;
-
- /* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
- * VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into
- * VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
- if ((tdesc->vt == VT_USERDEFINED) ||
- ((tdesc->vt == VT_PTR) && (tdesc->u.lptdesc->vt == VT_USERDEFINED)))
- {
- VARTYPE vt_userdefined = 0;
- const TYPEDESC *tdesc_userdefined = tdesc;
- if (tdesc->vt == VT_PTR)
- {
- vt_userdefined = VT_BYREF;
- tdesc_userdefined = tdesc->u.lptdesc;
- }
- hr = userdefined_to_variantvt(tinfo, tdesc_userdefined, &vt_userdefined);
- if ((hr == S_OK) &&
- (((vt_userdefined & VT_TYPEMASK) == VT_UNKNOWN) ||
- ((vt_userdefined & VT_TYPEMASK) == VT_DISPATCH)))
- {
- *vt |= vt_userdefined;
- return S_OK;
- }
- }
- *vt = VT_BYREF;
- }
-
- switch (tdesc->vt)
- {
- case VT_HRESULT:
- *vt |= VT_ERROR;
- break;
- case VT_USERDEFINED:
- hr = userdefined_to_variantvt(tinfo, tdesc, vt);
- break;
- case VT_PTR:
- ERR("cannot convert VT_PTR into variant VT\n");
- hr = E_FAIL;
- break;
- default:
- *vt |= tdesc->vt;
- break;
- }
- return hr;
-}
-
-/***********************************************************************
- * DispCallFunc (OLEAUT32.@)
- *
- * Invokes a function of the specifed calling convention, passing the
- * specified arguments and returns the result.
- *
- * PARAMS
- * pvInstance [I] Optional pointer to the instance whose function to invoke.
- * oVft [I] The offset in the vtable. See notes.
- * cc [I] Calling convention of the function to call.
- * vtReturn [I] The return type of the function.
- * cActuals [I] Number of parameters.
- * prgvt [I] The types of the parameters to pass. This is used for sizing only.
- * prgpvarg [I] The arguments to pass.
- * pvargResult [O] The return value of the function. Can be NULL.
- *
- * RETURNS
- * Success: S_OK.
- * Failure: HRESULT code.
- *
- * NOTES
- * The HRESULT return value of this function is not affected by the return
- * value of the user supplied function, which is returned in pvargResult.
- *
- * If pvInstance is NULL then a non-object function is to be called and oVft
- * is the address of the function to call.
- *
- * The cc parameter can be one of the following values:
- *|CC_FASTCALL
- *|CC_CDECL
- *|CC_PASCAL
- *|CC_STDCALL
- *|CC_FPFASTCALL
- *|CC_SYSCALL
- *|CC_MPWCDECL
- *|CC_MPWPASCAL
- *
- * BUGS
- * Native accepts arguments in the reverse order. I.e. the first item in the
- * prgpvarg array is the last argument in the C/C++ declaration of the
- * function to be called.
- */
-HRESULT WINAPI
-DispCallFunc(
- void* pvInstance, ULONG_PTR oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
- VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult)
-{
- int i, argsize, argspos;
- DWORD *args;
- HRESULT hres;
-
- TRACE("(%p, %ld, %d, %d, %d, %p, %p, %p (vt=%d))\n",
- pvInstance, oVft, cc, vtReturn, cActuals, prgvt, prgpvarg,
- pvargResult, V_VT(pvargResult));
-
- argsize = 0;
- if (pvInstance)
- argsize++; /* for This pointer */
-
- for (i=0;i<cActuals;i++)
- {
- TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_argsize(prgvt[i]));
- dump_Variant(prgpvarg[i]);
- argsize += _argsize(prgvt[i]);
- }
- args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
-
- argspos = 0;
- if (pvInstance)
- {
- args[0] = (DWORD)pvInstance; /* the This pointer is always the first parameter */
- argspos++;
- }
-
- for (i=0;i<cActuals;i++)
- {
- VARIANT *arg = prgpvarg[i];
- TRACE("Storing arg %d (%d as %d)\n",i,V_VT(arg),prgvt[i]);
- memcpy(&args[argspos], &V_NONE(arg), _argsize(prgvt[i]) * sizeof(DWORD));
- argspos += _argsize(prgvt[i]);
- }
-
- if (pvInstance)
- {
- FARPROC *vtable = *(FARPROC**)pvInstance;
- hres = _invoke(vtable[oVft/sizeof(void *)], cc, argsize, args);
- }
- else
- /* if we aren't invoking an object then the function pointer is stored
- * in oVft */
- hres = _invoke((FARPROC)oVft, cc, argsize, args);
-
- if (pvargResult && (vtReturn != VT_EMPTY))
- {
- TRACE("Method returned 0x%08lx\n",hres);
- V_VT(pvargResult) = vtReturn;
- V_UI4(pvargResult) = hres;
- }
-
- HeapFree(GetProcessHeap(),0,args);
- return S_OK;
-}
-
-static HRESULT WINAPI ITypeInfo_fnInvoke(
- ITypeInfo2 *iface,
- VOID *pIUnk,
- MEMBERID memid,
- UINT16 wFlags,
- DISPPARAMS *pDispParams,
- VARIANT *pVarResult,
- EXCEPINFO *pExcepInfo,
- UINT *pArgErr)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- int i;
- unsigned int var_index;
- TYPEKIND type_kind;
- HRESULT hres;
- const TLBFuncDesc *pFuncInfo;
-
- TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p)\n",
- This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
- );
- dump_DispParms(pDispParams);
-
- /* we do this instead of using GetFuncDesc since it will return a fake
- * 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))
- break;
-
- if (pFuncInfo) {
- const FUNCDESC *func_desc = &pFuncInfo->funcdesc;
-
- if (TRACE_ON(ole))
- {
- TRACE("invoking:\n");
- dump_TLBFuncDescOne(pFuncInfo);
- }
-
- switch (func_desc->funckind) {
- case FUNC_PUREVIRTUAL:
- case FUNC_VIRTUAL: {
- DWORD res;
- int numargs, numargs2, argspos, args2pos;
- DWORD *args , *args2;
- VARIANT *rgvarg = HeapAlloc(GetProcessHeap(), 0, sizeof(VARIANT) * func_desc->cParams);
- memcpy(rgvarg,pDispParams->rgvarg,sizeof(VARIANT)*pDispParams->cArgs);
-
- hres = S_OK;
- numargs = 1; /* sizeof(thisptr) */
- numargs2 = 0;
- for (i = 0; i < func_desc->cParams; i++)
- {
- TYPEDESC *tdesc = &func_desc->lprgelemdescParam[i].tdesc;
-
- numargs += _argsize(tdesc->vt);
- if (i>=pDispParams->cArgs) { /* arguments to return */
- if (tdesc->vt == VT_PTR) {
- numargs2 += _argsize(tdesc->u.lptdesc->vt);
- } else {
- FIXME("The variant type here should have been VT_PTR, not vt %d\n", tdesc->vt);
- numargs2 += _argsize(tdesc->vt);
- }
- }
- }
-
- args = HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
- args2 = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(DWORD)*numargs2);
-
- args[0] = (DWORD)pIUnk;
- argspos = 1; args2pos = 0;
- for (i = 0; i < func_desc->cParams; i++)
- {
- ELEMDESC *elemdesc = &(func_desc->lprgelemdescParam[i]);
- TYPEDESC *tdesc = &(elemdesc->tdesc);
- USHORT paramFlags = elemdesc->u.paramdesc.wParamFlags;
- int arglen = _argsize(tdesc->vt);
-
- if (i<pDispParams->cArgs)
- {
- VARIANT *arg = &rgvarg[pDispParams->cArgs-i-1];
-
- if (paramFlags & PARAMFLAG_FOPT) {
- if(i < func_desc->cParams - func_desc->cParamsOpt)
- ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
- if(V_VT(arg) == VT_EMPTY
- || ((V_ISBYREF(arg)) && !V_BYREF(arg))) {
- /* FIXME: Documentation says that we do this when parameter is left unspecified.
- How to determine it? */
-
- if(paramFlags & PARAMFLAG_FHASDEFAULT)
- FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n");
- V_VT(arg) = VT_ERROR;
- V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
- arglen = _argsize(VT_ERROR);
- }
- }
- hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
- if (FAILED(hres)) goto func_fail;
- argspos += arglen;
- }
- else if (paramFlags & PARAMFLAG_FOPT)
- {
- VARIANT *arg = &rgvarg[i];
-
- if (i < func_desc->cParams - func_desc->cParamsOpt)
- ERR("Parameter has PARAMFLAG_FOPT flag but is not one of last cParamOpt parameters\n");
- if (paramFlags & PARAMFLAG_FHASDEFAULT)
- FIXME("PARAMFLAG_FHASDEFAULT flag not supported\n");
-
- V_VT(arg) = VT_ERROR;
- V_ERROR(arg) = DISP_E_PARAMNOTFOUND;
- arglen = _argsize(VT_ERROR);
- hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
- if (FAILED(hres)) goto func_fail;
- argspos += arglen;
- }
- else
- {
- if (tdesc->vt == VT_PTR)
- arglen = _argsize(tdesc->u.lptdesc->vt);
- else
- FIXME("set %d to pointer for get (type is %d)\n",i,tdesc->vt);
-
- /* Supply pointers for the rest, so propertyget works*/
- args[argspos] = (DWORD)&args2[args2pos];
-
- /* If pointer to variant, pass reference it. */
- if ((tdesc->vt == VT_PTR) &&
- (tdesc->u.lptdesc->vt == VT_VARIANT) &&
- pVarResult
- )
- args[argspos]= (DWORD)pVarResult;
- argspos += 1;
- args2pos += arglen;
- }
- }
- if (func_desc->cParamsOpt < 0)
- FIXME("Does not support optional parameters (%d)\n", func_desc->cParamsOpt);
-
- res = _invoke((*(FARPROC**)pIUnk)[func_desc->oVft/4],
- func_desc->callconv,
- numargs,
- args
- );
-
- for (i = 0; i < func_desc->cParams; i++)
- {
- USHORT wParamFlags = func_desc->lprgelemdescParam[i].u.paramdesc.wParamFlags;
- if (wParamFlags & PARAMFLAG_FRETVAL)
- {
- ELEMDESC *elemdesc = &func_desc->lprgelemdescParam[i];
- TYPEDESC *tdesc = &elemdesc->tdesc;
- VARIANTARG varresult;
- V_VT(&varresult) = 0;
- hres = typedescvt_to_variantvt((ITypeInfo *)iface, tdesc, &V_VT(&varresult));
- if (hres)
- break;
- /* FIXME: this is really messy - we should keep the
- * args in VARIANTARGs rather than a DWORD array */
- memcpy(&V_UI4(&varresult), &args[i+1], sizeof(DWORD));
- if (TRACE_ON(ole))
- {
- TRACE("varresult: ");
- dump_Variant(&varresult);
- }
-
- if (pVarResult)
- /* deref return value */
- hres = VariantCopyInd(pVarResult, &varresult);
-
- /* 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(&varresult) == (VT_UNKNOWN | VT_BYREF)) ||
- (V_VT(&varresult) == (VT_DISPATCH | VT_BYREF)))
- {
- if(*V_UNKNOWNREF(&varresult))
- IUnknown_Release(*V_UNKNOWNREF(&varresult));
- }
- break;
- }
- }
-
- if ((func_desc->elemdescFunc.tdesc.vt == VT_HRESULT) && FAILED(res))
- {
- WARN("invoked function failed with error 0x%08lx\n", res);
- hres = DISP_E_EXCEPTION;
- if (pExcepInfo) pExcepInfo->scode = res;
- }
-
-func_fail:
- HeapFree(GetProcessHeap(), 0, rgvarg);
- HeapFree(GetProcessHeap(),0,args2);
- HeapFree(GetProcessHeap(),0,args);
- break;
- }
- case FUNC_DISPATCH: {
- IDispatch *disp;
-
- hres = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
- if (SUCCEEDED(hres)) {
- FIXME("Calling Invoke in IDispatch iface. untested!\n");
- hres = IDispatch_Invoke(
- disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,wFlags,pDispParams,
- pVarResult,pExcepInfo,pArgErr
- );
- if (FAILED(hres))
- FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n", hres);
- IDispatch_Release(disp);
- } else
- FIXME("FUNC_DISPATCH used on object without IDispatch iface?\n");
- break;
- }
- default:
- FIXME("Unknown function invocation type %d\n", func_desc->funckind);
- hres = E_FAIL;
- break;
- }
-
- TRACE("-- 0x%08lx\n", hres);
- return hres;
-
- } else if(SUCCEEDED(hres = ITypeInfo2_GetVarIndexOfMemId(iface, memid, &var_index))) {
- VARDESC *var_desc;
-
- hres = ITypeInfo2_GetVarDesc(iface, var_index, &var_desc);
- if(FAILED(hres)) return hres;
-
- FIXME("varseek: Found memid, but variable-based invoking not supported\n");
- dump_VARDESC(var_desc);
- ITypeInfo2_ReleaseVarDesc(iface, var_desc);
- return E_NOTIMPL;
- }
-
- /* not found, look for it in inherited interfaces */
- ITypeInfo2_GetTypeKind(iface, &type_kind);
- if(type_kind == TKIND_INTERFACE || type_kind == TKIND_DISPATCH) {
- HREFTYPE ref_type;
- if(SUCCEEDED(ITypeInfo2_GetRefTypeOfImplType(iface, 0, &ref_type))) {
- /* recursive search */
- ITypeInfo *pTInfo;
- hres = ITypeInfo_GetRefTypeInfo(iface, ref_type, &pTInfo);
- if(SUCCEEDED(hres)){
- hres = ITypeInfo_Invoke(pTInfo,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
- ITypeInfo_Release(pTInfo);
- return hres;
- }
- WARN("Could not search inherited interface!\n");
- }
- }
- ERR("did not find member id %ld, flags 0x%x!\n", memid, wFlags);
- return DISP_E_MEMBERNOTFOUND;
-}
-
-/* ITypeInfo::GetDocumentation
- *
- * Retrieves the documentation string, the complete Help file name and path,
- * and the context ID for the Help topic for a specified type description.
- *
- * (Can be tested by the Visual Basic Editor in Word for instance.)
- */
-static HRESULT WINAPI ITypeInfo_fnGetDocumentation( ITypeInfo2 *iface,
- MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
- DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
- TRACE("(%p) memid %ld Name(%p) DocString(%p)"
- " HelpContext(%p) HelpFile(%p)\n",
- This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
- if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
- if(pBstrName)
- *pBstrName=SysAllocString(This->Name);
- if(pBstrDocString)
- *pBstrDocString=SysAllocString(This->DocString);
- if(pdwHelpContext)
- *pdwHelpContext=This->dwHelpContext;
- if(pBstrHelpFile)
- *pBstrHelpFile=SysAllocString(This->DocString);/* FIXME */
- return S_OK;
- }else {/* for a member */
- for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
- if(pFDesc->funcdesc.memid==memid){
- if(pBstrName)
- *pBstrName = SysAllocString(pFDesc->Name);
- if(pBstrDocString)
- *pBstrDocString=SysAllocString(pFDesc->HelpString);
- if(pdwHelpContext)
- *pdwHelpContext=pFDesc->helpcontext;
- return S_OK;
- }
- for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
- if(pVDesc->vardesc.memid==memid){
- if(pBstrName)
- *pBstrName = SysAllocString(pVDesc->Name);
- if(pBstrDocString)
- *pBstrDocString=SysAllocString(pVDesc->HelpString);
- if(pdwHelpContext)
- *pdwHelpContext=pVDesc->HelpContext;
- return S_OK;
- }
- }
- WARN("member %ld not found\n", memid);
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo::GetDllEntry
- *
- * Retrieves a description or specification of an entry point for a function
- * in a DLL.
- */
-static HRESULT WINAPI ITypeInfo_fnGetDllEntry( ITypeInfo2 *iface, MEMBERID memid,
- INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
- WORD *pwOrdinal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc *pFDesc;
-
- TRACE("(%p)->(memid %lx, %d, %p, %p, %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
-
- if (pBstrDllName) *pBstrDllName = NULL;
- if (pBstrName) *pBstrName = NULL;
- if (pwOrdinal) *pwOrdinal = 0;
-
- if (This->TypeAttr.typekind != TKIND_MODULE)
- return TYPE_E_BADMODULEKIND;
-
- for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
- if(pFDesc->funcdesc.memid==memid){
- dump_TypeInfo(This);
- if (TRACE_ON(ole))
- dump_TLBFuncDescOne(pFDesc);
-
- if (pBstrDllName)
- *pBstrDllName = SysAllocString(This->DllName);
-
- if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
- if (pBstrName)
- *pBstrName = SysAllocString(pFDesc->Entry);
- if (pwOrdinal)
- *pwOrdinal = -1;
- return S_OK;
- }
- if (pBstrName)
- *pBstrName = NULL;
- if (pwOrdinal)
- *pwOrdinal = (DWORD)pFDesc->Entry;
- return S_OK;
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo::GetRefTypeInfo
- *
- * If a type description references other type descriptions, it retrieves
- * the referenced type descriptions.
- */
-static HRESULT WINAPI ITypeInfo_fnGetRefTypeInfo(
- ITypeInfo2 *iface,
- HREFTYPE hRefType,
- ITypeInfo **ppTInfo)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- HRESULT result = E_FAIL;
-
- if ((This->hreftype != -1) && (This->hreftype == hRefType))
- {
- *ppTInfo = (ITypeInfo *)&This->lpVtbl;
- ITypeInfo_AddRef(*ppTInfo);
- result = S_OK;
- }
- else if (hRefType == -1 &&
- (((ITypeInfoImpl*) This)->TypeAttr.typekind == TKIND_DISPATCH) &&
- (((ITypeInfoImpl*) This)->TypeAttr.wTypeFlags & TYPEFLAG_FDUAL))
- {
- /* when we meet a DUAL dispinterface, we must create the interface
- * version of it.
- */
- ITypeInfoImpl* pTypeInfoImpl = (ITypeInfoImpl*) ITypeInfo_Constructor();
-
-
- /* the interface version contains the same information as the dispinterface
- * copy the contents of the structs.
- */
- *pTypeInfoImpl = *This;
- pTypeInfoImpl->ref = 1;
-
- /* change the type to interface */
- pTypeInfoImpl->TypeAttr.typekind = TKIND_INTERFACE;
-
- *ppTInfo = (ITypeInfo*) pTypeInfoImpl;
-
- ITypeInfo_AddRef((ITypeInfo*) pTypeInfoImpl);
-
- result = S_OK;
-
- } else {
- TLBRefType *pRefType;
- for(pRefType = This->reflist; pRefType; pRefType = pRefType->next) {
- if(pRefType->reference == hRefType)
- break;
- }
- if(!pRefType)
- FIXME("Can't find pRefType for ref %lx\n", hRefType);
- if(pRefType && hRefType != -1) {
- ITypeLib *pTLib = NULL;
-
- if(pRefType->pImpTLInfo == TLB_REF_INTERNAL) {
- UINT Index;
- result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
- } else {
- if(pRefType->pImpTLInfo->pImpTypeLib) {
- TRACE("typeinfo in imported typelib that is already loaded\n");
- pTLib = (ITypeLib*)pRefType->pImpTLInfo->pImpTypeLib;
- ITypeLib2_AddRef((ITypeLib*) pTLib);
- result = S_OK;
- } else {
- TRACE("typeinfo in imported typelib that isn't already loaded\n");
- result = LoadRegTypeLib( &pRefType->pImpTLInfo->guid,
- pRefType->pImpTLInfo->wVersionMajor,
- pRefType->pImpTLInfo->wVersionMinor,
- pRefType->pImpTLInfo->lcid,
- &pTLib);
-
- if(!SUCCEEDED(result)) {
- BSTR libnam=SysAllocString(pRefType->pImpTLInfo->name);
- result=LoadTypeLib(libnam, &pTLib);
- SysFreeString(libnam);
- }
- if(SUCCEEDED(result)) {
- pRefType->pImpTLInfo->pImpTypeLib = (ITypeLibImpl*)pTLib;
- ITypeLib2_AddRef(pTLib);
- }
- }
- }
- if(SUCCEEDED(result)) {
- if(pRefType->index == TLB_REF_USE_GUID)
- result = ITypeLib2_GetTypeInfoOfGuid(pTLib,
- &pRefType->guid,
- ppTInfo);
- else
- result = ITypeLib2_GetTypeInfo(pTLib, pRefType->index,
- ppTInfo);
- }
- if (pTLib != NULL)
- ITypeLib2_Release(pTLib);
- }
- }
-
- TRACE("(%p) hreftype 0x%04lx loaded %s (%p)\n", This, hRefType,
- SUCCEEDED(result)? "SUCCESS":"FAILURE", *ppTInfo);
- return result;
-}
-
-/* ITypeInfo::AddressOfMember
- *
- * Retrieves the addresses of static functions or variables, such as those
- * defined in a DLL.
- */
-static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
- MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- HRESULT hr;
- BSTR dll, entry;
- WORD ordinal;
- HMODULE module;
-
- TRACE("(%p)->(0x%lx, 0x%x, %p)\n", This, memid, invKind, ppv);
-
- hr = ITypeInfo_GetDllEntry(iface, memid, invKind, &dll, &entry, &ordinal);
- if (FAILED(hr))
- return hr;
-
- module = LoadLibraryW(dll);
- if (!module)
- {
- ERR("couldn't load %s\n", debugstr_w(dll));
- SysFreeString(dll);
- if (entry) SysFreeString(entry);
- return STG_E_FILENOTFOUND;
- }
- /* FIXME: store library somewhere where we can free it */
-
- if (entry)
- {
- LPSTR entryA;
- INT len = WideCharToMultiByte(CP_ACP, 0, entry, -1, NULL, 0, NULL, NULL);
- entryA = HeapAlloc(GetProcessHeap(), 0, len);
- WideCharToMultiByte(CP_ACP, 0, entry, -1, entryA, len, NULL, NULL);
-
- *ppv = GetProcAddress(module, entryA);
- if (!*ppv)
- ERR("function not found %s\n", debugstr_a(entryA));
-
- HeapFree(GetProcessHeap(), 0, entryA);
- }
- else
- {
- *ppv = GetProcAddress(module, MAKEINTRESOURCEA(ordinal));
- if (!*ppv)
- ERR("function not found %d\n", ordinal);
- }
-
- SysFreeString(dll);
- if (entry) SysFreeString(entry);
-
- if (!*ppv)
- return TYPE_E_DLLFUNCTIONNOTFOUND;
-
- return S_OK;
-}
-
-/* ITypeInfo::CreateInstance
- *
- * Creates a new instance of a type that describes a component object class
- * (coclass).
- */
-static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
- IUnknown *pUnk, REFIID riid, VOID **ppvObj)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- FIXME("(%p) stub!\n", This);
- return S_OK;
-}
-
-/* ITypeInfo::GetMops
- *
- * Retrieves marshalling information.
- */
-static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
- BSTR *pBstrMops)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- FIXME("(%p) stub!\n", This);
- return S_OK;
-}
-
-/* ITypeInfo::GetContainingTypeLib
- *
- * Retrieves the containing type library and the index of the type description
- * within that type library.
- */
-static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
- ITypeLib * *ppTLib, UINT *pIndex)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
-
- /* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */
- if (pIndex) {
- *pIndex=This->index;
- TRACE("returning pIndex=%d\n", *pIndex);
- }
-
- if (ppTLib) {
- *ppTLib=(LPTYPELIB )(This->pTypeLib);
- ITypeLib2_AddRef(*ppTLib);
- TRACE("returning ppTLib=%p\n", *ppTLib);
- }
-
- return S_OK;
-}
-
-/* ITypeInfo::ReleaseTypeAttr
- *
- * Releases a TYPEATTR previously returned by GetTypeAttr.
- *
- */
-static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
- TYPEATTR* pTypeAttr)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TRACE("(%p)->(%p)\n", This, pTypeAttr);
- HeapFree(GetProcessHeap(), 0, pTypeAttr);
-}
-
-/* ITypeInfo::ReleaseFuncDesc
- *
- * Releases a FUNCDESC previously returned by GetFuncDesc. *
- */
-static void WINAPI ITypeInfo_fnReleaseFuncDesc(
- ITypeInfo2 *iface,
- FUNCDESC *pFuncDesc)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- SHORT i;
-
- TRACE("(%p)->(%p)\n", This, pFuncDesc);
-
- for (i = 0; i < pFuncDesc->cParams; i++)
- TLB_FreeElemDesc(&pFuncDesc->lprgelemdescParam[i]);
- TLB_FreeElemDesc(&pFuncDesc->elemdescFunc);
-
- SysFreeString((BSTR)pFuncDesc);
-}
-
-/* ITypeInfo::ReleaseVarDesc
- *
- * Releases a VARDESC previously returned by GetVarDesc.
- */
-static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
- VARDESC *pVarDesc)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TRACE("(%p)->(%p)\n", This, pVarDesc);
-
- TLB_FreeElemDesc(&pVarDesc->elemdescVar);
- if (pVarDesc->varkind == VAR_CONST)
- VariantClear(pVarDesc->u.lpvarValue);
- SysFreeString((BSTR)pVarDesc);
-}
-
-/* ITypeInfo2::GetTypeKind
- *
- * Returns the TYPEKIND enumeration quickly, without doing any allocations.
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
- TYPEKIND *pTypeKind)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- *pTypeKind=This->TypeAttr.typekind;
- TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
- return S_OK;
-}
-
-/* ITypeInfo2::GetTypeFlags
- *
- * Returns the type flags without any allocations. This returns a DWORD type
- * flag, which expands the type flags without growing the TYPEATTR (type
- * attribute).
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pTypeFlags)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- *pTypeFlags=This->TypeAttr.wTypeFlags;
- TRACE("(%p) flags 0x%lx\n", This,*pTypeFlags);
- return S_OK;
-}
-
-/* ITypeInfo2::GetFuncIndexOfMemId
- * Binds to a specific member based on a known DISPID, where the member name
- * is not known (for example, when binding to a default member).
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
- MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc *pFuncInfo;
- int i;
- HRESULT result;
-
- for(i = 0, pFuncInfo = This->funclist; pFuncInfo; i++, pFuncInfo=pFuncInfo->next)
- if(memid == pFuncInfo->funcdesc.memid && (invKind & pFuncInfo->funcdesc.invkind))
- break;
- if(pFuncInfo) {
- *pFuncIndex = i;
- result = S_OK;
- } else
- result = TYPE_E_ELEMENTNOTFOUND;
-
- TRACE("(%p) memid 0x%08lx invKind 0x%04x -> %s\n", This,
- memid, invKind, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
- return result;
-}
-
-/* TypeInfo2::GetVarIndexOfMemId
- *
- * Binds to a specific member based on a known DISPID, where the member name
- * is not known (for example, when binding to a default member).
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
- MEMBERID memid, UINT *pVarIndex)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBVarDesc *pVarInfo;
- int i;
- HRESULT result;
- for(i=0, pVarInfo=This->varlist; pVarInfo &&
- memid != pVarInfo->vardesc.memid; i++, pVarInfo=pVarInfo->next)
- ;
- if(pVarInfo) {
- *pVarIndex = i;
- result = S_OK;
- } else
- result = TYPE_E_ELEMENTNOTFOUND;
-
- TRACE("(%p) memid 0x%08lx -> %s\n", This,
- memid, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
- return result;
-}
-
-/* ITypeInfo2::GetCustData
- *
- * Gets the custom data
- */
-static HRESULT WINAPI ITypeInfo2_fnGetCustData(
- ITypeInfo2 * iface,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData;
-
- for(pCData=This->pCustData; pCData; pCData = pCData->next)
- if( IsEqualIID(guid, &pCData->guid)) break;
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData)
- {
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeInfo2::GetFuncCustData
- *
- * Gets the custom data
- */
-static HRESULT WINAPI ITypeInfo2_fnGetFuncCustData(
- ITypeInfo2 * iface,
- UINT index,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData=NULL;
- TLBFuncDesc * pFDesc;
- int i;
- for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
- pFDesc=pFDesc->next);
-
- if(pFDesc)
- for(pCData=pFDesc->pCustData; pCData; pCData = pCData->next)
- if( IsEqualIID(guid, &pCData->guid)) break;
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData){
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeInfo2::GetParamCustData
- *
- * Gets the custom data
- */
-static HRESULT WINAPI ITypeInfo2_fnGetParamCustData(
- ITypeInfo2 * iface,
- UINT indexFunc,
- UINT indexParam,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData=NULL;
- TLBFuncDesc * pFDesc;
- int i;
-
- for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,pFDesc=pFDesc->next);
-
- if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams)
- for(pCData=pFDesc->pParamDesc[indexParam].pCustData; pCData;
- pCData = pCData->next)
- if( IsEqualIID(guid, &pCData->guid)) break;
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData)
- {
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeInfo2::GetVarCustData
- *
- * Gets the custom data
- */
-static HRESULT WINAPI ITypeInfo2_fnGetVarCustData(
- ITypeInfo2 * iface,
- UINT index,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData=NULL;
- TLBVarDesc * pVDesc;
- int i;
-
- for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++, pVDesc=pVDesc->next);
-
- if(pVDesc)
- {
- for(pCData=pVDesc->pCustData; pCData; pCData = pCData->next)
- {
- if( IsEqualIID(guid, &pCData->guid)) break;
- }
- }
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData)
- {
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeInfo2::GetImplCustData
- *
- * Gets the custom data
- */
-static HRESULT WINAPI ITypeInfo2_fnGetImplTypeCustData(
- ITypeInfo2 * iface,
- UINT index,
- REFGUID guid,
- VARIANT *pVarVal)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData=NULL;
- TLBImplType * pRDesc;
- int i;
-
- for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++, pRDesc=pRDesc->next);
-
- if(pRDesc)
- {
- for(pCData=pRDesc->pCustData; pCData; pCData = pCData->next)
- {
- if( IsEqualIID(guid, &pCData->guid)) break;
- }
- }
-
- TRACE("(%p) guid %s %s found!x)\n", This, debugstr_guid(guid), pCData? "" : "NOT");
-
- if(pCData)
- {
- VariantInit( pVarVal);
- VariantCopy( pVarVal, &pCData->data);
- return S_OK;
- }
- return E_INVALIDARG; /* FIXME: correct? */
-}
-
-/* ITypeInfo2::GetDocumentation2
- *
- * Retrieves the documentation string, the complete Help file name and path,
- * the localization context to use, and the context ID for the library Help
- * topic in the Help file.
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetDocumentation2(
- ITypeInfo2 * iface,
- MEMBERID memid,
- LCID lcid,
- BSTR *pbstrHelpString,
- DWORD *pdwHelpStringContext,
- BSTR *pbstrHelpStringDll)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
- TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
- "HelpStringContext(%p) HelpStringDll(%p)\n",
- This, memid, lcid, pbstrHelpString, pdwHelpStringContext,
- pbstrHelpStringDll );
- /* the help string should be obtained from the helpstringdll,
- * using the _DLLGetDocumentation function, based on the supplied
- * lcid. Nice to do sometime...
- */
- if(memid==MEMBERID_NIL){ /* documentation for the typeinfo */
- if(pbstrHelpString)
- *pbstrHelpString=SysAllocString(This->Name);
- if(pdwHelpStringContext)
- *pdwHelpStringContext=This->dwHelpStringContext;
- if(pbstrHelpStringDll)
- *pbstrHelpStringDll=
- SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
- return S_OK;
- }else {/* for a member */
- for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
- if(pFDesc->funcdesc.memid==memid){
- if(pbstrHelpString)
- *pbstrHelpString=SysAllocString(pFDesc->HelpString);
- if(pdwHelpStringContext)
- *pdwHelpStringContext=pFDesc->HelpStringContext;
- if(pbstrHelpStringDll)
- *pbstrHelpStringDll=
- SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
- return S_OK;
- }
- for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next)
- if(pVDesc->vardesc.memid==memid){
- if(pbstrHelpString)
- *pbstrHelpString=SysAllocString(pVDesc->HelpString);
- if(pdwHelpStringContext)
- *pdwHelpStringContext=pVDesc->HelpStringContext;
- if(pbstrHelpStringDll)
- *pbstrHelpStringDll=
- SysAllocString(This->pTypeLib->HelpStringDll);/* FIXME */
- return S_OK;
- }
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo2::GetAllCustData
- *
- * Gets all custom data items for the Type info.
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetAllCustData(
- ITypeInfo2 * iface,
- CUSTDATA *pCustData)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData;
- int i;
-
- TRACE("(%p) returning %d items\n", This, This->ctCustData);
-
- pCustData->prgCustData = TLB_Alloc(This->ctCustData * sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=This->ctCustData;
- for(i=0, pCData=This->pCustData; pCData; i++, pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
-}
-
-/* ITypeInfo2::GetAllFuncCustData
- *
- * Gets all custom data items for the specified Function
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetAllFuncCustData(
- ITypeInfo2 * iface,
- UINT index,
- CUSTDATA *pCustData)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData;
- TLBFuncDesc * pFDesc;
- int i;
- TRACE("(%p) index %d\n", This, index);
- for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++,
- pFDesc=pFDesc->next)
- ;
- if(pFDesc){
- pCustData->prgCustData =
- TLB_Alloc(pFDesc->ctCustData * sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=pFDesc->ctCustData;
- for(i=0, pCData=pFDesc->pCustData; pCData; i++,
- pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue,
- & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo2::GetAllParamCustData
- *
- * Gets all custom data items for the Functions
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
- UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData=NULL;
- TLBFuncDesc * pFDesc;
- int i;
- TRACE("(%p) index %d\n", This, indexFunc);
- for(i=0, pFDesc=This->funclist; i!=indexFunc && pFDesc; i++,
- pFDesc=pFDesc->next)
- ;
- if(pFDesc && indexParam >=0 && indexParam<pFDesc->funcdesc.cParams){
- pCustData->prgCustData =
- TLB_Alloc(pFDesc->pParamDesc[indexParam].ctCustData *
- sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=pFDesc->pParamDesc[indexParam].ctCustData;
- for(i=0, pCData=pFDesc->pParamDesc[indexParam].pCustData;
- pCData; i++, pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue,
- & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo2::GetAllVarCustData
- *
- * Gets all custom data items for the specified Variable
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
- UINT index, CUSTDATA *pCustData)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData;
- TLBVarDesc * pVDesc;
- int i;
- TRACE("(%p) index %d\n", This, index);
- for(i=0, pVDesc=This->varlist; i!=index && pVDesc; i++,
- pVDesc=pVDesc->next)
- ;
- if(pVDesc){
- pCustData->prgCustData =
- TLB_Alloc(pVDesc->ctCustData * sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=pVDesc->ctCustData;
- for(i=0, pCData=pVDesc->pCustData; pCData; i++,
- pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue,
- & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-/* ITypeInfo2::GetAllImplCustData
- *
- * Gets all custom data items for the specified implementation type
- *
- */
-static HRESULT WINAPI ITypeInfo2_fnGetAllImplTypeCustData(
- ITypeInfo2 * iface,
- UINT index,
- CUSTDATA *pCustData)
-{
- ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
- TLBCustData *pCData;
- TLBImplType * pRDesc;
- int i;
- TRACE("(%p) index %d\n", This, index);
- for(i=0, pRDesc=This->impltypelist; i!=index && pRDesc; i++,
- pRDesc=pRDesc->next)
- ;
- if(pRDesc){
- pCustData->prgCustData =
- TLB_Alloc(pRDesc->ctCustData * sizeof(CUSTDATAITEM));
- if(pCustData->prgCustData ){
- pCustData->cCustData=pRDesc->ctCustData;
- for(i=0, pCData=pRDesc->pCustData; pCData; i++,
- pCData = pCData->next){
- pCustData->prgCustData[i].guid=pCData->guid;
- VariantCopy(& pCustData->prgCustData[i].varValue,
- & pCData->data);
- }
- }else{
- ERR(" OUT OF MEMORY!\n");
- return E_OUTOFMEMORY;
- }
- return S_OK;
- }
- return TYPE_E_ELEMENTNOTFOUND;
-}
-
-static const ITypeInfo2Vtbl tinfvt =
-{
-
- ITypeInfo_fnQueryInterface,
- ITypeInfo_fnAddRef,
- ITypeInfo_fnRelease,
-
- ITypeInfo_fnGetTypeAttr,
- ITypeInfo_fnGetTypeComp,
- ITypeInfo_fnGetFuncDesc,
- ITypeInfo_fnGetVarDesc,
- ITypeInfo_fnGetNames,
- ITypeInfo_fnGetRefTypeOfImplType,
- ITypeInfo_fnGetImplTypeFlags,
- ITypeInfo_fnGetIDsOfNames,
- ITypeInfo_fnInvoke,
- ITypeInfo_fnGetDocumentation,
- ITypeInfo_fnGetDllEntry,
- ITypeInfo_fnGetRefTypeInfo,
- ITypeInfo_fnAddressOfMember,
- ITypeInfo_fnCreateInstance,
- ITypeInfo_fnGetMops,
- ITypeInfo_fnGetContainingTypeLib,
- ITypeInfo_fnReleaseTypeAttr,
- ITypeInfo_fnReleaseFuncDesc,
- ITypeInfo_fnReleaseVarDesc,
-
- ITypeInfo2_fnGetTypeKind,
- ITypeInfo2_fnGetTypeFlags,
- ITypeInfo2_fnGetFuncIndexOfMemId,
- ITypeInfo2_fnGetVarIndexOfMemId,
- ITypeInfo2_fnGetCustData,
- ITypeInfo2_fnGetFuncCustData,
- ITypeInfo2_fnGetParamCustData,
- ITypeInfo2_fnGetVarCustData,
- ITypeInfo2_fnGetImplTypeCustData,
- ITypeInfo2_fnGetDocumentation2,
- ITypeInfo2_fnGetAllCustData,
- ITypeInfo2_fnGetAllFuncCustData,
- ITypeInfo2_fnGetAllParamCustData,
- ITypeInfo2_fnGetAllVarCustData,
- ITypeInfo2_fnGetAllImplTypeCustData,
-};
-
-/******************************************************************************
- * CreateDispTypeInfo [OLEAUT32.31]
- *
- * Build type information for an object so it can be called through an
- * IDispatch interface.
- *
- * RETURNS
- * Success: S_OK. pptinfo contains the created ITypeInfo object.
- * Failure: E_INVALIDARG, if one or more arguments is invalid.
- *
- * NOTES
- * This call allows an objects methods to be accessed through IDispatch, by
- * building an ITypeInfo object that IDispatch can use to call through.
- */
-HRESULT WINAPI CreateDispTypeInfo(
- INTERFACEDATA *pidata, /* [I] Description of the interface to build type info for */
- LCID lcid, /* [I] Locale Id */
- ITypeInfo **pptinfo) /* [O] Destination for created ITypeInfo object */
-{
- ITypeInfoImpl *pTIImpl;
- int param, func;
- TLBFuncDesc **ppFuncDesc;
-
- pTIImpl = (ITypeInfoImpl*)ITypeInfo_Constructor();
- pTIImpl->pTypeLib = NULL;
- pTIImpl->index = 0;
- pTIImpl->Name = NULL;
- pTIImpl->dwHelpContext = -1;
- memset(&pTIImpl->TypeAttr.guid, 0, sizeof(GUID));
- pTIImpl->TypeAttr.lcid = lcid;
- pTIImpl->TypeAttr.typekind = TKIND_COCLASS;
- pTIImpl->TypeAttr.wMajorVerNum = 0;
- pTIImpl->TypeAttr.wMinorVerNum = 0;
- pTIImpl->TypeAttr.cbAlignment = 2;
- pTIImpl->TypeAttr.cbSizeInstance = -1;
- pTIImpl->TypeAttr.cbSizeVft = -1;
- pTIImpl->TypeAttr.cFuncs = 0;
- pTIImpl->TypeAttr.cImplTypes = 1;
- pTIImpl->TypeAttr.cVars = 0;
- pTIImpl->TypeAttr.wTypeFlags = 0;
-
- ppFuncDesc = &pTIImpl->funclist;
- for(func = 0; func < pidata->cMembers; func++) {
- METHODDATA *md = pidata->pmethdata + func;
- *ppFuncDesc = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppFuncDesc));
- (*ppFuncDesc)->Name = SysAllocString(md->szName);
- (*ppFuncDesc)->funcdesc.memid = md->dispid;
- (*ppFuncDesc)->funcdesc.invkind = md->wFlags;
- (*ppFuncDesc)->funcdesc.callconv = md->cc;
- (*ppFuncDesc)->funcdesc.cParams = md->cArgs;
- (*ppFuncDesc)->funcdesc.cParamsOpt = 0;
- (*ppFuncDesc)->funcdesc.oVft = md->iMeth;
- (*ppFuncDesc)->funcdesc.wFuncFlags = 0; /*??*/
- (*ppFuncDesc)->funcdesc.elemdescFunc.tdesc.vt = md->vtReturn;
- (*ppFuncDesc)->funcdesc.lprgelemdescParam = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- md->cArgs * sizeof(ELEMDESC));
- (*ppFuncDesc)->pParamDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
- md->cArgs * sizeof(TLBParDesc));
- for(param = 0; param < md->cArgs; param++) {
- (*ppFuncDesc)->funcdesc.lprgelemdescParam[param].tdesc.vt = md->ppdata[param].vt;
- (*ppFuncDesc)->pParamDesc[param].Name = SysAllocString(md->ppdata[param].szName);
- }
- ppFuncDesc = &(*ppFuncDesc)->next;
- }
- *pptinfo = (ITypeInfo*)pTIImpl;
- return S_OK;
-
-}
-
-static HRESULT WINAPI ITypeComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
-{
- ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
-
- return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv);
-}
-
-static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp * iface)
-{
- ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
-
- return ITypeInfo_AddRef((ITypeInfo *)This);
-}
-
-static ULONG WINAPI ITypeComp_fnRelease(ITypeComp * iface)
-{
- ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
-
- return ITypeInfo_Release((ITypeInfo *)This);
-}
-
-static HRESULT WINAPI ITypeComp_fnBind(
- ITypeComp * iface,
- OLECHAR * szName,
- ULONG lHash,
- WORD wFlags,
- ITypeInfo ** ppTInfo,
- DESCKIND * pDescKind,
- BINDPTR * pBindPtr)
-{
- ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
-
- TRACE("(%s, %lx, 0x%x, %p, %p, %p)\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
-
- *pDescKind = DESCKIND_NONE;
- pBindPtr->lpfuncdesc = NULL;
- *ppTInfo = NULL;
-
- for(pFDesc = This->funclist; pFDesc; pFDesc = pFDesc->next)
- if (!wFlags || (pFDesc->funcdesc.invkind & wFlags))
- if (!strcmpW(pFDesc->Name, szName)) {
- break;
- }
-
- if (pFDesc)
- {
- HRESULT hr = TLB_AllocAndInitFuncDesc(
- &pFDesc->funcdesc,
- &pBindPtr->lpfuncdesc,
- This->TypeAttr.typekind == TKIND_DISPATCH);
- if (FAILED(hr))
- return hr;
- *pDescKind = DESCKIND_FUNCDESC;
- *ppTInfo = (ITypeInfo *)&This->lpVtbl;
- ITypeInfo_AddRef(*ppTInfo);
- return S_OK;
- } else {
- for(pVDesc = This->varlist; pVDesc; pVDesc = pVDesc->next) {
- if (!strcmpW(pVDesc->Name, szName)) {
- HRESULT hr = TLB_AllocAndInitVarDesc(&pVDesc->vardesc, &pBindPtr->lpvardesc);
- if (FAILED(hr))
- return hr;
- *pDescKind = DESCKIND_VARDESC;
- *ppTInfo = (ITypeInfo *)&This->lpVtbl;
- ITypeInfo_AddRef(*ppTInfo);
- return S_OK;
- }
- }
- }
- /* FIXME: search each inherited interface, not just the first */
- if (This->TypeAttr.cImplTypes) {
- /* recursive search */
- ITypeInfo *pTInfo;
- ITypeComp *pTComp;
- HRESULT hr;
- hr=ITypeInfo_GetRefTypeInfo((ITypeInfo *)&This->lpVtbl, This->impltypelist->hRef, &pTInfo);
- if (SUCCEEDED(hr))
- {
- hr = ITypeInfo_GetTypeComp(pTInfo,&pTComp);
- ITypeInfo_Release(pTInfo);
- }
- if (SUCCEEDED(hr))
- {
- hr = ITypeComp_Bind(pTComp, szName, lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
- ITypeComp_Release(pTComp);
- return hr;
- }
- WARN("Could not search inherited interface!\n");
- }
- WARN("did not find member with name %s, flags 0x%x!\n", debugstr_w(szName), wFlags);
- return DISP_E_MEMBERNOTFOUND;
-}
-
-static HRESULT WINAPI ITypeComp_fnBindType(
- ITypeComp * iface,
- OLECHAR * szName,
- ULONG lHash,
- ITypeInfo ** ppTInfo,
- ITypeComp ** ppTComp)
-{
- TRACE("(%s, %lx, %p, %p)\n", debugstr_w(szName), lHash, ppTInfo, ppTComp);
-
- /* strange behaviour (does nothing) but like the
- * original */
-
- if (!ppTInfo || !ppTComp)
- return E_POINTER;
-
- *ppTInfo = NULL;
- *ppTComp = NULL;
-
- return S_OK;
-}
-
-static const ITypeCompVtbl tcompvt =
-{
-
- ITypeComp_fnQueryInterface,
- ITypeComp_fnAddRef,
- ITypeComp_fnRelease,
-
- ITypeComp_fnBind,
- ITypeComp_fnBindType
-};