Annotation of embedaddon/php/ext/com_dotnet/com_typeinfo.c, revision 1.1.1.4

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
1.1.1.4 ! misho       5:    | Copyright (c) 1997-2014 The PHP Group                                |
1.1       misho       6:    +----------------------------------------------------------------------+
                      7:    | This source file is subject to version 3.01 of the PHP license,      |
                      8:    | that is bundled with this package in the file LICENSE, and is        |
                      9:    | available through the world-wide-web at the following url:           |
                     10:    | http://www.php.net/license/3_01.txt                                  |
                     11:    | If you did not receive a copy of the PHP license and are unable to   |
                     12:    | obtain it through the world-wide-web, please send a note to          |
                     13:    | license@php.net so we can mail you a copy immediately.               |
                     14:    +----------------------------------------------------------------------+
                     15:    | Author: Wez Furlong <wez@thebrainroom.com>                           |
                     16:    |         Harald Radi <h.radi@nme.at>                                  |
                     17:    +----------------------------------------------------------------------+
                     18:  */
                     19: 
1.1.1.2   misho      20: /* $Id$ */
1.1       misho      21: 
                     22: #ifdef HAVE_CONFIG_H
                     23: #include "config.h"
                     24: #endif
                     25: 
                     26: #include "php.h"
                     27: #include "php_ini.h"
                     28: #include "ext/standard/info.h"
                     29: #include "php_com_dotnet.h"
                     30: #include "php_com_dotnet_internal.h"
                     31: 
                     32: 
                     33: /* The search string can be either:
                     34:  * a) a file name
                     35:  * b) a CLSID, major, minor e.g. "{00000200-0000-0010-8000-00AA006D2EA4},2,0"
                     36:  * c) a Type Library name e.g. "Microsoft OLE DB ActiveX Data Objects 1.0 Library"
                     37:  */
