Back to index

php5  5.3.10
Classes | Defines | Typedefs | Functions | Variables
php_com_dotnet_internal.h File Reference
#include <ocidl.h>
#include <oleauto.h>
#include <unknwn.h>
#include <dispex.h>
#include "win32/winutil.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _php_com_dotnet_object

Defines

#define _WIN32_DCOM
#define COBJMACROS
#define CDNO_FETCH(zv)   (php_com_dotnet_object*)zend_object_store_get_object(zv TSRMLS_CC)
#define CDNO_FETCH_VERIFY(obj, zv)

Typedefs

typedef struct
_php_com_dotnet_object 
php_com_dotnet_object

Functions

static int php_com_is_valid_object (zval *zv TSRMLS_DC)
zend_object_value php_com_object_new (zend_class_entry *ce TSRMLS_DC)
void php_com_object_clone (void *object, void **clone_ptr TSRMLS_DC)
void php_com_object_free_storage (void *object TSRMLS_DC)
void php_com_object_enable_event_sink (php_com_dotnet_object *obj, int enable TSRMLS_DC)
zend_object_iterator * php_com_saproxy_iter_get (zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
int php_com_saproxy_create (zval *com_object, zval *proxy_out, zval *index TSRMLS_DC)
PHPAPI char * php_com_olestring_to_string (OLECHAR *olestring, uint *string_len, int codepage TSRMLS_DC)
PHPAPI OLECHAR * php_com_string_to_olestring (char *string, uint string_len, int codepage TSRMLS_DC)
 PHP_FUNCTION (com_create_instance)
 PHP_FUNCTION (com_event_sink)
 PHP_FUNCTION (com_create_guid)
 PHP_FUNCTION (com_print_typeinfo)
 PHP_FUNCTION (com_message_pump)
 PHP_FUNCTION (com_load_typelib)
 PHP_FUNCTION (com_get_active_object)
HRESULT php_com_invoke_helper (php_com_dotnet_object *obj, DISPID id_member, WORD flags, DISPPARAMS *disp_params, VARIANT *v, int silent, int allow_noarg TSRMLS_DC)
HRESULT php_com_get_id_of_name (php_com_dotnet_object *obj, char *name, int namelen, DISPID *dispid TSRMLS_DC)
int php_com_do_invoke_by_id (php_com_dotnet_object *obj, DISPID dispid, WORD flags, VARIANT *v, int nargs, zval **args, int silent, int allow_noarg TSRMLS_DC)
int php_com_do_invoke (php_com_dotnet_object *obj, char *name, int namelen, WORD flags, VARIANT *v, int nargs, zval **args, int allow_noarg TSRMLS_DC)
int php_com_do_invoke_byref (php_com_dotnet_object *obj, char *name, int namelen, WORD flags, VARIANT *v, int nargs, zval ***args TSRMLS_DC)
int php_com_wrapper_minit (INIT_FUNC_ARGS)
PHPAPI IDispatch * php_com_wrapper_export_as_sink (zval *val, GUID *sinkid, HashTable *id_to_name TSRMLS_DC)
PHPAPI IDispatch * php_com_wrapper_export (zval *val TSRMLS_DC)
int php_com_persist_minit (INIT_FUNC_ARGS)
 PHP_FUNCTION (com_variant_create_instance)
 PHP_FUNCTION (variant_set)
 PHP_FUNCTION (variant_add)
 PHP_FUNCTION (variant_cat)
 PHP_FUNCTION (variant_sub)
 PHP_FUNCTION (variant_mul)
 PHP_FUNCTION (variant_and)
 PHP_FUNCTION (variant_div)
 PHP_FUNCTION (variant_eqv)
 PHP_FUNCTION (variant_idiv)
 PHP_FUNCTION (variant_imp)
 PHP_FUNCTION (variant_mod)
 PHP_FUNCTION (variant_or)
 PHP_FUNCTION (variant_pow)
 PHP_FUNCTION (variant_xor)
 PHP_FUNCTION (variant_abs)
 PHP_FUNCTION (variant_fix)
 PHP_FUNCTION (variant_int)
 PHP_FUNCTION (variant_neg)
 PHP_FUNCTION (variant_not)
 PHP_FUNCTION (variant_round)
 PHP_FUNCTION (variant_cmp)
 PHP_FUNCTION (variant_date_to_timestamp)
 PHP_FUNCTION (variant_date_from_timestamp)
 PHP_FUNCTION (variant_get_type)
 PHP_FUNCTION (variant_set_type)
 PHP_FUNCTION (variant_cast)
PHPAPI void php_com_variant_from_zval_with_type (VARIANT *v, zval *z, VARTYPE type, int codepage TSRMLS_DC)
PHPAPI void php_com_variant_from_zval (VARIANT *v, zval *z, int codepage TSRMLS_DC)
PHPAPI int php_com_zval_from_variant (zval *z, VARIANT *v, int codepage TSRMLS_DC)
PHPAPI int php_com_copy_variant (VARIANT *dst, VARIANT *src TSRMLS_DC)
 PHP_FUNCTION (com_dotnet_create_instance)
void php_com_dotnet_rshutdown (TSRMLS_D)
void php_com_dotnet_mshutdown (TSRMLS_D)
void php_com_throw_exception (HRESULT code, char *message TSRMLS_DC)
PHPAPI void php_com_wrap_dispatch (zval *z, IDispatch *disp, int codepage TSRMLS_DC)
PHPAPI void php_com_wrap_variant (zval *z, VARIANT *v, int codepage TSRMLS_DC)
PHPAPI int php_com_safearray_get_elem (VARIANT *array, VARIANT *dest, LONG dim1 TSRMLS_DC)
PHPAPI ITypeLib * php_com_load_typelib_via_cache (char *search_string, int codepage, int *cached TSRMLS_DC)
PHPAPI ITypeLib * php_com_load_typelib (char *search_string, int codepage TSRMLS_DC)
PHPAPI int php_com_import_typelib (ITypeLib *TL, int mode, int codepage TSRMLS_DC)
void php_com_typelibrary_dtor (void *pDest)
ITypeInfo * php_com_locate_typeinfo (char *typelibname, php_com_dotnet_object *obj, char *dispname, int sink TSRMLS_DC)
int php_com_process_typeinfo (ITypeInfo *typeinfo, HashTable *id_to_name, int printdef, GUID *guid, int codepage TSRMLS_DC)
zend_object_iterator * php_com_iter_get (zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)

Variables

TsHashTable php_com_typelibraries
zend_class_entry * php_com_variant_class_entry
zend_class_entry * php_com_exception_class_entry
zend_class_entry * php_com_saproxy_class_entry
zend_object_handlers php_com_object_handlers

Class Documentation

struct _php_com_dotnet_object

Definition at line 35 of file php_com_dotnet_internal.h.

Collaboration diagram for _php_com_dotnet_object:
Class Members
zend_class_entry * ce
long code_page
HashTable * id_of_name_cache
HashTable * method_cache
int modified
DWORD sink_cookie
IDispatch * sink_dispatch
GUID sink_id
ITypeInfo * typeinfo
VARIANT v
zend_object zo

Define Documentation

#define _WIN32_DCOM

Definition at line 24 of file php_com_dotnet_internal.h.

Definition at line 65 of file php_com_dotnet_internal.h.

#define CDNO_FETCH_VERIFY (   obj,
  zv 
)
Value:
do { \
       if (!php_com_is_valid_object(zv TSRMLS_CC)) { \
              php_com_throw_exception(E_UNEXPECTED, "expected a variant object" TSRMLS_CC); \
              return; \
       } \
       obj = (php_com_dotnet_object*)zend_object_store_get_object(zv TSRMLS_CC); \
} while(0)

Definition at line 66 of file php_com_dotnet_internal.h.

#define COBJMACROS

Definition at line 25 of file php_com_dotnet_internal.h.


Typedef Documentation


Function Documentation

PHPAPI int php_com_copy_variant ( VARIANT *  dst,
VARIANT *src  TSRMLS_DC 
)
int php_com_do_invoke ( php_com_dotnet_object obj,
char *  name,
int  namelen,
WORD  flags,
VARIANT *  v,
int  nargs,
zval **  args,
int allow_noarg  TSRMLS_DC 
)

Definition at line 632 of file com_com.c.

