root/ext/com_dotnet/com_typeinfo.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_com_load_typelib
  2. php_com_import_typelib
  3. php_com_typelibrary_dtor
  4. php_com_load_typelib_via_cache
  5. php_com_locate_typeinfo
  6. vt_to_string
  7. php_com_string_from_clsid
  8. php_com_process_typeinfo

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   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 
  20 /* $Id$ */
  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  */
  38 PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib(char *search_string, int codepage)
  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);
  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                  * attempt 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                         UINT 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                         long 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 = (long)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);
 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 */
 156 PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepage)
 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         size_t len;
 168 
 169         if (TL == NULL) {
 170                 return FAILURE;
 171         }
 172 
 173         interfaces = ITypeLib_GetTypeInfoCount(TL);
 174         for (i = 0; i < interfaces; i++) {
 175                 ITypeLib_GetTypeInfoType(TL, i, &pTKind);
 176                 if (pTKind == TKIND_ENUM) {
 177                         ITypeLib_GetTypeInfo(TL, i, &TypeInfo);
 178                         for (j = 0; ; j++) {
 179                                 if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) {
 180                                         break;
 181                                 }
 182                                 ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
 183                                 if (NameCount != 1) {
 184                                         ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
 185                                         continue;
 186                                 }
 187 
 188                                 const_name = php_com_olestring_to_string(bstr_ids, &len, codepage);
 189                                 c.name = zend_string_init(const_name, len, 1);
 190                                 // TODO: avoid reallocation???
 191                                 efree(const_name);
 192                                 if(c.name == NULL) {
 193                                         ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
 194                                         continue;
 195                                 }
 196 //???                           c.name_len++; /* include NUL */
 197                                 SysFreeString(bstr_ids);
 198 
 199                                 /* sanity check for the case where the constant is already defined */
 200                                 if ((exists = zend_get_constant(c.name)) != NULL) {
 201                                         if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, exists)) {
 202                                                 php_error_docref(NULL, E_WARNING, "Type library constant %s is already defined", c.name);
 203                                         }
 204                                         zend_string_release(c.name);
 205                                         ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
 206                                         continue;
 207                                 }
 208 
 209                                 /* register the constant */
 210                                 php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage);
 211                                 if (Z_TYPE(value) == IS_LONG) {
 212                                         c.flags = mode;
 213                                         ZVAL_LONG(&c.value, Z_LVAL(value));
 214                                         c.module_number = 0;
 215                                         zend_register_constant(&c);
 216                                 }
 217                                 ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
 218                         }
 219                         ITypeInfo_Release(TypeInfo);
 220                 }
 221         }
 222         return SUCCESS;
 223 }
 224 
 225 /* Type-library stuff */
 226 void php_com_typelibrary_dtor(void *pDest)
 227 {
 228         ITypeLib **Lib = (ITypeLib**)pDest;
 229         ITypeLib_Release(*Lib);
 230 }
 231 
 232 PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
 233         int codepage, int *cached)
 234 {
 235         ITypeLib *TL;
 236         char *name_dup;
 237         size_t l;
 238 
 239         l = strlen(search_string);
 240 
 241         if ((TL = zend_ts_hash_str_find_ptr(&php_com_typelibraries, search_string, l)) != NULL) {
 242                 *cached = 1;
 243                 /* add a reference for the caller */
 244                 ITypeLib_AddRef(TL);
 245                 return TL;
 246         }
 247 
 248         *cached = 0;
 249         name_dup = estrndup(search_string, l);
 250         TL = php_com_load_typelib(name_dup, codepage);
 251         efree(name_dup);
 252 
 253         if (TL) {
 254                 if (NULL != zend_ts_hash_str_update_ptr(&php_com_typelibraries,
 255                                 search_string, l, TL)) {
 256                         /* add a reference for the hash table */
 257                         ITypeLib_AddRef(TL);
 258                 }
 259         }
 260 
 261         return TL;
 262 }
 263 
 264 ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj, char *dispname, int sink)
 265 {
 266         ITypeInfo *typeinfo = NULL;
 267         ITypeLib *typelib = NULL;
 268         int gotguid = 0;
 269         GUID iid;
 270 
 271         if (obj) {
 272                 if (dispname == NULL && sink) {
 273                         IProvideClassInfo2 *pci2;
 274                         IProvideClassInfo *pci;
 275 
 276                         if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo2, (void**)&pci2))) {
 277                                 gotguid = SUCCEEDED(IProvideClassInfo2_GetGUID(pci2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid));
 278                                 IProvideClassInfo2_Release(pci2);
 279                         }
 280                         if (!gotguid && SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo, (void**)&pci))) {
 281                                 /* examine the available interfaces */
 282                                 /* TODO: write some code here */
 283                                 php_error_docref(NULL, E_WARNING, "IProvideClassInfo: this code not yet written!");
 284                                 IProvideClassInfo_Release(pci);
 285                         }
 286                 } else if (dispname == NULL) {
 287                         if (obj->typeinfo) {
 288                                 ITypeInfo_AddRef(obj->typeinfo);
 289                                 return obj->typeinfo;
 290                         } else {
 291                                 IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
 292                                 if (typeinfo) {
 293                                         return typeinfo;
 294                                 }
 295                         }
 296                 } else if (dispname && obj->typeinfo) {
 297                         unsigned int idx;
 298                         /* get the library from the object; the rest will be dealt with later */
 299                         ITypeInfo_GetContainingTypeLib(obj->typeinfo, &typelib, &idx);
 300                 } else if (typelibname == NULL) {
 301                         IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
 302                         if (dispname) {
 303                                 unsigned int idx;
 304                                 /* get the library from the object; the rest will be dealt with later */
 305                                 ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, &idx);
 306 
 307                                 if (typelib) {
 308                                         ITypeInfo_Release(typeinfo);
 309                                         typeinfo = NULL;
 310                                 }
 311                         }
 312                 }
 313         } else if (typelibname) {
 314                 /* Fetch the typelibrary and use that to look things up */
 315                 typelib = php_com_load_typelib(typelibname, CP_THREAD_ACP);
 316         }
 317 
 318         if (!gotguid && dispname && typelib) {
 319                 unsigned short cfound;
 320                 MEMBERID memid;
 321                 OLECHAR *olename = php_com_string_to_olestring(dispname, strlen(dispname), CP_ACP);
 322 
 323                 cfound = 1;
 324                 if (FAILED(ITypeLib_FindName(typelib, olename, 0, &typeinfo, &memid, &cfound)) || cfound == 0) {
 325                         CLSID coclass;
 326                         ITypeInfo *coinfo;
 327 
 328                         /* assume that it might be a progid instead */
 329                         if (SUCCEEDED(CLSIDFromProgID(olename, &coclass)) &&
 330                                         SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &coclass, &coinfo))) {
 331 
 332                                 /* enumerate implemented interfaces and pick the one as indicated by sink */
 333                                 TYPEATTR *attr;
 334                                 int i;
 335 
 336                                 ITypeInfo_GetTypeAttr(coinfo, &attr);
 337 
 338                                 for (i = 0; i < attr->cImplTypes; i++) {
 339                                         HREFTYPE rt;
 340                                         int tf;
 341 
 342                                         if (FAILED(ITypeInfo_GetImplTypeFlags(coinfo, i, &tf))) {
 343                                                 continue;
 344                                         }
 345 
 346                                         if ((sink && tf == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) ||
 347                                                 (!sink && (tf & IMPLTYPEFLAG_FSOURCE) == 0)) {
 348 
 349                                                 /* flags match what we are looking for */
 350 
 351                                                 if (SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(coinfo, i, &rt)))
 352                                                         if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(coinfo, rt, &typeinfo)))
 353                                                                 break;
 354 
 355                                         }
 356                                 }
 357 
 358                                 ITypeInfo_ReleaseTypeAttr(coinfo, attr);
 359                                 ITypeInfo_Release(coinfo);
 360                         }
 361                 }
 362 
 363 
 364                 efree(olename);
 365         } else if (gotguid) {
 366                 ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo);
 367         }
 368 
 369         if (typelib) {
 370                 ITypeLib_Release(typelib);
 371         }
 372 
 373         return typeinfo;
 374 }
 375 
 376 static const struct {
 377         VARTYPE vt;
 378         const char *name;
 379 } vt_names[] = {
 380         { VT_NULL,              "VT_NULL" },
 381         { VT_EMPTY,             "VT_EMPTY" },
 382         { VT_UI1,               "VT_UI1" },
 383         { VT_I2,                "VT_I2" },
 384         { VT_I4,                "VT_I4" },
 385         { VT_R4,                "VT_R4" },
 386         { VT_R8,                "VT_R8" },
 387         { VT_BOOL,              "VT_BOOL" },
 388         { VT_ERROR,             "VT_ERROR" },
 389         { VT_CY,                "VT_CY" },
 390         { VT_DATE,              "VT_DATE" },
 391         { VT_BSTR,              "VT_BSTR" },
 392         { VT_DECIMAL,   "VT_DECIMAL" },
 393         { VT_UNKNOWN,   "VT_UNKNOWN" },
 394         { VT_DISPATCH,  "VT_DISPATCH" },
 395         { VT_VARIANT,   "VT_VARIANT" },
 396         { VT_I1,                "VT_I1" },
 397         { VT_UI2,               "VT_UI2" },
 398         { VT_UI4,               "VT_UI4" },
 399         { VT_INT,               "VT_INT" },
 400         { VT_UINT,              "VT_UINT" },
 401         { VT_ARRAY,             "VT_ARRAY" },
 402         { VT_BYREF,             "VT_BYREF" },
 403         { VT_VOID,              "VT_VOID" },
 404         { VT_PTR,               "VT_PTR" },
 405         { VT_HRESULT,   "VT_HRESULT" },
 406         { VT_SAFEARRAY, "VT_SAFEARRAY" },
 407         { 0, NULL }
 408 };
 409 
 410 static inline const char *vt_to_string(VARTYPE vt)
 411 {
 412         int i;
 413         for (i = 0; vt_names[i].name != NULL; i++) {
 414                 if (vt_names[i].vt == vt)
 415                         return vt_names[i].name;
 416         }
 417         return "?";
 418 }
 419 
 420 static char *php_com_string_from_clsid(const CLSID *clsid, int codepage)
 421 {
 422         LPOLESTR ole_clsid;
 423         char *clsid_str;
 424 
 425         StringFromCLSID(clsid, &ole_clsid);
 426         clsid_str = php_com_olestring_to_string(ole_clsid, NULL, codepage);
 427         LocalFree(ole_clsid);
 428 
 429         return clsid_str;
 430 }
 431 
 432 
 433 int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage)
 434 {
 435         TYPEATTR *attr;
 436         FUNCDESC *func;
 437         int i;
 438         OLECHAR *olename;
 439         char *ansiname = NULL;
 440         size_t ansinamelen;
 441         int ret = 0;
 442 
 443         if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) {
 444                 return 0;
 445         }
 446 
 447         /* verify that it is suitable */
 448         if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) {
 449 
 450                 if (guid) {
 451                         memcpy(guid, &attr->guid, sizeof(GUID));
 452                 }
 453 
 454                 if (printdef) {
 455                         char *guidstring;
 456 
 457                         ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL);
 458                         ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage);
 459                         SysFreeString(olename);
 460 
 461                         guidstring = php_com_string_from_clsid(&attr->guid, codepage);
 462                         php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring);
 463                         efree(guidstring);
 464 
 465                         efree(ansiname);
 466                 }
 467 
 468                 if (id_to_name) {
 469                         zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
 470                 }
 471 
 472                 /* So we've got the dispatch interface; lets list the event methods */
 473                 for (i = 0; i < attr->cFuncs; i++) {
 474                         zval tmp;
 475                         DISPID lastid = 0;      /* for props */
 476                         int isprop;
 477 
 478                         if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func)))
 479                                 break;
 480 
 481                         isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT);
 482 
 483                         if (!isprop || lastid != func->memid) {
 484 
 485                                 lastid = func->memid;
 486 
 487                                 ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL);
 488                                 ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage);
 489                                 SysFreeString(olename);
 490 
 491                                 if (printdef) {
 492                                         int j;
 493                                         char *funcdesc;
 494                                         size_t funcdesclen;
 495                                         unsigned int 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);
 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);
 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);
 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                                         ZVAL_STRINGL(&tmp, ansiname, ansinamelen);
 586                                         zend_hash_index_update(id_to_name, func->memid, &tmp);
 587                                         // TODO: avoid reallocation???
 588                                         efree(ansiname);
 589                                 }
 590                         }
 591                         ITypeInfo_ReleaseFuncDesc(typeinfo, func);
 592                 }
 593 
 594                 if (printdef) {
 595                         php_printf("}\n");
 596                 }
 597 
 598                 ret = 1;
 599         } else {
 600                 zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind);
 601         }
 602 
 603         ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
 604 
 605         return ret;
 606 }
 607 
 608 

/* [<][>][^][v][top][bottom][index][help] */