diff options
Diffstat (limited to 'ext/com_dotnet/com_wrapper.c')
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_wrapper.c | 165 |
1 files changed, 83 insertions, 82 deletions
diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 54b6fb9ae7..a55c767423 100644..100755 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -39,7 +39,7 @@ typedef struct { /* now the PHP stuff */ DWORD engine_thread; /* for sanity checking */ - zval *object; /* the object exported */ + zval object; /* the object exported */ LONG refcount; /* COM reference count */ HashTable *dispid_to_name; /* keep track of dispid -> name mappings */ @@ -47,14 +47,14 @@ typedef struct { GUID sinkid; /* iid that we "implement" for event sinking */ - int id; + zend_resource *res; } php_dispatchex; static int le_dispatch; static void disp_destructor(php_dispatchex *disp TSRMLS_DC); -static void dispatch_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void dispatch_dtor(zend_resource *rsrc TSRMLS_DC) { php_dispatchex *disp = (php_dispatchex *)rsrc->ptr; disp_destructor(disp TSRMLS_CC); @@ -90,9 +90,9 @@ static inline void trace(char *fmt, ...) php_dispatchex *disp = (php_dispatchex*)This; \ TSRMLS_FETCH(); \ if (COMG(rshutdown_started)) { \ - trace(" PHP Object:%p (name:unknown) %s\n", disp->object, methname); \ + trace(" PHP Object:%p (name:unknown) %s\n", Z_OBJ(disp->object), methname); \ } else { \ - trace(" PHP Object:%p (name:%s) %s\n", disp->object, Z_OBJCE_P(disp->object)->name, methname); \ + trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val, methname); \ } \ if (GetCurrentThreadId() != disp->engine_thread) { \ return RPC_E_WRONG_THREAD; \ @@ -134,8 +134,8 @@ static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This) trace("-- refcount now %d\n", ret); if (ret == 0) { /* destroy it */ - if (disp->id) - zend_list_delete(disp->id); + if (disp->res) + zend_list_delete(disp->res); } return ret; } @@ -177,16 +177,16 @@ static HRESULT STDMETHODCALLTYPE disp_getidsofnames( for (i = 0; i < cNames; i++) { char *name; unsigned int namelen; - zval **tmp; + zval *tmp; name = php_com_olestring_to_string(rgszNames[i], &namelen, COMG(code_page) TSRMLS_CC); /* Lookup the name in the hash */ - if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) { + if ((tmp = zend_hash_str_find(disp->name_to_dispid, name, namelen)) == NULL) { ret = DISP_E_UNKNOWNNAME; rgDispId[i] = 0; } else { - rgDispId[i] = Z_LVAL_PP(tmp); + rgDispId[i] = Z_LVAL_P(tmp); } efree(name); @@ -221,7 +221,7 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( HRESULT ret = DISP_E_UNKNOWNNAME; char *name; unsigned int namelen; - zval **tmp; + zval *tmp; FETCH_DISP("GetDispID"); name = php_com_olestring_to_string(bstrName, &namelen, COMG(code_page) TSRMLS_CC); @@ -229,9 +229,9 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( trace("Looking for %s, namelen=%d in %p\n", name, namelen, disp->name_to_dispid); /* Lookup the name in the hash */ - if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) { + if ((tmp = zend_hash_str_find(disp->name_to_dispid, name, namelen)) != NULL) { trace("found it\n"); - *pid = Z_LVAL_PP(tmp); + *pid = Z_LVAL_P(tmp); ret = S_OK; } @@ -250,34 +250,30 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( /* [out] */ EXCEPINFO *pei, /* [unique][in] */ IServiceProvider *pspCaller) { - zval **name; + zval *name; UINT i; - zval *retval = NULL; - zval ***params = NULL; + zval rv, *retval = NULL; + zval *params = NULL; HRESULT ret = DISP_E_MEMBERNOTFOUND; FETCH_DISP("InvokeEx"); - if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) { + if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { /* TODO: add support for overloaded objects */ - trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_PP(name), Z_STRLEN_PP(name), wFlags, pdp->cArgs); + trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); /* convert args into zvals. * Args are in reverse order */ if (pdp->cArgs) { - params = (zval ***)safe_emalloc(sizeof(zval **), pdp->cArgs, 0); + params = (zval *)safe_emalloc(sizeof(zval), pdp->cArgs, 0); for (i = 0; i < pdp->cArgs; i++) { VARIANT *arg; - zval *zarg; arg = &pdp->rgvarg[ pdp->cArgs - 1 - i]; trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg)); - ALLOC_INIT_ZVAL(zarg); - php_com_wrap_variant(zarg, arg, COMG(code_page) TSRMLS_CC); - params[i] = (zval**)emalloc(sizeof(zval**)); - *params[i] = zarg; + php_com_wrap_variant(¶ms[i], arg, COMG(code_page) TSRMLS_CC); } } @@ -287,19 +283,20 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( * and expose it as a COM exception */ if (wFlags & DISPATCH_PROPERTYGET) { - retval = zend_read_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, 1 TSRMLS_CC); + retval = zend_read_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, 1 TSRMLS_CC); } else if (wFlags & DISPATCH_PROPERTYPUT) { - zend_update_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, *params[0] TSRMLS_CC); + zend_update_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name), ¶ms[0] TSRMLS_CC); } else if (wFlags & DISPATCH_METHOD) { zend_try { - if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name, - &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) { + retval = &rv; + if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, name, + retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) { ret = S_OK; trace("function called ok\n"); /* Copy any modified values to callers copy of variant*/ for (i = 0; i < pdp->cArgs; i++) { - php_com_dotnet_object *obj = CDNO_FETCH(*params[i]); + php_com_dotnet_object *obj = CDNO_FETCH(¶ms[i]); VARIANT *srcvar = &obj->v; VARIANT *dstvar = &pdp->rgvarg[ pdp->cArgs - 1 - i]; if ((V_VT(dstvar) & VT_BYREF) && obj->modified ) { @@ -322,8 +319,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( /* release arguments */ if (params) { for (i = 0; i < pdp->cArgs; i++) { - zval_ptr_dtor(params[i]); - efree(params[i]); + zval_ptr_dtor(¶ms[i]); } efree(params); } @@ -334,7 +330,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( VariantInit(pvarRes); php_com_variant_from_zval(pvarRes, retval, COMG(code_page) TSRMLS_CC); } - zval_ptr_dtor(&retval); + zval_ptr_dtor(retval); } else if (pvarRes) { VariantInit(pvarRes); } @@ -388,7 +384,7 @@ static HRESULT STDMETHODCALLTYPE disp_getmembername( zval *name; FETCH_DISP("GetMemberName"); - if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) { + if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { OLECHAR *olestr = php_com_string_to_olestring(Z_STRVAL_P(name), Z_STRLEN_P(name), COMG(code_page) TSRMLS_CC); *pbstrName = SysAllocString(olestr); efree(olestr); @@ -451,9 +447,8 @@ static struct IDispatchExVtbl php_dispatch_vtbl = { static void generate_dispids(php_dispatchex *disp TSRMLS_DC) { HashPosition pos; - char *name = NULL; - zval *tmp; - int namelen; + zend_string *name = NULL; + zval *tmp, tmp2; int keytype; ulong pid; @@ -465,65 +460,71 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC) } /* properties */ - if (Z_OBJPROP_P(disp->object)) { - zend_hash_internal_pointer_reset_ex(Z_OBJPROP_P(disp->object), &pos); + if (Z_OBJPROP(disp->object)) { + zend_hash_internal_pointer_reset_ex(Z_OBJPROP(disp->object), &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(Z_OBJPROP_P(disp->object), &name, - &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(Z_OBJPROP(disp->object), &name, + &pid, 0, &pos))) { char namebuf[32]; if (keytype == HASH_KEY_IS_LONG) { snprintf(namebuf, sizeof(namebuf), "%d", pid); - name = namebuf; - namelen = strlen(namebuf)+1; + name = STR_INIT(namebuf, strlen(namebuf), 0); + } else { + STR_ADDREF(name); } - zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos); + zend_hash_move_forward_ex(Z_OBJPROP(disp->object), &pos); /* Find the existing id */ - if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS) + if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { + STR_RELEASE(name); continue; + } /* add the mappings */ - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, name, namelen-1, 1); + ZVAL_STR(&tmp2, STR_COPY(name)); pid = zend_hash_next_free_element(disp->dispid_to_name); - zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL); + zend_hash_index_update(disp->dispid_to_name, pid, &tmp2); + + ZVAL_LONG(&tmp2, pid); + zend_hash_update(disp->name_to_dispid, name, &tmp2); - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, pid); - zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL); + STR_RELEASE(name); } } /* functions */ - if (Z_OBJCE_P(disp->object)) { - zend_hash_internal_pointer_reset_ex(&Z_OBJCE_P(disp->object)->function_table, &pos); + if (Z_OBJCE(disp->object)) { + zend_hash_internal_pointer_reset_ex(&Z_OBJCE(disp->object)->function_table, &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(&Z_OBJCE_P(disp->object)->function_table, - &name, &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(&Z_OBJCE(disp->object)->function_table, + &name, &pid, 0, &pos))) { char namebuf[32]; if (keytype == HASH_KEY_IS_LONG) { snprintf(namebuf, sizeof(namebuf), "%d", pid); - name = namebuf; - namelen = strlen(namebuf) + 1; + name = STR_INIT(namebuf, strlen(namebuf), 0); + } else { + STR_ADDREF(name); } - zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos); + zend_hash_move_forward_ex(&Z_OBJCE(disp->object)->function_table, &pos); /* Find the existing id */ - if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS) + if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { + STR_RELEASE(name); continue; + } /* add the mappings */ - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, name, namelen-1, 1); + ZVAL_STR(&tmp2, STR_COPY(name)); pid = zend_hash_next_free_element(disp->dispid_to_name); - zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL); + zend_hash_index_update(disp->dispid_to_name, pid, &tmp2); + + ZVAL_LONG(&tmp2, pid); + zend_hash_update(disp->name_to_dispid, name, &tmp2); - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, pid); - zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL); + STR_RELEASE(name); } } } @@ -531,6 +532,7 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC) static php_dispatchex *disp_constructor(zval *object TSRMLS_DC) { php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex)); + zval *tmp; trace("constructing a COM wrapper for PHP object %p (%s)\n", object, Z_OBJCE_P(object)->name); @@ -544,11 +546,14 @@ static php_dispatchex *disp_constructor(zval *object TSRMLS_DC) disp->refcount = 1; - if (object) - Z_ADDREF_P(object); - disp->object = object; + if (object) { + ZVAL_COPY(&disp->object, object); + } else { + ZVAL_UNDEF(&disp->object); + } - disp->id = zend_list_insert(disp, le_dispatch TSRMLS_CC); + tmp = zend_list_insert(disp, le_dispatch TSRMLS_CC); + disp->res = Z_RES_P(tmp); return disp; } @@ -557,12 +562,12 @@ static void disp_destructor(php_dispatchex *disp TSRMLS_DC) { /* Object store not available during request shutdown */ if (COMG(rshutdown_started)) { - trace("destroying COM wrapper for PHP object %p (name:unknown)\n", disp->object); + trace("destroying COM wrapper for PHP object %p (name:unknown)\n", Z_OBJ(disp->object)); } else { - trace("destroying COM wrapper for PHP object %p (name:%s)\n", disp->object, Z_OBJCE_P(disp->object)->name); + trace("destroying COM wrapper for PHP object %p (name:%s)\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val); } - disp->id = 0; + disp->res = NULL; if (disp->refcount > 0) CoDisconnectObject((IUnknown*)disp, 0); @@ -572,8 +577,7 @@ static void disp_destructor(php_dispatchex *disp TSRMLS_DC) FREE_HASHTABLE(disp->dispid_to_name); FREE_HASHTABLE(disp->name_to_dispid); - if (disp->object) - zval_ptr_dtor(&disp->object); + zval_ptr_dtor(&disp->object); CoTaskMemFree(disp); } @@ -583,9 +587,8 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si { php_dispatchex *disp = disp_constructor(val TSRMLS_CC); HashPosition pos; - char *name = NULL; - zval *tmp, **ntmp; - int namelen; + zend_string *name = NULL; + zval tmp, *ntmp; int keytype; ulong pid; @@ -599,16 +602,14 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si zend_hash_internal_pointer_reset_ex(id_to_name, &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(id_to_name, &name, &pid, 0, &pos))) { if (keytype == HASH_KEY_IS_LONG) { - zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos); + ntmp = zend_hash_get_current_data_ex(id_to_name, &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); + ZVAL_LONG(&tmp, pid); + zend_hash_update(disp->name_to_dispid, Z_STR_P(ntmp), &tmp); } zend_hash_move_forward_ex(id_to_name, &pos); |