{
       DISPID dispid;
       HRESULT hr;
       char *winerr = NULL;
       char *msg = NULL;

       hr = php_com_get_id_of_name(obj, name, namelen, &dispid TSRMLS_CC);

       if (FAILED(hr)) {
              winerr = php_win_err(hr);
              spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr);
              LocalFree(winerr);
              php_com_throw_exception(hr, msg TSRMLS_CC);
              efree(msg);
              return FAILURE;
       }

       return php_com_do_invoke_by_id(obj, dispid, flags, v, nargs, args, 0, allow_noarg TSRMLS_CC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int php_com_do_invoke_by_id ( php_com_dotnet_object obj,
DISPID  dispid,
WORD  flags,
VARIANT *  v,
int  nargs,
zval **  args,
int  silent,
int allow_noarg  TSRMLS_DC 
)

Definition at line 585 of file com_com.c.

{
       DISPID altdispid;
       DISPPARAMS disp_params;
       HRESULT hr;
       VARIANT *vargs = NULL;
       int i;

       if (nargs) {
              vargs = (VARIANT*)safe_emalloc(sizeof(VARIANT), nargs, 0);
       }

       /* Invoke'd args are in reverse order */
       for (i = 0; i < nargs; i++) {
              php_com_variant_from_zval(&vargs[i], args[nargs - i - 1], obj->code_page TSRMLS_CC);
       }

       disp_params.cArgs = nargs;
       disp_params.cNamedArgs = 0;
       disp_params.rgvarg = vargs;
       disp_params.rgdispidNamedArgs = NULL;

       if (flags & DISPATCH_PROPERTYPUT) {
              altdispid = DISPID_PROPERTYPUT;
              disp_params.rgdispidNamedArgs = &altdispid;
              disp_params.cNamedArgs = 1;
       }

       /* this will create an exception if needed */
       hr = php_com_invoke_helper(obj, dispid, flags, &disp_params, v, silent, allow_noarg TSRMLS_CC);   

       /* release variants */
       if (vargs) {
              for (i = 0; i < nargs; i++) {
                     VariantClear(&vargs[i]);
              }
              efree(vargs);
       }

       /* a bit of a hack this, but it's needed for COM array access. */
       if (hr == DISP_E_BADPARAMCOUNT)
              return hr;
       
       return SUCCEEDED(hr) ? SUCCESS : FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int php_com_do_invoke_byref ( php_com_dotnet_object obj,
char *  name,
int  namelen,
WORD  flags,
VARIANT *  v,
int  nargs,
zval ***args  TSRMLS_DC 
)

Definition at line 464 of file com_com.c.

{
       DISPID dispid, altdispid;
       DISPPARAMS disp_params;
       HRESULT hr;
       VARIANT *vargs = NULL, *byref_vals = NULL;
       int i, byref_count = 0, j;
       zend_internal_function *f = (zend_internal_function*)EG(current_execute_data)->function_state.function;

       /* assumption: that the active function (f) is the function we generated for the engine */
       if (!f || f->arg_info == NULL) {
          f = NULL;
       }
       
       hr = php_com_get_id_of_name(obj, name, namelen, &dispid TSRMLS_CC);

       if (FAILED(hr)) {
              char *winerr = NULL;
              char *msg = NULL;
              winerr = php_win_err(hr);
              spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr);
              LocalFree(winerr);
              php_com_throw_exception(hr, msg TSRMLS_CC);
              efree(msg);
              return FAILURE;
       }


       if (nargs) {
              vargs = (VARIANT*)safe_emalloc(sizeof(VARIANT), nargs, 0);
       }

       if (f) {
              for (i = 0; i < nargs; i++) {
                     if (f->arg_info[nargs - i - 1].pass_by_reference) {
                            byref_count++;
                     }
              }
       }

       if (byref_count) {
              byref_vals = (VARIANT*)safe_emalloc(sizeof(VARIANT), byref_count, 0);
              for (j = 0, i = 0; i < nargs; i++) {
                     if (f->arg_info[nargs - i - 1].pass_by_reference) {
                            /* put the value into byref_vals instead */
                            php_com_variant_from_zval(&byref_vals[j], *args[nargs - i - 1], obj->code_page TSRMLS_CC);

                            /* if it is already byref, "move" it into the vargs array, otherwise
                             * make vargs a reference to this value */
                            if (V_VT(&byref_vals[j]) & VT_BYREF) {
                                   memcpy(&vargs[i], &byref_vals[j], sizeof(vargs[i]));
                                   VariantInit(&byref_vals[j]); /* leave the variant slot empty to simplify cleanup */
                            } else {
                                   VariantInit(&vargs[i]);
                                   V_VT(&vargs[i]) = V_VT(&byref_vals[j]) | VT_BYREF;
                                   /* union magic ensures that this works out */
                                   vargs[i].byref = &V_UINT(&byref_vals[j]);
                            }
                            j++;
                     } else {
                            php_com_variant_from_zval(&vargs[i], *args[nargs - i - 1], obj->code_page TSRMLS_CC);
                     }
              }
              
       } else {
              /* Invoke'd args are in reverse order */
              for (i = 0; i < nargs; i++) {
                     php_com_variant_from_zval(&vargs[i], *args[nargs - i - 1], obj->code_page TSRMLS_CC);
              }
       }

       disp_params.cArgs = nargs;
       disp_params.cNamedArgs = 0;
       disp_params.rgvarg = vargs;
       disp_params.rgdispidNamedArgs = NULL;

       if (flags & DISPATCH_PROPERTYPUT) {
              altdispid = DISPID_PROPERTYPUT;
              disp_params.rgdispidNamedArgs = &altdispid;
              disp_params.cNamedArgs = 1;
       }

       /* this will create an exception if needed */
       hr = php_com_invoke_helper(obj, dispid, flags, &disp_params, v, 0, 0 TSRMLS_CC);    

       /* release variants */
       if (vargs) {
              for (i = 0, j = 0; i < nargs; i++) {
                     /* if this was byref, update the zval */
                     if (f && f->arg_info[nargs - i - 1].pass_by_reference) {
                            SEPARATE_ZVAL_IF_NOT_REF(args[nargs - i - 1]);

                            /* if the variant is pointing at the byref_vals, we need to map
                             * the pointee value as a zval; otherwise, the value is pointing
                             * into an existing PHP variant record */
                            if (V_VT(&vargs[i]) & VT_BYREF) {
                                   if (vargs[i].byref == &V_UINT(&byref_vals[j])) {
                                          /* copy that value */
                                          php_com_zval_from_variant(*args[nargs - i - 1], &byref_vals[j],
                                                 obj->code_page TSRMLS_CC);
                                   }
                            } else {
                                   /* not sure if this can ever happen; the variant we marked as BYREF
                                    * is no longer BYREF - copy its value */
                                   php_com_zval_from_variant(*args[nargs - i - 1], &vargs[i],
                                          obj->code_page TSRMLS_CC);
                            }
                            VariantClear(&byref_vals[j]);
                            j++;
                     }      
                     VariantClear(&vargs[i]);
              }
              efree(vargs);
       }

       return SUCCEEDED(hr) ? SUCCESS : FAILURE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

HRESULT php_com_get_id_of_name ( php_com_dotnet_object obj,
char *  name,
int  namelen,
DISPID *dispid  TSRMLS_DC 
)

Definition at line 418 of file com_com.c.

{
       OLECHAR *olename;
       HRESULT hr;
       DISPID *dispid_ptr;

       if (namelen == -1) {
              namelen = strlen(name);
       }

       if (obj->id_of_name_cache && SUCCESS == zend_hash_find(obj->id_of_name_cache, name, namelen, (void**)&dispid_ptr)) {
              *dispid = *dispid_ptr;
              return S_OK;
       }
       
       olename = php_com_string_to_olestring(name, namelen, obj->code_page TSRMLS_CC);

       if (obj->typeinfo) {
              hr = ITypeInfo_GetIDsOfNames(obj->typeinfo, &olename, 1, dispid);
              if (FAILED(hr)) {
                     hr = IDispatch_GetIDsOfNames(V_DISPATCH(&obj->v), &IID_NULL, &olename, 1, LOCALE_SYSTEM_DEFAULT, dispid);
                     if (SUCCEEDED(hr)) {
                            /* fall back on IDispatch direct */
                            ITypeInfo_Release(obj->typeinfo);
                            obj->typeinfo = NULL;
                     }
              }
       } else {
              hr = IDispatch_GetIDsOfNames(V_DISPATCH(&obj->v), &IID_NULL, &olename, 1, LOCALE_SYSTEM_DEFAULT, dispid);
       }
       efree(olename);

       if (SUCCEEDED(hr)) {
              /* cache the mapping */
              if (!obj->id_of_name_cache) {
                     ALLOC_HASHTABLE(obj->id_of_name_cache);
                     zend_hash_init(obj->id_of_name_cache, 2, NULL, NULL, 0);
              }
              zend_hash_update(obj->id_of_name_cache, name, namelen, dispid, sizeof(*dispid), NULL);
       }
       
       return hr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI int php_com_import_typelib ( ITypeLib *  TL,
int  mode,
int codepage  TSRMLS_DC 
)

Definition at line 156 of file com_typeinfo.c.

{
       int i, j, interfaces;
       TYPEKIND pTKind;
       ITypeInfo *TypeInfo;
       VARDESC *pVarDesc;
       UINT NameCount;
       BSTR bstr_ids;
       zend_constant c;
       zval exists, results, value;
       char *const_name;

       if (TL == NULL) {
              return FAILURE;
       }

       interfaces = ITypeLib_GetTypeInfoCount(TL);
       for (i = 0; i < interfaces; i++) {
              ITypeLib_GetTypeInfoType(TL, i, &pTKind);
              if (pTKind == TKIND_ENUM) {
                     ITypeLib_GetTypeInfo(TL, i, &TypeInfo);
                     for (j = 0; ; j++) {
                            if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) {
                                   break;
                            }
                            ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
                            if (NameCount != 1) {
                                   ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                                   continue;
                            }

                            const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC);
                            c.name = zend_strndup(const_name, c.name_len);
                            efree(const_name);
                            c.name_len++; /* include NUL */
                            SysFreeString(bstr_ids);

                            /* sanity check for the case where the constant is already defined */
                            if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) {
                                   if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists TSRMLS_CC)) {
                                          php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name);
                                   }
                                   free(c.name);
                                   ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                                   continue;
                            }

                            /* register the constant */
                            php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC);
                            if (Z_TYPE(value) == IS_LONG) {
                                   c.flags = mode;
                                   c.value.type = IS_LONG;
                                   c.value.value.lval = Z_LVAL(value);
                                   c.module_number = 0;
                                   zend_register_constant(&c TSRMLS_CC);
                            }
                            ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
                     }
                     ITypeInfo_Release(TypeInfo);
              }
       }
       return SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HRESULT php_com_invoke_helper ( php_com_dotnet_object obj,
DISPID  id_member,
WORD  flags,
DISPPARAMS *  disp_params,
VARIANT *  v,
int  silent,
int allow_noarg  TSRMLS_DC 
)

Definition at line 340 of file com_com.c.

{
       HRESULT hr;
       unsigned int arg_err;
       EXCEPINFO e = {0};

       hr = IDispatch_Invoke(V_DISPATCH(&obj->v), id_member,
              &IID_NULL, LOCALE_SYSTEM_DEFAULT, flags, disp_params, v, &e, &arg_err);

       if (silent == 0 && FAILED(hr)) {
              char *source = NULL, *desc = NULL, *msg = NULL;
              int source_len, desc_len;

              switch (hr) {
                     case DISP_E_EXCEPTION:
                            if (e.bstrSource) {
                                   source = php_com_olestring_to_string(e.bstrSource, &source_len, obj->code_page TSRMLS_CC);
                                   SysFreeString(e.bstrSource);
                            }
                            if (e.bstrDescription) {
                                   desc = php_com_olestring_to_string(e.bstrDescription, &desc_len, obj->code_page TSRMLS_CC);
                                   SysFreeString(e.bstrDescription);
                            }
                            if (PG(html_errors)) {
                                   spprintf(&msg, 0, "<b>Source:</b> %s<br/><b>Description:</b> %s",
                                          source ? source : "Unknown",
                                          desc ? desc : "Unknown");
                            } else {
                                   spprintf(&msg, 0, "Source: %s\nDescription: %s",
                                          source ? source : "Unknown",
                                          desc ? desc : "Unknown");
                            }
                            if (desc) {
                                   efree(desc);
                            }
                            if (source) {
                                   efree(source);
                            }
                            if (e.bstrHelpFile) {
                                   SysFreeString(e.bstrHelpFile);
                            }
                            break;

                     case DISP_E_PARAMNOTFOUND:
                     case DISP_E_TYPEMISMATCH:
                            desc = php_win_err(hr);
                            spprintf(&msg, 0, "Parameter %d: %s", arg_err, desc);
                            LocalFree(desc);
                            break;

                     case DISP_E_BADPARAMCOUNT:
                            if ((disp_params->cArgs + disp_params->cNamedArgs == 0) && (allow_noarg == 1)) {
                                   /* if getting a property and they are missing all parameters,
                                    * we want to create a proxy object for them; so lets not create an
                                    * exception here */
                                   msg = NULL;
                                   break;
                            }
                            /* else fall through */
                            
                     default:
                            desc = php_win_err(hr);
                            spprintf(&msg, 0, "Error [0x%08x] %s", hr, desc);
                            LocalFree(desc);
                            break;
              }

              if (msg) {
                     php_com_throw_exception(hr, msg TSRMLS_CC);
                     efree(msg);
              }
       }

       return hr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int php_com_is_valid_object ( zval *zv  TSRMLS_DC) [inline, static]

Definition at line 57 of file php_com_dotnet_internal.h.

{
       zend_class_entry *ce = Z_OBJCE_P(zv);
       return strcmp("com", ce->name) == 0 ||
              strcmp("dotnet", ce->name) == 0 ||
              strcmp("variant", ce->name) == 0;
}

Here is the caller graph for this function:

zend_object_iterator* php_com_iter_get ( zend_class_entry *  ce,
zval *  object,
int by_ref  TSRMLS_DC 
)

Definition at line 142 of file com_iterator.c.

{
       php_com_dotnet_object *obj;
       struct php_com_iterator *I;
       IEnumVARIANT *iev = NULL;
       DISPPARAMS dp;
       VARIANT v;
       unsigned long n_fetched;
       zval *ptr;

       if (by_ref) {
              zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
       }

       obj = CDNO_FETCH(object);

       if (V_VT(&obj->v) != VT_DISPATCH && !V_ISARRAY(&obj->v)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "variant is not an object or array VT=%d", V_VT(&obj->v));
              return NULL;
       }

       memset(&dp, 0, sizeof(dp));
       VariantInit(&v);     

       I = (struct php_com_iterator*)ecalloc(1, sizeof(*I));
       I->iter.funcs = &com_iter_funcs;
       I->iter.data = I;
       I->code_page = obj->code_page;
       I->zdata = NULL;
       VariantInit(&I->safe_array);
       VariantInit(&I->v);

       if (V_ISARRAY(&obj->v)) {
              LONG bound;
              UINT dims;
       
              dims = SafeArrayGetDim(V_ARRAY(&obj->v));

              if (dims != 1) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING,
                               "Can only handle single dimension variant arrays (this array has %d)", dims);
                     goto fail;
              }
              
              /* same semantics as foreach on a PHP array;
               * make a copy and enumerate that copy */
              VariantCopy(&I->safe_array, &obj->v);

              /* determine the key value for the array */
              SafeArrayGetLBound(V_ARRAY(&I->safe_array), 1, &bound);
              SafeArrayGetUBound(V_ARRAY(&I->safe_array), 1, &I->sa_max);

              /* pre-fetch the element */
              if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound TSRMLS_CC)) {
                     I->key = bound;
                     MAKE_STD_ZVAL(ptr);
                     php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
                     I->zdata = ptr;
              } else {
                     I->key = (ulong)-1;
              }
              
       } else {
              /* can we enumerate it? */
              if (FAILED(IDispatch_Invoke(V_DISPATCH(&obj->v), DISPID_NEWENUM,
                                          &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET,
                                          &dp, &v, NULL, NULL))) {
                     goto fail;
              }

              /* get something useful out of it */
              if (V_VT(&v) == VT_UNKNOWN) {
                     IUnknown_QueryInterface(V_UNKNOWN(&v), &IID_IEnumVARIANT, (void**)&iev);
              } else if (V_VT(&v) == VT_DISPATCH) {
                     IDispatch_QueryInterface(V_DISPATCH(&v), &IID_IEnumVARIANT, (void**)&iev);
              }

              VariantClear(&v);

              if (iev == NULL) {
                     goto fail;
              }
       
              I->ev = iev;

              /* Get the first element now */
              if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) {
                     /* indicate that we have element 0 */
                     I->key = 0;
                     MAKE_STD_ZVAL(ptr);
                     php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC);
                     I->zdata = ptr;
              } else {
                     /* indicate that there are no more items */
                     I->key = (ulong)-1;
              }
       }

       return &I->iter;

fail:
       if (I) {
              VariantClear(&I->safe_array);
              VariantClear(&I->v);
              efree(I);
       }
       return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI ITypeLib* php_com_load_typelib ( char *  search_string,
int codepage  TSRMLS_DC 
)

Definition at line 38 of file com_typeinfo.c.

{
       ITypeLib *TL = NULL;
       char *strtok_buf, *major, *minor;
       CLSID clsid;
       OLECHAR *p;
       HRESULT hr;

       search_string = php_strtok_r(search_string, ",", &strtok_buf);

       if (search_string == NULL) {
              return NULL;
       }

       major = php_strtok_r(NULL, ",", &strtok_buf);
       minor = php_strtok_r(NULL, ",", &strtok_buf);

       p = php_com_string_to_olestring(search_string, strlen(search_string), codepage TSRMLS_CC);

       if (SUCCEEDED(CLSIDFromString(p, &clsid))) {
              WORD major_i = 1, minor_i = 0;

              /* pick up the major/minor numbers; if none specified, default to 1,0 */
              if (major && minor) {
                     major_i = (WORD)atoi(major);
                     minor_i = (WORD)atoi(minor);
              }

              /* Load the TypeLib by GUID */
              hr = LoadRegTypeLib((REFGUID)&clsid, major_i, minor_i, LANG_NEUTRAL, &TL);

              /* if that failed, assumed that the GUID is actually a CLSID and
               * attemp to get the library via an instance of that class */
              if (FAILED(hr) && (major == NULL || minor == NULL)) {
                     IDispatch *disp = NULL;
                     ITypeInfo *info = NULL;
                     int idx;

                     if (SUCCEEDED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&disp)) &&
                                   SUCCEEDED(hr = IDispatch_GetTypeInfo(disp, 0, LANG_NEUTRAL, &info))) {
                            hr = ITypeInfo_GetContainingTypeLib(info, &TL, &idx);
                     }

                     if (info) {
                            ITypeInfo_Release(info);
                     }
                     if (disp) {
                            IDispatch_Release(disp);
                     }
              }
       } else {
              /* Try to load it from a file; if it fails, do a really painful search of
               * the registry */
              if (FAILED(LoadTypeLib(p, &TL))) {
                     HKEY hkey, hsubkey;
                     DWORD SubKeys, MaxSubKeyLength;
                     char *keyname;
                     unsigned int i, j;
                     DWORD VersionCount;
                     char version[20];
                     char *libname;
                     DWORD libnamelen;

                     if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, "TypeLib", 0, KEY_READ, &hkey) &&
                                   ERROR_SUCCESS == RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys,
                                   &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) {

                            MaxSubKeyLength++; /* make room for NUL */
                            keyname = emalloc(MaxSubKeyLength);
                            libname = emalloc(strlen(search_string) + 1);

                            for (i = 0; i < SubKeys && TL == NULL; i++) {
                                   if (ERROR_SUCCESS == RegEnumKey(hkey, i, keyname, MaxSubKeyLength) &&
                                                 ERROR_SUCCESS == RegOpenKeyEx(hkey, keyname, 0, KEY_READ, &hsubkey)) {
                                          if (ERROR_SUCCESS == RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount,
                                                        NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
                                                 for (j = 0; j < VersionCount; j++) {
                                                        if (ERROR_SUCCESS != RegEnumKey(hsubkey, j, version, sizeof(version))) {
                                                               continue;
                                                        }
                                                        /* get the default value for this key and compare */
                                                        libnamelen = strlen(search_string)+1;
                                                        if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) {
                                                               if (0 == stricmp(libname, search_string)) {
                                                                      char *str = NULL;
                                                                      int major_tmp, minor_tmp;

                                                                      /* fetch the GUID and add the version numbers */
                                                                      if (2 != sscanf(version, "%d.%d", &major_tmp, &minor_tmp)) {
                                                                             major_tmp = 1;
                                                                             minor_tmp = 0;
                                                                      }
                                                                      spprintf(&str, 0, "%s,%d,%d", keyname, major_tmp, minor_tmp);
                                                                      /* recurse */
                                                                      TL = php_com_load_typelib(str, codepage TSRMLS_CC);

                                                                      efree(str);
                                                                      break;
                                                               }
                                                        }
                                                 }
                                          }
                                          RegCloseKey(hsubkey);
                                   }
                            }
                            RegCloseKey(hkey);
                            efree(keyname);
                            efree(libname);
                     }
              }
       }
       
       efree(p);

       return TL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI ITypeLib* php_com_load_typelib_via_cache ( char *  search_string,
int  codepage,
int *cached  TSRMLS_DC 
)

Definition at line 227 of file com_typeinfo.c.

{
       ITypeLib **TLp;
       ITypeLib *TL;
       char *name_dup;
       int l;

       l = strlen(search_string);

       if (zend_ts_hash_find(&php_com_typelibraries, search_string, l+1,
                     (void**)&TLp) == SUCCESS) {
              *cached = 1;
              /* add a reference for the caller */
              ITypeLib_AddRef(*TLp);
              return *TLp;
       }

       *cached = 0;
       name_dup = estrndup(search_string, l);
       TL = php_com_load_typelib(name_dup, codepage TSRMLS_CC);
       efree(name_dup);

       if (TL) {
              if (SUCCESS == zend_ts_hash_update(&php_com_typelibraries,
                            search_string, l+1, (void*)&TL, sizeof(ITypeLib*), NULL)) {
                     /* add a reference for the hash table */
                     ITypeLib_AddRef(TL);
              }
       }

       return TL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ITypeInfo* php_com_locate_typeinfo ( char *  typelibname,
php_com_dotnet_object obj,
char *  dispname,
int sink  TSRMLS_DC 
)

Definition at line 261 of file com_typeinfo.c.

{
       ITypeInfo *typeinfo = NULL;
       ITypeLib *typelib = NULL;
       int gotguid = 0;
       GUID iid;
       
       if (obj) {
              if (dispname == NULL && sink) {
                     IProvideClassInfo2 *pci2;
                     IProvideClassInfo *pci;

                     if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo2, (void**)&pci2))) {
                            gotguid = SUCCEEDED(IProvideClassInfo2_GetGUID(pci2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid));
                            IProvideClassInfo2_Release(pci2);
                     }
                     if (!gotguid && SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v), &IID_IProvideClassInfo, (void**)&pci))) {
                            /* examine the available interfaces */
                            /* TODO: write some code here */
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "IProvideClassInfo: this code not yet written!");
                            IProvideClassInfo_Release(pci);
                     }
              } else if (dispname == NULL) {
                     if (obj->typeinfo) {
                            ITypeInfo_AddRef(obj->typeinfo);
                            return obj->typeinfo;
                     } else {
                            IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
                            if (typeinfo) {
                                   return typeinfo;
                            }
                     }
              } else if (dispname && obj->typeinfo) {
                     unsigned int idx;
                     /* get the library from the object; the rest will be dealt with later */
                     ITypeInfo_GetContainingTypeLib(obj->typeinfo, &typelib, &idx);
              } else if (typelibname == NULL) {
                     IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &typeinfo);
                     if (dispname) {
                            unsigned int idx;
                            /* get the library from the object; the rest will be dealt with later */
                            ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, &idx);

                            if (typelib) {
                                   ITypeInfo_Release(typeinfo);
                                   typeinfo = NULL;
                            }
                     }
              }
       } else if (typelibname) {
              /* Fetch the typelibrary and use that to look things up */
              typelib = php_com_load_typelib(typelibname, CP_THREAD_ACP TSRMLS_CC);
       } 

       if (!gotguid && dispname && typelib) {
              unsigned short cfound;
              MEMBERID memid;
              OLECHAR *olename = php_com_string_to_olestring(dispname, strlen(dispname), CP_ACP TSRMLS_CC);
                     
              cfound = 1;
              if (FAILED(ITypeLib_FindName(typelib, olename, 0, &typeinfo, &memid, &cfound)) || cfound == 0) {
                     CLSID coclass;
                     ITypeInfo *coinfo;
       
                     /* assume that it might be a progid instead */
                     if (SUCCEEDED(CLSIDFromProgID(olename, &coclass)) &&
                                   SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &coclass, &coinfo))) {

                            /* enumerate implemented interfaces and pick the one as indicated by sink */
                            TYPEATTR *attr;
                            int i;

                            ITypeInfo_GetTypeAttr(coinfo, &attr);

                            for (i = 0; i < attr->cImplTypes; i++) {
                                   HREFTYPE rt;
                                   int tf;

                                   if (FAILED(ITypeInfo_GetImplTypeFlags(coinfo, i, &tf))) {
                                          continue;
                                   }

                                   if ((sink && tf == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) ||
                                          (!sink && (tf & IMPLTYPEFLAG_FSOURCE) == 0)) {

                                          /* flags match what we are looking for */

                                          if (SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(coinfo, i, &rt)))
                                                 if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(coinfo, rt, &typeinfo)))
                                                        break;
                                          
                                   }
                            }
                            
                            ITypeInfo_ReleaseTypeAttr(coinfo, attr);
                            ITypeInfo_Release(coinfo);
                     }
              }

              
              efree(olename);
       } else if (gotguid) {
              ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo);
       }

       if (typelib) {
              ITypeLib_Release(typelib);
       }

       return typeinfo;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void php_com_object_clone ( void *  object,
void **clone_ptr  TSRMLS_DC 
)

Definition at line 638 of file com_handlers.c.

{
       php_com_dotnet_object *cloneobj, *origobject;

       origobject = (php_com_dotnet_object*)object;
       cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object));
       
       memcpy(cloneobj, origobject, sizeof(*cloneobj));

       /* VariantCopy will perform VariantClear; we don't want to clobber
        * the IDispatch that we memcpy'd, so we init a new variant in the
        * clone structure */
       VariantInit(&cloneobj->v);
       /* We use the Indirection-following version of the API since we
        * want to clone as much as possible */
       VariantCopyInd(&cloneobj->v, &origobject->v); 

       if (cloneobj->typeinfo) {
              ITypeInfo_AddRef(cloneobj->typeinfo);
       }

       *clone_ptr = cloneobj;
}

Here is the caller graph for this function:

void php_com_object_enable_event_sink ( php_com_dotnet_object obj,
int enable  TSRMLS_DC 
)

Definition at line 586 of file com_handlers.c.

{
       if (obj->sink_dispatch) {
              IConnectionPointContainer *cont;
              IConnectionPoint *point;
              
              if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->v),
                            &IID_IConnectionPointContainer, (void**)&cont))) {
                     
                     if (SUCCEEDED(IConnectionPointContainer_FindConnectionPoint(cont,
                                   &obj->sink_id, &point))) {

                            if (enable) {
                                   IConnectionPoint_Advise(point, (IUnknown*)obj->sink_dispatch, &obj->sink_cookie);
                            } else {
                                   IConnectionPoint_Unadvise(point, obj->sink_cookie);
                            }
                            IConnectionPoint_Release(point);
                     }
                     IConnectionPointContainer_Release(cont);
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void php_com_object_free_storage ( void *object  TSRMLS_DC)

Definition at line 610 of file com_handlers.c.

{
       php_com_dotnet_object *obj = (php_com_dotnet_object*)object;

       if (obj->typeinfo) {
              ITypeInfo_Release(obj->typeinfo);
              obj->typeinfo = NULL;
       }

       if (obj->sink_dispatch) {
              php_com_object_enable_event_sink(obj, FALSE TSRMLS_CC);
              IDispatch_Release(obj->sink_dispatch);
              obj->sink_dispatch = NULL;
       }

       VariantClear(&obj->v);

       if (obj->method_cache) {
              zend_hash_destroy(obj->method_cache);
              FREE_HASHTABLE(obj->method_cache);
       }
       if (obj->id_of_name_cache) {
              zend_hash_destroy(obj->id_of_name_cache);
              FREE_HASHTABLE(obj->id_of_name_cache);
       }
       efree(obj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

zend_object_value php_com_object_new ( zend_class_entry *ce  TSRMLS_DC)

Definition at line 662 of file com_handlers.c.

{
       php_com_dotnet_object *obj;
       zend_object_value retval;

       php_com_initialize(TSRMLS_C);
       obj = emalloc(sizeof(*obj));
       memset(obj, 0, sizeof(*obj));

       VariantInit(&obj->v);
       obj->code_page = CP_ACP;
       obj->ce = ce;
       obj->zo.ce = ce;

       retval.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
       retval.handlers = &php_com_object_handlers;

       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI char* php_com_olestring_to_string ( OLECHAR *  olestring,
uint string_len,
int codepage  TSRMLS_DC 
)

Definition at line 68 of file com_olechar.c.

{
       char *string;
       uint length = 0;
       BOOL ok;

       length = WideCharToMultiByte(codepage, 0, olestring, -1, NULL, 0, NULL, NULL);

       if (length) {
              string = (char*)safe_emalloc(length, sizeof(char), 0);
              length = WideCharToMultiByte(codepage, 0, olestring, -1, string, length, NULL, NULL);
              ok = length > 0;
       } else {
              string = (char*)emalloc(sizeof(char));
              *string = '\0';
              ok = FALSE;
              length = 0;
       }

       if (!ok) {
              char *msg = php_win_err(GetLastError());

              php_error_docref(NULL TSRMLS_CC, E_WARNING,
                     "Could not convert string from unicode: `%s'", msg);

              LocalFree(msg);
       }

       if (string_len) {
              *string_len = length-1;
       }

       return string;
}

Here is the caller graph for this function:

Definition at line 764 of file com_persist.c.

{
       zend_class_entry ce;

       memcpy(&helper_handlers, zend_get_std_object_handlers(), sizeof(helper_handlers));
       helper_handlers.clone_obj = NULL;

       INIT_CLASS_ENTRY(ce, "COMPersistHelper", com_persist_helper_methods);
       ce.create_object = helper_new;
       helper_ce = zend_register_internal_class(&ce TSRMLS_CC);
       helper_ce->ce_flags |= ZEND_ACC_FINAL;

       le_istream = zend_register_list_destructors_ex(istream_dtor,
                     NULL, "com_dotnet_istream_wrapper", module_number);
       
       return SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int php_com_process_typeinfo ( ITypeInfo *  typeinfo,
HashTable id_to_name,
int  printdef,
GUID *  guid,
int codepage  TSRMLS_DC 
)

Definition at line 430 of file com_typeinfo.c.

{
       TYPEATTR *attr;
       FUNCDESC *func;
       int i;
       OLECHAR *olename;
       char *ansiname = NULL;
       unsigned int ansinamelen;
       int ret = 0;

       if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &attr))) {
              return 0;
       }

       /* verify that it is suitable */
       if (id_to_name == NULL || attr->typekind == TKIND_DISPATCH) {

              if (guid) {
                     memcpy(guid, &attr->guid, sizeof(GUID));
              }
              
              if (printdef) {
                     char *guidstring;

                     ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename, NULL, NULL, NULL);
                     ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC);
                     SysFreeString(olename);

                     guidstring = php_com_string_from_clsid(&attr->guid, codepage TSRMLS_CC);
                     php_printf("class %s { /* GUID=%s */\n", ansiname, guidstring);
                     efree(guidstring);

                     efree(ansiname);
              }

              if (id_to_name) {
                     zend_hash_init(id_to_name, 0, NULL, ZVAL_PTR_DTOR, 0);
              }

              /* So we've got the dispatch interface; lets list the event methods */
              for (i = 0; i < attr->cFuncs; i++) {
                     zval *tmp;
                     DISPID lastid = 0;   /* for props */
                     int isprop;

                     if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &func)))
                            break;

                     isprop = (func->invkind & DISPATCH_PROPERTYGET || func->invkind & DISPATCH_PROPERTYPUT);

                     if (!isprop || lastid != func->memid) {

                            lastid = func->memid;
                            
                            ITypeInfo_GetDocumentation(typeinfo, func->memid, &olename, NULL, NULL, NULL);
                            ansiname = php_com_olestring_to_string(olename, &ansinamelen, codepage TSRMLS_CC);
                            SysFreeString(olename);

                            if (printdef) {
                                   int j;
                                   char *funcdesc;
                                   unsigned int funcdesclen, cnames = 0;
                                   BSTR *names;

                                   names = (BSTR*)safe_emalloc((func->cParams + 1), sizeof(BSTR), 0);

                                   ITypeInfo_GetNames(typeinfo, func->memid, names, func->cParams + 1, &cnames);
                                   /* first element is the function name */
                                   SysFreeString(names[0]);

                                   php_printf("\t/* DISPID=%d */\n", func->memid);

                                   if (func->elemdescFunc.tdesc.vt != VT_VOID) {
                                          php_printf("\t/* %s [%d] */\n",
                                                        vt_to_string(func->elemdescFunc.tdesc.vt),
                                                        func->elemdescFunc.tdesc.vt
                                                        );
                                   }

                                   if (isprop) {

                                          ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
                                          if (olename) {
                                                 funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC);
                                                 SysFreeString(olename);
                                                 php_printf("\t/* %s */\n", funcdesc);
                                                 efree(funcdesc);
                                          }

                                          php_printf("\tvar $%s;\n\n", ansiname);

                                   } else {
                                          /* a function */

                                          php_printf("\tfunction %s(\n", ansiname);

                                          for (j = 0; j < func->cParams; j++) {
                                                 ELEMDESC *elem = &func->lprgelemdescParam[j];

                                                 php_printf("\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt);

                                                 if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN)
                                                        php_printf("[in]");
                                                 if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT)
                                                        php_printf("[out]");

                                                 if (elem->tdesc.vt == VT_PTR) {
                                                        /* what does it point to ? */
                                                        php_printf(" --> %s [%d] ",
                                                                      vt_to_string(elem->tdesc.lptdesc->vt),
                                                                      elem->tdesc.lptdesc->vt
                                                                      );
                                                 }

                                                 /* when we handle prop put and get, this will look nicer */
                                                 if (j+1 < (int)cnames) {
                                                        funcdesc = php_com_olestring_to_string(names[j+1], &funcdesclen, codepage TSRMLS_CC);
                                                        SysFreeString(names[j+1]);
                                                 } else {
                                                        funcdesc = "???";
                                                 }

                                                 php_printf(" */ %s%s%c\n",
                                                               elem->tdesc.vt == VT_PTR ? "&$" : "$",
                                                               funcdesc,
                                                               j == func->cParams - 1 ? ' ' : ','
                                                               );

                                                 if (j+1 < (int)cnames) {
                                                        efree(funcdesc);
                                                 }
                                          }

                                          php_printf("\t\t)\n\t{\n");

                                          ITypeInfo_GetDocumentation(typeinfo, func->memid, NULL, &olename, NULL, NULL);
                                          if (olename) {
                                                 funcdesc = php_com_olestring_to_string(olename, &funcdesclen, codepage TSRMLS_CC);
                                                 SysFreeString(olename);
                                                 php_printf("\t\t/* %s */\n", funcdesc);
                                                 efree(funcdesc);
                                          }

                                          php_printf("\t}\n");
                                   }

                                   efree(names);
                            }

                            if (id_to_name) {
                                   zend_str_tolower(ansiname, ansinamelen);
                                   MAKE_STD_ZVAL(tmp);
                                   ZVAL_STRINGL(tmp, ansiname, ansinamelen, 0);
                                   zend_hash_index_update(id_to_name, func->memid, (void*)&tmp, sizeof(zval *), NULL);
                            }
                     }
                     ITypeInfo_ReleaseFuncDesc(typeinfo, func);
              }

              if (printdef) {
                     php_printf("}\n");
              }

              ret = 1;
       } else {
              zend_error(E_WARNING, "That's not a dispatchable interface!! type kind = %08x", attr->typekind);
       }

       ITypeInfo_ReleaseTypeAttr(typeinfo, attr);

       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI int php_com_safearray_get_elem ( VARIANT *  array,
VARIANT *  dest,
LONG dim1  TSRMLS_DC 
)

