31static MUTEX_T php_com_typelibraries_mutex;
39 php_com_typelibraries_mutex = tsrm_mutex_alloc();
50 tsrm_mutex_free(php_com_typelibraries_mutex);
69 search_string =
php_strtok_r(search_string,
",", &strtok_buf);
71 if (search_string ==
NULL) {
80 if (SUCCEEDED(CLSIDFromString(
p, &clsid))) {
81 WORD major_i = 1, minor_i = 0;
90 hr = LoadRegTypeLib((REFGUID)&clsid, major_i, minor_i, LANG_NEUTRAL, &TL);
95 IDispatch *disp =
NULL;
96 ITypeInfo *info =
NULL;
99 if (SUCCEEDED(hr = CoCreateInstance(&clsid,
NULL,
CLSCTX_SERVER, &IID_IDispatch, (LPVOID*)&disp)) &&
100 SUCCEEDED(hr = IDispatch_GetTypeInfo(disp, 0, LANG_NEUTRAL, &info))) {
101 hr = ITypeInfo_GetContainingTypeLib(info, &TL, &idx);
105 ITypeInfo_Release(info);
108 IDispatch_Release(disp);
114 if (FAILED(LoadTypeLib(
p, &TL))) {
116 DWORD SubKeys, MaxSubKeyLength;
124 if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT,
"TypeLib", 0, KEY_READ, &hkey) &&
125 ERROR_SUCCESS == RegQueryInfoKey(hkey,
NULL,
NULL,
NULL, &SubKeys,
129 keyname =
emalloc(MaxSubKeyLength);
132 for (i = 0; i < SubKeys && TL ==
NULL; i++) {
133 if (ERROR_SUCCESS == RegEnumKey(hkey, i, keyname, MaxSubKeyLength) &&
134 ERROR_SUCCESS == RegOpenKeyEx(hkey, keyname, 0, KEY_READ, &hsubkey)) {
135 if (ERROR_SUCCESS == RegQueryInfoKey(hsubkey,
NULL,
NULL,
NULL, &VersionCount,
137 for (
j = 0;
j < VersionCount;
j++) {
138 if (ERROR_SUCCESS != RegEnumKey(hsubkey,
j, version,
sizeof(version))) {
142 libnamelen = (long)
strlen(search_string)+1;
143 if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) {
144 if (0 ==
stricmp(libname, search_string)) {
146 int major_tmp, minor_tmp;
149 if (2 !=
sscanf(version,
"%d.%d", &major_tmp, &minor_tmp)) {
153 spprintf(&str, 0,
"%s,%d,%d", keyname, major_tmp, minor_tmp);
163 RegCloseKey(hsubkey);
181 int i,
j, interfaces;
194 interfaces = ITypeLib_GetTypeInfoCount(TL);
195 for (i = 0; i < interfaces; i++) {
196 ITypeLib_GetTypeInfoType(TL, i, &pTKind);
197 if (pTKind == TKIND_ENUM) {
198 ITypeLib_GetTypeInfo(TL, i, &TypeInfo);
202 if (FAILED(ITypeInfo_GetVarDesc(TypeInfo,
j, &pVarDesc))) {
205 ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);
206 if (NameCount != 1) {
207 ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
212 SysFreeString(bstr_ids);
221 ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
231 c.
name = zend_string_dup(const_name,
true);
238 ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);
240 ITypeInfo_Release(TypeInfo);
249 ITypeLib *Lib = (ITypeLib*)
Z_PTR_P(pDest);
250 ITypeLib_Release(Lib);
256 tsrm_mutex_lock(php_com_typelibraries_mutex);
259 result = zend_hash_str_add_ptr(&php_com_typelibraries, cache_key, cache_key_len, TL);
262 tsrm_mutex_unlock(php_com_typelibraries_mutex);
275 tsrm_mutex_lock(php_com_typelibraries_mutex);
278 if ((TL = zend_hash_find_ptr(&php_com_typelibraries,
key)) !=
NULL) {
282 goto php_com_load_typelib_via_cache_return;
290 if (
NULL != zend_hash_add_ptr(&php_com_typelibraries,
key, TL)) {
296php_com_load_typelib_via_cache_return:
298 tsrm_mutex_unlock(php_com_typelibraries_mutex);
300 zend_string_release(
key);
308 ITypeInfo *typeinfo =
NULL;
309 ITypeLib *typelib =
NULL;
314 if (dispatch_name ==
NULL && sink) {
316 IProvideClassInfo2 *pci2;
317 IProvideClassInfo *pci;
319 if (SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->
v), &IID_IProvideClassInfo2, (
void**)&pci2))) {
320 gotguid = SUCCEEDED(IProvideClassInfo2_GetGUID(pci2, GUIDKIND_DEFAULT_SOURCE_DISP_IID, &iid));
321 IProvideClassInfo2_Release(pci2);
323 if (!gotguid && SUCCEEDED(IDispatch_QueryInterface(V_DISPATCH(&obj->
v), &IID_IProvideClassInfo, (
void**)&pci))) {
327 IProvideClassInfo_Release(pci);
330 }
else if (dispatch_name ==
NULL) {
335 IDispatch_GetTypeInfo(V_DISPATCH(&obj->
v), 0, LANG_NEUTRAL, &typeinfo);
340 }
else if (dispatch_name && obj->
typeinfo) {
343 ITypeInfo_GetContainingTypeLib(obj->
typeinfo, &typelib, &idx);
344 }
else if (type_lib_name ==
NULL) {
346 IDispatch_GetTypeInfo(V_DISPATCH(&obj->
v), 0, LANG_NEUTRAL, &typeinfo);
350 ITypeInfo_GetContainingTypeLib(typeinfo, &typelib, &idx);
353 ITypeInfo_Release(typeinfo);
359 }
else if (type_lib_name) {
364 if (!gotguid && dispatch_name && typelib) {
365 unsigned short cfound;
370 if (FAILED(ITypeLib_FindName(typelib, olename, 0, &typeinfo, &memid, &cfound)) || cfound == 0) {
375 if (SUCCEEDED(CLSIDFromProgID(olename, &coclass)) &&
376 SUCCEEDED(ITypeLib_GetTypeInfoOfGuid(typelib, &coclass, &coinfo))) {
382 ITypeInfo_GetTypeAttr(coinfo, &
attr);
384 for (i = 0; i <
attr->cImplTypes; i++) {
388 if (FAILED(ITypeInfo_GetImplTypeFlags(coinfo, i, &tf))) {
392 if ((sink && tf == (IMPLTYPEFLAG_FSOURCE|IMPLTYPEFLAG_FDEFAULT)) ||
393 (!sink && (tf & IMPLTYPEFLAG_FSOURCE) == 0)) {
397 if (SUCCEEDED(ITypeInfo_GetRefTypeOfImplType(coinfo, i, &rt)))
398 if (SUCCEEDED(ITypeInfo_GetRefTypeInfo(coinfo, rt, &typeinfo)))
404 ITypeInfo_ReleaseTypeAttr(coinfo,
attr);
405 ITypeInfo_Release(coinfo);
411 }
else if (gotguid) {
412 ITypeLib_GetTypeInfoOfGuid(typelib, &iid, &typeinfo);
416 ITypeLib_Release(typelib);
449 { VT_VOID,
"VT_VOID" },
450 { VT_PTR,
"VT_PTR" },
451 { VT_HRESULT,
"VT_HRESULT" },
452 { VT_SAFEARRAY,
"VT_SAFEARRAY" },
456static inline const char *vt_to_string(VARTYPE
vt)
459 for (i = 0; vt_names[i].name !=
NULL; i++) {
460 if (vt_names[i].
vt ==
vt)
461 return vt_names[i].name;
466static zend_string *php_com_string_from_clsid(
const CLSID *clsid,
int codepage)
471 StringFromCLSID(clsid, &ole_clsid);
473 LocalFree(ole_clsid);
488 if (FAILED(ITypeInfo_GetTypeAttr(typeinfo, &
attr))) {
493 if (id_to_name ==
NULL ||
attr->typekind == TKIND_DISPATCH) {
502 ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &olename,
NULL,
NULL,
NULL);
504 SysFreeString(olename);
506 guid_str = php_com_string_from_clsid(&
attr->guid, codepage);
517 for (i = 0; i <
attr->cFuncs; i++) {
521 if (FAILED(ITypeInfo_GetFuncDesc(typeinfo, i, &
func)))
524 isprop = (
func->invkind & DISPATCH_PROPERTYGET ||
func->invkind & DISPATCH_PROPERTYPUT);
526 if (!isprop || lastid !=
func->memid) {
528 lastid =
func->memid;
530 ITypeInfo_GetDocumentation(typeinfo,
func->memid, &olename,
NULL,
NULL,
NULL);
532 SysFreeString(olename);
537 unsigned int cnames = 0;
542 ITypeInfo_GetNames(typeinfo,
func->memid, names,
func->cParams + 1, &cnames);
544 SysFreeString(names[0]);
548 if (
func->elemdescFunc.tdesc.vt != VT_VOID) {
550 vt_to_string(
func->elemdescFunc.tdesc.vt),
551 func->elemdescFunc.tdesc.vt
557 ITypeInfo_GetDocumentation(typeinfo,
func->memid,
NULL, &olename,
NULL,
NULL);
560 SysFreeString(olename);
572 for (
j = 0;
j <
func->cParams;
j++) {
573 ELEMDESC *elem = &
func->lprgelemdescParam[
j];
575 php_printf(
"\t\t/* %s [%d] ", vt_to_string(elem->tdesc.vt), elem->tdesc.vt);
577 if (elem->paramdesc.wParamFlags & PARAMFLAG_FIN)
579 if (elem->paramdesc.wParamFlags & PARAMFLAG_FOUT)
582 if (elem->tdesc.vt == VT_PTR) {
585 vt_to_string(elem->tdesc.lptdesc->vt),
586 elem->tdesc.lptdesc->vt
591 if (
j+1 < (
int)cnames) {
593 SysFreeString(names[
j+1]);
595 elem->tdesc.vt == VT_PTR ?
"&$" :
"$",
597 j ==
func->cParams - 1 ?
' ' :
','
601 elem->tdesc.vt == VT_PTR ?
"&$" :
"$",
602 j ==
func->cParams - 1 ?
' ' :
','
606 if (
j+1 < (
int)cnames) {
613 ITypeInfo_GetDocumentation(typeinfo,
func->memid,
NULL, &olename,
NULL,
NULL);
616 SysFreeString(olename);
628 zend_string *lc_ansi_name = zend_string_tolower(ansi_name);
634 ITypeInfo_ReleaseFuncDesc(typeinfo,
func);
644 ITypeInfo_ReleaseTypeAttr(typeinfo,
attr);
sscanf(string $string, string $format, mixed &... $vars)
PHP_COM_DOTNET_API zend_string * php_com_olestring_to_string(OLECHAR *olestring, int codepage)
PHP_COM_DOTNET_API OLECHAR * php_com_string_to_olestring(const char *string, size_t string_len, int codepage)
ITypeLib * php_com_cache_typelib(ITypeLib *TL, char *cache_key, zend_long cache_key_len)
ITypeInfo * php_com_locate_typeinfo(zend_string *type_lib_name, php_com_dotnet_object *obj, zend_string *dispatch_name, bool sink)
PHP_COM_DOTNET_API ITypeLib * php_com_load_typelib_via_cache(const char *search_string, int codepage)
PHP_COM_DOTNET_API zend_result php_com_import_typelib(ITypeLib *TL, int mode, int codepage)
bool php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, bool printdef, GUID *guid, int codepage)
void php_com_typelibrary_dtor(zval *pDest)
PHP_COM_DOTNET_API ITypeLib * php_com_load_typelib(char *search_string, int codepage)
PHP_COM_DOTNET_API zend_result php_com_zval_from_variant(zval *z, VARIANT *v, int codepage)
PHPAPI size_t php_printf(const char *format,...)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
#define PHP_MSHUTDOWN_FUNCTION
#define PHP_MINIT_FUNCTION
#define PHP_COM_DOTNET_API
struct _php_com_dotnet_object php_com_dotnet_object
PHPAPI char * php_strtok_r(char *s, const char *delim, char **last)
unsigned char key[REFLECTION_KEY_LEN]
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
#define estrndup(s, length)
#define safe_emalloc(nmemb, size, offset)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API zval * zend_get_constant(zend_string *name)
ZEND_API zend_result zend_register_constant(zend_constant *c)
#define ZEND_CONSTANT_SET_FLAGS(c, _flags, _module_number)
struct _zend_constant zend_constant
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
struct _zend_string zend_string
ZEND_API zend_result ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2)
struct _zend_array HashTable
ZEND_RESULT_CODE zend_result