phanto Sun Apr 22 04:57:18 2001 EDT Added files: (Branch: PHP_4_0_5) /php4/ext/com com.h Modified files: /php4/ext/com COM.c php_COM.h typedef_VARIANT.c Log: merging changes from main branch to fix a memory leak #sorry for being late, but i was on holiday
Index: php4/ext/com/COM.c diff -u php4/ext/com/COM.c:1.6 php4/ext/com/COM.c:1.6.2.1 --- php4/ext/com/COM.c:1.6 Sun Feb 25 22:06:49 2001 +++ php4/ext/com/COM.c Sun Apr 22 04:57:18 2001 @@ -50,27 +50,17 @@ #define _WIN32_DCOM -#ifdef CP_THREAD_ACP -#define PHP_COM_CODEPAGE CP_THREAD_ACP -#else -#define PHP_COM_CODEPAGE CP_ACP -#endif - #include <iostream.h> #include <math.h> #include "php.h" #include "php_ini.h" +#include "com.h" #include "conversion.h" -#include "unknwn.h" - -BEGIN_EXTERN_C() zend_class_entry com_class_entry; -END_EXTERN_C() - PHP_FUNCTION(COM_load); PHP_FUNCTION(COM_invoke); PHP_FUNCTION(com_propget); @@ -101,27 +91,94 @@ static int php_COM_load_typelib(char *typelib_name, int mode); +PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, +DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult) +{ + if(obj->typelib) { + return obj->i.dispatch->lpVtbl->Invoke(obj->i.dispatch, dispIdMember, +&IID_NULL, LOCALE_SYSTEM_DEFAULT, + + wFlags, pDispParams, pVarResult, NULL, NULL); + } else { + return obj->i.typeinfo->lpVtbl->Invoke(obj->i.typeinfo, +obj->i.dispatch, dispIdMember, + + wFlags, pDispParams, pVarResult, NULL, NULL); + } +} + +PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszNames, +DISPID FAR* rgDispId) +{ + if(obj->typelib) { + return obj->i.dispatch->lpVtbl->GetIDsOfNames(obj->i.dispatch, +&IID_NULL, rgszNames, 1, LOCALE_SYSTEM_DEFAULT, rgDispId); + } else { + return obj->i.typeinfo->lpVtbl->GetIDsOfNames(obj->i.typeinfo, +rgszNames, 1, rgDispId); + } +} + +PHPAPI HRESULT php_COM_release(i_dispatch *obj) +{ + HRESULT hr; + + hr = obj->i.dispatch->lpVtbl->Release(obj->i.dispatch); + obj->i.dispatch = NULL; + obj->i.typeinfo = NULL; + obj->typelib = FALSE; + + return hr; +} + +PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup) +{ + HRESULT hr; + + obj->i.dispatch = pDisp; + obj->typelib = !FAILED(obj->i.dispatch->lpVtbl->GetTypeInfo(obj->i.dispatch, +0, LANG_NEUTRAL, &obj->i.typeinfo)); + + if(cleanup) { + pDisp = NULL; + } else { + hr = obj->i.dispatch->lpVtbl->AddRef(obj->i.dispatch); + } + + return hr; +} + +PHPAPI HRESULT php_COM_clone(i_dispatch *obj, i_dispatch *clone, int cleanup) +{ + HRESULT hr; + + obj->typelib = clone->typelib; + obj->i.dispatch = clone->i.dispatch; + obj->i.typeinfo = clone->i.typeinfo; + + if(cleanup) { + obj->i.dispatch = NULL; + obj->i.typeinfo = NULL; + obj->typelib = FALSE; + } else { + hr = obj->i.dispatch->lpVtbl->AddRef(obj->i.dispatch); + } + + return hr; +} + PHPAPI char *php_COM_error_message(HRESULT hr) { - char *pMsgBuf; + void *pMsgBuf; if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &pMsgBuf, 0, NULL)) { char error_string[] = "No description available"; - pMsgBuf = (char *) LocalAlloc(LMEM_FIXED, sizeof(error_string)); + pMsgBuf = LocalAlloc(LMEM_FIXED, sizeof(error_string)); memcpy(pMsgBuf, error_string, sizeof(error_string)); } return pMsgBuf; } -static char *php_string_from_clsid(const CLSID clsid) +static char *php_string_from_clsid(const CLSID *clsid) { LPOLESTR ole_clsid; char *clsid_str; - StringFromCLSID(&clsid, &ole_clsid); + StringFromCLSID(clsid, &ole_clsid); clsid_str = php_OLECHAR_to_char(ole_clsid, NULL, 0, codepage); LocalFree(ole_clsid); @@ -130,9 +187,9 @@ static void php_idispatch_destructor(zend_rsrc_list_entry *rsrc) { - IDispatch *i_dispatch = (IDispatch *)rsrc->ptr; - - i_dispatch->lpVtbl->Release(i_dispatch); + i_dispatch *obj = (i_dispatch *)rsrc->ptr; + php_COM_release(obj); + efree(obj); } static PHP_INI_MH(OnTypelibFileChange) @@ -199,12 +256,12 @@ PHP_INI_BEGIN() - PHP_INI_ENTRY1_EX("allow_dcom", "0", PHP_INI_SYSTEM, NULL, NULL, php_ini_boolean_displayer_cb) - PHP_INI_ENTRY1("typelib_file", NULL, PHP_INI_SYSTEM, OnTypelibFileChange, NULL) + PHP_INI_ENTRY_EX("com.allow_dcom", "0", PHP_INI_SYSTEM, NULL, +php_ini_boolean_displayer_cb) + PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypelibFileChange) PHP_INI_END() -/* {{{ proto int com_load(string module_name) +/* {{{ proto int com_load(string module_name [, string remote_host [, int codepage]]) Loads a COM module */ PHP_FUNCTION(COM_load) { @@ -212,7 +269,7 @@ CLSID clsid; HRESULT hr; OLECHAR *ProgID; - IDispatch *i_dispatch; + i_dispatch *obj; char *error_message; char *clsid_str; @@ -222,7 +279,7 @@ codepage = CP_ACP; break; case 2: - if (!INI_INT("allow_dcom")) { + if (!INI_INT("com.allow_dcom")) { php_error(E_WARNING, "DCOM is disabled"); RETURN_FALSE; } @@ -237,7 +294,7 @@ efree(server_name); server_name = NULL; } else { - if (!INI_INT("allow_dcom")) { + if (!INI_INT("com.allow_dcom")) { php_error(E_WARNING, "DCOM is disabled"); RETURN_FALSE; } @@ -254,7 +311,7 @@ convert_to_string(module_name); ProgID = php_char_to_OLECHAR(module_name->value.str.val, module_name->value.str.len, codepage); - hr = CLSIDFromProgID(ProgID, &clsid); + hr=CLSIDFromProgID(ProgID, &clsid); efree(ProgID); /* obtain CLSID */ @@ -265,9 +322,12 @@ RETURN_FALSE; } + obj = (i_dispatch *) emalloc(sizeof(i_dispatch)); + /* obtain IDispatch */ if (!server_name) { - hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &i_dispatch); + hr = CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, +(LPVOID *) &(obj->i.dispatch)); + php_COM_set(obj, obj->i.dispatch, TRUE); } else { COSERVERINFO server_info; MULTI_QI pResults; @@ -283,27 +343,28 @@ hr=CoCreateInstanceEx(&clsid, NULL, CLSCTX_SERVER, &server_info, 1, &pResults); if (SUCCEEDED(hr)) { hr = pResults.hr; - i_dispatch = (IDispatch *) pResults.pItf; + obj->i.dispatch = (IDispatch *) pResults.pItf; + php_COM_set(obj, obj->i.dispatch, TRUE); } efree(server_info.pwszName); } if (FAILED(hr)) { error_message = php_COM_error_message(hr); - clsid_str = php_string_from_clsid(clsid); + clsid_str = php_string_from_clsid(&clsid); php_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s",clsid_str,error_message); LocalFree(error_message); efree(clsid_str); + efree(obj); RETURN_FALSE; } - - RETURN_LONG(zend_list_insert(i_dispatch,le_idispatch)); + RETURN_LONG(zend_list_insert(obj, le_idispatch)); } /* }}} */ -int do_COM_invoke(IDispatch *i_dispatch, pval *function_name, VARIANTARG *var_result, pval **arguments, int arg_count) +int do_COM_invoke(i_dispatch *obj, pval *function_name, VARIANTARG *var_result, pval +**arguments, int arg_count) { DISPID dispid; HRESULT hr; @@ -315,7 +376,7 @@ funcname = php_char_to_OLECHAR(function_name->value.str.val, function_name->value.str.len, codepage); - hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &funcname, 1, LOCALE_SYSTEM_DEFAULT, &dispid); + hr = php_COM_get_ids_of_names(obj, &funcname, &dispid); if (FAILED(hr)) { error_message = php_COM_error_message(hr); @@ -337,9 +398,7 @@ dispparams.cArgs = arg_count; dispparams.cNamedArgs = 0; - hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL, - LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD|DISPATCH_PROPERTYGET, - &dispparams, var_result, NULL, NULL); + hr = php_COM_invoke(obj, dispid, DISPATCH_METHOD|DISPATCH_PROPERTYGET, +&dispparams, var_result); if (FAILED(hr)) { error_message = php_COM_error_message(hr); @@ -362,7 +421,7 @@ { pval **arguments; pval *object, *function_name; - IDispatch *i_dispatch; + i_dispatch *obj; int type; int arg_count = ZEND_NUM_ARGS(); VARIANTARG var_result; @@ -378,10 +437,10 @@ object = arguments[0]; function_name = arguments[1]; - /* obtain i_dispatch interface */ + /* obtain IDispatch interface */ convert_to_long(object); - i_dispatch = (IDispatch *)zend_list_find(object->value.lval, &type); - if (!i_dispatch || (type!=le_idispatch)) { + obj = (i_dispatch *)zend_list_find(object->value.lval, &type); + if (!obj || (type!=le_idispatch)) { php_error(E_WARNING,"%d is not a COM object handler", function_name->value.str.val); RETURN_FALSE; } @@ -389,7 +448,7 @@ /* obtain property/method handler */ convert_to_string(function_name); - if (do_COM_invoke(i_dispatch, function_name, &var_result, arguments+2, arg_count-2)==FAILURE) { + if (do_COM_invoke(obj, function_name, &var_result, arguments+2, +arg_count-2)==FAILURE) { RETURN_FALSE; } efree(arguments); @@ -403,16 +462,21 @@ switch (array->vt) { case VT_DISPATCH: { /* a Collection, possibly */ pval function_name; - IDispatch *i_dispatch = array->pdispVal; + i_dispatch *obj; int retval; + obj = (i_dispatch *) emalloc(sizeof(i_dispatch)); + php_COM_set(obj, array->pdispVal, TRUE); + function_name.value.str.val = "Item"; function_name.value.str.len = 4; function_name.type = IS_STRING; - retval = do_COM_invoke(i_dispatch, &function_name, var_result, &arg_property, 1); + retval = do_COM_invoke(obj, &function_name, var_result, +&arg_property, 1); if (cleanup) { - i_dispatch->lpVtbl->Release(i_dispatch); + php_COM_release(obj); } + efree(obj); + return retval; } } @@ -420,7 +484,7 @@ } -static int do_COM_propget(VARIANTARG *var_result, IDispatch *i_dispatch, pval *arg_property, int cleanup) +static int do_COM_propget(VARIANTARG *var_result, i_dispatch *obj, pval +*arg_property, int cleanup) { DISPID dispid; HRESULT hr; @@ -432,7 +496,7 @@ /* obtain property handler */ propname = php_char_to_OLECHAR(arg_property->value.str.val, arg_property->value.str.len, codepage); - hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &propname, 1, LOCALE_SYSTEM_DEFAULT, &dispid); + hr = php_COM_get_ids_of_names(obj, &propname, &dispid); if (FAILED(hr)) { error_message = php_COM_error_message(hr); @@ -440,7 +504,7 @@ LocalFree(error_message); efree(propname); if (cleanup) { - i_dispatch->lpVtbl->Release(i_dispatch); + php_COM_release(obj); } return FAILURE; } @@ -448,7 +512,7 @@ dispparams.cArgs = 0; dispparams.cNamedArgs = 0; - hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, var_result, NULL, 0); + hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, +var_result); if (FAILED(hr)) { error_message = php_COM_error_message(hr); @@ -456,35 +520,37 @@ LocalFree(error_message); efree(propname); if (cleanup) { - i_dispatch->lpVtbl->Release(i_dispatch); + php_COM_release(obj); } return FAILURE; } efree(propname); if (cleanup) { - i_dispatch->lpVtbl->Release(i_dispatch); + php_COM_release(obj); } return SUCCESS; } -static void do_COM_propput(pval *return_value, IDispatch *i_dispatch, pval *arg_property, pval *value) +static void do_COM_propput(pval *return_value, i_dispatch *obj, pval *arg_property, +pval *value) { DISPID dispid; HRESULT hr; OLECHAR *propname; char *error_message; - VARIANTARG var_result; + VARIANT *var_result; DISPPARAMS dispparams; VARIANTARG new_value; DISPID mydispid = DISPID_PROPERTYPUT; + var_result = emalloc(sizeof(VARIANT)); + /* obtain property handler */ propname = php_char_to_OLECHAR(arg_property->value.str.val, arg_property->value.str.len, codepage); - hr = i_dispatch->lpVtbl->GetIDsOfNames(i_dispatch, &IID_NULL, &propname, 1, LOCALE_SYSTEM_DEFAULT, &dispid); + hr = php_COM_get_ids_of_names(obj, &propname, &dispid); if (FAILED(hr)) { error_message = php_COM_error_message(hr); @@ -494,16 +560,14 @@ RETURN_FALSE; } - php_pval_to_variant(value, &new_value, codepage); dispparams.rgvarg = &new_value; dispparams.rgdispidNamedArgs = &mydispid; dispparams.cArgs = 1; dispparams.cNamedArgs = 1; - hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL, - LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, - &dispparams, NULL, NULL, 0); + hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYPUT, &dispparams, NULL); + if (FAILED(hr)) { error_message = php_COM_error_message(hr); php_error(E_WARNING,"PropPut() failed: %s\n", error_message); @@ -514,19 +578,17 @@ dispparams.cArgs = 0; dispparams.cNamedArgs = 0; - - hr = i_dispatch->lpVtbl->Invoke(i_dispatch, dispid, &IID_NULL, - LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, - &dispparams, &var_result, NULL, 0); + hr = php_COM_invoke(obj, dispid, DISPATCH_PROPERTYGET, &dispparams, +var_result); if (SUCCEEDED(hr)) { - php_variant_to_pval(&var_result, return_value, 0, codepage); + php_variant_to_pval(var_result, return_value, 0, codepage); } else { *return_value = *value; zval_copy_ctor(return_value); } + efree(var_result); efree(propname); } @@ -537,23 +599,22 @@ { pval *arg_idispatch, *arg_property; int type; - IDispatch *i_dispatch; + i_dispatch *obj; VARIANTARG var_result; if (ZEND_NUM_ARGS()!=2 || getParameters(ht, 2, &arg_idispatch, &arg_property)==FAILURE) { WRONG_PARAM_COUNT; } - /* obtain i_dispatch interface */ + /* obtain IDispatch interface */ convert_to_long(arg_idispatch); - /* obtain i_dispatch interface */ - i_dispatch = (IDispatch *)zend_list_find(arg_idispatch->value.lval,&type); - if (!i_dispatch || (type!=le_idispatch)) { + obj = (i_dispatch *)zend_list_find(arg_idispatch->value.lval,&type); + if (!obj || (type!=le_idispatch)) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } convert_to_string(arg_property); - if (do_COM_propget(&var_result, i_dispatch, arg_property, 0)==FAILURE) { + if (do_COM_propget(&var_result, obj, arg_property, 0)==FAILURE) { RETURN_FALSE; } php_variant_to_pval(&var_result, return_value, 0, codepage); @@ -567,7 +628,7 @@ { pval *arg_idispatch, *arg_property, *arg_value; int type; - IDispatch *i_dispatch; + i_dispatch *obj; if (ZEND_NUM_ARGS()!=3 || getParameters(ht, 3, &arg_idispatch, &arg_property, &arg_value)==FAILURE) { WRONG_PARAM_COUNT; @@ -576,62 +637,72 @@ /* obtain i_dispatch interface */ convert_to_long(arg_idispatch); /* obtain i_dispatch interface */ - i_dispatch = (IDispatch *)zend_list_find(arg_idispatch->value.lval,&type); - if (!i_dispatch || (type!=le_idispatch)) { + obj = (i_dispatch *)zend_list_find(arg_idispatch->value.lval,&type); + if (!obj || (type!=le_idispatch)) { php_error(E_WARNING,"%d is not a COM object handler", arg_idispatch->value.lval); } convert_to_string(arg_property); - do_COM_propput(return_value, i_dispatch, arg_property, arg_value); + do_COM_propput(return_value, obj, arg_property, arg_value); } /* }}} */ -VARIANTARG _php_COM_get_property_handler(zend_property_reference *property_reference) +VARIANT *_php_COM_get_property_handler(zend_property_reference *property_reference) { zend_overloaded_element *overloaded_property; zend_llist_element *element; pval **idispatch_handle; pval *object = property_reference->object; - IDispatch *i_dispatch; int type; - VARIANTARG var_result; + VARIANT *var_result; + i_dispatch *obj, *obj_prop; /* fetch the IDispatch interface */ zend_hash_index_find(object->value.obj.properties, 0, (void **) &idispatch_handle); - i_dispatch = (IDispatch *)zend_list_find((*idispatch_handle)->value.lval,&type); - if (!i_dispatch || (type!=le_idispatch)) { - var_result.vt = VT_EMPTY; - return var_result; + obj = (i_dispatch *) zend_list_find((*idispatch_handle)->value.lval, &type); + if (!obj || (type!=le_idispatch)) { + return NULL; } - var_result.vt = VT_DISPATCH; - var_result.pdispVal = i_dispatch; + obj_prop = (i_dispatch *) emalloc(sizeof(i_dispatch)); + php_COM_clone(obj_prop, obj, FALSE); + + var_result = (VARIANT *) emalloc(sizeof(VARIANT)); + var_result->vt = VT_DISPATCH; + var_result->pdispVal = obj_prop->i.dispatch; for (element=property_reference->elements_list->head; element; element=element->next) { overloaded_property = (zend_overloaded_element *) element->data; switch (overloaded_property->type) { case OE_IS_ARRAY: - if (do_COM_offget(&var_result, &var_result, &overloaded_property->element, element!=property_reference->elements_list->head)==FAILURE) { - var_result.vt = VT_EMPTY; + if (do_COM_offget(var_result, var_result, +&overloaded_property->element, +element!=property_reference->elements_list->head)==FAILURE) { + var_result->vt = VT_EMPTY; + efree(obj_prop); return var_result; } - /*printf("Array offset: ");*/ break; + case OE_IS_OBJECT: - if (var_result.vt != VT_DISPATCH) { - var_result.vt = VT_EMPTY; + if (var_result->vt != VT_DISPATCH) { + var_result->vt = VT_EMPTY; + efree(obj_prop); return var_result; } else { - if (do_COM_propget(&var_result, var_result.pdispVal, &overloaded_property->element, element!=property_reference->elements_list->head)==FAILURE) { - var_result.vt = VT_EMPTY; + php_COM_set(obj_prop, var_result->pdispVal, +TRUE); + if (do_COM_propget(var_result, obj_prop, +&overloaded_property->element, +element!=property_reference->elements_list->head)==FAILURE) { + var_result->vt = VT_EMPTY; + efree(obj_prop); return var_result; } - /*printf("Object property: ");*/ + } break; + case OE_IS_METHOD: + var_result->pdispVal = obj_prop->i.dispatch; + efree(obj_prop); return var_result; break; } @@ -647,15 +718,17 @@ */ pval_destructor(&overloaded_property->element); } + efree(obj_prop); return var_result; } PHPAPI pval php_COM_get_property_handler(zend_property_reference *property_reference) { pval result; - VARIANTARG var_result = _php_COM_get_property_handler(property_reference); + VARIANT *var_result = _php_COM_get_property_handler(property_reference); - php_variant_to_pval(&var_result, &result, 0, codepage); + php_variant_to_pval(var_result, &result, 0, codepage); + efree(var_result); return result; } @@ -667,19 +740,19 @@ zend_llist_element *element; pval **idispatch_handle; pval *object = property_reference->object; - IDispatch *i_dispatch; + i_dispatch *obj; int type; VARIANTARG var_result; /* fetch the IDispatch interface */ zend_hash_index_find(object->value.obj.properties, 0, (void **) &idispatch_handle); - i_dispatch = (IDispatch *)zend_list_find((*idispatch_handle)->value.lval,&type); - if (!i_dispatch || (type!=le_idispatch)) { + obj = (i_dispatch *)zend_list_find((*idispatch_handle)->value.lval,&type); + if (!obj || (type!=le_idispatch)) { return FAILURE; } var_result.vt = VT_DISPATCH; - var_result.pdispVal = i_dispatch; + var_result.pdispVal = obj->i.dispatch; for (element=property_reference->elements_list->head; element && element!=property_reference->elements_list->tail; element=element->next) { overloaded_property = (zend_overloaded_element *) element->data; @@ -691,7 +764,8 @@ if (var_result.vt != VT_DISPATCH) { return FAILURE; } else { - do_COM_propget(&var_result, i_dispatch, &overloaded_property->element, element!=property_reference->elements_list->head); + // ?????? + do_COM_propget(&var_result, obj, +&overloaded_property->element, element!=property_reference->elements_list->head); /*printf("Object property: ");*/ } break; @@ -715,9 +789,15 @@ if (var_result.vt != VT_DISPATCH) { return FAILURE; } + obj = (i_dispatch *) emalloc(sizeof(i_dispatch)); + obj->typelib = FALSE; + obj->i.dispatch = var_result.pdispVal; + overloaded_property = (zend_overloaded_element *) element->data; - do_COM_propput(&result, var_result.pdispVal, &overloaded_property->element, value); + do_COM_propput(&result, obj, &overloaded_property->element, value); pval_destructor(&overloaded_property->element); + efree(obj); + return SUCCESS; } @@ -745,24 +825,26 @@ zend_hash_index_update(object->value.obj.properties, 0, &object_handle, sizeof(pval *), NULL); pval_destructor(&function_name->element); } else { - VARIANTARG object_handle = _php_COM_get_property_handler(property_reference); + i_dispatch *obj; pval **arguments; int arg_count = ZEND_NUM_ARGS(); VARIANTARG var_result; var_result.vt = VT_EMPTY; - if (object_handle.vt != VT_DISPATCH) { - /* that shouldn't happen */ - return; - } + obj = (i_dispatch *) emalloc(sizeof(i_dispatch)); + php_COM_set(obj, +_php_COM_get_property_handler(property_reference)->pdispVal, TRUE); + arguments = (pval **) emalloc(sizeof(pval *)*arg_count); getParametersArray(ht, arg_count, arguments); - if (do_COM_invoke((IDispatch *) object_handle.pdispVal, &function_name->element, &var_result, arguments, arg_count)==FAILURE) { + if (do_COM_invoke(obj , &function_name->element, &var_result, +arguments, arg_count)==FAILURE) { RETVAL_FALSE; } + pval_destructor(&function_name->element); + php_COM_release(obj); + efree(obj); efree(arguments); php_variant_to_pval(&var_result, return_value, 0, codepage); } @@ -788,18 +870,52 @@ ITypeLib *TypeLib; ITypeComp *TypeComp; OLECHAR *p; + CLSID clsid; + char *strtok_buf, *major, *minor; int i; int interfaces; ELS_FETCH(); + + typelib_name = php_strtok_r(typelib_name, ",", &strtok_buf); + major = php_strtok_r(NULL, ",", &strtok_buf); + minor = php_strtok_r(NULL, ",", &strtok_buf); + p = php_char_to_OLECHAR(typelib_name, strlen(typelib_name), codepage); - if (FAILED(LoadTypeLib(p, &TypeLib))) { - efree(p); - return FAILURE; + if (!FAILED(CLSIDFromString(p, &clsid))) { + HRESULT hr; + + if (major && minor) { + hr = LoadRegTypeLib((REFGUID) &clsid, 1, 0, LANG_NEUTRAL, +&TypeLib); + } + + if (!major || !minor || FAILED(hr)) { + IDispatch *i_dispatch; + ITypeInfo *TypeInfo; + int idx; + + if (FAILED(CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, +&IID_IDispatch, (LPVOID *) &i_dispatch))) { + efree(p); + return FAILURE; + } + if (FAILED(i_dispatch->lpVtbl->GetTypeInfo(i_dispatch, 0, +LANG_NEUTRAL, &TypeInfo))) { + efree(p); + return FAILURE; + } + if (FAILED(TypeInfo->lpVtbl->GetContainingTypeLib(TypeInfo, +&TypeLib, &idx))) { + efree(p); + return FAILURE; + } + } + } else { + if (FAILED(LoadTypeLib(p, &TypeLib))) { + efree(p); + return FAILURE; + } } - interfaces = TypeLib->lpVtbl->GetTypeInfoCount(TypeLib); + interfaces = TypeLib->lpVtbl->GetTypeInfoCount(TypeLib); TypeLib->lpVtbl->GetTypeComp(TypeLib, &TypeComp); for (i=0; i<interfaces; i++) { @@ -865,7 +981,6 @@ zend_register_internal_class(&com_class_entry); } - PHP_MINIT_FUNCTION(COM) { CoInitialize(NULL); @@ -883,7 +998,6 @@ return SUCCESS; } -BEGIN_EXTERN_C() // exports for external object creation zend_module_entry COM_module_entry = { @@ -893,7 +1007,5 @@ PHPAPI int php_COM_get_le_idispatch() { return le_idispatch; } - -END_EXTERN_C() #endif Index: php4/ext/com/php_COM.h diff -u php4/ext/com/php_COM.h:1.4 php4/ext/com/php_COM.h:1.4.2.1 --- php4/ext/com/php_COM.h:1.4 Mon Jan 29 13:54:09 2001 +++ php4/ext/com/php_COM.h Sun Apr 22 04:57:18 2001 @@ -3,7 +3,7 @@ #if PHP_WIN32 -BEGIN_EXTERN_C() +#include "com.h" extern PHP_MINIT_FUNCTION(COM); extern PHP_MSHUTDOWN_FUNCTION(COM); @@ -13,16 +13,10 @@ extern zend_module_entry COM_module_entry; extern zend_class_entry com_class_entry; -END_EXTERN_C() - -#ifdef __cplusplus - extern pval php_COM_get_property_handler(zend_property_reference *property_reference); extern int php_COM_set_property_handler(zend_property_reference *property_reference, pval *value); extern char *php_COM_error_message(HRESULT hr); extern void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference); - -#endif #define COM_module_ptr &COM_module_entry Index: php4/ext/com/typedef_VARIANT.c diff -u php4/ext/com/typedef_VARIANT.c:1.8 php4/ext/com/typedef_VARIANT.c:1.8.2.1 --- php4/ext/com/typedef_VARIANT.c:1.8 Sun Feb 25 22:06:49 2001 +++ php4/ext/com/typedef_VARIANT.c Sun Apr 22 04:57:18 2001 @@ -69,38 +69,38 @@ le_variant = zend_register_list_destructors_ex(php_variant_destructor, NULL, "VARIANT", module_number); /* variant datatypes */ - REGISTER_LONG_CONSTANT("VT_NULL", VT_NULL, 0); - REGISTER_LONG_CONSTANT("VT_EMPTY", VT_EMPTY, 0); - REGISTER_LONG_CONSTANT("VT_UI1", VT_UI1, 0); - REGISTER_LONG_CONSTANT("VT_I2", VT_I2, 0); - REGISTER_LONG_CONSTANT("VT_I4", VT_I4, 0); - REGISTER_LONG_CONSTANT("VT_R4", VT_R4, 0); - REGISTER_LONG_CONSTANT("VT_R8", VT_R8, 0); - REGISTER_LONG_CONSTANT("VT_BOOL", VT_BOOL, 0); - REGISTER_LONG_CONSTANT("VT_ERROR", VT_ERROR, 0); - REGISTER_LONG_CONSTANT("VT_CY", VT_CY, 0); - REGISTER_LONG_CONSTANT("VT_DATE", VT_CY, 0); - REGISTER_LONG_CONSTANT("VT_BSTR", VT_BSTR, 0); - REGISTER_LONG_CONSTANT("VT_DECIMAL", VT_DECIMAL, 0); - REGISTER_LONG_CONSTANT("VT_UNKNOWN", VT_UNKNOWN, 0); - REGISTER_LONG_CONSTANT("VT_DISPATCH", VT_DISPATCH, 0); - REGISTER_LONG_CONSTANT("VT_VARIANT", VT_VARIANT, 0); - REGISTER_LONG_CONSTANT("VT_I1", VT_I1, 0); - REGISTER_LONG_CONSTANT("VT_UI2", VT_UI2, 0); - REGISTER_LONG_CONSTANT("VT_UI4", VT_UI4, 0); - REGISTER_LONG_CONSTANT("VT_INT", VT_INT, 0); - REGISTER_LONG_CONSTANT("VT_UINT", VT_UINT, 0); - REGISTER_LONG_CONSTANT("VT_ARRAY", VT_ARRAY, 0); - REGISTER_LONG_CONSTANT("VT_BYREF", VT_BYREF, 0); + REGISTER_LONG_CONSTANT("VT_NULL", VT_NULL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_EMPTY", VT_EMPTY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_UI1", VT_UI1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_I2", VT_I2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_I4", VT_I4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_R4", VT_R4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_R8", VT_R8, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_BOOL", VT_BOOL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_ERROR", VT_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_CY", VT_CY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_DATE", VT_CY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_BSTR", VT_BSTR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_DECIMAL", VT_DECIMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_UNKNOWN", VT_UNKNOWN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_DISPATCH", VT_DISPATCH, CONST_CS | +CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_VARIANT", VT_VARIANT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_I1", VT_I1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_UI2", VT_UI2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_UI4", VT_UI4, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_INT", VT_INT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_UINT", VT_UINT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_ARRAY", VT_ARRAY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("VT_BYREF", VT_BYREF, CONST_CS | CONST_PERSISTENT); /* codepages */ - REGISTER_LONG_CONSTANT("CP_ACP", CP_ACP, 0); - REGISTER_LONG_CONSTANT("CP_MACCP", CP_MACCP, 0); - REGISTER_LONG_CONSTANT("CP_OEMCP", CP_OEMCP, 0); - REGISTER_LONG_CONSTANT("CP_SYMBOL", CP_SYMBOL, 0); - REGISTER_LONG_CONSTANT("CP_THREAD_ACP", CP_THREAD_ACP, 0); - REGISTER_LONG_CONSTANT("CP_UTF7", CP_UTF7, 0); - REGISTER_LONG_CONSTANT("CP_UTF8", CP_UTF8, 0); + REGISTER_LONG_CONSTANT("CP_ACP", CP_ACP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_MACCP", CP_MACCP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_OEMCP", CP_OEMCP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_SYMBOL", CP_SYMBOL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_THREAD_ACP", CP_THREAD_ACP, CONST_CS | +CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_UTF7", CP_UTF7, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("CP_UTF8", CP_UTF8, CONST_CS | CONST_PERSISTENT); php_register_VARIANT_class(); return SUCCESS; Index: php4/ext/com/com.h +++ php4/ext/com/com.h #ifndef COM_H #define COM_H #if PHP_WIN32 #include "unknwn.h" typedef struct i_dispatch_ { int typelib; struct { IDispatch *dispatch; ITypeInfo *typeinfo; } i; } i_dispatch; PHPAPI HRESULT php_COM_invoke(i_dispatch *obj, DISPID dispIdMember, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult); PHPAPI HRESULT php_COM_get_ids_of_names(i_dispatch *obj, OLECHAR FAR* FAR* rgszNames, DISPID FAR* rgDispId); PHPAPI HRESULT php_COM_release(i_dispatch *obj); PHPAPI HRESULT php_COM_set(i_dispatch *obj, IDispatch FAR* pDisp, int cleanup); PHPAPI HRESULT php_COM_clone(i_dispatch *obj, i_dispatch *clone, int cleanup); #endif /* PHP_WIN32 */ #endif /* COM_H */
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]