Definition at line 95 of file com_misc.c.

{
       UINT dims;
       LONG lbound, ubound;
       LONG indices[1];
       VARTYPE vt;
       
       if (!V_ISARRAY(array)) {
              return 0;
       }
       
       dims = SafeArrayGetDim(V_ARRAY(array));

       if (dims != 1) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING,
                        "Can only handle single dimension variant arrays (this array has %d)", dims);
              return 0;
       }
       
       if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
              vt = V_VT(array) & ~VT_ARRAY;
       }

       /* determine the bounds */
       SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
       SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);
       
       /* check bounds */
       if (dim1 < lbound || dim1 > ubound) {
              php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
              return 0;
       }
       
       /* now fetch that element */
       VariantInit(dest);
              
       indices[0] = dim1;

       if (vt == VT_VARIANT) {
              SafeArrayGetElement(V_ARRAY(array), indices, dest);
       } else {
              V_VT(dest) = vt;
              /* store the value into "lVal" member of the variant.
               * This works because it is a union; since we know the variant
               * type, we end up with a working variant */
              SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
       }

       return 1;     
}

Here is the call graph for this function:

Here is the caller graph for this function:

int php_com_saproxy_create ( zval *  com_object,
zval *  proxy_out,
zval *index  TSRMLS_DC 
)

Definition at line 435 of file com_saproxy.c.

{
       php_com_saproxy *proxy, *rel = NULL;

       proxy = ecalloc(1, sizeof(*proxy));
       proxy->dimensions = 1;

       if (Z_OBJCE_P(com_object) == php_com_saproxy_class_entry) {
              rel = SA_FETCH(com_object);
              proxy->obj = rel->obj;
              proxy->zobj = rel->zobj;
              proxy->dimensions += rel->dimensions;
       } else {
              proxy->obj = CDNO_FETCH(com_object);
              proxy->zobj = com_object;
       }

       Z_ADDREF_P(proxy->zobj);
       proxy->indices = safe_emalloc(proxy->dimensions, sizeof(zval *), 0);

       if (rel) {
              clone_indices(proxy, rel, rel->dimensions);
       }

       MAKE_STD_ZVAL(proxy->indices[proxy->dimensions-1]);
       *proxy->indices[proxy->dimensions-1] = *index;
       zval_copy_ctor(proxy->indices[proxy->dimensions-1]);

       Z_TYPE_P(proxy_out) = IS_OBJECT;
       Z_OBJ_HANDLE_P(proxy_out) = zend_objects_store_put(proxy, NULL, saproxy_free_storage, saproxy_clone TSRMLS_CC);
       Z_OBJ_HT_P(proxy_out) = &php_com_saproxy_handlers;
       
       return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

zend_object_iterator* php_com_saproxy_iter_get ( zend_class_entry *  ce,
zval *  object,
int by_ref  TSRMLS_DC 
)

Definition at line 555 of file com_saproxy.c.

{
       php_com_saproxy *proxy = SA_FETCH(object);
       php_com_saproxy_iter *I;
       int i;

       if (by_ref) {
              zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
       }

       I = ecalloc(1, sizeof(*I));
       I->iter.funcs = &saproxy_iter_funcs;
       I->iter.data = I;

       I->proxy = proxy;
       I->proxy_obj = object;
       Z_ADDREF_P(I->proxy_obj);

       I->indices = safe_emalloc(proxy->dimensions + 1, sizeof(LONG), 0);
       for (i = 0; i < proxy->dimensions; i++) {
              convert_to_long(proxy->indices[i]);
              I->indices[i] = Z_LVAL_P(proxy->indices[i]);
       }

       SafeArrayGetLBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imin);
       SafeArrayGetUBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imax);

       I->key = I->imin;    
       
       return &I->iter;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI OLECHAR* php_com_string_to_olestring ( char *  string,
uint  string_len,
int codepage  TSRMLS_DC 
)

Definition at line 33 of file com_olechar.c.

{
       OLECHAR *olestring = NULL;
       DWORD flags = codepage == CP_UTF8 ? 0 : MB_PRECOMPOSED | MB_ERR_INVALID_CHARS;
       BOOL ok;

       if (string_len == -1) {
              /* determine required length for the buffer (includes NUL terminator) */
              string_len = MultiByteToWideChar(codepage, flags, string, -1, NULL, 0);
       } else {
              /* allow room for NUL terminator */
              string_len++;
       }

       if (string_len > 0) {
              olestring = (OLECHAR*)safe_emalloc(string_len, sizeof(OLECHAR), 0);
              ok = MultiByteToWideChar(codepage, flags, string, string_len, olestring, string_len);
       } else {
              ok = FALSE;
              olestring = (OLECHAR*)emalloc(sizeof(OLECHAR));
              *olestring = 0;
       }

       if (!ok) {
              char *msg = php_win_err(GetLastError());

              php_error_docref(NULL TSRMLS_CC, E_WARNING,
                     "Could not convert string to unicode: `%s'", msg);

              LocalFree(msg);
       }

       return olestring;
}

Here is the caller graph for this function:

void php_com_throw_exception ( HRESULT  code,
char *message  TSRMLS_DC 
)

Definition at line 32 of file com_misc.c.