1.1.1.3   misho      38: PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib(char *search_string, int codepage TSRMLS_DC)
1.1       misho      39: {
                     40:        ITypeLib *TL = NULL;
                     41:        char *strtok_buf, *major, *minor;
                     42:        CLSID clsid;
                     43:        OLECHAR *p;
                     44:        HRESULT hr;
                     45: 
                     46:        search_string = php_strtok_r(search_string, ",", &strtok_buf);
                     47: 
                     48:        if (search_string == NULL) {
                     49:                return NULL;
                     50:        }
                     51: 
                     52:        major = php_strtok_r(NULL, ",", &strtok_buf);
                     53:        minor = php_strtok_r(NULL, ",", &strtok_buf);
                     54: 
                     55:        p = php_com_string_to_olestring(search_string, strlen(search_string), codepage TSRMLS_CC);
                     56: 
                     57:        if (SUCCEEDED(CLSIDFromString(p, &clsid))) {
                     58:                WORD major_i = 1, minor_i = 0;
                     59: 
                     60:                /* pick up the major/minor numbers; if none specified, default to 1,0 */
                     61:                if (major && minor) {
                     62:                        major_i = (WORD)atoi(major);
                     63:                        minor_i = (WORD)atoi(minor);
                     64:                }
                     65: 
                     66:                /* Load the TypeLib by GUID */
                     67:                hr = LoadRegTypeLib((REFGUID)&clsid, major_i, minor_i, LANG_NEUTRAL, &TL);
                     68: 
                     69:                /* if that failed, assumed that the GUID is actually a CLSID and
                     70:                 * attemp to get the library via an instance of that class */
                     71:                if (FAILED(hr) && (major == NULL || minor == NULL)) {
                     72:                        IDispatch *disp = NULL;
                     73:                        ITypeInfo *info = NULL;
                     74:                        int idx;
                     75: 
                     76:                        if (SUCCEEDED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&disp)) &&
                     77:                                        SUCCEEDED(hr = IDispatch_GetTypeInfo(disp, 0, LANG_NEUTRAL, &info))) {
                     78:                                hr = ITypeInfo_GetContainingTypeLib(info, &TL, &idx);
                     79:                        }
                     80: 
                     81:                        if (info) {
                     82:                                ITypeInfo_Release(info);
                     83:                        }
                     84:                        if (disp) {
                     85:                                IDispatch_Release(disp);
                     86:                        }
                     87:                }
                     88:        } else {
                     89:                /* Try to load it from a file; if it fails, do a really painful search of
                     90:                 * the registry */
                     91:                if (FAILED(LoadTypeLib(p, &TL))) {
                     92:                        HKEY hkey, hsubkey;
                     93:                        DWORD SubKeys, MaxSubKeyLength;
                     94:                        char *keyname;
                     95:                        unsigned int i, j;
                     96:                        DWORD VersionCount;
                     97:                        char version[20];
                     98:                        char *libname;
                     99:                        DWORD libnamelen;
                    100: 
                    101:                        if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "TypeLib", 0, KEY_READ, &hkey) &&
                    102:                                        ERROR_SUCCESS == RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys,
                    103:                                        &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) {
                    104: 
                    105:                                MaxSubKeyLength++; /* make room for NUL */
                    106:                                keyname = emalloc(MaxSubKeyLength);
                    107:                                libname = emalloc(strlen(search_string) + 1);
                    108: 
                    109:                                for (i = 0; i < SubKeys && TL == NULL; i++) {
                    110:                                        if (ERROR_SUCCESS == RegEnumKey(hkey, i, keyname, MaxSubKeyLength) &&
                    111:                                                        ERROR_SUCCESS == RegOpenKeyEx(hkey, keyname, 0, KEY_READ, &hsubkey)) {
                    112:                                                if (ERROR_SUCCESS == RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount,
                    113:                                                                NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
                    114:                                                        for (j = 0; j < VersionCount; j++) {
                    115:                                                                if (ERROR_SUCCESS != RegEnumKey(hsubkey, j, version, sizeof(version))) {
                    116:                                                                        continue;
                    117:                                                                }
                    118:                                                                /* get the default value for this key and compare */
                    119:                                                                libnamelen = strlen(search_string)+1;
                    120:                                                                if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) {
                    121:                                                                        if (0 == stricmp(libname, search_string)) {
                    122:                                                                                char *str = NULL;
                    123:                                                                                int major_tmp, minor_tmp;
                    124: 
                    125:                                                                                /* fetch the GUID and add the version numbers */
                    126:                                                                                if (2 != sscanf(version, "%d.%d", &major_tmp, &minor_tmp)) {
                    127:                                                                                        major_tmp = 1;
                    128:                                                                                        minor_tmp = 0;
                    129:                                                                                }
                    130:                                                                                spprintf(&str, 0, "%s,%d,%d", keyname, major_tmp, minor_tmp);
                    131:                                                                                /* recurse */
                    132:                                                                                TL = php_com_load_typelib(str, codepage TSRMLS_CC);
                    133: 
                    134:                                                                                efree(str);
                    135:                                                                                break;
                    136:                                                                        }
                    137:                                                                }
                    138:                                                        }
                    139:                                                }
                    140:                                                RegCloseKey(hsubkey);
                    141:                                        }
                    142:                                }
                    143:                                RegCloseKey(hkey);
                    144:                                efree(keyname);
                    145:                                efree(libname);
                    146:                        }
                    147:                }
                    148:        }
                    149:        
                    150:        efree(p);
                    151: 
                    152:        return TL;
                    153: }
                    154: 
                    155: /* Given a type-library, merge it into the current engine state */
