cvs: php4 /ext/com COM.c php_COM.h
| From: | Wez Furlong | Date: | Mon, 26 Aug 2002 13:36:35 +0000 |
| Subject: | cvs: php4 /ext/com COM.c php_COM.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-13678@lists.php.net to get a copy of this message | ||
wez Mon Aug 26 09:36:35 2002 EDT
Modified files:
/php4/ext/com COM.c php_COM.h
Log:
Implement com_invoke_ex, which allows the user to specify the invoke kind
flags, so that custom invocations can be made.
Tidy up code for com_propget and com_propset, so that it can work with
objects as well as resources.
# This code is from a couple of months ago, and has been hanging around
# on my windows dev box; I'm not entirely sure where I needed com_invoke_ex,
# but the additions to propget and propset are useful.
Index: php4/ext/com/COM.c diff -u php4/ext/com/COM.c:1.85 php4/ext/com/COM.c:1.86 --- php4/ext/com/COM.c:1.85 Mon Aug 5 19:41:25 2002 +++ php4/ext/com/COM.c Mon Aug 26 09:36:35 2002 @@ -18,7 +18,7 @@ | Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: COM.c,v 1.85 2002/08/05 23:41:25 phanto Exp $ */ +/* $Id: COM.c,v 1.86 2002/08/26 13:36:35 wez Exp $ */ /* * This module implements support for COM components that support the IDispatch * interface. Both local (COM) and remote (DCOM) components can be accessed. @@ -87,6 +87,7 @@ function_entry COM_functions[] = { PHP_FE(com_load, NULL) PHP_FE(com_invoke, NULL) + PHP_FE(com_invoke_ex, NULL) PHP_FE(com_addref, NULL) PHP_FE(com_release, NULL) PHP_FE(com_propget, NULL) @@ -133,6 +134,7 @@ C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); C_HASTLIB(obj) = FALSE; + C_TYPEINFO(obj) = NULL; } } } else { @@ -143,22 +145,25 @@ switch (hr) { case DISP_E_EXCEPTION: { - char *src=estrdup("Unavailable"); - int srclen=strlen(src); - char *desc=estrdup("Unavailable"); - int desclen=strlen(desc); + char *src = NULL; + int srclen = 0; + char *desc = NULL; + int desclen = 0; - if (ExceptInfo.bstrSource) - { - efree(src); + if (ExceptInfo.bstrSource) { src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC); SysFreeString(ExceptInfo.bstrSource); + } else { + src = estrdup("Unavailable"); + srclen = strlen(src); } - if (ExceptInfo.bstrDescription) - { - efree(desc); + + if (ExceptInfo.bstrDescription) { desc = php_OLECHAR_to_char(ExceptInfo.bstrDescription, &desclen, codepage TSRMLS_CC); SysFreeString(ExceptInfo.bstrDescription); + } else { + desc = estrdup("Unavailable"); + desclen = strlen(desc); } *ErrString = pemalloc(srclen+desclen+50, 1); @@ -211,6 +216,7 @@ C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); C_HASTLIB(obj) = FALSE; + C_TYPEINFO(obj) = NULL; } } } else { @@ -233,12 +239,17 @@ } else if (obj->refcount == 1) { if (C_HASTLIB(obj)) { C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); + C_TYPEINFO(obj) = NULL; + C_HASTLIB(obj) = FALSE; } if (C_HASENUM(obj)) { hr = C_ENUMVARIANT_VT(obj)->Release(C_ENUMVARIANT(obj)); + C_ENUMVARIANT(obj) = NULL; + C_HASENUM(obj) = FALSE; } hr = C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj)); C_RELEASE(obj); + C_DISPATCH(obj) = NULL; } return obj->refcount; @@ -250,7 +261,6 @@ if (C_ISREFD(obj)) { C_ADDREF(obj); } - return obj->refcount; } @@ -723,9 +733,9 @@ /* }}} */ -int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC) +static int do_COM_invoke(comval *obj, WORD dispflags, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC) { - DISPID dispid; + DISPID dispid, altdispid; DISPPARAMS dispparams; HRESULT hr; OLECHAR *funcname; @@ -876,7 +886,14 @@ dispparams.cArgs = arg_count; dispparams.cNamedArgs = 0; - hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); + if (dispflags & DISPATCH_PROPERTYPUT) { + /* Make this work for property set-ing */ + altdispid = DISPID_PROPERTYPUT; + dispparams.rgdispidNamedArgs = &altdispid; + dispparams.cNamedArgs = 1; + } + + hr = php_COM_invoke(obj, dispid, dispflags, &dispparams, var_result, &ErrString TSRMLS_CC); efree(funcname); for (current_arg=0;current_arg<arg_count;current_arg++) { @@ -903,6 +920,62 @@ return SUCCESS; } +/* {{{ proto mixed com_invoke_ex(int module, int invokeflags, string handler_name [, mixed arg [, mixed ...]]) + Invokes a COM module */ +PHP_FUNCTION(com_invoke_ex) +{ + pval **arguments; + pval *object, *function_name, *invokeflags; + comval *obj = NULL; + WORD dispflags = 0; + int arg_count = ZEND_NUM_ARGS(); + VARIANT *var_result; + + if (arg_count<3) { + ZEND_WRONG_PARAM_COUNT(); + } + arguments = (pval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } + + object = arguments[0]; + function_name = arguments[2]; + invokeflags = arguments[1]; + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); + convert_to_long(invokeflags); + dispflags = (WORD)Z_LVAL_P(invokeflags); + + /* obtain IDispatch interface */ + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(object)); + RETURN_NULL(); + } + + ALLOC_VARIANT(var_result); + + if (do_COM_invoke(obj, dispflags, function_name, var_result, arguments+3, arg_count-3 TSRMLS_CC)==FAILURE) { + FREE_VARIANT(var_result); + efree(arguments); + + RETURN_NULL(); + } + + RETVAL_VARIANT(var_result); + + efree(arguments); +} +/* }}} */ + /* {{{ proto mixed com_invoke(int module, string handler_name [, mixed arg [, mixed ...]]) Invokes a COM module */ @@ -930,7 +1003,7 @@ convert_to_long(object); obj = (comval *)zend_list_find(Z_LVAL_P(object), &type); if (!obj || (type != IS_COM)) { - php_error(E_WARNING,"%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_STRVAL_P(function_name)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a COM object handler", Z_STRVAL_P(function_name)); RETURN_NULL(); } @@ -939,7 +1012,7 @@ ALLOC_VARIANT(var_result); - if (do_COM_invoke(obj, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { + if (do_COM_invoke(obj, DISPATCH_METHOD|DISPATCH_PROPERTYGET, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { FREE_VARIANT(var_result); efree(arguments); @@ -1475,7 +1548,7 @@ int retval; ZVAL_STRINGL(&function_name, "Item", 4, 0); - retval = do_COM_invoke(array, &function_name, result, &property, 1 TSRMLS_CC); + retval = do_COM_invoke(array, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name, result, &property, 1 TSRMLS_CC); if (cleanup) { php_COM_destruct(array TSRMLS_CC); } @@ -1629,63 +1702,105 @@ } -/* {{{ proto mixed com_propget(int module, string property_name) +/* {{{ proto mixed com_propget(int module, string property_name [, mixed arg ... ]) Gets properties from a COM module */ PHP_FUNCTION(com_propget) { - pval *arg_comval, *arg_property; - int type; - comval *obj; + zval **arguments; + zval *object, *function_name; + comval *obj = NULL; + int arg_count = ZEND_NUM_ARGS(); VARIANT *var_result; - if ((ZEND_NUM_ARGS() != 2) || (zend_get_parameters(ht, 2, &arg_comval, &arg_property) == FAILURE)) { + if (arg_count<3) { ZEND_WRONG_PARAM_COUNT(); } + arguments = (zval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } - /* obtain IDispatch interface */ - convert_to_long(arg_comval); - obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type); - if (!obj || (type != IS_COM)) { - php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_LVAL_P(arg_comval)); + object = arguments[0]; + function_name = arguments[1]; + + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler"); RETURN_NULL(); } - convert_to_string_ex(&arg_property); + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); ALLOC_VARIANT(var_result); - if (do_COM_propget(var_result, obj, arg_property, FALSE TSRMLS_CC) == FAILURE) { + if (do_COM_invoke(obj, DISPATCH_PROPERTYGET, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { FREE_VARIANT(var_result); + efree(arguments); + RETURN_NULL(); } RETVAL_VARIANT(var_result); + + efree(arguments); } /* }}} */ -/* {{{ proto bool com_propput(int module, string property_name, mixed value) +/* {{{ proto bool com_propput(int module, string property_name, mixed value, ...) Puts the properties for a module */ PHP_FUNCTION(com_propput) { - pval *arg_comval, *arg_property, *arg_value; - int type; + zval **arguments; + zval *object, *function_name; comval *obj; + int arg_count = ZEND_NUM_ARGS(); + VARIANT *var_result; - if (ZEND_NUM_ARGS()!=3 || zend_get_parameters(ht, 3, &arg_comval, &arg_property, &arg_value)==FAILURE) { + if (arg_count<3) { ZEND_WRONG_PARAM_COUNT(); } + arguments = (zval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } - /* obtain comval interface */ - convert_to_long(arg_comval); - /* obtain comval interface */ - obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type); - if (!obj || (type != IS_COM)) { - php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_LVAL_P(arg_comval)); + object = arguments[0]; + function_name = arguments[1]; + + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler"); + RETURN_NULL(); + } + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); + + ALLOC_VARIANT(var_result); + + if (do_COM_invoke(obj, DISPATCH_PROPERTYPUT, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { + FREE_VARIANT(var_result); + efree(arguments); RETURN_NULL(); } - convert_to_string_ex(&arg_property); - do_COM_propput(return_value, obj, arg_property, arg_value TSRMLS_CC); + RETVAL_VARIANT(var_result); + + efree(arguments); } /* }}} */ @@ -1979,7 +2094,7 @@ arguments = (pval **) emalloc(sizeof(pval *)*arg_count); zend_get_parameters_array(ht, arg_count, arguments); - if (do_COM_invoke(obj , &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) { + if (do_COM_invoke(obj , DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) { php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); } @@ -2313,7 +2428,9 @@ REGISTER_LONG_CONSTANT("CLSCTX_REMOTE_SERVER", CLSCTX_REMOTE_SERVER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CLSCTX_SERVER", CLSCTX_SERVER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CLSCTX_ALL", CLSCTX_ALL, CONST_CS | CONST_PERSISTENT); - + REGISTER_LONG_CONSTANT("DISPATCH_METHOD", DISPATCH_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYGET", DISPATCH_PROPERTYGET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYPUT", DISPATCH_PROPERTYPUT, CONST_CS | CONST_PERSISTENT); REGISTER_INI_ENTRIES(); return SUCCESS; Index: php4/ext/com/php_COM.h diff -u php4/ext/com/php_COM.h:1.12 php4/ext/com/php_COM.h:1.13 --- php4/ext/com/php_COM.h:1.12 Tue May 21 14:58:10 2002 +++ php4/ext/com/php_COM.h Mon Aug 26 09:36:35 2002 @@ -12,6 +12,7 @@ PHP_FUNCTION(com_load); PHP_FUNCTION(com_invoke); +PHP_FUNCTION(com_invoke_ex); PHP_FUNCTION(com_addref); PHP_FUNCTION(com_release); PHP_FUNCTION(com_propget);
Index: php4/ext/com/COM.c diff -u php4/ext/com/COM.c:1.85 php4/ext/com/COM.c:1.86 --- php4/ext/com/COM.c:1.85 Mon Aug 5 19:41:25 2002 +++ php4/ext/com/COM.c Mon Aug 26 09:36:35 2002 @@ -18,7 +18,7 @@ | Wez Furlong <wez@thebrainroom.com> | +----------------------------------------------------------------------+ */ -/* $Id: COM.c,v 1.85 2002/08/05 23:41:25 phanto Exp $ */ +/* $Id: COM.c,v 1.86 2002/08/26 13:36:35 wez Exp $ */ /* * This module implements support for COM components that support the IDispatch * interface. Both local (COM) and remote (DCOM) components can be accessed. @@ -87,6 +87,7 @@ function_entry COM_functions[] = { PHP_FE(com_load, NULL) PHP_FE(com_invoke, NULL) + PHP_FE(com_invoke_ex, NULL) PHP_FE(com_addref, NULL) PHP_FE(com_release, NULL) PHP_FE(com_propget, NULL) @@ -133,6 +134,7 @@ C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); C_HASTLIB(obj) = FALSE; + C_TYPEINFO(obj) = NULL; } } } else { @@ -143,22 +145,25 @@ switch (hr) { case DISP_E_EXCEPTION: { - char *src=estrdup("Unavailable"); - int srclen=strlen(src); - char *desc=estrdup("Unavailable"); - int desclen=strlen(desc); + char *src = NULL; + int srclen = 0; + char *desc = NULL; + int desclen = 0; - if (ExceptInfo.bstrSource) - { - efree(src); + if (ExceptInfo.bstrSource) { src = php_OLECHAR_to_char(ExceptInfo.bstrSource, &srclen, codepage TSRMLS_CC); SysFreeString(ExceptInfo.bstrSource); + } else { + src = estrdup("Unavailable"); + srclen = strlen(src); } - if (ExceptInfo.bstrDescription) - { - efree(desc); + + if (ExceptInfo.bstrDescription) { desc = php_OLECHAR_to_char(ExceptInfo.bstrDescription, &desclen, codepage TSRMLS_CC); SysFreeString(ExceptInfo.bstrDescription); + } else { + desc = estrdup("Unavailable"); + desclen = strlen(desc); } *ErrString = pemalloc(srclen+desclen+50, 1); @@ -211,6 +216,7 @@ C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); C_HASTLIB(obj) = FALSE; + C_TYPEINFO(obj) = NULL; } } } else { @@ -233,12 +239,17 @@ } else if (obj->refcount == 1) { if (C_HASTLIB(obj)) { C_TYPEINFO_VT(obj)->Release(C_TYPEINFO(obj)); + C_TYPEINFO(obj) = NULL; + C_HASTLIB(obj) = FALSE; } if (C_HASENUM(obj)) { hr = C_ENUMVARIANT_VT(obj)->Release(C_ENUMVARIANT(obj)); + C_ENUMVARIANT(obj) = NULL; + C_HASENUM(obj) = FALSE; } hr = C_DISPATCH_VT(obj)->Release(C_DISPATCH(obj)); C_RELEASE(obj); + C_DISPATCH(obj) = NULL; } return obj->refcount; @@ -250,7 +261,6 @@ if (C_ISREFD(obj)) { C_ADDREF(obj); } - return obj->refcount; } @@ -723,9 +733,9 @@ /* }}} */ -int do_COM_invoke(comval *obj, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC) +static int do_COM_invoke(comval *obj, WORD dispflags, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC) { - DISPID dispid; + DISPID dispid, altdispid; DISPPARAMS dispparams; HRESULT hr; OLECHAR *funcname; @@ -876,7 +886,14 @@ dispparams.cArgs = arg_count; dispparams.cNamedArgs = 0; - hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); + if (dispflags & DISPATCH_PROPERTYPUT) { + /* Make this work for property set-ing */ + altdispid = DISPID_PROPERTYPUT; + dispparams.rgdispidNamedArgs = &altdispid; + dispparams.cNamedArgs = 1; + } + + hr = php_COM_invoke(obj, dispid, dispflags, &dispparams, var_result, &ErrString TSRMLS_CC); efree(funcname); for (current_arg=0;current_arg<arg_count;current_arg++) { @@ -903,6 +920,62 @@ return SUCCESS; } +/* {{{ proto mixed com_invoke_ex(int module, int invokeflags, string handler_name [, mixed arg [, mixed ...]]) + Invokes a COM module */ +PHP_FUNCTION(com_invoke_ex) +{ + pval **arguments; + pval *object, *function_name, *invokeflags; + comval *obj = NULL; + WORD dispflags = 0; + int arg_count = ZEND_NUM_ARGS(); + VARIANT *var_result; + + if (arg_count<3) { + ZEND_WRONG_PARAM_COUNT(); + } + arguments = (pval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } + + object = arguments[0]; + function_name = arguments[2]; + invokeflags = arguments[1]; + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); + convert_to_long(invokeflags); + dispflags = (WORD)Z_LVAL_P(invokeflags); + + /* obtain IDispatch interface */ + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error(E_WARNING, "%d is not a COM object handler", Z_LVAL_P(object)); + RETURN_NULL(); + } + + ALLOC_VARIANT(var_result); + + if (do_COM_invoke(obj, dispflags, function_name, var_result, arguments+3, arg_count-3 TSRMLS_CC)==FAILURE) { + FREE_VARIANT(var_result); + efree(arguments); + + RETURN_NULL(); + } + + RETVAL_VARIANT(var_result); + + efree(arguments); +} +/* }}} */ + /* {{{ proto mixed com_invoke(int module, string handler_name [, mixed arg [, mixed ...]]) Invokes a COM module */ @@ -930,7 +1003,7 @@ convert_to_long(object); obj = (comval *)zend_list_find(Z_LVAL_P(object), &type); if (!obj || (type != IS_COM)) { - php_error(E_WARNING,"%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_STRVAL_P(function_name)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s is not a COM object handler", Z_STRVAL_P(function_name)); RETURN_NULL(); } @@ -939,7 +1012,7 @@ ALLOC_VARIANT(var_result); - if (do_COM_invoke(obj, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { + if (do_COM_invoke(obj, DISPATCH_METHOD|DISPATCH_PROPERTYGET, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { FREE_VARIANT(var_result); efree(arguments); @@ -1475,7 +1548,7 @@ int retval; ZVAL_STRINGL(&function_name, "Item", 4, 0); - retval = do_COM_invoke(array, &function_name, result, &property, 1 TSRMLS_CC); + retval = do_COM_invoke(array, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name, result, &property, 1 TSRMLS_CC); if (cleanup) { php_COM_destruct(array TSRMLS_CC); } @@ -1629,63 +1702,105 @@ } -/* {{{ proto mixed com_propget(int module, string property_name) +/* {{{ proto mixed com_propget(int module, string property_name [, mixed arg ... ]) Gets properties from a COM module */ PHP_FUNCTION(com_propget) { - pval *arg_comval, *arg_property; - int type; - comval *obj; + zval **arguments; + zval *object, *function_name; + comval *obj = NULL; + int arg_count = ZEND_NUM_ARGS(); VARIANT *var_result; - if ((ZEND_NUM_ARGS() != 2) || (zend_get_parameters(ht, 2, &arg_comval, &arg_property) == FAILURE)) { + if (arg_count<3) { ZEND_WRONG_PARAM_COUNT(); } + arguments = (zval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } - /* obtain IDispatch interface */ - convert_to_long(arg_comval); - obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type); - if (!obj || (type != IS_COM)) { - php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_LVAL_P(arg_comval)); + object = arguments[0]; + function_name = arguments[1]; + + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler"); RETURN_NULL(); } - convert_to_string_ex(&arg_property); + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); ALLOC_VARIANT(var_result); - if (do_COM_propget(var_result, obj, arg_property, FALSE TSRMLS_CC) == FAILURE) { + if (do_COM_invoke(obj, DISPATCH_PROPERTYGET, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { FREE_VARIANT(var_result); + efree(arguments); + RETURN_NULL(); } RETVAL_VARIANT(var_result); + + efree(arguments); } /* }}} */ -/* {{{ proto bool com_propput(int module, string property_name, mixed value) +/* {{{ proto bool com_propput(int module, string property_name, mixed value, ...) Puts the properties for a module */ PHP_FUNCTION(com_propput) { - pval *arg_comval, *arg_property, *arg_value; - int type; + zval **arguments; + zval *object, *function_name; comval *obj; + int arg_count = ZEND_NUM_ARGS(); + VARIANT *var_result; - if (ZEND_NUM_ARGS()!=3 || zend_get_parameters(ht, 3, &arg_comval, &arg_property, &arg_value)==FAILURE) { + if (arg_count<3) { ZEND_WRONG_PARAM_COUNT(); } + arguments = (zval **) emalloc(sizeof(pval *)*arg_count); + if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { + RETURN_NULL(); + } - /* obtain comval interface */ - convert_to_long(arg_comval); - /* obtain comval interface */ - obj = (comval *)zend_list_find(Z_LVAL_P(arg_comval), &type); - if (!obj || (type != IS_COM)) { - php_error(E_WARNING, "%s(): %d is not a COM object handler", get_active_function_name(TSRMLS_C), Z_LVAL_P(arg_comval)); + object = arguments[0]; + function_name = arguments[1]; + + if (Z_TYPE_P(object) == IS_OBJECT && (Z_OBJCE_P(object) == &COM_class_entry || !strcmp(Z_OBJCE_P(object)->name, "COM"))) { + zval **tmp; + zend_hash_index_find(Z_OBJPROP_P(object), 0, (void**)&tmp); + ZEND_FETCH_RESOURCE(obj, comval*, tmp, -1, "comval", IS_COM); + } else if (Z_TYPE_P(object) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(obj, comval*, &object, -1, "comval", IS_COM); + } + if (obj == NULL) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 1 is not a COM object handler"); + RETURN_NULL(); + } + + /* obtain property/method handler */ + convert_to_string_ex(&function_name); + + ALLOC_VARIANT(var_result); + + if (do_COM_invoke(obj, DISPATCH_PROPERTYPUT, function_name, var_result, arguments+2, arg_count-2 TSRMLS_CC)==FAILURE) { + FREE_VARIANT(var_result); + efree(arguments); RETURN_NULL(); } - convert_to_string_ex(&arg_property); - do_COM_propput(return_value, obj, arg_property, arg_value TSRMLS_CC); + RETVAL_VARIANT(var_result); + + efree(arguments); } /* }}} */ @@ -1979,7 +2094,7 @@ arguments = (pval **) emalloc(sizeof(pval *)*arg_count); zend_get_parameters_array(ht, arg_count, arguments); - if (do_COM_invoke(obj , &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) { + if (do_COM_invoke(obj , DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) { php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); } @@ -2313,7 +2428,9 @@ REGISTER_LONG_CONSTANT("CLSCTX_REMOTE_SERVER", CLSCTX_REMOTE_SERVER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CLSCTX_SERVER", CLSCTX_SERVER, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("CLSCTX_ALL", CLSCTX_ALL, CONST_CS | CONST_PERSISTENT); - + REGISTER_LONG_CONSTANT("DISPATCH_METHOD", DISPATCH_METHOD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYGET", DISPATCH_PROPERTYGET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYPUT", DISPATCH_PROPERTYPUT, CONST_CS | CONST_PERSISTENT); REGISTER_INI_ENTRIES(); return SUCCESS; Index: php4/ext/com/php_COM.h diff -u php4/ext/com/php_COM.h:1.12 php4/ext/com/php_COM.h:1.13 --- php4/ext/com/php_COM.h:1.12 Tue May 21 14:58:10 2002 +++ php4/ext/com/php_COM.h Mon Aug 26 09:36:35 2002 @@ -12,6 +12,7 @@ PHP_FUNCTION(com_load); PHP_FUNCTION(com_invoke); +PHP_FUNCTION(com_invoke_ex); PHP_FUNCTION(com_addref); PHP_FUNCTION(com_release); PHP_FUNCTION(com_propget);