{
       int free_msg = 0;
       if (message == NULL) {
              message = php_win_err(code);
              free_msg = 1;
       }
       zend_throw_exception(php_com_exception_class_entry, message, (long)code TSRMLS_CC);
       if (free_msg) {
              LocalFree(message);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void php_com_typelibrary_dtor ( void *  pDest)

Definition at line 221 of file com_typeinfo.c.

{
       ITypeLib **Lib = (ITypeLib**)pDest;
       ITypeLib_Release(*Lib);
}

Here is the caller graph for this function:

PHPAPI void php_com_variant_from_zval ( VARIANT *  v,
zval *  z,
int codepage  TSRMLS_DC 
)

Definition at line 101 of file com_variant.c.

{
       OLECHAR *olestring;
       php_com_dotnet_object *obj;
       
       switch (Z_TYPE_P(z)) {
              case IS_NULL:
                     V_VT(v) = VT_NULL;
                     break;

              case IS_BOOL:
                     V_VT(v) = VT_BOOL;
                     V_BOOL(v) = Z_BVAL_P(z) ? VARIANT_TRUE : VARIANT_FALSE;
                     break;

              case IS_OBJECT:
                     if (php_com_is_valid_object(z TSRMLS_CC)) {
                            obj = CDNO_FETCH(z);
                            if (V_VT(&obj->v) == VT_DISPATCH) {
                                   /* pass the underlying object */
                                   V_VT(v) = VT_DISPATCH;
                                   if (V_DISPATCH(&obj->v)) {
                                          IDispatch_AddRef(V_DISPATCH(&obj->v));
                                   }
                                   V_DISPATCH(v) = V_DISPATCH(&obj->v);
                            } else {
                                   /* pass the variant by reference */
                                   V_VT(v) = VT_VARIANT | VT_BYREF;
                                   V_VARIANTREF(v) = &obj->v;
                            }
                     } else {
                            /* export the PHP object using our COM wrapper */
                            V_VT(v) = VT_DISPATCH;
                            V_DISPATCH(v) = php_com_wrapper_export(z TSRMLS_CC);
                     }
                     break;
                     
              case IS_ARRAY:
                     /* map as safe array */
                     safe_array_from_zval(v, z, codepage TSRMLS_CC);
                     break;

              case IS_LONG:
                     V_VT(v) = VT_I4;
                     V_I4(v) = Z_LVAL_P(z);
                     break;

              case IS_DOUBLE:
                     V_VT(v) = VT_R8;
                     V_R8(v) = Z_DVAL_P(z);
                     break;

              case IS_STRING:
                     V_VT(v) = VT_BSTR;
                     olestring = php_com_string_to_olestring(Z_STRVAL_P(z), Z_STRLEN_P(z), codepage TSRMLS_CC);
                     V_BSTR(v) = SysAllocStringByteLen((char*)olestring, Z_STRLEN_P(z) * sizeof(OLECHAR));
                     efree(olestring);
                     break;

              case IS_RESOURCE:
              case IS_CONSTANT:
              case IS_CONSTANT_ARRAY:
              default:
                     V_VT(v) = VT_NULL;
                     break;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_com_variant_from_zval_with_type ( VARIANT *  v,
zval *  z,
VARTYPE  type,
int codepage  TSRMLS_DC 
)
PHPAPI void php_com_wrap_dispatch ( zval *  z,
IDispatch *  disp,
int codepage  TSRMLS_DC 
)

Definition at line 45 of file com_misc.c.

{
       php_com_dotnet_object *obj;

       obj = emalloc(sizeof(*obj));
       memset(obj, 0, sizeof(*obj));
       obj->code_page = codepage;
       obj->ce = php_com_variant_class_entry;
       obj->zo.ce = php_com_variant_class_entry;

       VariantInit(&obj->v);
       V_VT(&obj->v) = VT_DISPATCH;
       V_DISPATCH(&obj->v) = disp;

       IDispatch_AddRef(V_DISPATCH(&obj->v));
       IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);

       Z_TYPE_P(z) = IS_OBJECT;
       z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
       z->value.obj.handlers = &php_com_object_handlers;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI void php_com_wrap_variant ( zval *  z,
VARIANT *  v,
int codepage  TSRMLS_DC 
)

Definition at line 68 of file com_misc.c.

{
       php_com_dotnet_object *obj;

       obj = emalloc(sizeof(*obj));
       memset(obj, 0, sizeof(*obj));
       obj->code_page = codepage;
       obj->ce = php_com_variant_class_entry;
       obj->zo.ce = php_com_variant_class_entry;

       VariantInit(&obj->v);
       VariantCopyInd(&obj->v, v);
       obj->modified = 0;

       if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
              IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
       }

       Z_TYPE_P(z) = IS_OBJECT;
       
       z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
       z->value.obj.handlers = &php_com_object_handlers;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI IDispatch* php_com_wrapper_export ( zval *val  TSRMLS_DC)

Definition at line 628 of file com_wrapper.c.

{
       php_dispatchex *disp = NULL;

       if (Z_TYPE_P(val) != IS_OBJECT) {
              return NULL;
       }

       if (php_com_is_valid_object(val TSRMLS_CC)) {
              /* pass back its IDispatch directly */
              php_com_dotnet_object *obj = CDNO_FETCH(val);
              
              if (obj == NULL)
                     return NULL;

              if (V_VT(&obj->v) == VT_DISPATCH && V_DISPATCH(&obj->v)) {
                     IDispatch_AddRef(V_DISPATCH(&obj->v));
                     return V_DISPATCH(&obj->v);
              }
                     
              return NULL;
       }

       disp = disp_constructor(val TSRMLS_CC);
       generate_dispids(disp TSRMLS_CC);

       return (IDispatch*)disp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI IDispatch* php_com_wrapper_export_as_sink ( zval *  val,
GUID *  sinkid,
HashTable *id_to_name  TSRMLS_DC 
)

Definition at line 589 of file com_wrapper.c.

{
       php_dispatchex *disp = disp_constructor(val TSRMLS_CC);
       HashPosition pos;
       char *name = NULL;
       zval *tmp, **ntmp;
       int namelen;
       int keytype;
       ulong pid;

       disp->dispid_to_name = id_to_name;

       memcpy(&disp->sinkid, sinkid, sizeof(disp->sinkid));
       
       /* build up the reverse mapping */
       ALLOC_HASHTABLE(disp->name_to_dispid);
       zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
       
       zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
       while (HASH_KEY_NON_EXISTANT != (keytype =
                            zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) {

              if (keytype == HASH_KEY_IS_LONG) {

                     zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos);
                     
                     MAKE_STD_ZVAL(tmp);
                     ZVAL_LONG(tmp, pid);
                     zend_hash_update(disp->name_to_dispid, Z_STRVAL_PP(ntmp),
                            Z_STRLEN_PP(ntmp)+1, (void*)&tmp, sizeof(zval *), NULL);
              }

              zend_hash_move_forward_ex(id_to_name, &pos);
       }

       return (IDispatch*)disp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 63 of file com_wrapper.c.

{
       le_dispatch = zend_register_list_destructors_ex(dispatch_dtor,
              NULL, "com_dotnet_dispatch_wrapper", module_number);
       return le_dispatch;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHPAPI int php_com_zval_from_variant ( zval *  z,
VARIANT *  v,
int codepage  TSRMLS_DC 
)

Definition at line 169 of file com_variant.c.

{
       OLECHAR *olestring = NULL;
       int ret = SUCCESS;

       switch (V_VT(v)) {
              case VT_EMPTY:
              case VT_NULL:
              case VT_VOID:
                     ZVAL_NULL(z);
                     break;
              case VT_UI1:
                     ZVAL_LONG(z, (long)V_UI1(v));
                     break;
              case VT_I1:
                     ZVAL_LONG(z, (long)V_I1(v));
                     break;
              case VT_UI2:
                     ZVAL_LONG(z, (long)V_UI2(v));
                     break;
              case VT_I2:
                     ZVAL_LONG(z, (long)V_I2(v));
                     break;
              case VT_UI4:  /* TODO: promote to double if large? */
                     ZVAL_LONG(z, (long)V_UI4(v));
                     break;
              case VT_I4:
                     ZVAL_LONG(z, (long)V_I4(v));
                     break;
              case VT_INT:
                     ZVAL_LONG(z, V_INT(v));
                     break;
              case VT_UINT: /* TODO: promote to double if large? */
                     ZVAL_LONG(z, (long)V_UINT(v));
                     break;
              case VT_R4:
                     ZVAL_DOUBLE(z, (double)V_R4(v));
                     break;
              case VT_R8:
                     ZVAL_DOUBLE(z, V_R8(v));
                     break;
              case VT_BOOL:
                     ZVAL_BOOL(z, V_BOOL(v) ? 1 : 0);
                     break;
              case VT_BSTR:
                     olestring = V_BSTR(v);
                     if (olestring) {
                            Z_TYPE_P(z) = IS_STRING;
                            Z_STRVAL_P(z) = php_com_olestring_to_string(olestring,
                                   &Z_STRLEN_P(z), codepage TSRMLS_CC);
                            olestring = NULL;
                     }
                     break;
              case VT_UNKNOWN:
                     if (V_UNKNOWN(v) != NULL) {
                            IDispatch *disp;

                            if (SUCCEEDED(IUnknown_QueryInterface(V_UNKNOWN(v), &IID_IDispatch, &disp))) {
                                   php_com_wrap_dispatch(z, disp, codepage TSRMLS_CC);
                                   IDispatch_Release(disp);
                            } else {
                                   ret = FAILURE;
                            }
                     }
                     break;

              case VT_DISPATCH:
                     if (V_DISPATCH(v) != NULL) {
                            php_com_wrap_dispatch(z, V_DISPATCH(v), codepage TSRMLS_CC);
                     }
                     break;

              case VT_VARIANT:
                     /* points to another variant */
                     return php_com_zval_from_variant(z, V_VARIANTREF(v), codepage TSRMLS_CC);
                     
              default:
                     php_com_wrap_variant(z, v, codepage TSRMLS_CC);
       }

       if (olestring) {
              efree(olestring);
       }

       if (ret == FAILURE) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "variant->zval: conversion from 0x%x ret=%d", V_VT(v), ret);
       }

       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHP_FUNCTION ( com_create_instance  )

Definition at line 33 of file com_com.c.

{
       zval *object = getThis();
       zval *server_params = NULL;
       php_com_dotnet_object *obj;
       char *module_name, *typelib_name = NULL, *server_name = NULL;
       char *user_name = NULL, *domain_name = NULL, *password = NULL;
       int module_name_len, typelib_name_len, server_name_len,
              user_name_len, domain_name_len, password_len;
       OLECHAR *moniker;
       CLSID clsid;
       CLSCTX ctx = CLSCTX_SERVER;
       HRESULT res = E_FAIL;
       int mode = COMG(autoreg_case_sensitive) ? CONST_CS : 0;
       ITypeLib *TL = NULL;
       COSERVERINFO  info;
       COAUTHIDENTITY       authid = {0};
       COAUTHINFO           authinfo = {
              RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
              RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
              &authid, EOAC_NONE
       };

       php_com_initialize(TSRMLS_C);
       obj = CDNO_FETCH(object);

       if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "s|s!ls",
                     &module_name, &module_name_len, &server_name, &server_name_len,
                     &obj->code_page, &typelib_name, &typelib_name_len) &&
              FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "sa|ls",
                     &module_name, &module_name_len, &server_params, &obj->code_page,
                     &typelib_name, &typelib_name_len)) {

              php_com_throw_exception(E_INVALIDARG, "Could not create COM object - invalid arguments!" TSRMLS_CC);
              ZVAL_NULL(object);
              return;
       }

       if (server_name) {
              ctx = CLSCTX_REMOTE_SERVER;
       } else if (server_params) {
              zval **tmp;

              /* decode the data from the array */

              if (SUCCESS == zend_hash_find(HASH_OF(server_params),
                            "Server", sizeof("Server"), (void**)&tmp)) {
                     convert_to_string_ex(tmp);
                     server_name = Z_STRVAL_PP(tmp);
                     server_name_len = Z_STRLEN_PP(tmp);
                     ctx = CLSCTX_REMOTE_SERVER;
              }

              if (SUCCESS == zend_hash_find(HASH_OF(server_params),
                            "Username", sizeof("Username"), (void**)&tmp)) {
                     convert_to_string_ex(tmp);
                     user_name = Z_STRVAL_PP(tmp);
                     user_name_len = Z_STRLEN_PP(tmp);
              }

              if (SUCCESS == zend_hash_find(HASH_OF(server_params),
                            "Password", sizeof("Password"), (void**)&tmp)) {
                     convert_to_string_ex(tmp);
                     password = Z_STRVAL_PP(tmp);
                     password_len = Z_STRLEN_PP(tmp);
              }

              if (SUCCESS == zend_hash_find(HASH_OF(server_params),
                            "Domain", sizeof("Domain"), (void**)&tmp)) {
                     convert_to_string_ex(tmp);
                     domain_name = Z_STRVAL_PP(tmp);
                     domain_name_len = Z_STRLEN_PP(tmp);
              }

              if (SUCCESS == zend_hash_find(HASH_OF(server_params),
                            "Flags", sizeof("Flags"), (void**)&tmp)) {
                     convert_to_long_ex(tmp);
                     ctx = (CLSCTX)Z_LVAL_PP(tmp);
              }
       }

       if (server_name && !COMG(allow_dcom)) {
              php_com_throw_exception(E_ERROR, "DCOM has been disabled by your administrator [com.allow_dcom=0]" TSRMLS_CC);
              return;
       }

       moniker = php_com_string_to_olestring(module_name, module_name_len, obj->code_page TSRMLS_CC);

       /* if instantiating a remote object, either directly, or via
        * a moniker, fill in the relevant info */
       if (server_name) {
              info.dwReserved1 = 0;
              info.dwReserved2 = 0;
              info.pwszName = php_com_string_to_olestring(server_name, server_name_len, obj->code_page TSRMLS_CC);

              if (user_name) {
                     authid.User = php_com_string_to_olestring(user_name, -1, obj->code_page TSRMLS_CC);
                     authid.UserLength = user_name_len;

                     if (password) {
                            authid.Password = (OLECHAR*)password;
                            authid.PasswordLength = password_len;
                     } else {
                            authid.Password = (OLECHAR*)"";
                            authid.PasswordLength = 0;
                     }

                     if (domain_name) {
                            authid.Domain = (OLECHAR*)domain_name;
                            authid.DomainLength = domain_name_len;
                     } else {
                            authid.Domain = (OLECHAR*)"";
                            authid.DomainLength = 0;
                     }
                     authid.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
                     info.pAuthInfo = &authinfo;
              } else {
                     info.pAuthInfo = NULL;
              }
       }

       if (FAILED(CLSIDFromString(moniker, &clsid))) {
              /* try to use it as a moniker */
              IBindCtx *pBindCtx = NULL;
              IMoniker *pMoniker = NULL;
              ULONG ulEaten;
              BIND_OPTS2 bopt = {0};

              if (SUCCEEDED(res = CreateBindCtx(0, &pBindCtx))) {
                     if (server_name) {
                            /* fill in the remote server info.
                             * MSDN docs indicate that this might be ignored in
                             * current win32 implementations, but at least we are
                             * doing the right thing in readiness for the day that
                             * it does work */
                            bopt.cbStruct = sizeof(bopt);
                            IBindCtx_GetBindOptions(pBindCtx, (BIND_OPTS*)&bopt);
                            bopt.pServerInfo = &info;
                            /* apparently, GetBindOptions will only ever return
                             * a regular BIND_OPTS structure.  My gut feeling is
                             * that it will modify the size field to reflect that
                             * so lets be safe and set it to the BIND_OPTS2 size
                             * again */
                            bopt.cbStruct = sizeof(bopt);
                            IBindCtx_SetBindOptions(pBindCtx, (BIND_OPTS*)&bopt);
                     }
                     
                     if (SUCCEEDED(res = MkParseDisplayName(pBindCtx, moniker, &ulEaten, &pMoniker))) {
                            res = IMoniker_BindToObject(pMoniker, pBindCtx,
                                   NULL, &IID_IDispatch, (LPVOID*)&V_DISPATCH(&obj->v));
                     
                            if (SUCCEEDED(res)) {
                                   V_VT(&obj->v) = VT_DISPATCH;
                            }

                            IMoniker_Release(pMoniker);
                     }
              }
              if (pBindCtx) {
                     IBindCtx_Release(pBindCtx);
              }
       } else if (server_name) {
              MULTI_QI             qi;

              qi.pIID = &IID_IDispatch;
              qi.pItf = NULL;
              qi.hr = S_OK;

              res = CoCreateInstanceEx(&clsid, NULL, ctx, &info, 1, &qi);

              if (SUCCEEDED(res)) {
                     res = qi.hr;
                     V_DISPATCH(&obj->v) = (IDispatch*)qi.pItf;
                     V_VT(&obj->v) = VT_DISPATCH;
              }
       } else {
              res = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&V_DISPATCH(&obj->v));
              if (SUCCEEDED(res)) {
                     V_VT(&obj->v) = VT_DISPATCH;
              }
       }

       if (server_name) {
              STR_FREE((char*)info.pwszName);
              STR_FREE((char*)authid.User);
       }

       efree(moniker);

       if (FAILED(res)) {
              char *werr, *msg;

              werr = php_win_err(res);
              spprintf(&msg, 0, "Failed to create COM object `%s': %s", module_name, werr);
              LocalFree(werr);

              php_com_throw_exception(res, msg TSRMLS_CC);
              efree(msg);
              ZVAL_NULL(object);
              return;
       }

       /* we got the object and it lives ! */

       /* see if it has TypeInfo available */
       if (FAILED(IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo)) && typelib_name) {
              /* load up the library from the named file */
              int cached;

              TL = php_com_load_typelib_via_cache(typelib_name, obj->code_page, &cached TSRMLS_CC);

              if (TL) {
                     if (COMG(autoreg_on) && !cached) {
                            php_com_import_typelib(TL, mode, obj->code_page TSRMLS_CC);
                     }

                     /* cross your fingers... there is no guarantee that this ITypeInfo
                      * instance has any relation to this IDispatch instance... */
                     ITypeLib_GetTypeInfo(TL, 0, &obj->typeinfo);
                     ITypeLib_Release(TL);
              }
       } else if (obj->typeinfo && COMG(autoreg_on)) {
              int idx;

              if (SUCCEEDED(ITypeInfo_GetContainingTypeLib(obj->typeinfo, &TL, &idx))) {
                     /* check if the library is already in the cache by getting its name */
                     BSTR name;

                     if (SUCCEEDED(ITypeLib_GetDocumentation(TL, -1, &name, NULL, NULL, NULL))) {
                            typelib_name = php_com_olestring_to_string(name, &typelib_name_len, obj->code_page TSRMLS_CC);

                            if (SUCCESS == zend_ts_hash_add(&php_com_typelibraries, typelib_name, typelib_name_len+1, (void*)&TL, sizeof(ITypeLib*), NULL)) {
                                   php_com_import_typelib(TL, mode, obj->code_page TSRMLS_CC);

                                   /* add a reference for the hash */
                                   ITypeLib_AddRef(TL);
                            }

                     } else {
                            /* try it anyway */
                            php_com_import_typelib(TL, mode, obj->code_page TSRMLS_CC);
                     }

                     ITypeLib_Release(TL);
              }
       }

}

Here is the call graph for this function:

PHP_FUNCTION ( com_event_sink  )

Definition at line 679 of file com_com.c.

{
       zval *object, *sinkobject, *sink=NULL;
       char *dispname = NULL, *typelibname = NULL;
       zend_bool gotguid = 0;
       php_com_dotnet_object *obj;
       ITypeInfo *typeinfo = NULL;

       RETVAL_FALSE;
       
       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oo|z/",
                     &object, php_com_variant_class_entry, &sinkobject, &sink)) {
              RETURN_FALSE;
       }

       php_com_initialize(TSRMLS_C);
       obj = CDNO_FETCH(object);
       
       if (sink && Z_TYPE_P(sink) == IS_ARRAY) {
              /* 0 => typelibname, 1 => dispname */
              zval **tmp;

              if (zend_hash_index_find(Z_ARRVAL_P(sink), 0, (void**)&tmp) == SUCCESS)
                     typelibname = Z_STRVAL_PP(tmp);
              if (zend_hash_index_find(Z_ARRVAL_P(sink), 1, (void**)&tmp) == SUCCESS)
                     dispname = Z_STRVAL_PP(tmp);
       } else if (sink != NULL) {
              convert_to_string(sink);
              dispname = Z_STRVAL_P(sink);
       }
       
       typeinfo = php_com_locate_typeinfo(typelibname, obj, dispname, 1 TSRMLS_CC);

       if (typeinfo) {
              HashTable *id_to_name;
              
              ALLOC_HASHTABLE(id_to_name);
              
              if (php_com_process_typeinfo(typeinfo, id_to_name, 0, &obj->sink_id, obj->code_page TSRMLS_CC)) {

                     /* Create the COM wrapper for this sink */
                     obj->sink_dispatch = php_com_wrapper_export_as_sink(sinkobject, &obj->sink_id, id_to_name TSRMLS_CC);

                     /* Now hook it up to the source */
                     php_com_object_enable_event_sink(obj, TRUE TSRMLS_CC);
                     RETVAL_TRUE;

              } else {
                     FREE_HASHTABLE(id_to_name);
              }
       }
       
       if (typeinfo) {
              ITypeInfo_Release(typeinfo);
       }

}

Here is the call graph for this function:

PHP_FUNCTION ( com_create_guid  )

Definition at line 656 of file com_com.c.

{
       GUID retval;
       OLECHAR *guid_string;

       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       php_com_initialize(TSRMLS_C);
       if (CoCreateGuid(&retval) == S_OK && StringFromCLSID(&retval, &guid_string) == S_OK) {
              Z_TYPE_P(return_value) = IS_STRING;
              Z_STRVAL_P(return_value) = php_com_olestring_to_string(guid_string, &Z_STRLEN_P(return_value), CP_ACP TSRMLS_CC);

              CoTaskMemFree(guid_string);
       } else {
              RETURN_FALSE;
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( com_print_typeinfo  )

Definition at line 740 of file com_com.c.

{
       zval *arg1;
       char *ifacename = NULL;
       char *typelibname = NULL;
       int ifacelen;
       zend_bool wantsink = 0;
       php_com_dotnet_object *obj = NULL;
       ITypeInfo *typeinfo;
       
       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z/|s!b", &arg1, &ifacename,
                            &ifacelen, &wantsink)) {
              RETURN_FALSE;
       }

       php_com_initialize(TSRMLS_C);
       if (Z_TYPE_P(arg1) == IS_OBJECT) {
              CDNO_FETCH_VERIFY(obj, arg1);
       } else {
              convert_to_string(arg1);
              typelibname = Z_STRVAL_P(arg1);
       }

       typeinfo = php_com_locate_typeinfo(typelibname, obj, ifacename, wantsink ? 1 : 0 TSRMLS_CC);
       if (typeinfo) {
              php_com_process_typeinfo(typeinfo, NULL, 1, NULL, obj ? obj->code_page : COMG(code_page) TSRMLS_CC);
              ITypeInfo_Release(typeinfo);
              RETURN_TRUE;
       } else {
              zend_error(E_WARNING, "Unable to find typeinfo using the parameters supplied");
       }
       RETURN_FALSE;
}

Here is the call graph for this function:

PHP_FUNCTION ( com_message_pump  )

Definition at line 777 of file com_com.c.

{
       long timeoutms = 0;
       MSG msg;
       DWORD result;
       
       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &timeoutms) == FAILURE)
              RETURN_FALSE;
       
       php_com_initialize(TSRMLS_C);
       result = MsgWaitForMultipleObjects(0, NULL, FALSE, timeoutms, QS_ALLINPUT);

       if (result == WAIT_OBJECT_0) {
              while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
                     TranslateMessage(&msg);
                     DispatchMessage(&msg);
              }
              /* we processed messages */
              RETVAL_TRUE;
       } else {
              /* we did not process messages (timed out) */
              RETVAL_FALSE;
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( com_load_typelib  )

Definition at line 805 of file com_com.c.

{
       char *name;
       int namelen;
       ITypeLib *pTL = NULL;
       zend_bool cs = TRUE;
       int codepage = COMG(code_page);
       int cached = 0;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &name, &namelen, &cs)) {
              return;
       }

       RETVAL_FALSE;
       
       php_com_initialize(TSRMLS_C);
       pTL = php_com_load_typelib_via_cache(name, codepage, &cached TSRMLS_CC);
       if (pTL) {
              if (cached) {
                     RETVAL_TRUE;
              } else if (php_com_import_typelib(pTL, cs ? CONST_CS : 0, codepage TSRMLS_CC) == SUCCESS) {
                     RETVAL_TRUE;
              }

              ITypeLib_Release(pTL);
              pTL = NULL;
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( com_get_active_object  )

Definition at line 287 of file com_com.c.

{
       CLSID clsid;
       char *module_name;
       int module_name_len;
       long code_page = COMG(code_page);
       IUnknown *unk = NULL;
       IDispatch *obj = NULL;
       HRESULT res;
       OLECHAR *module = NULL;

       php_com_initialize(TSRMLS_C);
       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l",
                            &module_name, &module_name_len, &code_page)) {
              php_com_throw_exception(E_INVALIDARG, "Invalid arguments!" TSRMLS_CC);
              return;
       }

       module = php_com_string_to_olestring(module_name, module_name_len, code_page TSRMLS_CC);

       res = CLSIDFromString(module, &clsid);

       if (FAILED(res)) {
              php_com_throw_exception(res, NULL TSRMLS_CC);
       } else {
              res = GetActiveObject(&clsid, NULL, &unk);

              if (FAILED(res)) {
                     php_com_throw_exception(res, NULL TSRMLS_CC);
              } else {
                     res = IUnknown_QueryInterface(unk, &IID_IDispatch, &obj);

                     if (FAILED(res)) {
                            php_com_throw_exception(res, NULL TSRMLS_CC);
                     } else if (obj) {
                            /* we got our dispatchable object */
                            php_com_wrap_dispatch(return_value, obj, code_page TSRMLS_CC);
                     }
              }
       }

       if (obj) {
              IDispatch_Release(obj);
       }
       if (unk) {
              IUnknown_Release(obj);
       }
       efree(module);
}

Here is the call graph for this function:

PHP_FUNCTION ( com_variant_create_instance  )

Definition at line 395 of file com_variant.c.

