* 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
#include <stdio.h>
#include <ctype.h>
+#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
+
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "wine/unicode.h"
#include "objbase.h"
-#include "heap.h"
-#include "ole2disp.h"
#include "typelib.h"
#include "wine/debug.h"
#include "variant.h"
/* 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, TYPEDESC *tdesc, VARTYPE *vt);
+static HRESULT TLB_AllocAndInitVarDesc(const VARDESC *src, VARDESC **dest_ptr);
+
/****************************************************************************
* FromLExxx
*
#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
- * path of typelib
+ * 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, /* [in] referenced guid */
- WORD wMaj, /* [in] major version */
- WORD wMin, /* [in] minor version */
- LCID lcid, /* [in] locale id */
- LPBSTR path ) /* [out] path of typelib */
+HRESULT WINAPI QueryPathOfRegTypeLib(
+ REFGUID guid,
+ WORD wMaj,
+ WORD wMin,
+ LCID lcid,
+ LPBSTR path )
{
- /* don't need to ZeroMemory those arrays since sprintf and RegQueryValue add
- string termination character on output strings */
+ HRESULT hr = TYPE_E_LIBNOTREGISTERED;
+ LCID myLCID = lcid;
+ HKEY hkey;
+ WCHAR buffer[60];
+ WCHAR Path[MAX_PATH];
+ LONG res;
- HRESULT hr = E_FAIL;
+ TRACE_(typelib)("(%s, %x.%x, 0x%lx, %p)\n", debugstr_guid(guid), wMaj, wMin, lcid, path);
- LCID myLCID = lcid;
+ get_typelib_key( guid, wMaj, wMin, buffer );
- char szXGUID[80];
- char szTypeLibKey[100];
- char szPath[MAX_PATH];
- DWORD dwPathLen = sizeof(szPath);
-
- if ( !HIWORD(guid) )
+ res = RegOpenKeyExW( HKEY_CLASSES_ROOT, buffer, 0, KEY_READ, &hkey );
+ if (res == ERROR_FILE_NOT_FOUND)
{
- sprintf(szXGUID,
- "<guid 0x%08lx>",
- (DWORD) guid);
-
- FIXME("(%s,%d,%d,0x%04lx,%p),stub!\n", szXGUID, wMaj, wMin, (DWORD)lcid, path);
- return E_FAIL;
+ 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)
{
- sprintf(szTypeLibKey,
- "SOFTWARE\\Classes\\Typelib\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\\%d.%d\\%lx\\win32",
- guid->Data1, guid->Data2, guid->Data3,
- guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
- guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7],
- wMaj,
- wMin,
- myLCID);
-
- if (RegQueryValueA(HKEY_LOCAL_MACHINE, szTypeLibKey, szPath, &dwPathLen))
+ LONG dwPathLen = sizeof(Path);
+
+ get_lcid_subkey( myLCID, SYS_WIN32, buffer );
+
+ if (RegQueryValueW(hkey, buffer, Path, &dwPathLen))
{
if (!lcid)
break;
}
else
{
- DWORD len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, dwPathLen, NULL, 0 );
- BSTR bstrPath = SysAllocStringLen(NULL,len);
-
- MultiByteToWideChar(CP_ACP,
- MB_PRECOMPOSED,
- szPath,
- dwPathLen,
- bstrPath,
- len);
- *path = bstrPath;
- hr = S_OK;
+ *path = SysAllocString( Path );
+ hr = S_OK;
}
}
-
- if (hr != S_OK)
- TRACE_(typelib)("%s not found\n", szTypeLibKey);
-
+ RegCloseKey( hkey );
+ TRACE_(typelib)("-- 0x%08lx\n", hr);
return hr;
}
FIXME("(%d,%s,%p), stub!\n",syskind,debugstr_w(szFile),ppctlib);
return E_FAIL;
}
+
/******************************************************************************
* LoadTypeLib [OLEAUT32.161]
- * Loads and registers a type library
- * NOTES
- * Docs: OLECHAR FAR* szFile
- * Docs: iTypeLib FAR* FAR* pptLib
+ *
+ * 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.
*/
-int TLB_ReadTypeLib(LPCWSTR file, INT index, ITypeLib2 **ppTypelib);
-
-HRESULT WINAPI LoadTypeLib(
- const OLECHAR *szFile,/* [in] Name of file to load from */
- ITypeLib * *pptLib) /* [out] Pointer to pointer to loaded type library */
+HRESULT WINAPI LoadTypeLib(const OLECHAR *szFile, ITypeLib * *pptLib)
{
- TRACE("\n");
+ 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
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)) {
return TYPE_E_CANTLOADLIBRARY;
if (GetFileAttributesW(szFileCopy) & FILE_ATTRIBUTE_DIRECTORY)
return TYPE_E_CANTLOADLIBRARY;
- } else {
- WCHAR tstpath[260];
- WCHAR stdole32tlb[] = { 's','t','d','o','l','e','3','2','.','t','l','b',0 };
- int i;
-
- lstrcpyW(tstpath,szFile);
- CharLowerW(tstpath);
- for (i=0;i<strlenW(tstpath);i++) {
- if (tstpath[i] == 's') {
- if (!strcmpW(tstpath+i,stdole32tlb)) {
- MESSAGE("\n");
- MESSAGE("**************************************************************************\n");
- MESSAGE("You must copy a 'stdole32.tlb' file to your Windows\\System directory!\n");
- MESSAGE("You can get one from a Windows installation, or look for the DCOM95 package\n");
- MESSAGE("on the Microsoft Download Pages.\n");
- MESSAGE("A free download link is on http://sourceforge.net/projects/wine/, look for dcom95.exe.\n");
- MESSAGE("**************************************************************************\n");
- break;
- }
- }
- }
- FIXME("Wanted to load %s as typelib, but file was not found.\n",debugstr_w(szFile));
- return TYPE_E_CANTLOADLIBRARY;
}
}
/******************************************************************************
* 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, /* [in] referenced guid */
- WORD wVerMajor, /* [in] major version */
- WORD wVerMinor, /* [in] minor version */
- LCID lcid, /* [in] locale id */
- ITypeLib **ppTLib) /* [out] path of typelib */
+ REFGUID rguid,
+ WORD wVerMajor,
+ WORD wVerMinor,
+ LCID lcid,
+ ITypeLib **ppTLib)
{
BSTR bstr=NULL;
HRESULT res=QueryPathOfRegTypeLib( rguid, wVerMajor, wVerMinor, lcid, &bstr);
}
+/* 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
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;
- OLECHAR guid[80];
- LPSTR guidA;
- CHAR keyName[120];
- CHAR tmp[MAX_PATH];
+ WCHAR keyName[60];
+ WCHAR tmp[16];
HKEY key, subKey;
UINT types, tidx;
TYPEKIND kind;
DWORD disposition;
- static const char *PSOA = "{00020424-0000-0000-C000-000000000046}";
if (ptlib == NULL || szFullPath == NULL)
return E_INVALIDARG;
if (!SUCCEEDED(ITypeLib_GetLibAttr(ptlib, &attr)))
return E_FAIL;
- StringFromGUID2(&attr->guid, guid, 80);
- guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
- snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
- guidA, attr->wMajorVerNum, attr->wMinorVerNum);
- HeapFree(GetProcessHeap(), 0, guidA);
+ get_typelib_key( &attr->guid, attr->wMajorVerNum, attr->wMinorVerNum, keyName );
res = S_OK;
- if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
+ if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS)
{
LPOLESTR doc;
res = E_FAIL;
/* Make up the name of the typelib path subkey */
- sprintf(tmp, "%lu\\", attr->lcid);
- switch(attr->syskind) {
- case SYS_WIN16:
- strcat(tmp, "win16");
- break;
-
- case SYS_WIN32:
- strcat(tmp, "win32");
- break;
-
- default:
- TRACE("Typelib is for unsupported syskind %i\n", attr->syskind);
- res = E_FAIL;
- break;
- }
+ if (!get_lcid_subkey( attr->lcid, attr->syskind, tmp )) res = E_FAIL;
/* Create the typelib path subkey */
- if (res == S_OK && RegCreateKeyExA(key, tmp, 0, NULL, 0,
+ if (res == S_OK && RegCreateKeyExW(key, tmp, 0, NULL, 0,
KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
{
if (RegSetValueExW(subKey, NULL, 0, REG_SZ,
res = E_FAIL;
/* Create the flags subkey */
- if (res == S_OK && RegCreateKeyExA(key, "FLAGS", 0, NULL, 0,
+ if (res == S_OK && RegCreateKeyExW(key, FLAGSW, 0, NULL, 0,
KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS)
{
- CHAR buf[20];
/* FIXME: is %u correct? */
- snprintf(buf, sizeof(buf), "%u", attr->wLibFlags);
- if (RegSetValueExA(subKey, NULL, 0, REG_SZ,
- buf, lstrlenA(buf) + 1) != ERROR_SUCCESS)
+ 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);
res = E_FAIL;
/* create the helpdir subkey */
- if (res == S_OK && RegCreateKeyExA(key, "HELPDIR", 0, NULL, 0,
+ if (res == S_OK && RegCreateKeyExW(key, HELPDIRW, 0, NULL, 0,
KEY_WRITE, NULL, &subKey, &disposition) == ERROR_SUCCESS)
{
BOOL freeHelpDir = FALSE;
MESSAGE("\n");
}
- /*
- * FIXME: The 1 is just here until we implement rpcrt4
- * stub/proxy handling. Until then it helps IShield
- * v6 to work.
- */
- if (1 || (tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION))
+ if (tattr->wTypeFlags & (TYPEFLAG_FOLEAUTOMATION|TYPEFLAG_FDUAL))
{
- if (!(tattr->wTypeFlags & TYPEFLAG_FOLEAUTOMATION)) {
- FIXME("Registering non-oleautomation interface!\n");
- }
-
/* register interface<->typelib coupling */
- StringFromGUID2(&tattr->guid, guid, 80);
- guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
- snprintf(keyName, sizeof(keyName), "Interface\\%s", guidA);
- HeapFree(GetProcessHeap(), 0, guidA);
-
- if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyName, 0, NULL, 0,
- KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
+ 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, lstrlenW(name) * sizeof(OLECHAR));
+ (BYTE *)name, (strlenW(name)+1) * sizeof(OLECHAR));
- if (RegCreateKeyExA(key, "ProxyStubClsid", 0, NULL, 0,
+ if (RegCreateKeyExW(key, ProxyStubClsidW, 0, NULL, 0,
KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
- RegSetValueExA(subKey, NULL, 0, REG_SZ,
- PSOA, strlen(PSOA));
+ RegSetValueExW(subKey, NULL, 0, REG_SZ,
+ (BYTE*)PSOA, sizeof PSOA);
RegCloseKey(subKey);
}
- if (RegCreateKeyExA(key, "ProxyStubClsid32", 0, NULL, 0,
+ if (RegCreateKeyExW(key, ProxyStubClsid32W, 0, NULL, 0,
KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
- RegSetValueExA(subKey, NULL, 0, REG_SZ,
- PSOA, strlen(PSOA));
+ RegSetValueExW(subKey, NULL, 0, REG_SZ,
+ (BYTE*)PSOA, sizeof PSOA);
RegCloseKey(subKey);
}
- if (RegCreateKeyExA(key, "TypeLib", 0, NULL, 0,
- KEY_WRITE, NULL, &subKey, NULL) == ERROR_SUCCESS) {
- CHAR ver[32];
- StringFromGUID2(&attr->guid, guid, 80);
- snprintf(ver, sizeof(ver), "%x.%x",
- attr->wMajorVerNum, attr->wMinorVerNum);
+ 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 *)guid, lstrlenW(guid) * sizeof(OLECHAR));
- RegSetValueExA(subKey, "Version", 0, REG_SZ,
- ver, lstrlenA(ver));
+ (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);
}
{
BSTR tlibPath = NULL;
DWORD tmpLength;
- CHAR keyName[MAX_PATH];
- CHAR* syskindName;
- CHAR subKeyName[MAX_PATH];
- LPSTR guidA;
+ WCHAR keyName[60];
+ WCHAR subKeyName[50];
int result = S_OK;
DWORD i = 0;
- OLECHAR guid[80];
BOOL deleteOtherStuff;
HKEY key = NULL;
HKEY subKey = NULL;
TRACE("(IID: %s): stub\n",debugstr_guid(libid));
/* Create the path to the key */
- StringFromGUID2(libid, guid, 80);
- guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
- snprintf(keyName, sizeof(keyName), "TypeLib\\%s\\%x.%x",
- guidA, wVerMajor, wVerMinor);
- HeapFree(GetProcessHeap(), 0, guidA);
-
- /* Work out the syskind name */
- switch(syskind) {
- case SYS_WIN16:
- syskindName = "win16";
- break;
-
- case SYS_WIN32:
- syskindName = "win32";
- break;
+ get_typelib_key( libid, wVerMajor, wVerMinor, keyName );
- default:
+ if (syskind != SYS_WIN16 && syskind != SYS_WIN32)
+ {
TRACE("Unsupported syskind %i\n", syskind);
result = E_INVALIDARG;
goto end;
}
/* Try and open the key to the type library. */
- if (RegOpenKeyExA(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) {
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyName, 0, KEY_READ | KEY_WRITE, &key) != S_OK) {
result = E_INVALIDARG;
goto end;
}
}
/* the path to the type */
- StringFromGUID2(&typeAttr->guid, guid, 80);
- guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
- snprintf(subKeyName, sizeof(subKeyName), "Interface\\%s", guidA);
- HeapFree(GetProcessHeap(), 0, guidA);
+ get_interface_key( &typeAttr->guid, subKeyName );
/* Delete its bits */
- if (RegOpenKeyExA(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) {
+ if (RegOpenKeyExW(HKEY_CLASSES_ROOT, subKeyName, 0, KEY_WRITE, &subKey) != S_OK) {
goto enddeleteloop;
}
- RegDeleteKeyA(subKey, "ProxyStubClsid");
- RegDeleteKeyA(subKey, "ProxyStubClsid32");
- RegDeleteKeyA(subKey, "TypeLib");
+ RegDeleteKeyW(subKey, ProxyStubClsidW);
+ RegDeleteKeyW(subKey, ProxyStubClsid32W);
+ RegDeleteKeyW(subKey, TypeLibW);
RegCloseKey(subKey);
subKey = NULL;
- RegDeleteKeyA(HKEY_CLASSES_ROOT, subKeyName);
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, subKeyName);
enddeleteloop:
if (typeAttr) ITypeInfo_ReleaseTypeAttr(typeInfo, typeAttr);
}
/* Now, delete the type library path subkey */
- sprintf(subKeyName, "%lu\\%s", lcid, syskindName);
- RegDeleteKeyA(key, subKeyName);
- sprintf(subKeyName, "%lu", lcid);
- RegDeleteKeyA(key, subKeyName);
+ 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);
+ tmpLength = sizeof(subKeyName)/sizeof(WCHAR);
deleteOtherStuff = TRUE;
i = 0;
- while(RegEnumKeyExA(key, i++, subKeyName, &tmpLength, NULL, NULL, NULL, NULL) == S_OK) {
- tmpLength = sizeof(subKeyName);
+ 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 (!strcmp(subKeyName, "FLAGS")) continue;
- if (!strcmp(subKeyName, "HELPDIR")) continue;
+ 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) {
- RegDeleteKeyA(key, "FLAGS");
- RegDeleteKeyA(key, "HELPDIR");
+ RegDeleteKeyW(key, FLAGSW);
+ RegDeleteKeyW(key, HELPDIRW);
RegCloseKey(key);
key = NULL;
- StringFromGUID2(libid, guid, 80);
- guidA = HEAP_strdupWtoA(GetProcessHeap(), 0, guid);
- sprintf(keyName, "TypeLib\\%s\\%x.%x", guidA, wVerMajor, wVerMinor);
- RegDeleteKeyA(HKEY_CLASSES_ROOT, keyName);
- sprintf(keyName, "TypeLib\\%s", guidA);
- RegDeleteKeyA(HKEY_CLASSES_ROOT, keyName);
- HeapFree(GetProcessHeap(), 0, guidA);
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
+ *strrchrW( keyName, '\\' ) = 0; /* remove last path component */
+ RegDeleteKeyW(HKEY_CLASSES_ROOT, keyName);
}
end:
/* internal ITypeLib data */
typedef struct tagITypeLibImpl
{
- ICOM_VFIELD(ITypeLib2);
- ICOM_VTABLE(ITypeComp) * lpVtblTypeComp;
- UINT ref;
+ 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*
libary. Only used while read MSFT
typelibs */
- /* typelibs are cached, keyed by path, so store the linked list info within them */
+ /* 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 struct ICOM_VTABLE(ITypeLib2) tlbvt;
-static struct ICOM_VTABLE(ITypeComp) tlbtcvt;
+static const ITypeLib2Vtbl tlbvt;
+static const ITypeCompVtbl tlbtcvt;
-#define _ITypeComp_Offset(impl) ((int)(&(((impl*)0)->lpVtblTypeComp)))
-#define ICOM_THIS_From_ITypeComp(impl, iface) impl* This = (impl*)(((char*)iface)-_ITypeComp_Offset(impl))
+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);
/*======================= ITypeInfo implementation =======================*/
-/* data for refernced types */
+/* data for referenced types */
typedef struct tagTLBRefType
{
INT index; /* Type index for internal ref or for external ref
/* internal TypeInfo data */
typedef struct tagITypeInfoImpl
{
- ICOM_VFIELD(ITypeInfo2);
- ICOM_VTABLE(ITypeComp) * lpVtblTypeComp;
- UINT ref;
+ 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;
struct tagITypeInfoImpl * next;
} ITypeInfoImpl;
-static struct ICOM_VTABLE(ITypeInfo2) tinfvt;
-static struct ICOM_VTABLE(ITypeComp) tcompvt;
+static inline ITypeInfoImpl *info_impl_from_ITypeComp( ITypeComp *iface )
+{
+ return (ITypeInfoImpl *)((char*)iface - FIELD_OFFSET(ITypeInfoImpl, lpVtblTypeComp));
+}
-static ITypeInfo2 * WINAPI ITypeInfo_Constructor();
+static const ITypeInfo2Vtbl tinfvt;
+static const ITypeCompVtbl tcompvt;
+
+static ITypeInfo2 * WINAPI ITypeInfo_Constructor(void);
typedef struct tagTLBContext
{
/*
debug
*/
-static void dump_TypeDesc(TYPEDESC *pTD,char *szVarType) {
+static void dump_TypeDesc(const TYPEDESC *pTD,char *szVarType) {
if (pTD->vt & VT_RESERVED)
szVarType += strlen(strcpy(szVarType, "reserved | "));
if (pTD->vt & VT_BYREF)
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 ");
}
}
-void dump_ELEMDESC(ELEMDESC *edesc) {
+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.parmadesc.flags %x\n",edesc->u.paramdesc.wParamFlags);
- MESSAGE("\t\tu.parmadesc.lpex %p\n",edesc->u.paramdesc.pparamdescex);
-}
-void dump_FUNCDESC(FUNCDESC *funcdesc) {
+ 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(")\n\toVft: %d\n", funcdesc->oVft);
MESSAGE("\tcParamsOpt: %d\n", funcdesc->cParamsOpt);
MESSAGE("\twFlags: %x\n", funcdesc->wFuncFlags);
-}
-void dump_IDLDESC(IDLDESC *idl) {
- MESSAGE("\t\twIdlflags: %d\n",idl->wIDLFlags);
+ MESSAGE("\telemdescFunc (return value type):\n");
+ dump_ELEMDESC(&funcdesc->elemdescFunc);
}
static const char * typekind_desc[] =
"TKIND_MAX"
};
-void dump_TYPEATTR(TYPEATTR *tattr) {
- char buf[200];
- MESSAGE("\tguid: %s\n",debugstr_guid(&tattr->guid));
- MESSAGE("\tlcid: %ld\n",tattr->lcid);
- MESSAGE("\tmemidConstructor: %ld\n",tattr->memidConstructor);
- MESSAGE("\tmemidDestructor: %ld\n",tattr->memidDestructor);
- MESSAGE("\tschema: %s\n",debugstr_w(tattr->lpstrSchema));
- MESSAGE("\tsizeInstance: %ld\n",tattr->cbSizeInstance);
- MESSAGE("\tkind:%s\n", typekind_desc[tattr->typekind]);
- MESSAGE("\tcFuncs: %d\n", tattr->cFuncs);
- MESSAGE("\tcVars: %d\n", tattr->cVars);
- MESSAGE("\tcImplTypes: %d\n", tattr->cImplTypes);
- MESSAGE("\tcbSizeVft: %d\n", tattr->cbSizeVft);
- MESSAGE("\tcbAlignment: %d\n", tattr->cbAlignment);
- MESSAGE("\twTypeFlags: %d\n", tattr->wTypeFlags);
- MESSAGE("\tVernum: %d.%d\n", tattr->wMajorVerNum,tattr->wMinorVerNum);
- dump_TypeDesc(&tattr->tdescAlias,buf);
- MESSAGE("\ttypedesc: %s\n", buf);
- dump_IDLDESC(&tattr->idldescType);
-}
-
-static void dump_TLBFuncDescOne(TLBFuncDesc * pfd)
+static void dump_TLBFuncDescOne(const TLBFuncDesc * pfd)
{
int i;
if (!TRACE_ON(typelib))
MESSAGE("\thelpstring: %s\n", debugstr_w(pfd->HelpString));
MESSAGE("\tentry: %s\n", debugstr_w(pfd->Entry));
}
-static void dump_TLBFuncDesc(TLBFuncDesc * pfd)
+static void dump_TLBFuncDesc(const TLBFuncDesc * pfd)
{
while (pfd)
{
pfd = pfd->next;
};
}
-static void dump_TLBVarDesc(TLBVarDesc * pvd)
+static void dump_TLBVarDesc(const TLBVarDesc * pvd)
{
while (pvd)
{
};
}
-static void dump_TLBImpLib(TLBImpLib *import)
+static void dump_TLBImpLib(const TLBImpLib *import)
{
TRACE_(typelib)("%s %s\n", debugstr_guid(&(import->guid)),
debugstr_w(import->name));
import->wVersionMinor, import->lcid, import->offset);
}
-static void dump_TLBRefType(TLBRefType * prt)
+static void dump_TLBRefType(const TLBRefType * prt)
{
while (prt)
{
};
}
-static void dump_TLBImplType(TLBImplType * impl)
+static void dump_TLBImplType(const TLBImplType * impl)
{
while (impl) {
TRACE_(typelib)(
}
}
-void dump_Variant(VARIANT * pvar)
+void dump_Variant(const VARIANT * pvar)
{
SYSTEMTIME st;
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;
-#ifndef __REACTOS /*FIXME*/
case VT_DATE:
if(!VariantTimeToSystemTime(V_DATE(pvar), &st))
TRACE(",<invalid>");
TRACE(",%04d/%02d/%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay,
st.wHour, st.wMinute, st.wSecond);
break;
-#endif
case VT_ERROR:
case VT_VOID:
case VT_USERDEFINED:
TRACE("}\n");
}
-static void dump_DispParms(DISPPARAMS * pdp)
+static void dump_DispParms(const DISPPARAMS * pdp)
{
int index = 0;
}
}
-static void dump_TypeInfo(ITypeInfoImpl * pty)
+static void dump_TypeInfo(const ITypeInfoImpl * pty)
{
- TRACE("%p ref=%u\n", pty, pty->ref);
+ TRACE("%p ref=%lu\n", pty, pty->ref);
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("parent tlb:%p index in TLB:%u\n",pty->pTypeLib, pty->index);
TRACE("%s %s\n", debugstr_w(pty->Name), debugstr_w(pty->DocString));
+ if (pty->TypeAttr.typekind == TKIND_MODULE) TRACE("dllname:%s\n", debugstr_w(pty->DllName));
dump_TLBFuncDesc(pty->funclist);
dump_TLBVarDesc(pty->varlist);
dump_TLBImplType(pty->impltypelist);
}
-void dump_VARDESC(VARDESC *v)
+static void dump_VARDESC(const VARDESC *v)
{
MESSAGE("memid %ld\n",v->memid);
MESSAGE("lpstrSchema %s\n",debugstr_w(v->lpstrSchema));
{{0},30},{{0},31}
};
-static void TLB_abort()
+static void TLB_abort(void)
{
DebugBreak();
}
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 */
-DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
+static DWORD MSFT_Read(void *buffer, DWORD count, TLBContext *pcx, long where )
{
TRACE_(typelib)("pos=0x%08x len=0x%08lx 0x%08x 0x%08x 0x%08lx\n",
pcx->pos, count, pcx->oStart, pcx->length, where);
TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
}
-BSTR MSFT_ReadName( TLBContext *pcx, int offset)
+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;
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 ? */
return bstrName;
}
-BSTR MSFT_ReadString( TLBContext *pcx, int offset)
+static BSTR MSFT_ReadString( TLBContext *pcx, int offset)
{
char * string;
INT16 length;
if(offset <0) { /* data are packed in here */
V_VT(pVar) = (offset & 0x7c000000 )>> 26;
- V_UNION(pVar, iVal) = offset & 0xffff;
+ V_I4(pVar) = offset & 0x3ffffff;
return;
}
MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
case VT_BSTR :{
char * ptr;
MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
- if(size <= 0) {
+ 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_UNION(pVar, bstrVal)=SysAllocStringLen(NULL,size);
+ 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];
}
if(size>0) /* (big|small) endian correct? */
- MSFT_Read(&(V_UNION(pVar, iVal)), size, pcx, DO_NOT_SEEK );
+ MSFT_Read(&(V_I2(pVar)), size, pcx, DO_NOT_SEEK );
return;
}
/*
* 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
+ * 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.
*
- * First entry is always the length of the record (excluding this
+ * The first entry is always the length of the record (including this
* length word).
- * Rest of the record depends on the type of the member. If there is
- * a field indicating the member type (function variable intereface etc)
+ * 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 memeber id
+ * Second follows an array sized nrMEM*sizeof(INT) with a member id
* for each member;
*
- * Third is a equal sized array with file offsets to the name entry
+ * Third is an equal sized array with file offsets to the name entry
* of each member.
*
- * Forth and last (?) part is an array with offsets to the records in the
- * first part of this file segment.
+ * 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;
char recbuf[512];
MSFT_FuncRecord * pFuncRec=(MSFT_FuncRecord *) recbuf;
+ TLBFuncDesc *ptfd_prev = NULL;
TRACE_(typelib)("\n");
MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
- (*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
+ /* 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);
for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
{
- TYPEDESC* lpArgTypeDesc = 0;
+ TYPEDESC *lpArgTypeDesc;
+ ELEMDESC *elemdesc = &(*pptfd)->funcdesc.lprgelemdescParam[j];
MSFT_GetTdesc(pcx,
paraminfo.DataType,
- &(*pptfd)->funcdesc.lprgelemdescParam[j].tdesc,
+ &elemdesc->tdesc,
pTI);
- (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags = paraminfo.Flags;
+ elemdesc->u.paramdesc.wParamFlags = paraminfo.Flags;
- (*pptfd)->pParamDesc[j].Name = (void *) paraminfo.oName;
+ /* 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));
- /* 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)));
- lpArgTypeDesc =
- & ((*pptfd)->funcdesc.lprgelemdescParam[j].tdesc);
+ lpArgTypeDesc = &elemdesc->tdesc;
+ /* resolve referenced type if any */
while ( lpArgTypeDesc != NULL )
{
switch ( lpArgTypeDesc->vt )
lpArgTypeDesc = NULL;
}
}
- }
-
-
- /* parameter is the return value! */
- if ( paraminfo.Flags & PARAMFLAG_FRETVAL )
- {
- TYPEDESC* lpArgTypeDesc;
-
- (*pptfd)->funcdesc.elemdescFunc =
- (*pptfd)->funcdesc.lprgelemdescParam[j];
-
- lpArgTypeDesc = & ((*pptfd)->funcdesc.elemdescFunc.tdesc) ;
-
- 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;
- }
- }
- }
-
- /* second time around */
- for(j=0;j<pFuncRec->nrargs;j++)
- {
- /* name */
- (*pptfd)->pParamDesc[j].Name =
- MSFT_ReadName( pcx, (int)(*pptfd)->pParamDesc[j].Name );
/* default value */
- if ( (PARAMFLAG_FHASDEFAULT &
- (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc.wParamFlags) &&
- ((pFuncRec->FKCCIC) & 0x1000) )
+ if ( (elemdesc->u.paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT) &&
+ (pFuncRec->FKCCIC & 0x1000) )
{
INT* pInt = (INT *)((char *)pFuncRec +
reclength -
(pFuncRec->nrargs * 4 + 1) * sizeof(INT) );
- PARAMDESC* pParamDesc = & (*pptfd)->funcdesc.lprgelemdescParam[j].u.paramdesc;
+ 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 )
{
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;
}
recoffset += reclength;
}
}
-/* fill in data for a hreftype (offset). When the refernced type is contained
+/* 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
* */
if(pImpLib){
(*ppRefType)->reference=offset;
(*ppRefType)->pImpTLInfo = pImpLib;
- MSFT_ReadGuid(&(*ppRefType)->guid, impinfo.oGuid, pcx);
- (*ppRefType)->index = TLB_REF_USE_GUID;
+ 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;
/*
* process a typeinfo record
*/
-ITypeInfoImpl * MSFT_DoTypeInfo(
+static ITypeInfoImpl * MSFT_DoTypeInfo(
TLBContext *pcx,
int count,
ITypeLibImpl * pLibInfo)
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;
/* 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 :(
*/
{
0, 0, &cache_section,
{ &cache_section_debug.ProcessLocksList, &cache_section_debug.ProcessLocksList },
- 0, 0, { 0, (DWORD)(__FILE__ ": typelib loader cache") }
+ 0, 0, { (DWORD_PTR)(__FILE__ ": typelib loader cache") }
};
static CRITICAL_SECTION cache_section = { &cache_section_debug, -1, 0, 0, 0, 0 };
EnterCriticalSection(&cache_section);
for (entry = tlb_cache_first; entry != NULL; entry = entry->next)
{
- if (!strcmpiW(entry->path, pszFileName))
+ if (!strcmpiW(entry->path, pszFileName) && entry->index == index)
{
TRACE("cache hit\n");
*ppTypeLib = (ITypeLib2*)entry;
hFile = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
if (INVALID_HANDLE_VALUE != hFile)
{
- HANDLE hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
+ HANDLE hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL );
if (hMapping)
{
LPVOID pBase = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
}
CloseHandle(hFile);
}
+ else
+ {
+ TRACE("not found, trying to load %s as library\n", debugstr_w(pszFileName));
+ }
- if( (WORD)dwSignature == IMAGE_DOS_SIGNATURE )
+ /* 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)
{
- HRSRC hrsrc = FindResourceA(hinstDLL, MAKEINTRESOURCEA(index),
- "TYPELIB");
+ 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);
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);
{
*ppTI = MSFT_DoTypeInfo(&cx, i, pTypeLibImpl);
- ITypeInfo_AddRef((ITypeInfo*) *ppTI);
ppTI = &((*ppTI)->next);
(pTypeLibImpl->TypeInfoCount)++;
}
paramName = NULL;
HaveOffs = TRUE;
}
- else if(!isalnum(*(paramName-1)))
+ else if(paramName[-1] && !isalnum(paramName[-1]))
HaveOffs = TRUE;
pArg++;
return (SLTG_TypeInfoTail*)(pFirstItem + pMemHeader->cbExtra);
}
-/* Because SLTG_OtherTypeInfo is such a painfull struct, we make a more
+/* Because SLTG_OtherTypeInfo is such a painful struct, we make a more
managable copy of it into this */
typedef struct {
WORD small_no;
DWORD len, order;
ITypeInfoImpl **ppTypeInfoImpl;
- TRACE("%p, TLB length = %ld\n", pLib, dwTLBLength);
+ TRACE_(typelib)("%p, TLB length = %ld\n", pLib, dwTLBLength);
pTypeLibImpl = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ITypeLibImpl));
if (!pTypeLibImpl) return NULL;
pHeader = pLib;
- TRACE("header:\n");
- TRACE("\tmagic=0x%08lx, file blocks = %d\n", pHeader->SLTG_magic,
+ 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",
}
w = *(WORD*)(ptr + 4 + len);
if(w != 0xffff) {
- TRACE("\twith %s\n", debugstr_an(ptr + 6 + len, w));
+ TRACE_(typelib)("\twith %s\n", debugstr_an(ptr + 6 + len, w));
len += w;
pOtherTypeInfoBlks[i].other_name = HeapAlloc(GetProcessHeap(),0,
w+1);
(*ppTypeInfoImpl)->TypeAttr.cbSizeInstance = pTITail->cbSizeInstance;
(*ppTypeInfoImpl)->TypeAttr.cbSizeVft = pTITail->cbSizeVft;
-#define X(x) TRACE("tt "#x": %x\n",pTITail->res##x);
+#define X(x) TRACE_(typelib)("tt "#x": %x\n",pTITail->res##x);
X(06);
X(08);
X(0a);
REFIID riid,
VOID **ppvObject)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
*/
static ULONG WINAPI ITypeLib2_fnAddRef( ITypeLib2 *iface)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
+ ULONG ref = InterlockedIncrement(&This->ref);
- TRACE("(%p)->ref was %u\n",This, This->ref);
+ TRACE("(%p)->ref was %lu\n",This, ref - 1);
- return ++(This->ref);
+ return ref;
}
/* ITypeLib::Release
*/
static ULONG WINAPI ITypeLib2_fnRelease( ITypeLib2 *iface)
{
- ICOM_THIS( ITypeLibImpl, iface);
-
- --(This->ref);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
+ ULONG ref = InterlockedDecrement(&This->ref);
- TRACE("(%p)->(%u)\n",This, This->ref);
+ TRACE("(%p)->(%lu)\n",This, ref);
- if (!This->ref)
+ if (!ref)
{
/* remove cache entry */
TRACE("removing from cache list\n");
return 0;
}
- return This->ref;
+ return ref;
}
/* ITypeLib::GetTypeInfoCount
*/
static UINT WINAPI ITypeLib2_fnGetTypeInfoCount( ITypeLib2 *iface)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("(%p)->count is %d\n",This, This->TypeInfoCount);
return This->TypeInfoCount;
}
{
int i;
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
ITypeInfoImpl *pTypeInfo = This->pTypeInfo;
- TRACE("(%p)->(index=%d) \n", This, index);
+ TRACE("(%p)->(index=%d)\n", This, index);
if (!ppTInfo) return E_INVALIDARG;
UINT index,
TYPEKIND *pTKind)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
int i;
ITypeInfoImpl *pTInfo = This->pTypeInfo;
- TRACE("(%p) index %d \n",This, index);
+ TRACE("(%p) index %d\n", This, index);
if(!pTKind) return E_INVALIDARG;
REFGUID guid,
ITypeInfo **ppTInfo)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
ITypeInfoImpl *pTypeInfo = This->pTypeInfo; /* head of list */
TRACE("(%p)\n\tguid:\t%s)\n",This,debugstr_guid(guid));
ITypeLib2 *iface,
LPTLIBATTR *ppTLibAttr)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("(%p)\n",This);
*ppTLibAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(**ppTLibAttr));
memcpy(*ppTLibAttr, &This->LibAttr, sizeof(**ppTLibAttr));
ITypeLib2 *iface,
ITypeComp **ppTComp)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("(%p)->(%p)\n",This,ppTComp);
*ppTComp = (ITypeComp *)&This->lpVtblTypeComp;
DWORD *pdwHelpContext,
BSTR *pBstrHelpFile)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
HRESULT result = E_INVALIDARG;
if(pBstrName)
{
if (This->Name)
- if(!(*pBstrName = SysAllocString(This->Name))) goto memerr1;else;
+ {
+ if(!(*pBstrName = SysAllocString(This->Name)))
+ goto memerr1;
+ }
else
*pBstrName = NULL;
}
if(pBstrDocString)
{
if (This->DocString)
- if(!(*pBstrDocString = SysAllocString(This->DocString))) goto memerr2;else;
+ {
+ if(!(*pBstrDocString = SysAllocString(This->DocString)))
+ goto memerr2;
+ }
else if (This->Name)
- if(!(*pBstrDocString = SysAllocString(This->Name))) goto memerr2;else;
+ {
+ if(!(*pBstrDocString = SysAllocString(This->Name)))
+ goto memerr2;
+ }
else
*pBstrDocString = NULL;
}
if(pBstrHelpFile)
{
if (This->HelpFile)
- if(!(*pBstrHelpFile = SysAllocString(This->HelpFile))) goto memerr3;else;
+ {
+ if(!(*pBstrHelpFile = SysAllocString(This->HelpFile)))
+ goto memerr3;
+ }
else
*pBstrHelpFile = NULL;
}
ULONG lHashVal,
BOOL *pfName)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
ITypeInfoImpl *pTInfo;
TLBFuncDesc *pFInfo;
TLBVarDesc *pVInfo;
int i;
- UINT nNameBufLen = SysStringLen(szNameBuf);
+ UINT nNameBufLen = (lstrlenW(szNameBuf)+1)*sizeof(WCHAR);
TRACE("(%p)->(%s,%08lx,%p)\n", This, debugstr_w(szNameBuf), lHashVal,
pfName);
MEMBERID *rgMemId,
UINT16 *pcFound)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
ITypeInfoImpl *pTInfo;
TLBFuncDesc *pFInfo;
TLBVarDesc *pVInfo;
int i,j = 0;
-
- UINT nNameBufLen = SysStringLen(szNameBuf);
+ 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++)
+ 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;
ITypeLib2 *iface,
TLIBATTR *pTLibAttr)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("freeing (%p)\n",This);
HeapFree(GetProcessHeap(),0,pTLibAttr);
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TLBCustData *pCData;
for(pCData=This->pCustData; pCData; pCData = pCData->next)
ULONG *pcUniqueNames,
ULONG *pcchUniqueNames)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
FIXME("(%p): stub!\n", This);
DWORD *pdwHelpStringContext,
BSTR *pbstrHelpStringDll)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
HRESULT result;
ITypeInfo *pTInfo;
ITypeLib2 * iface,
CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TLBCustData *pCData;
int i;
TRACE("(%p) returning %d items\n", This, This->ctCustData);
VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
}
-static ICOM_VTABLE(ITypeLib2) tlbvt = {
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+static const ITypeLib2Vtbl tlbvt = {
ITypeLib2_fnQueryInterface,
ITypeLib2_fnAddRef,
ITypeLib2_fnRelease,
static HRESULT WINAPI ITypeLibComp_fnQueryInterface(ITypeComp * iface, REFIID riid, LPVOID * ppv)
{
- ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface);
+ ITypeLibImpl *This = impl_from_ITypeComp(iface);
- return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv);
+ return ITypeLib2_QueryInterface((ITypeLib *)This, riid, ppv);
}
static ULONG WINAPI ITypeLibComp_fnAddRef(ITypeComp * iface)
{
- ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface);
+ ITypeLibImpl *This = impl_from_ITypeComp(iface);
- return ITypeInfo_AddRef((ITypeInfo *)This);
+ return ITypeLib2_AddRef((ITypeLib2 *)This);
}
static ULONG WINAPI ITypeLibComp_fnRelease(ITypeComp * iface)
{
- ICOM_THIS_From_ITypeComp(ITypeLibImpl, iface);
+ ITypeLibImpl *This = impl_from_ITypeComp(iface);
- return ITypeInfo_Release((ITypeInfo *)This);
+ return ITypeLib2_Release((ITypeLib2 *)This);
}
static HRESULT WINAPI ITypeLibComp_fnBind(
ITypeComp * iface,
OLECHAR * szName,
- unsigned long lHash,
- unsigned short wFlags,
+ ULONG lHash,
+ WORD wFlags,
ITypeInfo ** ppTInfo,
DESCKIND * pDescKind,
BINDPTR * pBindPtr)
{
- FIXME("(%s, %lx, 0x%x, %p, %p, %p): stub\n", debugstr_w(szName), lHash, wFlags, ppTInfo, pDescKind, pBindPtr);
- return E_NOTIMPL;
+ 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,
- unsigned long lHash,
+ ULONG lHash,
ITypeInfo ** ppTInfo,
ITypeComp ** ppTComp)
{
return E_NOTIMPL;
}
-static ICOM_VTABLE(ITypeComp) tlbtcvt =
+static const ITypeCompVtbl tlbtcvt =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
ITypeLibComp_fnQueryInterface,
ITypeLibComp_fnAddRef,
pTypeInfoImpl->lpVtbl = &tinfvt;
pTypeInfoImpl->lpVtblTypeComp = &tcompvt;
pTypeInfoImpl->ref=1;
+ pTypeInfoImpl->hreftype = -1;
}
TRACE("(%p)\n", pTypeInfoImpl);
return (ITypeInfo2*) pTypeInfoImpl;
REFIID riid,
VOID **ppvObject)
{
- ICOM_THIS( ITypeLibImpl, iface);
+ ITypeLibImpl *This = (ITypeLibImpl *)iface;
TRACE("(%p)->(IID: %s)\n",This,debugstr_guid(riid));
*/
static ULONG WINAPI ITypeInfo_fnAddRef( ITypeInfo2 *iface)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ ULONG ref = InterlockedIncrement(&This->ref);
- ++(This->ref);
+ ITypeLib2_AddRef((ITypeLib2*)This->pTypeLib);
- TRACE("(%p)->ref is %u\n",This, This->ref);
- return This->ref;
+ TRACE("(%p)->ref is %lu\n",This, ref);
+ return ref;
}
/* ITypeInfo::Release
*/
-static ULONG WINAPI ITypeInfo_fnRelease( ITypeInfo2 *iface)
+static ULONG WINAPI ITypeInfo_fnRelease(ITypeInfo2 *iface)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ ULONG ref = InterlockedDecrement(&This->ref);
- --(This->ref);
+ TRACE("(%p)->(%lu)\n",This, ref);
- TRACE("(%p)->(%u)\n",This, This->ref);
-
- if (!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);
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 This->ref;
+ return ref;
}
/* ITypeInfo::GetTypeAttr
static HRESULT WINAPI ITypeInfo_fnGetTypeAttr( ITypeInfo2 *iface,
LPTYPEATTR *ppTypeAttr)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ const ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ SIZE_T size;
+
TRACE("(%p)\n",This);
- /* FIXME: must do a copy here */
- *ppTypeAttr=&This->TypeAttr;
+
+ 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;
}
static HRESULT WINAPI ITypeInfo_fnGetTypeComp( ITypeInfo2 *iface,
ITypeComp * *ppTComp)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TRACE("(%p)->(%p) stub!\n", This, ppTComp);
return S_OK;
}
-/* ITypeInfo::GetFuncDesc
- *
- * Retrieves the FUNCDESC structure that contains information about a
- * specified function.
- *
- */
-static HRESULT WINAPI ITypeInfo_fnGetFuncDesc( ITypeInfo2 *iface, UINT index,
- LPFUNCDESC *ppFuncDesc)
+static SIZE_T TLB_SizeElemDesc( const ELEMDESC *elemdesc )
{
- ICOM_THIS( ITypeInfoImpl, iface);
- int i;
- TLBFuncDesc * pFDesc;
- TRACE("(%p) index %d\n", This, index);
- for(i=0, pFDesc=This->funclist; i!=index && pFDesc; i++, pFDesc=pFDesc->next)
- ;
- if(pFDesc){
- /* FIXME: must do a copy here */
- *ppFuncDesc=&pFDesc->funcdesc;
+ 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)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
int i;
- TLBVarDesc * pVDesc;
+ 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){
- /* FIXME: must do a copy here */
- *ppVarDesc=&pVDesc->vardesc;
- return S_OK;
- }
+
+ if (pVDesc)
+ return TLB_AllocAndInitVarDesc(&pVDesc->vardesc, ppVarDesc);
+
return E_INVALIDARG;
}
static HRESULT WINAPI ITypeInfo_fnGetNames( ITypeInfo2 *iface, MEMBERID memid,
BSTR *rgBstrNames, UINT cMaxNames, UINT *pcNames)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc * pFDesc;
TLBVarDesc * pVDesc;
int i;
UINT index,
HREFTYPE *pRefType)
{
- ICOM_THIS( ITypeInfoImpl, iface);
- int(i);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
+ int i;
+ HRESULT hr = S_OK;
TLBImplType *pImpl = This->impltypelist;
TRACE("(%p) index %d\n", This, index);
}
else
{
- if (!pImpl) return TYPE_E_ELEMENTNOTFOUND;
- *pRefType = pImpl->hRef;
+ hr = TYPE_E_ELEMENTNOTFOUND;
}
}
else
pImpl = pImpl->next;
}
- if (!pImpl) return TYPE_E_ELEMENTNOTFOUND;
-
- *pRefType = pImpl->hRef;
-
- TRACE("-- 0x%08lx\n", pImpl->hRef );
+ if (pImpl)
+ *pRefType = pImpl->hRef;
+ else
+ hr = TYPE_E_ELEMENTNOTFOUND;
}
- return S_OK;
+ 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
static HRESULT WINAPI ITypeInfo_fnGetImplTypeFlags( ITypeInfo2 *iface,
UINT index, INT *pImplTypeFlags)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
int i;
TLBImplType *pImpl;
static HRESULT WINAPI ITypeInfo_fnGetIDsOfNames( ITypeInfo2 *iface,
LPOLESTR *rgszNames, UINT cNames, MEMBERID *pMemId)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc * pFDesc;
TLBVarDesc * pVDesc;
HRESULT ret=S_OK;
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;
default:
FIXME("unsupported number of arguments %d in stdcall\n",nrargs);
res = -1;
return res;
}
-extern int const _argsize(DWORD vt);
+extern int _argsize(DWORD vt);
/****************************************************************************
* Helper functions for Dispcall / Invoke, which copies one variant
DWORD *argpos, VARIANT *arg, VARTYPE vt
) {
UINT arglen = _argsize(vt)*sizeof(DWORD);
- VARTYPE oldvt;
VARIANT va;
if ((vt==VT_PTR) && tdesc && (tdesc->u.lptdesc->vt == VT_VARIANT)) {
}
if (V_VT(arg) == vt) {
- memcpy(argpos, &V_UNION(arg,lVal), arglen);
+ memcpy(argpos, &V_I4(arg), arglen);
return S_OK;
}
if (V_ISARRAY(arg) && (vt == VT_SAFEARRAY)) {
- memcpy(argpos, &V_UNION(arg,parray), sizeof(SAFEARRAY*));
+ memcpy(argpos, &V_ARRAY(arg), sizeof(SAFEARRAY*));
return S_OK;
}
}
/* Deref BYREF vars if there is need */
if(V_ISBYREF(arg) && ((V_VT(arg) & ~VT_BYREF)==vt)) {
- memcpy(argpos,(void*)V_UNION(arg,lVal), arglen);
+ 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_UNION(arg,lVal), arglen);
+ /* 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;
- TYPEATTR *tattr;
+ 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_UNION(arg,lVal), 4);
+ 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;
}
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
+ 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_UNION(arg,iVal);
- return S_OK;
+ *argpos = V_I2(arg);
+ hres = S_OK;
+ break;
case VT_I4:
- memcpy(argpos, &V_UNION(arg,lVal), 4);
- return S_OK;
+ 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);
- ITypeInfo_Release(tinfo2);
- return hres;
+ break;
case TKIND_INTERFACE:
if (V_VT(arg) == VT_DISPATCH) {
IDispatch *disp;
if (IsEqualIID(&IID_IDispatch,&(tattr->guid))) {
- memcpy(argpos, &V_UNION(arg,pdispVal), 4);
- return S_OK;
+ memcpy(argpos, &V_DISPATCH(arg), 4);
+ hres = S_OK;
+ break;
}
- hres=IUnknown_QueryInterface(V_UNION(arg,pdispVal),&IID_IDispatch,(LPVOID*)&disp);
+ hres=IUnknown_QueryInterface(V_DISPATCH(arg),
+ &IID_IDispatch,(LPVOID*)&disp);
if (SUCCEEDED(hres)) {
memcpy(argpos,&disp,4);
- IUnknown_Release(V_UNION(arg,pdispVal));
- return S_OK;
+ 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)));
- return E_FAIL;
+ 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_UNION(arg,punkVal), 4);
- return S_OK;
+ 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)));
+ 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_UNION(arg,pdispVal), 4);
- return S_OK;
+ memcpy(argpos, &V_DISPATCH(arg), 4);
+ hres = S_OK;
}
- FIXME("TKIND_DISPATCH unhandled for target vt 0x%x.\n",V_VT(arg));
+ 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;
}
- return E_FAIL;
+ ITypeInfo_ReleaseTypeAttr(tinfo2, tattr);
+ ITypeInfo_Release(tinfo2);
+ return hres;
}
- oldvt = V_VT(arg);
VariantInit(&va);
if (VariantChangeType(&va,arg,0,vt)==S_OK) {
- memcpy(argpos,&V_UNION(&va,lVal), arglen);
- FIXME("Should not use VariantChangeType here. (conversion from 0x%x -> 0x%x)\n",
- V_VT(arg), vt
+ 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;
}
return E_FAIL;
}
+static HRESULT userdefined_to_variantvt(ITypeInfo *tinfo, 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, 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;
+ 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 oVft, CALLCONV cc, VARTYPE vtReturn, UINT cActuals,
- VARTYPE* prgvt, VARIANTARG** prgpvarg, VARIANT* pvargResult
-) {
+ 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)
- );
- /* DispCallFunc is only used to invoke methods belonging to an IDispatch-derived COM interface.
- So we need to add a first parameter to the list of arguments, to supply the interface pointer */
- argsize = 1;
- for (i=0;i<cActuals;i++) {
- TRACE("arg %d: type %d, size %d\n",i,prgvt[i],_argsize(prgvt[i]));
- dump_Variant(prgpvarg[i]);
- argsize += _argsize(prgvt[i]);
- }
- args = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*argsize);
- args[0] = (DWORD)pvInstance; /* this is the fake IDispatch interface pointer */
- argspos = 1;
- for (i=0;i<cActuals;i++) {
- VARIANT *arg = prgpvarg[i];
- TRACE("Storing arg %d (%d as %d)\n",i,V_VT(arg),prgvt[i]);
- _copy_arg(NULL, NULL, &args[argspos], arg, prgvt[i]);
- argspos += _argsize(prgvt[i]);
- }
-
- if(pvargResult!=NULL && V_VT(pvargResult)==VT_EMPTY)
+ 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)
{
- _invoke((*(FARPROC**)pvInstance)[oVft/4],cc,argsize,args);
- hres=S_OK;
+ 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))
{
- FIXME("Do not know how to handle pvargResult %p. Expect crash ...\n",pvargResult);
- hres = _invoke((*(FARPROC**)pvInstance)[oVft/4],cc,argsize,args);
- FIXME("Method returned %lx\n",hres);
+ TRACE("Method returned 0x%08lx\n",hres);
+ V_VT(pvargResult) = vtReturn;
+ V_UI4(pvargResult) = hres;
}
+
HeapFree(GetProcessHeap(),0,args);
- return hres;
+ return S_OK;
}
static HRESULT WINAPI ITypeInfo_fnInvoke(
ITypeInfo2 *iface,
VOID *pIUnk,
MEMBERID memid,
- UINT16 dwFlags,
+ UINT16 wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *pArgErr)
{
- ICOM_THIS( ITypeInfoImpl, iface);
- TLBFuncDesc * pFDesc;
- TLBVarDesc * pVDesc;
+ 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) partial stub!\n",
- This,pIUnk,memid,dwFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
+ TRACE("(%p)(%p,id=%ld,flags=0x%08x,%p,%p,%p,%p)\n",
+ This,pIUnk,memid,wFlags,pDispParams,pVarResult,pExcepInfo,pArgErr
);
dump_DispParms(pDispParams);
- for(pFDesc=This->funclist; pFDesc; pFDesc=pFDesc->next)
- if (pFDesc->funcdesc.memid == memid) {
- if (pFDesc->funcdesc.invkind & dwFlags)
- break;
- }
-
- if (pFDesc) {
- if (TRACE_ON(typelib)) dump_TLBFuncDescOne(pFDesc);
- /* dump_FUNCDESC(&pFDesc->funcdesc);*/
- switch (pFDesc->funcdesc.funckind) {
+ /* 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_TLBFuncDesc(pFuncInfo);
+ }
+
+ switch (func_desc->funckind) {
case FUNC_PUREVIRTUAL:
case FUNC_VIRTUAL: {
DWORD res;
int numargs, numargs2, argspos, args2pos;
DWORD *args , *args2;
-
-
- numargs = 1; numargs2 = 0;
- for (i=0;i<pFDesc->funcdesc.cParams;i++) {
- if (i<pDispParams->cArgs)
- numargs += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
- else {
- numargs += 1; /* sizeof(lpvoid) */
- numargs2 += _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
+ 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 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs);
- args2 = (DWORD*)HeapAlloc(GetProcessHeap(),0,sizeof(DWORD)*numargs2);
+ 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<pFDesc->funcdesc.cParams;i++) {
- int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
+ 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 = &pDispParams->rgvarg[pDispParams->cArgs-i-1];
- TYPEDESC *tdesc = &pFDesc->funcdesc.lprgelemdescParam[i].tdesc;
- hres = _copy_arg(iface, tdesc, &args[argspos], arg, tdesc->vt);
- if (FAILED(hres)) return hres;
- argspos += arglen;
+ 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 {
- TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i].tdesc);
- if (tdesc->vt != VT_PTR)
+ 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);
- /*FIXME: give pointers for the rest, so propertyget works*/
+
+ /* 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;
+ )
+ args[argspos]= (DWORD)pVarResult;
argspos += 1;
args2pos += arglen;
}
}
- if (pFDesc->funcdesc.cParamsOpt)
- FIXME("Does not support optional parameters (%d)\n",
- pFDesc->funcdesc.cParamsOpt
- );
+ if (func_desc->cParamsOpt < 0)
+ FIXME("Does not support optional parameters (%d)\n", func_desc->cParamsOpt);
- res = _invoke((*(FARPROC**)pIUnk)[pFDesc->funcdesc.oVft/4],
- pFDesc->funcdesc.callconv,
+ res = _invoke((*(FARPROC**)pIUnk)[func_desc->oVft/4],
+ func_desc->callconv,
numargs,
args
);
- if (pVarResult && (dwFlags & (DISPATCH_PROPERTYGET))) {
- args2pos = 0;
- for (i=0;i<pFDesc->funcdesc.cParams-pDispParams->cArgs;i++) {
- int arglen = _argsize(pFDesc->funcdesc.lprgelemdescParam[i].tdesc.vt);
- TYPEDESC *tdesc = &(pFDesc->funcdesc.lprgelemdescParam[i+pDispParams->cArgs].tdesc);
- TYPEDESC i4_tdesc;
- i4_tdesc.vt = VT_I4;
-
- /* If we are a pointer to a variant, we are done already */
- if ((tdesc->vt==VT_PTR)&&(tdesc->u.lptdesc->vt==VT_VARIANT))
- continue;
-
- VariantInit(pVarResult);
- memcpy(&V_UNION(pVarResult,intVal),&args2[args2pos],arglen*sizeof(DWORD));
- if (tdesc->vt == VT_PTR)
- tdesc = tdesc->u.lptdesc;
- if (tdesc->vt == VT_USERDEFINED) {
- ITypeInfo *tinfo2;
- TYPEATTR *tattr;
-
- hres = ITypeInfo_GetRefTypeInfo(iface,tdesc->u.hreftype,&tinfo2);
- if (hres) {
- FIXME("Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.\n",tdesc->u.hreftype);
- return E_FAIL;
- }
- ITypeInfo_GetTypeAttr(tinfo2,&tattr);
- switch (tattr->typekind) {
- case TKIND_ENUM:
- /* force the return type to be VT_I4 */
- tdesc = &i4_tdesc;
- break;
- case TKIND_ALIAS:
- TRACE("TKIND_ALIAS to vt 0x%x\n",tattr->tdescAlias.vt);
- tdesc = &(tattr->tdescAlias);
- break;
-
- case TKIND_INTERFACE:
- FIXME("TKIND_INTERFACE unhandled.\n");
- break;
- case TKIND_DISPATCH:
- FIXME("TKIND_DISPATCH unhandled.\n");
- break;
- case TKIND_RECORD:
- FIXME("TKIND_RECORD unhandled.\n");
- break;
- default:
- FIXME("TKIND %d unhandled.\n",tattr->typekind);
- break;
- }
- ITypeInfo_Release(tinfo2);
+ if (pVarResult) {
+ 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);
+ }
+ 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;
}
- V_VT(pVarResult) = tdesc->vt;
-
- /* HACK: VB5 likes this.
- * I do not know why. There is 1 example in MSDN which uses
- * this which appears broken (mixes int vals and
- * IDispatch*.).
- */
- if ((tdesc->vt == VT_PTR) && (dwFlags & DISPATCH_METHOD))
- V_VT(pVarResult) = VT_DISPATCH;
- TRACE("storing into variant:\n");
- dump_Variant(pVarResult);
- args2pos += arglen;
}
}
+
+ 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);
- return S_OK;
+ break;
}
case FUNC_DISPATCH: {
IDispatch *disp;
- HRESULT hr;
- hr = IUnknown_QueryInterface((LPUNKNOWN)pIUnk,&IID_IDispatch,(LPVOID*)&disp);
- if (hr) {
+ 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");
- return hr;
- }
- FIXME("Calling Invoke in IDispatch iface. untested!\n");
- hr = IDispatch_Invoke(
- disp,memid,&IID_NULL,LOCALE_USER_DEFAULT,dwFlags,pDispParams,
- pVarResult,pExcepInfo,pArgErr
- );
- if (hr)
- FIXME("IDispatch::Invoke failed with %08lx. (Could be not a real error?)\n",hr);
- IDispatch_Release(disp);
- return hr;
+ break;
}
default:
- FIXME("Unknown function invocation type %d\n",pFDesc->funcdesc.funckind);
- return E_FAIL;
- }
- } else {
- for(pVDesc=This->varlist; pVDesc; pVDesc=pVDesc->next) {
- if (pVDesc->vardesc.memid == memid) {
- FIXME("varseek: Found memid name %s, but variable-based invoking not supported\n",debugstr_w(((LPWSTR)pVDesc->Name)));
- dump_TLBVarDesc(pVDesc);
- break;
- }
- }
+ 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 */
- if (This->TypeAttr.cImplTypes &&
- (This->TypeAttr.typekind==TKIND_INTERFACE || This->TypeAttr.typekind==TKIND_DISPATCH)) {
- /* recursive search */
- ITypeInfo *pTInfo;
- HRESULT hr;
- hr=ITypeInfo_GetRefTypeInfo(iface, This->impltypelist->hRef, &pTInfo);
- if(SUCCEEDED(hr)){
- hr=ITypeInfo_Invoke(pTInfo,pIUnk,memid,dwFlags,pDispParams,pVarResult,pExcepInfo,pArgErr);
- ITypeInfo_Release(pTInfo);
- return hr;
+ 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");
}
- WARN("Could not search inherited interface!\n");
}
- ERR("did not find member id %d, flags %d!\n", (int)memid, dwFlags);
+ ERR("did not find member id %ld, flags 0x%x!\n", memid, wFlags);
return DISP_E_MEMBERNOTFOUND;
}
MEMBERID memid, BSTR *pBstrName, BSTR *pBstrDocString,
DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc * pFDesc;
TLBVarDesc * pVDesc;
TRACE("(%p) memid %ld Name(%p) DocString(%p)"
return S_OK;
}
}
+ WARN("member %ld not found\n", memid);
return TYPE_E_ELEMENTNOTFOUND;
}
INVOKEKIND invKind, BSTR *pBstrDllName, BSTR *pBstrName,
WORD *pwOrdinal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc *pFDesc;
- FIXME("(%p, memid %lx, %d, %p, %p, %p), partial stub!\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
+ 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);
dump_TLBFuncDescOne(pFDesc);
- /* FIXME: This is wrong, but how do you find that out? */
- if (pBstrDllName) {
- const WCHAR oleaut32W[] = {'O','L','E','A','U','T','3','2','.','D','L','L',0};
- *pBstrDllName = SysAllocString(oleaut32W);
- }
+ if (pBstrDllName)
+ *pBstrDllName = SysAllocString(This->DllName);
if (HIWORD(pFDesc->Entry) && (pFDesc->Entry != (void*)-1)) {
if (pBstrName)
*pwOrdinal = (DWORD)pFDesc->Entry;
return S_OK;
}
- return E_FAIL;
+ return TYPE_E_ELEMENTNOTFOUND;
}
/* ITypeInfo::GetRefTypeInfo
HREFTYPE hRefType,
ITypeInfo **ppTInfo)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
HRESULT result = E_FAIL;
-
- if (hRefType == -1 &&
+ 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))
{
ITypeLib *pTLib = NULL;
if(pRefType->pImpTLInfo == TLB_REF_INTERNAL) {
- int Index;
+ UINT Index;
result = ITypeInfo_GetContainingTypeLib(iface, &pTLib, &Index);
} else {
if(pRefType->pImpTLInfo->pImpTypeLib) {
static HRESULT WINAPI ITypeInfo_fnAddressOfMember( ITypeInfo2 *iface,
MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
{
- ICOM_THIS( ITypeInfoImpl, iface);
- FIXME("(%p) stub!\n", This);
+ 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;
}
static HRESULT WINAPI ITypeInfo_fnCreateInstance( ITypeInfo2 *iface,
IUnknown *pUnk, REFIID riid, VOID **ppvObj)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
FIXME("(%p) stub!\n", This);
return S_OK;
}
static HRESULT WINAPI ITypeInfo_fnGetMops( ITypeInfo2 *iface, MEMBERID memid,
BSTR *pBstrMops)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
FIXME("(%p) stub!\n", This);
return S_OK;
}
static HRESULT WINAPI ITypeInfo_fnGetContainingTypeLib( ITypeInfo2 *iface,
ITypeLib * *ppTLib, UINT *pIndex)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
/* If a pointer is null, we simply ignore it, the ATL in particular passes pIndex as 0 */
if (pIndex) {
static void WINAPI ITypeInfo_fnReleaseTypeAttr( ITypeInfo2 *iface,
TYPEATTR* pTypeAttr)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TRACE("(%p)->(%p)\n", This, pTypeAttr);
+ HeapFree(GetProcessHeap(), 0, pTypeAttr);
}
/* ITypeInfo::ReleaseFuncDesc
ITypeInfo2 *iface,
FUNCDESC *pFuncDesc)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ 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
static void WINAPI ITypeInfo_fnReleaseVarDesc( ITypeInfo2 *iface,
VARDESC *pVarDesc)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ 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
static HRESULT WINAPI ITypeInfo2_fnGetTypeKind( ITypeInfo2 * iface,
TYPEKIND *pTypeKind)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
*pTypeKind=This->TypeAttr.typekind;
TRACE("(%p) type 0x%0x\n", This,*pTypeKind);
return S_OK;
*/
static HRESULT WINAPI ITypeInfo2_fnGetTypeFlags( ITypeInfo2 *iface, ULONG *pTypeFlags)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
*pTypeFlags=This->TypeAttr.wTypeFlags;
TRACE("(%p) flags 0x%lx\n", This,*pTypeFlags);
return S_OK;
static HRESULT WINAPI ITypeInfo2_fnGetFuncIndexOfMemId( ITypeInfo2 * iface,
MEMBERID memid, INVOKEKIND invKind, UINT *pFuncIndex)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc *pFuncInfo;
int i;
HRESULT result;
- /* FIXME: should check for invKind??? */
- for(i=0, pFuncInfo=This->funclist;pFuncInfo &&
- memid != pFuncInfo->funcdesc.memid; i++, pFuncInfo=pFuncInfo->next);
- if(pFuncInfo){
- *pFuncIndex=i;
- result= S_OK;
- }else{
- *pFuncIndex=0;
- result=E_INVALIDARG;
- }
+
+ 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)? "SUCCES":"FAILED");
+ memid, invKind, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
return result;
}
static HRESULT WINAPI ITypeInfo2_fnGetVarIndexOfMemId( ITypeInfo2 * iface,
MEMBERID memid, UINT *pVarIndex)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ 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{
- *pVarIndex=0;
- result=E_INVALIDARG;
- }
+ if(pVarInfo) {
+ *pVarIndex = i;
+ result = S_OK;
+ } else
+ result = TYPE_E_ELEMENTNOTFOUND;
+
TRACE("(%p) memid 0x%08lx -> %s\n", This,
- memid, SUCCEEDED(result)? "SUCCES":"FAILED");
+ memid, SUCCEEDED(result) ? "SUCCESS" : "FAILED");
return result;
}
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
for(pCData=This->pCustData; pCData; pCData = pCData->next)
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
int i;
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
int i;
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBVarDesc * pVDesc;
int i;
REFGUID guid,
VARIANT *pVarVal)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBImplType * pRDesc;
int i;
DWORD *pdwHelpStringContext,
BSTR *pbstrHelpStringDll)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBFuncDesc * pFDesc;
TLBVarDesc * pVDesc;
TRACE("(%p) memid %ld lcid(0x%lx) HelpString(%p) "
ITypeInfo2 * iface,
CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
int i;
VariantCopy(& pCustData->prgCustData[i].varValue, & pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
UINT index,
CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBFuncDesc * pFDesc;
int i;
& pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
static HRESULT WINAPI ITypeInfo2_fnGetAllParamCustData( ITypeInfo2 * iface,
UINT indexFunc, UINT indexParam, CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData=NULL;
TLBFuncDesc * pFDesc;
int i;
& pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
static HRESULT WINAPI ITypeInfo2_fnGetAllVarCustData( ITypeInfo2 * iface,
UINT index, CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBVarDesc * pVDesc;
int i;
& pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
UINT index,
CUSTDATA *pCustData)
{
- ICOM_THIS( ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = (ITypeInfoImpl *)iface;
TLBCustData *pCData;
TLBImplType * pRDesc;
int i;
& pCData->data);
}
}else{
- ERR(" OUT OF MEMORY! \n");
+ ERR(" OUT OF MEMORY!\n");
return E_OUTOFMEMORY;
}
return S_OK;
return TYPE_E_ELEMENTNOTFOUND;
}
-static ICOM_VTABLE(ITypeInfo2) tinfvt =
+static const ITypeInfo2Vtbl tinfvt =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
ITypeInfo_fnQueryInterface,
ITypeInfo_fnAddRef,
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)
{
- ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
return ITypeInfo_QueryInterface((ITypeInfo *)This, riid, ppv);
}
static ULONG WINAPI ITypeComp_fnAddRef(ITypeComp * iface)
{
- ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
return ITypeInfo_AddRef((ITypeInfo *)This);
}
static ULONG WINAPI ITypeComp_fnRelease(ITypeComp * iface)
{
- ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface);
+ ITypeInfoImpl *This = info_impl_from_ITypeComp(iface);
return ITypeInfo_Release((ITypeInfo *)This);
}
static HRESULT WINAPI ITypeComp_fnBind(
ITypeComp * iface,
OLECHAR * szName,
- unsigned long lHash,
- unsigned short wFlags,
+ ULONG lHash,
+ WORD wFlags,
ITypeInfo ** ppTInfo,
DESCKIND * pDescKind,
BINDPTR * pBindPtr)
{
- ICOM_THIS_From_ITypeComp(ITypeInfoImpl, iface);
+ 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 (pFDesc->funcdesc.invkind & wFlags)
+ 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;
- pBindPtr->lpfuncdesc = &pFDesc->funcdesc;
*ppTInfo = (ITypeInfo *)&This->lpVtbl;
+ ITypeInfo_AddRef(*ppTInfo);
return S_OK;
} else {
- if (!(wFlags & ~(INVOKE_PROPERTYGET)))
- {
- for(pVDesc = This->varlist; pVDesc; pVDesc = pVDesc->next) {
- if (!strcmpW(pVDesc->Name, szName)) {
- *pDescKind = DESCKIND_VARDESC;
- pBindPtr->lpvardesc = &pVDesc->vardesc;
- *ppTInfo = (ITypeInfo *)&This->lpVtbl;
- return S_OK;
- }
+ 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;
}
}
}
- /* not found, look for it in inherited interfaces */
- if (This->TypeAttr.cImplTypes &&
- (This->TypeAttr.typekind == TKIND_INTERFACE || This->TypeAttr.typekind == TKIND_DISPATCH)) {
+ /* FIXME: search each inherited interface, not just the first */
+ if (This->TypeAttr.cImplTypes) {
/* recursive search */
ITypeInfo *pTInfo;
ITypeComp *pTComp;
}
WARN("Could not search inherited interface!\n");
}
- ERR("did not find member with name %s, flags 0x%x!\n", debugstr_w(szName), wFlags);
- *pDescKind = DESCKIND_NONE;
- pBindPtr->lpfuncdesc = NULL;
- *ppTInfo = NULL;
+ 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,
- unsigned long lHash,
+ ULONG lHash,
ITypeInfo ** ppTInfo,
ITypeComp ** ppTComp)
{
return S_OK;
}
-static ICOM_VTABLE(ITypeComp) tcompvt =
+static const ITypeCompVtbl tcompvt =
{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
ITypeComp_fnQueryInterface,
ITypeComp_fnAddRef,