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 5                                                        |
   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 TSRMLS_DC)
  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 */
 156 PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepage TSRMLS_DC)
 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);
 190                                 if(c.name == NULL) {
 191                                         ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
 192                                         continue;
 193                                 }
 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 
 231 PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string,
 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 

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