{
       /* VARTYPE == unsigned short */ long vt = VT_EMPTY;
       long codepage = CP_ACP;
       zval *object = getThis();
       php_com_dotnet_object *obj;
       zval *zvalue = NULL;
       HRESULT res;

       if (ZEND_NUM_ARGS() == 0) {
              /* just leave things as-is - an empty variant */
              return;
       }
       
       obj = CDNO_FETCH(object);
       
       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
              "z!|ll", &zvalue, &vt, &codepage)) {
                     php_com_throw_exception(E_INVALIDARG, "Invalid arguments" TSRMLS_CC);
                     return;
       }

       php_com_initialize(TSRMLS_C);
       if (ZEND_NUM_ARGS() == 3) {
              obj->code_page = codepage;
       }

       if (zvalue) {
              php_com_variant_from_zval(&obj->v, zvalue, obj->code_page TSRMLS_CC);
       }

       /* Only perform conversion if variant not already of type passed */
       if ((ZEND_NUM_ARGS() >= 2) && (vt != V_VT(&obj->v))) {

              /* If already an array and VT_ARRAY is passed then:
                     - if only VT_ARRAY passed then do not perform a conversion
                     - if VT_ARRAY plus other type passed then perform conversion 
                       but will probably fail (origional behavior)
              */
              if ((vt & VT_ARRAY) && (V_VT(&obj->v) & VT_ARRAY)) {
                     long orig_vt = vt;

                     vt &= ~VT_ARRAY;
                     if (vt) {
                            vt = orig_vt;
                     }
              }

              if (vt) {
                     res = VariantChangeType(&obj->v, &obj->v, 0, (VARTYPE)vt);

                     if (FAILED(res)) {
                            char *werr, *msg;

                            werr = php_win_err(res);
                            spprintf(&msg, 0, "Variant type conversion failed: %s", werr);
                            LocalFree(werr);

                            php_com_throw_exception(res, msg TSRMLS_CC);
                            efree(msg);
                     }
              }
       }

       if (V_VT(&obj->v) != VT_DISPATCH && obj->typeinfo) {
              ITypeInfo_Release(obj->typeinfo);
              obj->typeinfo = NULL;
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_set  )

Definition at line 468 of file com_variant.c.

{
       zval *zobj, *zvalue = NULL;
       php_com_dotnet_object *obj;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                     "Oz!", &zobj, php_com_variant_class_entry, &zvalue)) {
              return;
       }

       obj = CDNO_FETCH(zobj);

       /* dtor the old value */
       if (obj->typeinfo) {
              ITypeInfo_Release(obj->typeinfo);
              obj->typeinfo = NULL;
       }
       if (obj->sink_dispatch) {
              php_com_object_enable_event_sink(obj, FALSE TSRMLS_CC);
              IDispatch_Release(obj->sink_dispatch);
              obj->sink_dispatch = NULL;
       }

       VariantClear(&obj->v);

       php_com_variant_from_zval(&obj->v, zvalue, obj->code_page TSRMLS_CC);
       /* remember we modified this variant */
       obj->modified = 1;
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_add  )

Definition at line 615 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_cat  )

Definition at line 623 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_sub  )

Definition at line 631 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_mul  )

Definition at line 639 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_and  )

Definition at line 647 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_div  )

Definition at line 655 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_eqv  )

Definition at line 663 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_idiv  )

Definition at line 671 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_imp  )

Definition at line 679 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_mod  )

Definition at line 687 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_or  )

Definition at line 695 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_pow  )

Definition at line 703 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_xor  )

Definition at line 711 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_abs  )

Definition at line 775 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_fix  )

Definition at line 783 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_int  )

Definition at line 791 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_neg  )

Definition at line 799 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_not  )

Definition at line 807 of file com_variant.c.

Here is the call graph for this function:

PHP_FUNCTION ( variant_round  )

Definition at line 815 of file com_variant.c.

{
       VARIANT vres;
       VARIANT left_val;
       VARIANT *vleft = NULL;
       zval *zleft = NULL;
       php_com_dotnet_object *obj;
       int codepage = CP_ACP;
       long decimals = 0;

       VariantInit(&left_val);
       VariantInit(&vres);

       if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "Ol", &zleft, php_com_variant_class_entry, &decimals)) {
              obj = CDNO_FETCH(zleft);
              vleft = &obj->v;
       } else if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                     "z!l", &zleft, &decimals)) {
              vleft = &left_val;
              php_com_variant_from_zval(vleft, zleft, codepage TSRMLS_CC);
       } else {
              return;
       }

       if (SUCCEEDED(VarRound(vleft, decimals, &vres))) {
              php_com_wrap_variant(return_value, &vres, codepage TSRMLS_CC);
       }

       VariantClear(&vres);
       VariantClear(&left_val);
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_cmp  )

Definition at line 851 of file com_variant.c.

{
       VARIANT left_val, right_val;
       VARIANT *vleft = NULL, *vright = NULL;
       zval *zleft = NULL, *zright = NULL;
       php_com_dotnet_object *obj;
       int codepage = CP_ACP;
       long lcid = LOCALE_SYSTEM_DEFAULT;
       long flags = 0;
       /* it is safe to ignore the warning for this line; see the comments in com_handlers.c */
       STDAPI VarCmp(LPVARIANT pvarLeft, LPVARIANT pvarRight, LCID lcid, DWORD flags);

       VariantInit(&left_val);
       VariantInit(&right_val);

       if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "OO|ll", &zleft, php_com_variant_class_entry,
                     &zright, php_com_variant_class_entry, &lcid, &flags)) {
              obj = CDNO_FETCH(zleft);
              vleft = &obj->v;
              obj = CDNO_FETCH(zright);
              vright = &obj->v;
       } else if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "Oz!|ll", &zleft, php_com_variant_class_entry,
                     &zright, &lcid, &flags)) {
              obj = CDNO_FETCH(zleft);
              vleft = &obj->v;
              vright = &right_val;
              php_com_variant_from_zval(vright, zright, codepage TSRMLS_CC);
       } else if (SUCCESS == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
                     ZEND_NUM_ARGS() TSRMLS_CC, "z!O|ll", &zleft, &zright, php_com_variant_class_entry,
                     &lcid, &flags)) {
              obj = CDNO_FETCH(zright);
              vright = &obj->v;
              vleft = &left_val;
              php_com_variant_from_zval(vleft, zleft, codepage TSRMLS_CC);
       } else if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
                     "z!z!|ll", &zleft, &zright, &lcid, &flags)) {

              vleft = &left_val;
              php_com_variant_from_zval(vleft, zleft, codepage TSRMLS_CC);

              vright = &right_val;
              php_com_variant_from_zval(vright, zright, codepage TSRMLS_CC);

       } else {
              return;
       }

       ZVAL_LONG(return_value, VarCmp(vleft, vright, lcid, flags));

       VariantClear(&left_val);
       VariantClear(&right_val);
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_date_to_timestamp  )

Definition at line 909 of file com_variant.c.

{
       VARIANT vres;
       zval *zleft = NULL;
       php_com_dotnet_object *obj;

       VariantInit(&vres);

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
              "O", &zleft, php_com_variant_class_entry)) {
              return;
       }
       obj = CDNO_FETCH(zleft);

       if (SUCCEEDED(VariantChangeType(&vres, &obj->v, 0, VT_DATE))) {
              SYSTEMTIME systime;
              struct tm tmv;

              VariantTimeToSystemTime(V_DATE(&vres), &systime);

              memset(&tmv, 0, sizeof(tmv));
              tmv.tm_year = systime.wYear - 1900;
              tmv.tm_mon = systime.wMonth - 1;
              tmv.tm_mday = systime.wDay;
              tmv.tm_hour = systime.wHour;
              tmv.tm_min = systime.wMinute;
              tmv.tm_sec = systime.wSecond;
              tmv.tm_isdst = -1;

              tzset();
              RETVAL_LONG(mktime(&tmv));
       }

       VariantClear(&vres);
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_date_from_timestamp  )

Definition at line 948 of file com_variant.c.

{
       long timestamp;
       time_t ttstamp;
       SYSTEMTIME systime;
       struct tm *tmv;
       VARIANT res;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
                     &timestamp)) {
              return;
       }

       if (timestamp < 0) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timestamp value must be a positive value.");
              RETURN_FALSE;
       }

       VariantInit(&res);
       tzset();
       ttstamp = timestamp;
       tmv = localtime(&ttstamp);
       memset(&systime, 0, sizeof(systime));

       systime.wDay = tmv->tm_mday;
       systime.wHour = tmv->tm_hour;
       systime.wMinute = tmv->tm_min;
       systime.wMonth = tmv->tm_mon + 1;
       systime.wSecond = tmv->tm_sec;
       systime.wYear = tmv->tm_year + 1900;

       V_VT(&res) = VT_DATE;
       SystemTimeToVariantTime(&systime, &V_DATE(&res));

       php_com_wrap_variant(return_value, &res, CP_ACP TSRMLS_CC);

       VariantClear(&res);
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_get_type  )

Definition at line 990 of file com_variant.c.

{
       zval *zobj;
       php_com_dotnet_object *obj;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
              "O", &zobj, php_com_variant_class_entry)) {
              return;
       }
       obj = CDNO_FETCH(zobj);
              
       RETURN_LONG(V_VT(&obj->v));
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_set_type  )

Definition at line 1007 of file com_variant.c.

{
       zval *zobj;
       php_com_dotnet_object *obj;
       /* VARTYPE == unsigned short */ long vt;
       HRESULT res;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
              "Ol", &zobj, php_com_variant_class_entry, &vt)) {
              return;
       }
       obj = CDNO_FETCH(zobj);

       res = VariantChangeType(&obj->v, &obj->v, 0, (VARTYPE)vt);

       if (SUCCEEDED(res)) {
              if (vt != VT_DISPATCH && obj->typeinfo) {
                     ITypeInfo_Release(obj->typeinfo);
                     obj->typeinfo = NULL;
              }
       } else {
              char *werr, *msg;

              werr = php_win_err(res);
              spprintf(&msg, 0, "Variant type conversion failed: %s", werr);
              LocalFree(werr);

              php_com_throw_exception(res, msg TSRMLS_CC);
              efree(msg);
       }
}

Here is the call graph for this function:

PHP_FUNCTION ( variant_cast  )

Definition at line 1042 of file com_variant.c.

{
       zval *zobj;
       php_com_dotnet_object *obj;
       /* VARTYPE == unsigned short */ long vt;
       VARIANT vres;
       HRESULT res;

       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
              "Ol", &zobj, php_com_variant_class_entry, &vt)) {
              return;
       }
       obj = CDNO_FETCH(zobj);

       VariantInit(&vres);
       res = VariantChangeType(&vres, &obj->v, 0, (VARTYPE)vt);

       if (SUCCEEDED(res)) {
              php_com_wrap_variant(return_value, &vres, obj->code_page TSRMLS_CC);
       } else {
              char *werr, *msg;

              werr = php_win_err(res);
              spprintf(&msg, 0, "Variant type conversion failed: %s", werr);
              LocalFree(werr);

              php_com_throw_exception(res, msg TSRMLS_CC);
              efree(msg);
       }

       VariantClear(&vres);
}

Here is the call graph for this function:

PHP_FUNCTION ( com_dotnet_create_instance  )

Variable Documentation

zend_class_entry * php_com_exception_class_entry

Definition at line 76 of file php_com_dotnet_internal.h.

zend_object_handlers php_com_object_handlers

Definition at line 82 of file php_com_dotnet_internal.h.

zend_class_entry * php_com_saproxy_class_entry

Definition at line 76 of file php_com_dotnet_internal.h.

Definition at line 75 of file php_com_dotnet_internal.h.

zend_class_entry* php_com_variant_class_entry

Definition at line 76 of file php_com_dotnet_internal.h.