⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 com.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	ALLOC_COM(obj_prop);	ALLOC_VARIANT(var_result);	for (element=property_reference->elements_list->head; element != property_reference->elements_list->tail; element=element->next) {		overloaded_property = (zend_overloaded_element *) element->data;		switch (Z_TYPE_P(overloaded_property)) {			case OE_IS_ARRAY:				if (do_COM_offget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE) {					FREE_VARIANT(var_result);					FREE_COM(obj_prop);					return FAILURE;				}				break;			case OE_IS_OBJECT:				if (do_COM_propget(var_result, obj, &overloaded_property->element, FALSE TSRMLS_CC) == FAILURE) {					FREE_VARIANT(var_result);					FREE_COM(obj_prop);					return FAILURE;				}				break;			case OE_IS_METHOD:				/* this shouldn't happen */				return FAILURE;				break;		}		if (V_VT(var_result) == VT_DISPATCH) {			if (V_DISPATCH(var_result) == NULL) {				FREE_VARIANT(var_result);				FREE_COM(obj_prop);				return FAILURE;			}			obj = obj_prop;			php_COM_set(obj, &V_DISPATCH(var_result), TRUE TSRMLS_CC);		} else {			FREE_COM(obj_prop);			FREE_VARIANT(var_result);			return FAILURE;		}		VariantInit(var_result);	/* to protect C_DISPATCH(obj) from being freed when var_result is destructed */		zval_dtor(&overloaded_property->element);	}	FREE_VARIANT(var_result);	overloaded_property = (zend_overloaded_element *) element->data;	do_COM_propput(NULL, obj, &overloaded_property->element, value TSRMLS_CC);	FREE_COM(obj_prop);	zval_dtor(&overloaded_property->element);	return SUCCESS;}/* create an overloaded COM object from a dispatch pointer */PHPAPI zval *php_COM_object_from_dispatch(IDispatch *disp, zval *val TSRMLS_DC){	comval *obj;	zval *zobj;		ALLOC_COM(obj);	MAKE_STD_ZVAL(zobj);	php_COM_set(obj, &disp, FALSE TSRMLS_CC);	ZVAL_COM_EX(zobj, obj, val);		return zobj;}PHPAPI void php_COM_call_function_handler(INTERNAL_FUNCTION_PARAMETERS, zend_property_reference *property_reference){	pval property, **handle;	pval *object = property_reference->object;	zend_overloaded_element *function_name = (zend_overloaded_element *) property_reference->elements_list->tail->data;	comval *obj;	int type;	if (zend_llist_count(property_reference->elements_list)==1			&& !strcmp(Z_STRVAL(function_name->element), "com")) {		zval *tmp;				/* constructor */		PHP_FN(com_load)(INTERNAL_FUNCTION_PARAM_PASSTHRU);		zend_hash_index_find(Z_OBJPROP_P(return_value), 0, (void**)&handle);		zend_list_addref(Z_RESVAL_PP(handle));		MAKE_STD_ZVAL(tmp);		ZVAL_RESOURCE(tmp, Z_RESVAL_PP(handle));		zend_hash_index_update(Z_OBJPROP_P(object), 0, &tmp, sizeof(tmp), NULL);		zval_dtor(&function_name->element);		return;	}	RETVAL_NULL();	property = php_COM_get_property_handler(property_reference);	if (Z_TYPE(property) != IS_OBJECT) {		zval_dtor(&property);		zval_dtor(&function_name->element);		/* error message - function call on a non-object */		return;	}	zend_hash_index_find(Z_OBJPROP(property), 0, (void **) &handle);	obj = (comval *)zend_list_find(Z_LVAL_PP(handle), &type);	if (!obj || (type != IS_COM)) {		zval_dtor(&property);		zval_dtor(&function_name->element);		return;	}	if (zend_llist_count(property_reference->elements_list)==1		&& !strcmp(Z_STRVAL_P(&function_name->element), "release")) {		RETVAL_LONG(php_COM_release(obj TSRMLS_CC));	} else if (zend_llist_count(property_reference->elements_list)==1			   && !strcmp(Z_STRVAL_P(&function_name->element), "addref")) {		RETVAL_LONG(php_COM_addref(obj TSRMLS_CC));	} else {		pval **arguments;		VARIANT *var_result;		int arg_count = ZEND_NUM_ARGS();		ALLOC_VARIANT(var_result);		arguments = (zval **) emalloc(sizeof(zval *)*arg_count);		zend_get_parameters_array(ht, arg_count, arguments);		if (do_COM_invoke(obj , DISPATCH_METHOD|DISPATCH_PROPERTYGET, &function_name->element, var_result, arguments, arg_count TSRMLS_CC) == SUCCESS) {			RETVAL_VARIANT(var_result);		} else {			FREE_VARIANT(var_result);		}				efree(arguments);	}	zval_dtor(&property);	zval_dtor(&function_name->element);}static ITypeLib *php_COM_find_typelib(char *search_string, int mode TSRMLS_DC){	ITypeLib *TypeLib = NULL;	char *strtok_buf, *major, *minor;	CLSID clsid;	OLECHAR *p;	/* Type Libraries:	 * The string we have is either:	 * a) a file name	 * b) a CLSID, major, minor e.g. "{00000200-0000-0010-8000-00AA006D2EA4},2,0"	 * c) a Type Library name e.g. "Microsoft OLE DB ActiveX Data Objects 1.0 Library"	 * Searching for the name will be more expensive that the	 * other two, so we will do that when both other attempts	 * fail.	 */	search_string = php_strtok_r(search_string, ",", &strtok_buf);	if (search_string == NULL)		return NULL;		major = php_strtok_r(NULL, ",", &strtok_buf);	minor = php_strtok_r(NULL, ",", &strtok_buf);	p = php_char_to_OLECHAR(search_string, strlen(search_string), codepage TSRMLS_CC);	/* Is the string a GUID ? */	if (!FAILED(CLSIDFromString(p, &clsid))) {		HRESULT hr;		WORD major_i = 1;		WORD minor_i = 0;		/* We have a valid GUID, check to see if a major/minor */		/* version was specified otherwise assume 1,0 */		if ((major != NULL) && (minor != NULL)) {			major_i = (WORD) atoi(major);			minor_i = (WORD) atoi(minor);		}		/* The GUID will either be a typelibrary or a CLSID */		hr = LoadRegTypeLib((REFGUID) &clsid, major_i, minor_i, LANG_NEUTRAL, &TypeLib);		/* If the LoadRegTypeLib fails, let's try to instantiate */		/* the class itself and then QI for the TypeInfo and */		/* retrieve the type info from that interface */		if (FAILED(hr) && (!major || !minor)) {			IDispatch *Dispatch;			ITypeInfo *TypeInfo;			int idx;			if (FAILED(CoCreateInstance(&clsid, NULL, CLSCTX_SERVER, &IID_IDispatch, (LPVOID *) &Dispatch))) {				efree(p);				return NULL;			}			if (FAILED(Dispatch->lpVtbl->GetTypeInfo(Dispatch, 0, LANG_NEUTRAL, &TypeInfo))) {				Dispatch->lpVtbl->Release(Dispatch);				efree(p);				return NULL;			}			Dispatch->lpVtbl->Release(Dispatch);			if (FAILED(TypeInfo->lpVtbl->GetContainingTypeLib(TypeInfo, &TypeLib, &idx))) {				TypeInfo->lpVtbl->Release(TypeInfo);				efree(p);				return NULL;			}			TypeInfo->lpVtbl->Release(TypeInfo);		}	} else {		if (FAILED(LoadTypeLib(p, &TypeLib))) {			/* Walk HKCR/TypeLib looking for the string */			/* If that succeeds, call ourself recursively */			/* using the CLSID found, else give up and bail */			HKEY hkey, hsubkey;			DWORD SubKeys, MaxSubKeyLength;			char *keyname;			register unsigned int ii, jj;			DWORD VersionCount;			char version[20]; /* All the version keys are 1.0, 4.6, ... */			char *libname;			DWORD libnamelen;			/* No Need for Unicode version any more */			efree(p);			/* Starting at HKEY_CLASSES_ROOT/TypeLib */			/* Walk all subkeys (Typelib GUIDs) looking */			/* at each version for a string match to the */			/* supplied argument */			if (ERROR_SUCCESS != RegOpenKey(HKEY_CLASSES_ROOT, "TypeLib",&hkey)) {				/* This is pretty bad - better bail */				return NULL;			}			if (ERROR_SUCCESS != RegQueryInfoKey(hkey, NULL, NULL, NULL, &SubKeys, &MaxSubKeyLength, NULL, NULL, NULL, NULL, NULL, NULL)) {				RegCloseKey(hkey);				return NULL;			}			MaxSubKeyLength++; /* \0 is not counted */			keyname = emalloc(MaxSubKeyLength);			libname = emalloc(strlen(search_string)+1);			for (ii=0;ii<SubKeys;ii++) {				if (ERROR_SUCCESS != RegEnumKey(hkey, ii, keyname, MaxSubKeyLength)) {					/* Failed - who cares */					continue;				}				if (ERROR_SUCCESS != RegOpenKey(hkey, keyname, &hsubkey)) {					/* Failed - who cares */					continue;				}				if (ERROR_SUCCESS != RegQueryInfoKey(hsubkey, NULL, NULL, NULL, &VersionCount, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {					/* Failed - who cares */					RegCloseKey(hsubkey);					continue;				}				for (jj=0;jj<VersionCount;jj++) {					if (ERROR_SUCCESS != RegEnumKey(hsubkey, jj, version, sizeof(version))) {						/* Failed - who cares */						continue;					}					/* OK we just need to retrieve the default */					/* value for this key and see if it matches */					libnamelen = strlen(search_string)+1;					if (ERROR_SUCCESS == RegQueryValue(hsubkey, version, libname, &libnamelen)) {						if ((mode & CONST_CS) ? (strcmp(libname, search_string) == 0) : (stricmp(libname, search_string) == 0)) {							char *str;							int major, minor;							/* Found it */							RegCloseKey(hkey);							RegCloseKey(hsubkey);							efree(libname);							/* We can either open up the "win32" key and find the DLL name */							/* Or just parse the version string and pass that in */							/* The version string seems like a more portable solution */							/* Given that there is a COM on Unix */							if (2 != sscanf(version, "%d.%d", &major, &minor)) {								major = 1;								minor = 0;							}							str = emalloc(strlen(keyname)+strlen(version)+20); /* 18 == safety, 2 == extra comma and \0 */							sprintf(str, "%s,%d,%d", keyname, major, minor);							efree(keyname);							TypeLib = php_COM_find_typelib(str, mode TSRMLS_CC);							efree(str);							/* This is probbaly much harder to read and follow */							/* But it is MUCH more effiecient than trying to */							/* test for errors and leave through a single "return" */							return TypeLib;						}					} else {						/* Failed - perhaps too small abuffer */						/* But if too small, then the name does not match */					}				}				RegCloseKey(hsubkey);			}			efree(keyname);			efree(libname);			return NULL;		}	}	efree(p);	return TypeLib;}PHPAPI int php_COM_load_typelib(ITypeLib *TypeLib, int mode TSRMLS_DC){	int i;	int interfaces;	if (NULL == TypeLib) {		return FAILURE;	}	interfaces = ITypeLib_GetTypeInfoCount(TypeLib);	for (i=0; i<interfaces; i++) {		TYPEKIND pTKind;		ITypeLib_GetTypeInfoType(TypeLib, i, &pTKind);		if (pTKind == TKIND_ENUM) {			ITypeInfo *TypeInfo;			VARDESC *pVarDesc;			UINT NameCount;			int j;			ITypeLib_GetTypeInfo(TypeLib, i, &TypeInfo);			for (j = 0; ; j++) {				BSTR bstr_ids;				zend_constant c;				zval exists, results, value;				char *const_name;				if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) {					break;				}								ITypeInfo_GetNames(TypeInfo, pVarDesc->memid, &bstr_ids, 1, &NameCount);				if (NameCount != 1) {					ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);					continue;				}				const_name = php_OLECHAR_to_char(bstr_ids, &c.name_len, codepage TSRMLS_CC);				c.name = zend_strndup(const_name, c.name_len);				efree(const_name);				c.name_len++; /* length should include the NULL */				SysFreeString(bstr_ids);				/* Before registering the contsnt, let's see if we can find it */				if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) {					/* Oops, it already exists. No problem if it is defined as the same value */					/* Check to see if they are the same */					if (!compare_function(&results, &c.value, &exists TSRMLS_CC) && INI_INT("com.autoregister_verbose")) {						php_error(E_WARNING, "%s(): Type library value %s is already defined and has a different value", get_active_function_name(TSRMLS_C), c.name);					}					free(c.name);					ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);					continue;				}				php_variant_to_pval(pVarDesc->lpvarValue, &value, codepage TSRMLS_CC);				 /* we only import enumerations (=int) */				if (Z_TYPE(value) == IS_LONG) {					c.flags = mode;					c.value.type = IS_LONG;					c.value.value.lval = Z_LVAL(value);					c.module_number = 0; /* the module number is not available here */					zend_register_constant(&c TSRMLS_CC);				}				ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc);			}			ITypeInfo_Release(TypeInfo);		}	}	return SUCCESS;}/* {{{ proto bool com_isenum(object com_module)   Grabs an IEnumVariant */PHP_FUNCTION(com_isenum){	pval *object;	comval *obj;	if (ZEND_NUM_ARGS() != 1) {		ZEND_WRONG_PARAM_COUNT();	}	zend_get_parameters(ht, 1, &object);	/* obtain IDispatch interface */	FETCH_COM_SAFE(object, obj);	RETURN_BOOL(C_HASENUM(obj));}/* }}} */static void php_register_COM_class(TSRMLS_D){	INIT_OVERLOADED_CLASS_ENTRY(COM_class_entry, "COM", NULL,								php_COM_call_function_handler,								php_COM_get_property_handler,								php_COM_set_property_handler);	zend_register_internal_class(&COM_class_entry TSRMLS_CC);}static void php_COM_init(int module_number TSRMLS_DC){	le_comval = zend_register_list_destructors_ex(php_comval_destructor, NULL, "COM", module_number);	php_register_COM_class(TSRMLS_C);}PHPAPI ZEND_DECLARE_MODULE_GLOBALS(com)static void php_com_init_globals(zend_com_globals *com_globals){}PHP_MINIT_FUNCTION(COM){	ZEND_INIT_MODULE_GLOBALS(com, php_com_init_globals, NULL);	php_COM_init(module_number TSRMLS_CC);	php_VARIANT_init(module_number TSRMLS_CC);	php_COM_dispatch_init(module_number TSRMLS_CC);	REGISTER_LONG_CONSTANT("CLSCTX_INPROC_SERVER",  CLSCTX_INPROC_SERVER, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("CLSCTX_INPROC_HANDLER", CLSCTX_INPROC_HANDLER, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("CLSCTX_LOCAL_SERVER",   CLSCTX_LOCAL_SERVER, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("CLSCTX_REMOTE_SERVER",  CLSCTX_REMOTE_SERVER, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("CLSCTX_SERVER",         CLSCTX_SERVER, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("CLSCTX_ALL",            CLSCTX_ALL, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("DISPATCH_METHOD",		DISPATCH_METHOD, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYGET",	DISPATCH_PROPERTYGET, CONST_CS | CONST_PERSISTENT);	REGISTER_LONG_CONSTANT("DISPATCH_PROPERTYPUT",	DISPATCH_PROPERTYPUT, CONST_CS | CONST_PERSISTENT);	REGISTER_INI_ENTRIES();	return SUCCESS;}PHP_MSHUTDOWN_FUNCTION(COM){	UNREGISTER_INI_ENTRIES();	return SUCCESS;}/* exports for external object creation */zend_module_entry COM_module_entry = {    STANDARD_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -