📄 com.c
字号:
typeinfo = locate_typeinfo(typelibname, obj, ifacename, wantsink TSRMLS_CC); if (typeinfo) { process_typeinfo(typeinfo, NULL, 1, NULL TSRMLS_CC); typeinfo->lpVtbl->Release(typeinfo); RETURN_TRUE; } else { zend_error(E_WARNING, "Unable to find typeinfo using the parameters supplied"); } RETURN_FALSE;}/* }}} *//* {{{ proto bool com_event_sink(mixed comobject, object sinkobject [, mixed sinkinterface]) Connect events from a COM object to a PHP object */PHP_FUNCTION(com_event_sink){ zval *object, *sinkobject, *sink=NULL; char *dispname = NULL, *typelibname = NULL; zend_bool gotguid = 0; comval *obj; ITypeInfo *typeinfo = NULL; RETVAL_FALSE; if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz|z/", &object, &sinkobject, &sink)) { RETURN_FALSE; } FETCH_COM_SAFE(object, obj); 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 = locate_typeinfo(typelibname, obj, dispname, 1 TSRMLS_CC); if (typeinfo) { HashTable *id_to_name; ALLOC_HASHTABLE(id_to_name); if (process_typeinfo(typeinfo, id_to_name, 0, &obj->sinkid TSRMLS_CC)) { /* Create the COM wrapper for this sink */ obj->sinkdispatch = php_COM_export_as_sink(sinkobject, &obj->sinkid, id_to_name TSRMLS_CC); /* Now hook it up to the source */ com_enable_events(obj, TRUE); RETVAL_TRUE; } else { FREE_HASHTABLE(id_to_name); } } if (typeinfo) typeinfo->lpVtbl->Release(typeinfo); }/* }}} */static int do_COM_offget(VARIANT *result, comval *array, pval *property, int cleanup TSRMLS_DC){ pval function_name; int retval; ZVAL_STRINGL(&function_name, "Item", 4, 0); retval = do_COM_invoke(array, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name, result, &property, 1 TSRMLS_CC); if (cleanup) { php_COM_destruct(array TSRMLS_CC); } return retval;}static int do_COM_propget(VARIANT *var_result, comval *obj, pval *arg_property, int cleanup TSRMLS_DC){ DISPID dispid; HRESULT hr; OLECHAR *propname; char *error_message; DISPPARAMS dispparams; char *ErrString; /* obtain property handler */ propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage TSRMLS_CC); hr = php_COM_get_ids_of_names(obj, &propname, &dispid TSRMLS_CC); if (FAILED(hr)) { error_message = php_COM_error_message(hr TSRMLS_CC); php_error(E_WARNING, "%s(): Unable to lookup %s: %s", get_active_function_name(TSRMLS_C), Z_STRVAL_P(arg_property), error_message); LocalFree(error_message); efree(propname); if (cleanup) { php_COM_destruct(obj TSRMLS_CC); } return FAILURE; } dispparams.cArgs = 0; dispparams.cNamedArgs = 0; hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); if (FAILED(hr)) { error_message = php_COM_error_message(hr TSRMLS_CC); if (ErrString) { php_error(E_WARNING, "%s(): PropGet() failed: %s %s", get_active_function_name(TSRMLS_C), error_message, ErrString); pefree(ErrString, 1); } else { php_error(E_WARNING, "%s(): PropGet() failed: %s", get_active_function_name(TSRMLS_C), error_message); } LocalFree(error_message); efree(propname); if (cleanup) { php_COM_destruct(obj TSRMLS_CC); } return FAILURE; } efree(propname); if (cleanup) { php_COM_destruct(obj TSRMLS_CC); } return SUCCESS;}static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, pval *value TSRMLS_DC){ DISPID dispid; HRESULT hr; OLECHAR *propname; char *error_message; VARIANT *var_result, *new_value; DISPPARAMS dispparams; DISPID mydispid = DISPID_PROPERTYPUT; char *ErrString; ALLOC_VARIANT(var_result); ALLOC_VARIANT(new_value); /* obtain property handler */ propname = php_char_to_OLECHAR(Z_STRVAL_P(arg_property), Z_STRLEN_P(arg_property), codepage TSRMLS_CC); hr = php_COM_get_ids_of_names(obj, &propname, &dispid TSRMLS_CC); if (FAILED(hr)) { error_message = php_COM_error_message(hr TSRMLS_CC); php_error(E_WARNING, "%s(): Unable to lookup %s: %s", get_active_function_name(TSRMLS_C), Z_STRVAL_P(arg_property), error_message); LocalFree(error_message); efree(propname); FREE_VARIANT(var_result); FREE_VARIANT(new_value); if (return_value) { RETVAL_NULL(); } return; } php_pval_to_variant(value, new_value, codepage TSRMLS_CC); dispparams.rgvarg = new_value; dispparams.rgdispidNamedArgs = &mydispid; dispparams.cArgs = 1; dispparams.cNamedArgs = 1; hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString TSRMLS_CC); if (FAILED(hr)) { error_message = php_COM_error_message(hr TSRMLS_CC); if (ErrString) { php_error(E_WARNING, "%s(): PropPut() failed: %s %s", get_active_function_name(TSRMLS_C), error_message, ErrString); pefree(ErrString, 1); } else { php_error(E_WARNING, "%s(): PropPut() failed: %s", get_active_function_name(TSRMLS_C), error_message); } LocalFree(error_message); FREE_VARIANT(var_result); /* free the string we allocated; invoked object made its own copy */ if (V_VT(new_value) == VT_BSTR) { VariantClear(new_value); } efree(new_value); efree(propname); if (return_value) { RETVAL_NULL(); } return; } if (return_value) { dispparams.cArgs = 0; dispparams.cNamedArgs = 0; hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); if (SUCCEEDED(hr)) { RETVAL_VARIANT(var_result); } else { FREE_VARIANT(var_result); *return_value = *value; zval_copy_ctor(return_value); } if (ErrString) { pefree(ErrString, 1); } } else { FREE_VARIANT(var_result); } /* free the string we allocated; invoked object made its own copy */ if (V_VT(new_value) == VT_BSTR) { VariantClear(new_value); } efree(new_value); efree(propname);}/* {{{ proto mixed com_propget(int module, string property_name [, mixed arg ... ]) Gets properties from a COM module */PHP_FUNCTION(com_propget){ zval **arguments; zval *object, *function_name; comval *obj = NULL; int arg_count = ZEND_NUM_ARGS(); VARIANT *var_result; if (arg_count < 2) { ZEND_WRONG_PARAM_COUNT(); } arguments = (zval **) emalloc(sizeof(pval *)*arg_count); if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) { RETURN_NULL(); } object = arguments[0]; function_name = arguments[1]; FETCH_COM_SAFE(object, obj); /* obtain property/method handler */ convert_to_string_ex(&function_name); ALLOC_VARIANT(var_result); 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, ...) Puts the properties for a module */PHP_FUNCTION(com_propput){ zval **arguments; zval *object, *function_name; comval *obj; int arg_count = ZEND_NUM_ARGS(); VARIANT *var_result; 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(); } object = arguments[0]; function_name = arguments[1]; FETCH_COM_SAFE(object, obj); /* 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(); } RETVAL_VARIANT(var_result); efree(arguments);}/* }}} *//* {{{ proto bool com_load_typelib(string typelib_name [, int case_insensitive]) Loads a Typelib */PHP_FUNCTION(com_load_typelib){ pval *arg_typelib, *arg_cis; ITypeLib *pTL; int mode = CONST_CS; switch (ZEND_NUM_ARGS()) { case 1: zend_get_parameters(ht, 1, &arg_typelib); break; case 2: zend_get_parameters(ht, 2, &arg_typelib, &arg_cis); convert_to_boolean_ex(&arg_cis); if (Z_LVAL_P(arg_cis)) { mode &= ~CONST_CS; } break; default: ZEND_WRONG_PARAM_COUNT(); } convert_to_string_ex(&arg_typelib); pTL = php_COM_find_typelib(Z_STRVAL_P(arg_typelib), mode TSRMLS_CC); if (php_COM_load_typelib(pTL, mode TSRMLS_CC) == SUCCESS) { pTL->lpVtbl->Release(pTL); RETURN_TRUE; } else { RETURN_FALSE; }}/* }}} */PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_reference){ zend_overloaded_element *overloaded_property; zend_llist_element *element; pval retval; pval **comval_handle; pval *object = property_reference->object; int type; comval *obj, *obj_prop; VARIANT *var_result; TSRMLS_FETCH(); INIT_ZVAL(retval); ZVAL_NULL(&retval); /* fetch the IDispatch interface */ zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &comval_handle); obj = (comval *) zend_list_find(Z_LVAL_P(*comval_handle), &type); if (!obj || (type != IS_COM)) { return retval; } ALLOC_COM(obj_prop); ALLOC_VARIANT(var_result); for (element=property_reference->elements_list->head; element; element=element->next) { overloaded_property = (zend_overloaded_element *) element->data; switch (Z_TYPE_P(overloaded_property)) { case OE_IS_ARRAY: if (do_COM_offget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE) { FREE_VARIANT(var_result); FREE_COM(obj_prop); return retval; } break; case OE_IS_OBJECT: if (do_COM_propget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE) { FREE_VARIANT(var_result); FREE_COM(obj_prop); return retval; } break; case OE_IS_METHOD: FREE_VARIANT(var_result); if (obj != obj_prop) { efree(obj_prop); retval = *object; zval_copy_ctor(&retval); } else { ZVAL_COM(&retval, obj); } return retval; } zval_dtor(&overloaded_property->element); if (V_VT(var_result) == VT_DISPATCH) { if (V_DISPATCH(var_result) == NULL) { FREE_VARIANT(var_result); FREE_COM(obj_prop); return retval; } obj = obj_prop; php_COM_set(obj, &V_DISPATCH(var_result), TRUE TSRMLS_CC); VariantInit(var_result); /* to protect C_DISPATCH(obj) from being freed when var_result is destructed */ } else { php_variant_to_pval(var_result, &retval, codepage TSRMLS_CC); FREE_COM(obj_prop); obj_prop = NULL; } } if (obj_prop != NULL) { ZVAL_COM(&retval, obj); } FREE_VARIANT(var_result); return retval;}PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value){ zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **comval_handle; pval *object = property_reference->object; comval *obj, *obj_prop; int type; VARIANT *var_result; TSRMLS_FETCH(); /* fetch the IDispatch interface */ zend_hash_index_find(Z_OBJPROP_P(object), 0, (void **) &comval_handle); obj = (comval *)zend_list_find(Z_LVAL_P(*comval_handle), &type); if (!obj || (type != IS_COM)) { return FAILURE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -