diff options
Diffstat (limited to 'ext/com_dotnet/com_typeinfo.c')
-rw-r--r-- | ext/com_dotnet/com_typeinfo.c | 603 |
1 files changed, 0 insertions, 603 deletions
diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c deleted file mode 100644 index 6e57eafeb9..0000000000 --- a/ext/com_dotnet/com_typeinfo.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2006 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.txt | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Author: Wez Furlong <wez@thebrainroom.com> | - | Harald Radi <h.radi@nme.at> | - +----------------------------------------------------------------------+ - */ - -/* $Id$ */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_com_dotnet.h" -#include "php_com_dotnet_internal.h" - - -/* The search string can be either: - * a) a file name - * b) a CLSID, major, minor e.g. "{00000200-0000-0010-8000-00AA006D2EA4},2,0" - * c) a Type Library name e.g. "Microsoft OLE DB ActiveX Data Objects 1.0 Library" - */ -PHPAPI ITypeLib *php_com_load_typelib(char *search_string, int codepage TSRMLS_DC) -{ - ITypeLib *TL = NULL; - char *strtok_buf, *major, *minor; - CLSID clsid; - OLECHAR *p; - HRESULT hr; - - search_string = php_strtok_r(search_string, ",", &strtok_buf); - - if (search_string == NULL) { - return NULL; - } - - major = php_strtok_r(NULL, ",", &strtok_buf); - minor = php_strtok_r(NULL, ",", &strtok_buf); - - p = php_com_string_to_olestring(search_string, strlen(search_string), codepage TSRMLS_CC); - - if (SUCCEEDED(CLSIDFromString(p, &clsid))) { - WORD major_i = 1, minor_i = 0; - - /* pick up the major/minor numbers; if none specified, default to 1,0 */ - if (major && minor) { - major_i = (WORD)atoi(major); - minor_i = (WORD)atoi(minor); - } - - /* Load the TypeLib by GUID */ - hr = LoadRegTypeLib((REFGUID)&clsid, major_i, minor_i, LANG_NEUTRAL, &TL); - - /* if that failed, assumed that the GUID is actually a CLSID and - * attemp to get the library via an instance of that class */ - if (FAILED(hr) && (major == NULL || minor == NULL)) { - IDispatch *disp = NULL; - ITypeInfo *info = NULL; - int idx; - - if (SUCCEEDED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&disp)) && - SUCCEEDED(hr = IDispatch_GetTypeInfo(disp, 0, LANG_NEUTRAL, &info))) { - hr = ITypeInfo_GetContainingTypeLib(info, &TL, &idx); - } - - if (info) { - ITypeInfo_Release(info); - } - if (disp) { - IDispatch_Release(disp); - } - } - } else { - /* Try to load it from a file; if it fails, do a really painful search of - * the registry */ - if (FAILED(LoadTypeLib(p, &TL))) { - HKEY hkey, hsubkey; - DWORD SubKeys, MaxSubKeyLength; - char *keyname; - unsigned int i, j; - DWORD VersionCount; - char version[20]; - char *libname; - DWORD libnamelen; - - if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "TypeLib", 0, KEY_READ, &hkey) && - ERROR_SUCCESS == RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys, - &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) { - - MaxSubKeyLength++; /* make room for NUL */ - keyname = emalloc(MaxSubKeyLength); - libname = emalloc(strlen(search_string) + 1); - - for (i = 0; i < SubKeys && TL == NULL; i++) { - if (ERROR_SUCCESS == RegEnumKey(hkey, i, keyname, MaxSubKeyLength) && - ERROR_SUCCESS == RegOpenKeyEx(hkey, keyname, 0, KEY_READ, &hsubkey)) { - if (ERROR_SUCCESS == RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount, - NULL, NULL, NULL, NULL, NULL, NULL, NULL)) { - for (j = 0; j < VersionCount; j++) { - if (ERROR_SUCCESS != RegEnumKey(hsubkey, j, version, sizeof(version))) { - continue; - } - /* get the default value for this key and compare */ - libnamelen = strlen(search_string)+1; - if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) { - if (0 == stricmp(libname, search_string)) { - char *str = NULL; - int major, minor; - - /* fetch the GUID and add the version numbers */ - if (2 != sscanf(version, "%d.%d", &major, &minor)) { - major = 1; - minor = 0; - } - spprintf(&str, 0, "%s,%d,%d", keyname, major, minor); - /* recurse */ - TL = php_com_load_typelib(str, codepage TSRMLS_CC); - - efree(str); - break; - } - } - } - } - RegCloseKey(hsubkey); - } - } - RegCloseKey(hkey); - efree(keyname); - efree(libname); - } - } - } - - efree(p); - - return TL; -} - -/* Given a type-library, merge it into the current engine state */ -PHPAPI int php_com_import_typelib(ITypeLib *TL, int mode, int codepage TSRMLS_DC) -{ - int i, j, interfaces; - TYPEKIND pTKind; - ITypeInfo *TypeInfo; - VARDESC *pVarDesc; - UINT NameCount; - BSTR bstr_ids; - zend_constant c; - zval exists, results, value; - char *const_name; - - if (TL == NULL) { - return FAILURE; - } - - interfaces = ITypeLib_GetTypeInfoCount(TL); - for (i = 0; i < interfaces; i++) { - ITypeLib_GetTypeInfoType(TL, i, &pTKind); - if (pTKind == TKIND_ENUM) { - ITypeLib_GetTypeInfo(TL, i, &TypeInfo); - for (j = 0; ; j++) { - if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) { - break; - } - ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount); - if (NameCount != 1) { - ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); - continue; - } - - const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC); - c.name = zend_strndup(const_name, c.name_len); - efree(const_name); - c.name_len++; /* include NUL */ - SysFreeString(bstr_ids); - - /* sanity check for the case where the constant is already defined */ - if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) { - if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists TSRMLS_CC)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name); - } - free(c.name); - ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); - continue; - } - - /* register the constant */ - php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC); - if (Z_TYPE(value) == IS_LONG) { - c.flags = mode; - c.value.type = IS_LONG; - c.value.value.lval = Z_LVAL(value); - c.module_number = 0; - zend_register_constant(&c TSRMLS_CC); - } - ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); - } - ITypeInfo_Release(TypeInfo); - } - } - return SUCCESS; -} - -/* Type-library stuff */ -void php_com_typelibrary_dtor(void *pDest) -{ - ITypeLib *Lib = *(ITypeLib**)pDest; - ITypeLib_Release(Lib); -} - -PHPAPI ITypeLib *php_com_load_typelib_via_cache(char *search_string, - int codepage, int *cached TSRMLS_DC) -{ - ITypeLib **TLp; - ITypeLib *TL; - char *name_dup; - int l; - - l = strlen(search_string); - - if (zend_ts_hash_find(&php_com_typelibraries, search_string, l+1, - (void**)&TLp) == SUCCESS) { - *cached = 1; - /* add a reference for the caller */ - ITypeLib_AddRef(*TLp); - return *TLp; - } - - *cached = 0; - name_dup = estrndup(search_string, l); - TL = php_com_load_typelib(name_dup, codepage TSRMLS_CC); - efree(name_dup); - - if (TL) { - if (SUCCESS == zend_ts_hash_update(&php_com_typelibraries, - search_string, l+1, (void*)TL, sizeof(ITypeLib*), NULL)) { - /* add a reference for the hash table */ - ITypeLib_AddRef(TL); - } - } - - return TL; -} - -ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj, char *dispname, int sink TSRMLS_DC) -{ - ITypeInfo *typeinfo = NULL; - ITypeLib *typelib = NULL; - int gotguid = 0; - GUID iid; - - if (obj) { - if (dispname == NULL && sink) { - IProvideClassInfo2 *pci2; - IProvideClassInfo *pci; - - if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo2, (void**)&pci2))) { - gotguid = SUCCEEDED(IProvideClassInfo2_GetGUID(pci2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid)); - IProvideClassInfo2_Release(pci2); - } - if (!gotguid && SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo, (void**)&pci))) { - /* examine the available interfaces */ - /* TODO: write some code here */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "IProvideClassInfo: this code not yet written!"); - IProvideClassInfo_Release(pci); - } - } else if (dispname == NULL) { - if (obj->typeinfo) { - ITypeInfo_AddRef(obj->typeinfo); - return obj->typeinfo; - } else { - IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo); - if (typeinfo) { - return typeinfo; - } - } - } else if (dispname && obj->typeinfo) { - unsigned int idx; - /* get the library from the object; the rest will be dealt with later */ - ITypeInfo_GetContainingTypeLib(obj->typeinfo, &typelib, &idx); - } else if (typelibname == NULL) { - IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo); - if (dispname) { - unsigned int idx; - /* get the library from the object; the rest will be dealt with later */ - ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, &idx); - - if (typelib) { - ITypeInfo_Release(typeinfo); - typeinfo = NULL; - } - } - } - } else if (typelibname) { - /* Fetch the typelibrary and use that to look things up */ - typelib = php_com_load_typelib(typelibname, obj->code_page TSRMLS_CC); - } - - if (!gotguid && dispname && typelib) { - unsigned short cfound; - MEMBERID memid; - OLECHAR *olename = php_com_string_to_olestring(dispname, strlen(dispname), CP_ACP TSRMLS_CC); - - cfound = 1; - if (FAILED(ITypeLib_FindName(typelib, olename, 0, &typeinfo, &memid, &cfound)) || cfound == 0) { - CLSID coclass; - ITypeInfo *coinfo; - - /* assume that it might be a progid instead */ - if (SUCCEEDED(CLSIDFromProgID(olename, &coclass)) && - SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &coclass, &coinfo))) { - - /* enumerate implemented interfaces and pick the one as indicated by sink */ - TYPEATTR *attr; - int i; - - ITypeInfo_GetTypeAttr(coinfo, &attr); - - for (i = 0; i < attr->cImplTypes; i++) { - HREFTYPE rt; - int tf; - - if (FAILED(ITypeInfo_GetImplTypeFlags(coinfo, i, &tf))) { - continue; - } - - if ((sink && tf == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) || - (!sink && (tf & IMPLTYPEFLAG_FSOURCE) == 0)) { - - /* flags match what we are looking for */ - - if (SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(coinfo, i, &rt))) - if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(coinfo, rt, &typeinfo))) - break; - - } - } - - ITypeInfo_ReleaseTypeAttr(coinfo, attr); - ITypeInfo_Release(coinfo); - } - } - - - efree(olename); - } else if (gotguid) { - ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo); - } - - if (typelib) { - ITypeLib_Release(typelib); - } - - return typeinfo; -} - -static const struct { - VARTYPE vt; - const char *name; -} vt_names[] = { - { VT_NULL, "VT_NULL" }, - { VT_EMPTY, "VT_EMPTY" }, - { VT_UI1, "VT_UI1" }, - { VT_I2, "VT_I2" }, - { VT_I4, "VT_I4" }, - { VT_R4, "VT_R4" }, - { VT_R8, "VT_R8" }, - { VT_BOOL, "VT_BOOL" }, - { VT_ERROR, "VT_ERROR" }, - { VT_CY, "VT_CY" }, - { VT_DATE, "VT_DATE" }, - { VT_BSTR, "VT_BSTR" }, - { VT_DECIMAL, "VT_DECIMAL" }, - { VT_UNKNOWN, "VT_UNKNOWN" }, - { VT_DISPATCH, "VT_DISPATCH" }, - { VT_VARIANT, "VT_VARIANT" }, - { VT_I1, "VT_I1" }, - { VT_UI2, "VT_UI2" }, - { VT_UI4, "VT_UI4" }, - { VT_INT, "VT_INT" }, - { VT_UINT, "VT_UINT" }, - { VT_ARRAY, "VT_ARRAY" }, - { VT_BYREF, "VT_BYREF" }, - { VT_VOID, "VT_VOID" }, - { VT_PTR, "VT_PTR" }, - { VT_HRESULT, "VT_HRESULT" }, - { VT_SAFEARRAY, "VT_SAFEARRAY" }, - { 0, NULL } -}; - -static inline const char *vt_to_string(VARTYPE vt) -{ - int i; - for (i = 0; vt_names[i].name != NULL; i++) { - if (vt_names[i].vt == vt) - return vt_names[i].name; - } - return "?"; -} - -static char *php_com_string_from_clsid(const CLSID *clsid, int codepage TSRMLS_DC) -{ - LPOLESTR ole_clsid; - char *clsid_str; - - StringFromCLSID(clsid, &ole_clsid); - clsid_str = php_com_olestring_to_string(ole_clsid, NULL, codepage TSRMLS_CC); - LocalFree(ole_clsid); - - return clsid_str; -} - - -int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage TSRMLS_DC) -{ - TYPEATTR *attr; - FUNCDESC *func; - int i; - OLECHAR *olename; - char *ansiname = NULL; - unsigned int ansinamelen; - int ret = 0; - - if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) { - return 0; - } - - /* verify that it is suitable */ - if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) { - - if (guid) { - memcpy(guid, &attr->guid, sizeof(GUID)); - } - - if (printdef) { - char *guidstring; - - ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL); - ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC); - SysFreeString(olename); - - guidstring = php_com_string_from_clsid(&attr->guid, codepage TSRMLS_CC); - php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring); - efree(guidstring); - - efree(ansiname); - } - - if (id_to_name) { - zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0); - } - - /* So we've got the dispatch interface; lets list the event methods */ - for (i = 0; i < attr->cFuncs; i++) { - zval *tmp; - DISPID lastid = 0; /* for props */ - int isprop; - - if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func))) - break; - - isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT); - - if (!isprop || lastid != func->memid) { - - lastid = func->memid; - - ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL); - ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC); - SysFreeString(olename); - - if (printdef) { - int j; - char *funcdesc; - unsigned int funcdesclen, cnames = 0; - BSTR *names; - - names = (BSTR*)safe_emalloc((func->cParams + 1), sizeof(BSTR), 0); - - ITypeInfo_GetNames(typeinfo, func->memid, names, func->cParams + 1, &cnames); - /* first element is the function name */ - SysFreeString(names[0]); - - php_printf("\t/* DISPID=%d */\n", func->memid); - - if (func->elemdescFunc.tdesc.vt != VT_VOID) { - php_printf("\t/* %s [%d] */\n", - vt_to_string(func->elemdescFunc.tdesc.vt), - func->elemdescFunc.tdesc.vt - ); - } - - if (isprop) { - - ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL); - if (olename) { - funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC); - SysFreeString(olename); - php_printf("\t/* %s */\n", funcdesc); - efree(funcdesc); - } - - php_printf("\tvar $%s;\n\n", ansiname); - - } else { - /* a function */ - - php_printf("\tfunction %s(\n", ansiname); - - for (j = 0; j < func->cParams; j++) { - ELEMDESC *elem = &func->lprgelemdescParam[j]; - - php_printf("\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt); - - if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN) - php_printf("[in]"); - if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT) - php_printf("[out]"); - - if (elem->tdesc.vt == VT_PTR) { - /* what does it point to ? */ - php_printf(" --> %s [%d] ", - vt_to_string(elem->tdesc.lptdesc->vt), - elem->tdesc.lptdesc->vt - ); - } - - /* when we handle prop put and get, this will look nicer */ - if (j+1 < (int)cnames) { - funcdesc = php_com_olestring_to_string(names[j+1], &funcdesclen, codepage TSRMLS_CC); - SysFreeString(names[j+1]); - } else { - funcdesc = "???"; - } - - php_printf(" */ %s%s%c\n", - elem->tdesc.vt == VT_PTR ? "&$" : "$", - funcdesc, - j == func->cParams - 1 ? ' ' : ',' - ); - - if (j+1 < (int)cnames) { - efree(funcdesc); - } - } - - php_printf("\t\t)\n\t{\n"); - - ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL); - if (olename) { - funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC); - SysFreeString(olename); - php_printf("\t\t/* %s */\n", funcdesc); - efree(funcdesc); - } - - php_printf("\t}\n"); - } - - efree(names); - } - - if (id_to_name) { - zend_str_tolower(ansiname, ansinamelen); - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, ansiname, ansinamelen, 0); - zend_hash_index_update(id_to_name, func->memid, (void*)&tmp, sizeof(zval *), NULL); - } - } - ITypeInfo_ReleaseFuncDesc(typeinfo, func); - } - - if (printdef) { - php_printf("}\n"); - } - - ret = 1; - } else { - zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind); - } - - ITypeInfo_ReleaseTypeAttr(typeinfo, attr); - - return ret; -} - - |