phanto Mon Feb 10 19:54:26 2003 EDT Modified files: /php4/ext/rpc/com com.c com.h Log: improved reverse lookup of ProgID based on an IDispatch pointer Index: php4/ext/rpc/com/com.c diff -u php4/ext/rpc/com/com.c:1.20 php4/ext/rpc/com/com.c:1.21 --- php4/ext/rpc/com/com.c:1.20 Mon Feb 10 15:58:53 2003 +++ php4/ext/rpc/com/com.c Mon Feb 10 19:54:25 2003 @@ -28,6 +28,7 @@ #include "variant.h" #include "ext/standard/php_smart_str.h" #include <oleauto.h> +#include <ocidl.h> /* protos */ @@ -44,7 +45,7 @@ static int com_unset_property(rpc_string, void *); static int com_get_properties(HashTable **, void *); -static PHP_INI_MH(com_typelib_file_change); +static ZEND_INI_MH(com_typelib_file_change); /* globals */ static IBindCtx *pBindCtx; @@ -88,6 +89,7 @@ ZEND_FE(com_skip, NULL) ZEND_FE(com_event_sink, arg1and2_force_ref) ZEND_FE(com_message_pump, NULL) + ZEND_FE(com_load_typelib, NULL) ZEND_FE(com_print_typeinfo, NULL) RPC_FUNCTION_ENTRY_END() @@ -149,28 +151,59 @@ static int com_hash(rpc_string name, rpc_string *hash, void *data, int num_args, char *arg_types, int type) { - OLECHAR *olestr = php_char_to_OLECHAR(name.str, name.len, CP_ACP, FALSE); - switch (type) { case CLASS: { CLSID *clsid = malloc(sizeof(CLSID)); - if (FAILED(CLSIDFromString(olestr, clsid))) { - /* Perhaps this is a Moniker? */ - free(clsid); + /* if name is {NULL, 0} then the corresponding hash value has +to be figured out + * of the *data struct. this might be not a trivial task. + */ + if (name.str) { + OLECHAR *olestr = php_char_to_OLECHAR(name.str, +name.len, CP_ACP, FALSE); + + if (FAILED(CLSIDFromString(olestr, clsid))) { + /* Perhaps this is a Moniker? */ + free(clsid); + efree(olestr); + + hash->str = strdup(name.str); + hash->len = name.len; + + return SUCCESS; + } - hash->str = strdup(name.str); - hash->len = name.len; + efree(olestr); } else { - hash->str = (char *) clsid; - /* str is actually not a string but a CLSID struct, thus set len to 0. - * nevertheless clsid is freed by the rpc_string_dtor - */ - hash->len = 0; + comval *obj = (comval *)data; + IProvideClassInfo2 *pci2; + + if +(SUCCEEDED(C_DISPATCH_VT(obj)->QueryInterface(C_DISPATCH(obj), +&IID_IProvideClassInfo2, (void**)&pci2))) { + if (FAILED(pci2->lpVtbl->GetGUID(pci2, +GUIDKIND_DEFAULT_SOURCE_DISP_IID, clsid))) { + free(clsid); + + return FAILURE; + } + pci2->lpVtbl->Release(pci2); + } else if (C_HASTLIB(obj)) { + TYPEATTR *typeattrib; + + if +(FAILED(C_TYPEINFO_VT(obj)->GetTypeAttr(C_TYPEINFO(obj), &typeattrib))) { + free(clsid); + + return FAILURE; + } + + *clsid = (typeattrib->guid); + +C_TYPEINFO_VT(obj)->ReleaseTypeAttr(C_TYPEINFO(obj), typeattrib); + } } - efree(olestr); + hash->str = (char *) clsid; + /* str is actually not a string but a CLSID struct, thus set +len to 0. + * nevertheless clsid is freed by the rpc_string_dtor + */ + hash->len = 0; return SUCCESS; } @@ -179,7 +212,8 @@ case PROPERTY: { DISPID *dispid = malloc(sizeof(DISPID)); - + OLECHAR *olestr = php_char_to_OLECHAR(name.str, name.len, +CP_ACP, FALSE); + if(SUCCEEDED(php_COM_get_ids_of_names((comval *) data, olestr, dispid))) { hash->str = (char *) dispid; /* str is actually not a string but a DISPID struct, thus set len to 0. @@ -199,8 +233,6 @@ } } - efree(olestr); - return FAILURE; } @@ -216,21 +248,24 @@ switch (type) { case CLASS: { - if (hash.str != NULL) { - OLECHAR *olestr; - - StringFromCLSID((CLSID *) hash.str, &olestr); - name->str = php_OLECHAR_to_char(olestr, &(name->len), CP_ACP, TRUE); - CoTaskMemFree(olestr); - - return SUCCESS; - } else { - comval *obj = (comval *) data; + CLSID clsid; + OLECHAR *olestr; - /* try to figure out classname */ + clsid = *((CLSID *) hash.str); + ProgIDFromCLSID(&clsid, &olestr); + if (olestr == NULL) { + StringFromCLSID(&clsid, &olestr); + } + + if (olestr == NULL) { return FAILURE; } + + name->str = php_OLECHAR_to_char(olestr, &(name->len), +CP_ACP, TRUE); + CoTaskMemFree(olestr); + + return SUCCESS; } case METHOD: @@ -575,14 +610,12 @@ GET_INTERNAL_EX(intern, data); obj = (comval*)data; - if (C_TYPEINFO(obj)) { - typeinfo = C_TYPEINFO(obj); - ITypeInfo_AddRef(typeinfo); - } else if (FAILED(C_DISPATCH_VT(obj)->GetTypeInfo(C_DISPATCH(obj), 0, LOCALE_SYSTEM_DEFAULT, &typeinfo))) { + if (!C_HASTLIB(obj)) { return FAILURE; } olename = php_char_to_OLECHAR(method_name.str, method_name.len, CP_ACP, FALSE); + typeinfo = C_TYPEINFO(obj); if (SUCCEEDED(ITypeInfo_GetIDsOfNames(typeinfo, &olename, 1, &fid)) && SUCCEEDED(ITypeInfo_GetFuncDesc(typeinfo, fid, &funcdesc))) { @@ -623,7 +656,6 @@ } efree(olename); - ITypeInfo_Release(typeinfo); return retval; } @@ -831,7 +863,7 @@ } /* }}} */ -PHP_FUNCTION(com_next) +ZEND_FUNCTION(com_next) { zval *object; rpc_internal *intern; @@ -915,7 +947,7 @@ RETURN_NULL(); } -PHP_FUNCTION(com_all) +ZEND_FUNCTION(com_all) { #if 0 } else if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "all")) { @@ -938,7 +970,7 @@ #endif } -PHP_FUNCTION(com_reset) +ZEND_FUNCTION(com_reset) { zval *object; rpc_internal *intern; @@ -972,7 +1004,7 @@ RETURN_FALSE; } -PHP_FUNCTION(com_skip) +ZEND_FUNCTION(com_skip) { zval *object; rpc_internal *intern; @@ -1027,7 +1059,7 @@ /* {{{ proto bool com_load_typelib(string typelib_name [, int case_insensitive]) Loads a Typelib */ -PHP_FUNCTION(com_load_typelib) +ZEND_FUNCTION(com_load_typelib) { char *typelib; int len, cis = FALSE; @@ -1052,7 +1084,7 @@ /* {{{ proto bool com_print_typeinfo(mixed comobject | string typelib, string dispinterface, bool wantsink) Print out a PHP class definition for a dispatchable interface */ -PHP_FUNCTION(com_print_typeinfo) +ZEND_FUNCTION(com_print_typeinfo) { zval *object; char *ifacename = NULL; @@ -1093,7 +1125,7 @@ /* {{{ 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) +ZEND_FUNCTION(com_event_sink) { zval *object, *sinkobject, *sink=NULL; char *dispname = NULL, *typelibname = NULL; @@ -1159,7 +1191,7 @@ /* ini callbacks */ -static PHP_INI_MH(com_typelib_file_change) +static ZEND_INI_MH(com_typelib_file_change) { FILE *typelib_file; char *typelib_name_buffer; Index: php4/ext/rpc/com/com.h diff -u php4/ext/rpc/com/com.h:1.4 php4/ext/rpc/com/com.h:1.5 --- php4/ext/rpc/com/com.h:1.4 Thu Jan 16 12:49:21 2003 +++ php4/ext/rpc/com/com.h Mon Feb 10 19:54:26 2003 @@ -37,6 +37,7 @@ ZEND_FUNCTION(com_skip); ZEND_FUNCTION(com_event_sink); ZEND_FUNCTION(com_message_pump); +ZEND_FUNCTION(com_load_typelib); ZEND_FUNCTION(com_print_typeinfo); #endif
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php