From d3ca5abab7ec5b434ae0ab97cb359691149ff20e Mon Sep 17 00:00:00 2001 From: Harald Radi Date: Thu, 30 May 2002 23:07:23 +0000 Subject: [PATCH] @ Added missing AddRef() calls in the COM extension. This should @ fix weird behaviour (in particular with ADODB). (Harald) # waah, this suxx --- ext/com/COM.c | 32 ++++++++++++++++++-------------- ext/com/VARIANT.c | 1 + ext/com/conversion.c | 3 ++- ext/com/dispatch.c | 1 + ext/rpc/com/com_wrapper.c | 32 ++++++++++++++++++-------------- ext/rpc/com/conversion.c | 3 ++- ext/rpc/com/dispatch.c | 1 + ext/rpc/com/variant.c | 1 + 8 files changed, 44 insertions(+), 30 deletions(-) diff --git a/ext/com/COM.c b/ext/com/COM.c index 288a03ac32..4354e9bcc2 100644 --- a/ext/com/COM.c +++ b/ext/com/COM.c @@ -281,9 +281,11 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) { if (V_VT(var_result) == VT_UNKNOWN) { + V_UNKNOWN(var_result)->lpVtbl->AddRef(V_UNKNOWN(var_result)); C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT, (void**)&C_ENUMVARIANT(obj))); } else if (V_VT(var_result) == VT_DISPATCH) { + V_DISPATCH(var_result)->lpVtbl->AddRef(V_DISPATCH(var_result)); C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT, (void**)&C_ENUMVARIANT(obj))); } @@ -1584,10 +1586,11 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, php_error(E_WARNING,"PropPut() failed: %s", error_message); } LocalFree(error_message); - efree(propname); FREE_VARIANT(var_result); - FREE_VARIANT(new_value); + + efree(new_value); + efree(propname); RETURN_NULL(); } @@ -1597,20 +1600,22 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); - if (SUCCEEDED(hr)) { - php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); - } else { - *return_value = *value; - zval_copy_ctor(return_value); - } + if (return_value) { + if (SUCCEEDED(hr)) { + php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); + } else { + *return_value = *value; + zval_copy_ctor(return_value); + } - if (ErrString) { - pefree(ErrString, 1); + if (ErrString) { + pefree(ErrString, 1); + } } FREE_VARIANT(var_result); - FREE_VARIANT(new_value); + efree(new_value); // FREE_VARIANT does a VariantClear() which is not desired here ! efree(propname); } @@ -1784,6 +1789,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer 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, &return_value, codepage TSRMLS_CC); @@ -1791,7 +1797,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer obj_prop = NULL; } - VariantInit(var_result); // to protect C_DISPATCH(obj) from being freed when var_result is destructed pval_destructor(&overloaded_property->element); } @@ -1808,7 +1813,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value) { - pval result; zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **comval_handle; @@ -1878,7 +1882,7 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere FREE_VARIANT(var_result); overloaded_property = (zend_overloaded_element *) element->data; - do_COM_propput(&result, obj, &overloaded_property->element, value TSRMLS_CC); + do_COM_propput(NULL, obj, &overloaded_property->element, value TSRMLS_CC); FREE_COM(obj_prop); pval_destructor(&overloaded_property->element); diff --git a/ext/com/VARIANT.c b/ext/com/VARIANT.c index 2303481cee..e06dd23e9e 100644 --- a/ext/com/VARIANT.c +++ b/ext/com/VARIANT.c @@ -181,6 +181,7 @@ static pval php_VARIANT_get_property_handler(zend_property_reference *property_r case OE_IS_OBJECT: if (!strcmp(Z_STRVAL(overloaded_property->element), "value")) { + // var_arg can't be an idispatch, so we don't care for the implicit AddRef() call here php_variant_to_pval(var_arg, &result, codepage TSRMLS_CC); } else if (!strcmp(Z_STRVAL(overloaded_property->element), "type")) { ZVAL_LONG(&result, V_VT(var_arg)) diff --git a/ext/com/conversion.c b/ext/com/conversion.c index c9e4f89414..189a578f53 100644 --- a/ext/com/conversion.c +++ b/ext/com/conversion.c @@ -720,9 +720,10 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int codepage TS ZVAL_NULL(pval_arg); } else { ALLOC_COM(obj); - php_COM_set(obj, &V_DISPATCH(var_arg), TRUE TSRMLS_CC); + php_COM_set(obj, &V_DISPATCH(var_arg), FALSE TSRMLS_CC); ZVAL_COM(pval_arg, obj); + VariantInit(var_arg); // to protect C_DISPATCH(obj) from being freed when var_result is destructed } } break; diff --git a/ext/com/dispatch.c b/ext/com/dispatch.c index 8d775a8662..23c3b0dd91 100644 --- a/ext/com/dispatch.c +++ b/ext/com/dispatch.c @@ -280,6 +280,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( ZVAL_NULL(zarg); } } else { + // arg can't be an idispatch, so we don't care for the implicit AddRef() call here if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) { trace("failed to convert arg %d to zval\n", i); ZVAL_NULL(zarg); diff --git a/ext/rpc/com/com_wrapper.c b/ext/rpc/com/com_wrapper.c index 288a03ac32..4354e9bcc2 100644 --- a/ext/rpc/com/com_wrapper.c +++ b/ext/rpc/com/com_wrapper.c @@ -281,9 +281,11 @@ PHPAPI HRESULT php_COM_set(comval *obj, IDispatch FAR* FAR* ppDisp, int cleanup if (C_HASENUM(obj) = SUCCEEDED(C_DISPATCH_VT(obj)->Invoke(C_DISPATCH(obj), DISPID_NEWENUM, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, NULL))) { if (V_VT(var_result) == VT_UNKNOWN) { + V_UNKNOWN(var_result)->lpVtbl->AddRef(V_UNKNOWN(var_result)); C_HASENUM(obj) = SUCCEEDED(V_UNKNOWN(var_result)->lpVtbl->QueryInterface(V_UNKNOWN(var_result), &IID_IEnumVARIANT, (void**)&C_ENUMVARIANT(obj))); } else if (V_VT(var_result) == VT_DISPATCH) { + V_DISPATCH(var_result)->lpVtbl->AddRef(V_DISPATCH(var_result)); C_HASENUM(obj) = SUCCEEDED(V_DISPATCH(var_result)->lpVtbl->QueryInterface(V_DISPATCH(var_result), &IID_IEnumVARIANT, (void**)&C_ENUMVARIANT(obj))); } @@ -1584,10 +1586,11 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, php_error(E_WARNING,"PropPut() failed: %s", error_message); } LocalFree(error_message); - efree(propname); FREE_VARIANT(var_result); - FREE_VARIANT(new_value); + + efree(new_value); + efree(propname); RETURN_NULL(); } @@ -1597,20 +1600,22 @@ static void do_COM_propput(pval *return_value, comval *obj, pval *arg_property, hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, var_result, &ErrString TSRMLS_CC); - if (SUCCEEDED(hr)) { - php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); - } else { - *return_value = *value; - zval_copy_ctor(return_value); - } + if (return_value) { + if (SUCCEEDED(hr)) { + php_variant_to_pval(var_result, return_value, codepage TSRMLS_CC); + } else { + *return_value = *value; + zval_copy_ctor(return_value); + } - if (ErrString) { - pefree(ErrString, 1); + if (ErrString) { + pefree(ErrString, 1); + } } FREE_VARIANT(var_result); - FREE_VARIANT(new_value); + efree(new_value); // FREE_VARIANT does a VariantClear() which is not desired here ! efree(propname); } @@ -1784,6 +1789,7 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer 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, &return_value, codepage TSRMLS_CC); @@ -1791,7 +1797,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer obj_prop = NULL; } - VariantInit(var_result); // to protect C_DISPATCH(obj) from being freed when var_result is destructed pval_destructor(&overloaded_property->element); } @@ -1808,7 +1813,6 @@ PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_refer PHPAPI int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value) { - pval result; zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **comval_handle; @@ -1878,7 +1882,7 @@ PHPAPI int php_COM_set_property_handler(zend_property_reference *property_refere FREE_VARIANT(var_result); overloaded_property = (zend_overloaded_element *) element->data; - do_COM_propput(&result, obj, &overloaded_property->element, value TSRMLS_CC); + do_COM_propput(NULL, obj, &overloaded_property->element, value TSRMLS_CC); FREE_COM(obj_prop); pval_destructor(&overloaded_property->element); diff --git a/ext/rpc/com/conversion.c b/ext/rpc/com/conversion.c index c9e4f89414..189a578f53 100644 --- a/ext/rpc/com/conversion.c +++ b/ext/rpc/com/conversion.c @@ -720,9 +720,10 @@ PHPAPI int php_variant_to_pval(VARIANT *var_arg, pval *pval_arg, int codepage TS ZVAL_NULL(pval_arg); } else { ALLOC_COM(obj); - php_COM_set(obj, &V_DISPATCH(var_arg), TRUE TSRMLS_CC); + php_COM_set(obj, &V_DISPATCH(var_arg), FALSE TSRMLS_CC); ZVAL_COM(pval_arg, obj); + VariantInit(var_arg); // to protect C_DISPATCH(obj) from being freed when var_result is destructed } } break; diff --git a/ext/rpc/com/dispatch.c b/ext/rpc/com/dispatch.c index 8d775a8662..23c3b0dd91 100644 --- a/ext/rpc/com/dispatch.c +++ b/ext/rpc/com/dispatch.c @@ -280,6 +280,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( ZVAL_NULL(zarg); } } else { + // arg can't be an idispatch, so we don't care for the implicit AddRef() call here if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) { trace("failed to convert arg %d to zval\n", i); ZVAL_NULL(zarg); diff --git a/ext/rpc/com/variant.c b/ext/rpc/com/variant.c index 2303481cee..e06dd23e9e 100644 --- a/ext/rpc/com/variant.c +++ b/ext/rpc/com/variant.c @@ -181,6 +181,7 @@ static pval php_VARIANT_get_property_handler(zend_property_reference *property_r case OE_IS_OBJECT: if (!strcmp(Z_STRVAL(overloaded_property->element), "value")) { + // var_arg can't be an idispatch, so we don't care for the implicit AddRef() call here php_variant_to_pval(var_arg, &result, codepage TSRMLS_CC); } else if (!strcmp(Z_STRVAL(overloaded_property->element), "type")) { ZVAL_LONG(&result, V_VT(var_arg)) -- 2.40.0