1.1.1.3   misho     156: PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepage TSRMLS_DC)
1.1       misho     157: {
                    158:        int i, j, interfaces;
                    159:        TYPEKIND pTKind;
                    160:        ITypeInfo *TypeInfo;
                    161:        VARDESC *pVarDesc;
                    162:        UINT NameCount;
                    163:        BSTR bstr_ids;
                    164:        zend_constant c;
                    165:        zval exists, results, value;
                    166:        char *const_name;
                    167: 
                    168:        if (TL == NULL) {
                    169:                return FAILURE;
                    170:        }
                    171: 
                    172:        interfaces = ITypeLib_GetTypeInfoCount(TL);
                    173:        for (i = 0; i < interfaces; i++) {
                    174:                ITypeLib_GetTypeInfoType(TL, i, &pTKind);
                    175:                if (pTKind == TKIND_ENUM) {
                    176:                        ITypeLib_GetTypeInfo(TL, i, &TypeInfo);
                    177:                        for (j = 0; ; j++) {
                    178:                                if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) {
                    179:                                        break;
                    180:                                }
                    181:                                ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
                    182:                                if (NameCount != 1) {
                    183:                                        ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                    184:                                        continue;
                    185:                                }
                    186: 
                    187:                                const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC);
                    188:                                c.name = zend_strndup(const_name, c.name_len);
                    189:                                efree(const_name);
1.1.1.2   misho     190:                                if(c.name == NULL) {
                    191:                                        ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                    192:                                        continue;
                    193:                                }
1.1       misho     194:                                c.name_len++; /* include NUL */
                    195:                                SysFreeString(bstr_ids);
                    196: 
                    197:                                /* sanity check for the case where the constant is already defined */
                    198:                                if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) {
                    199:                                        if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists TSRMLS_CC)) {
                    200:                                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name);
                    201:                                        }
                    202:                                        free(c.name);
                    203:                                        ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                    204:                                        continue;
                    205:                                }
                    206: 
                    207:                                /* register the constant */
                    208:                                php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC);
                    209:                                if (Z_TYPE(value) == IS_LONG) {
                    210:                                        c.flags = mode;
                    211:                                        c.value.type = IS_LONG;
                    212:                                        c.value.value.lval = Z_LVAL(value);
                    213:                                        c.module_number = 0;
                    214:                                        zend_register_constant(&c TSRMLS_CC);
                    215:                                }
                    216:                                ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                    217:                        }
                    218:                        ITypeInfo_Release(TypeInfo);
                    219:                }
                    220:        }
                    221:        return SUCCESS;
                    222: }
                    223: 
                    224: /* Type-library stuff */
                    225: void php_com_typelibrary_dtor(void *pDest)
                    226: {
                    227:        ITypeLib **Lib = (ITypeLib**)pDest;
                    228:        ITypeLib_Release(*Lib);
                    229: }
                    230: 
1.1.1.3   misho     231: PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
1.1       misho     232:        int codepage, int *cached TSRMLS_DC)
                    233: {
                    234:        ITypeLib **TLp;
                    235:        ITypeLib *TL;
                    236:        char *name_dup;
                    237:        int l;
                    238: 
                    239:        l = strlen(search_string);
                    240: 
                    241:        if (zend_ts_hash_find(&php_com_typelibraries, search_string, l+1,
                    242:                        (void**)&TLp) == SUCCESS) {
                    243:                *cached = 1;
                    244:                /* add a reference for the caller */
                    245:                ITypeLib_AddRef(*TLp);
                    246:                return *TLp;
                    247:        }
                    248: 
                    249:        *cached = 0;
                    250:        name_dup = estrndup(search_string, l);
                    251:        TL = php_com_load_typelib(name_dup, codepage TSRMLS_CC);
                    252:        efree(name_dup);
                    253: 
                    254:        if (TL) {
                    255:                if (SUCCESS == zend_ts_hash_update(&php_com_typelibraries,
                    256:                                search_string, l+1, (void*)&TL, sizeof(ITypeLib*), NULL)) {
                    257:                        /* add a reference for the hash table */
                    258:                        ITypeLib_AddRef(TL);
                    259:                }
                    260:        }
                    261: 
                    262:        return TL;
                    263: }
                    264: 
                    265: ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj, char *dispname, int sink TSRMLS_DC)
                    266: {
                    267:        ITypeInfo *typeinfo = NULL;
                    268:        ITypeLib *typelib = NULL;
                    269:        int gotguid = 0;
                    270:        GUID iid;
                    271:        
                    272:        if (obj) {
                    273:                if (dispname == NULL && sink) {
                    274:                        IProvideClassInfo2 *pci2;
                    275:                        IProvideClassInfo *pci;
                    276: 
                    277:                        if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo2, (void**)&pci2))) {
                    278:                                gotguid = SUCCEEDED(IProvideClassInfo2_GetGUID(pci2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid));
                    279:                                IProvideClassInfo2_Release(pci2);
                    280:                        }
                    281:                        if (!gotguid && SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo, (void**)&pci))) {
                    282:                                /* examine the available interfaces */
                    283:                                /* TODO: write some code here */
                    284:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "IProvideClassInfo: this code not yet written!");
                    285:                                IProvideClassInfo_Release(pci);
                    286:                        }
                    287:                } else if (dispname == NULL) {
                    288:                        if (obj->typeinfo) {
                    289:                                ITypeInfo_AddRef(obj->typeinfo);
                    290:                                return obj->typeinfo;
                    291:                        } else {
                    292:                                IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
                    293:                                if (typeinfo) {
                    294:                                        return typeinfo;
                    295:                                }
                    296:                        }
                    297:                } else if (dispname && obj->typeinfo) {
                    298:                        unsigned int idx;
                    299:                        /* get the library from the object; the rest will be dealt with later */
                    300:                        ITypeInfo_GetContainingTypeLib(obj->typeinfo, &typelib, &idx);
                    301:                } else if (typelibname == NULL) {
                    302:                        IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
                    303:                        if (dispname) {
                    304:                                unsigned int idx;
                    305:                                /* get the library from the object; the rest will be dealt with later */
                    306:                                ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, &idx);
                    307: 
                    308:                                if (typelib) {
                    309:                                        ITypeInfo_Release(typeinfo);
                    310:                                        typeinfo = NULL;
                    311:                                }
                    312:                        }
                    313:                }
                    314:        } else if (typelibname) {
                    315:                /* Fetch the typelibrary and use that to look things up */
                    316:                typelib = php_com_load_typelib(typelibname, CP_THREAD_ACP TSRMLS_CC);
                    317:        } 
                    318: 
                    319:        if (!gotguid && dispname && typelib) {
                    320:                unsigned short cfound;
                    321:                MEMBERID memid;
                    322:                OLECHAR *olename = php_com_string_to_olestring(dispname, strlen(dispname), CP_ACP TSRMLS_CC);
                    323:                        
                    324:                cfound = 1;
                    325:                if (FAILED(ITypeLib_FindName(typelib, olename, 0, &typeinfo, &memid, &cfound)) || cfound == 0) {
                    326:                        CLSID coclass;
                    327:                        ITypeInfo *coinfo;
                    328:        
                    329:                        /* assume that it might be a progid instead */
                    330:                        if (SUCCEEDED(CLSIDFromProgID(olename, &coclass)) &&
                    331:                                        SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &coclass, &coinfo))) {
                    332: 
                    333:                                /* enumerate implemented interfaces and pick the one as indicated by sink */
                    334:                                TYPEATTR *attr;
                    335:                                int i;
                    336: 
                    337:                                ITypeInfo_GetTypeAttr(coinfo, &attr);
                    338: 
                    339:                                for (i = 0; i < attr->cImplTypes; i++) {
                    340:                                        HREFTYPE rt;
                    341:                                        int tf;
                    342: 
                    343:                                        if (FAILED(ITypeInfo_GetImplTypeFlags(coinfo, i, &tf))) {
                    344:                                                continue;
                    345:                                        }
                    346: 
                    347:                                        if ((sink && tf == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) ||
                    348:                                                (!sink && (tf & IMPLTYPEFLAG_FSOURCE) == 0)) {
                    349: 
                    350:                                                /* flags match what we are looking for */
                    351: 
                    352:                                                if (SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(coinfo, i, &rt)))
                    353:                                                        if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(coinfo, rt, &typeinfo)))
                    354:                                                                break;
                    355:                                                
                    356:                                        }
                    357:                                }
                    358:                                
                    359:                                ITypeInfo_ReleaseTypeAttr(coinfo, attr);
                    360:                                ITypeInfo_Release(coinfo);
                    361:                        }
                    362:                }
                    363: 
                    364:                
                    365:                efree(olename);
                    366:        } else if (gotguid) {
                    367:                ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo);
                    368:        }
                    369: 
                    370:        if (typelib) {
                    371:                ITypeLib_Release(typelib);
                    372:        }
                    373: 
                    374:        return typeinfo;
                    375: }
                    376: 
                    377: static const struct {
                    378:        VARTYPE vt;
                    379:        const char *name;
                    380: } vt_names[] = {
                    381:        { VT_NULL,              "VT_NULL" },
                    382:        { VT_EMPTY,             "VT_EMPTY" },
                    383:        { VT_UI1,               "VT_UI1" },
                    384:        { VT_I2,                "VT_I2" },
                    385:        { VT_I4,                "VT_I4" },
                    386:        { VT_R4,                "VT_R4" },
                    387:        { VT_R8,                "VT_R8" },
                    388:        { VT_BOOL,              "VT_BOOL" },
                    389:        { VT_ERROR,             "VT_ERROR" },
                    390:        { VT_CY,                "VT_CY" },
                    391:        { VT_DATE,              "VT_DATE" },
                    392:        { VT_BSTR,              "VT_BSTR" },
                    393:        { VT_DECIMAL,   "VT_DECIMAL" },
                    394:        { VT_UNKNOWN,   "VT_UNKNOWN" },
                    395:        { VT_DISPATCH,  "VT_DISPATCH" },
                    396:        { VT_VARIANT,   "VT_VARIANT" },
                    397:        { VT_I1,                "VT_I1" },
                    398:        { VT_UI2,               "VT_UI2" },
                    399:        { VT_UI4,               "VT_UI4" },
                    400:        { VT_INT,               "VT_INT" },
                    401:        { VT_UINT,              "VT_UINT" },
                    402:        { VT_ARRAY,             "VT_ARRAY" },
                    403:        { VT_BYREF,             "VT_BYREF" },
                    404:        { VT_VOID,              "VT_VOID" },
                    405:        { VT_PTR,               "VT_PTR" },
                    406:        { VT_HRESULT,   "VT_HRESULT" },
                    407:        { VT_SAFEARRAY, "VT_SAFEARRAY" },
                    408:        { 0, NULL }
                    409: };
                    410: 
                    411: static inline const char *vt_to_string(VARTYPE vt)
                    412: {
                    413:        int i;
                    414:        for (i = 0; vt_names[i].name != NULL; i++) {
                    415:                if (vt_names[i].vt == vt)
                    416:                        return vt_names[i].name;
                    417:        }
                    418:        return "?";
                    419: }
                    420: 
                    421: static char *php_com_string_from_clsid(const CLSID *clsid, int codepage TSRMLS_DC)
                    422: {
                    423:        LPOLESTR ole_clsid;
                    424:        char *clsid_str;
                    425: 
                    426:        StringFromCLSID(clsid, &ole_clsid);
                    427:        clsid_str = php_com_olestring_to_string(ole_clsid, NULL, codepage TSRMLS_CC);
                    428:        LocalFree(ole_clsid);
                    429: 
                    430:        return clsid_str;
                    431: }
                    432: 
                    433: 
                    434: int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage TSRMLS_DC)
                    435: {
                    436:        TYPEATTR *attr;
                    437:        FUNCDESC *func;
                    438:        int i;
                    439:        OLECHAR *olename;
                    440:        char *ansiname = NULL;
                    441:        unsigned int ansinamelen;
                    442:        int ret = 0;
                    443: 
                    444:        if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) {
                    445:                return 0;
                    446:        }
                    447: 
                    448:        /* verify that it is suitable */
                    449:        if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) {
                    450: 
                    451:                if (guid) {
                    452:                        memcpy(guid, &attr->guid, sizeof(GUID));
                    453:                }
                    454:                
                    455:                if (printdef) {
                    456:                        char *guidstring;
                    457: 
                    458:                        ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL);
                    459:                        ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC);
                    460:                        SysFreeString(olename);
                    461: 
                    462:                        guidstring = php_com_string_from_clsid(&attr->guid, codepage TSRMLS_CC);
                    463:                        php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring);
                    464:                        efree(guidstring);
                    465: 
                    466:                        efree(ansiname);
                    467:                }
                    468: 
                    469:                if (id_to_name) {
                    470:                        zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
                    471:                }
                    472: 
                    473:                /* So we've got the dispatch interface; lets list the event methods */
                    474:                for (i = 0; i < attr->cFuncs; i++) {
                    475:                        zval *tmp;
                    476:                        DISPID lastid = 0;      /* for props */
                    477:                        int isprop;
                    478: 
                    479:                        if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func)))
                    480:                                break;
                    481: 
                    482:                        isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT);
                    483: 
                    484:                        if (!isprop || lastid != func->memid) {
                    485: 
                    486:                                lastid = func->memid;
                    487:                                
                    488:                                ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL);
                    489:                                ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC);
                    490:                                SysFreeString(olename);
                    491: 
                    492:                                if (printdef) {
                    493:                                        int j;
                    494:                                        char *funcdesc;
                    495:                                        unsigned int funcdesclen, cnames = 0;
                    496:                                        BSTR *names;
                    497: 
                    498:                                        names = (BSTR*)safe_emalloc((func->cParams + 1), sizeof(BSTR), 0);
                    499: 
                    500:                                        ITypeInfo_GetNames(typeinfo, func->memid, names, func->cParams + 1, &cnames);
                    501:                                        /* first element is the function name */
                    502:                                        SysFreeString(names[0]);
                    503: 
                    504:                                        php_printf("\t/* DISPID=%d */\n", func->memid);
                    505: 
                    506:                                        if (func->elemdescFunc.tdesc.vt != VT_VOID) {
                    507:                                                php_printf("\t/* %s [%d] */\n",
                    508:                                                                vt_to_string(func->elemdescFunc.tdesc.vt),
                    509:                                                                func->elemdescFunc.tdesc.vt
                    510:                                                                );
                    511:                                        }
                    512: 
                    513:                                        if (isprop) {
                    514: 
                    515:                                                ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
                    516:                                                if (olename) {
                    517:                                                        funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC);
                    518:                                                        SysFreeString(olename);
                    519:                                                        php_printf("\t/* %s */\n", funcdesc);
                    520:                                                        efree(funcdesc);
                    521:                                                }
                    522: 
                    523:                                                php_printf("\tvar $%s;\n\n", ansiname);
                    524: 
                    525:                                        } else {
                    526:                                                /* a function */
                    527: 
                    528:                                                php_printf("\tfunction %s(\n", ansiname);
                    529: 
                    530:                                                for (j = 0; j < func->cParams; j++) {
                    531:                                                        ELEMDESC *elem = &func->lprgelemdescParam[j];
                    532: 
                    533:                                                        php_printf("\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt);
                    534: 
                    535:                                                        if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN)
                    536:                                                                php_printf("[in]");
                    537:                                                        if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT)
                    538:                                                                php_printf("[out]");
                    539: 
                    540:                                                        if (elem->tdesc.vt == VT_PTR) {
                    541:                                                                /* what does it point to ? */
                    542:                                                                php_printf(" --> %s [%d] ",
                    543:                                                                                vt_to_string(elem->tdesc.lptdesc->vt),
                    544:                                                                                elem->tdesc.lptdesc->vt
                    545:                                                                                );
                    546:                                                        }
                    547: 
                    548:                                                        /* when we handle prop put and get, this will look nicer */
                    549:                                                        if (j+1 < (int)cnames) {
                    550:                                                                funcdesc = php_com_olestring_to_string(names[j+1], &funcdesclen, codepage TSRMLS_CC);
                    551:                                                                SysFreeString(names[j+1]);
                    552:                                                        } else {
                    553:                                                                funcdesc = "???";
                    554:                                                        }
                    555: 
                    556:                                                        php_printf(" */ %s%s%c\n",
                    557:                                                                        elem->tdesc.vt == VT_PTR ? "&$" : "$",
                    558:                                                                        funcdesc,
                    559:                                                                        j == func->cParams - 1 ? ' ' : ','
                    560:                                                                        );
                    561: 
                    562:                                                        if (j+1 < (int)cnames) {
                    563:                                                                efree(funcdesc);
                    564:                                                        }
                    565:                                                }
                    566: 
                    567:                                                php_printf("\t\t)\n\t{\n");
                    568: 
                    569:                                                ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
                    570:                                                if (olename) {
                    571:                                                        funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC);
                    572:                                                        SysFreeString(olename);
                    573:                                                        php_printf("\t\t/* %s */\n", funcdesc);
                    574:                                                        efree(funcdesc);
                    575:                                                }
                    576: 
                    577:                                                php_printf("\t}\n");
                    578:                                        }
                    579: 
                    580:                                        efree(names);
                    581:                                }
                    582: 
                    583:                                if (id_to_name) {
                    584:                                        zend_str_tolower(ansiname, ansinamelen);
                    585:                                        MAKE_STD_ZVAL(tmp);
                    586:                                        ZVAL_STRINGL(tmp, ansiname, ansinamelen, 0);
                    587:                                        zend_hash_index_update(id_to_name, func->memid, (void*)&tmp, sizeof(zval *), NULL);
                    588:                                }
                    589:                        }
                    590:                        ITypeInfo_ReleaseFuncDesc(typeinfo, func);
                    591:                }
                    592: 
                    593:                if (printdef) {
                    594:                        php_printf("}\n");
                    595:                }
                    596: 
                    597:                ret = 1;
                    598:        } else {
                    599:                zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind);
                    600:        }
                    601: 
                    602:        ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
                    603: 
                    604:        return ret;
                    605: }
                    606: 
                    607: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>