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

📄 com.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	char *clsid_str;	int mode = 0;	ITypeLib *pTL;	CLSCTX flags = CLSCTX_SERVER;	codepage = CP_ACP;	switch (ZEND_NUM_ARGS()) {		case 1:			zend_get_parameters(ht, 1, &module_name);			break;		case 2:			zend_get_parameters(ht, 2, &module_name, &server_name);			break;		case 3:			zend_get_parameters(ht, 3, &module_name, &server_name, &code_page);			convert_to_long_ex(&code_page);			codepage = Z_LVAL_P(code_page);			break;		case 4:			zend_get_parameters(ht, 4, &module_name, &server_name, &code_page, &typelib);			convert_to_string_ex(&typelib);			convert_to_long_ex(&code_page);			codepage = Z_LVAL_P(code_page);			break;		default:			ZEND_WRONG_PARAM_COUNT();	}	if (server_name != NULL) {		/* What is server name? A String or an array? */		if (Z_TYPE_P(server_name) == IS_NULL) {			server_name = NULL;		} else if (Z_TYPE_P(server_name) == IS_ARRAY) {			pval **tmp;			/* DAB: 22 Sept 2001			 * Aha - we have a number of possible arguments.			 * They are in the hash By name: Server, Domain, Username, Password			 * Flags.			 * This has been crafted to maintian maximum backward compatability.			 * If the server name is specified as a string, then the function			 * should behave as before by defaulting username and password and			 * using the (I believe) incorrect CLSCTX_SERVER instantiation			 * paramter. However if server is specified in this array then we			 * use either CLSCTX_REMOTE_SERVER or whatever flags are specified			 * in the array */			HashTable *ht = Z_ARRVAL(*server_name);			if (FAILURE == zend_hash_find(ht, "Server", 7, (void **) &tmp)) {				server_name = NULL;			} else {				server_name = *tmp;				convert_to_string_ex(&server_name);				/* CLSCTX_SERVER includes INPROC and LOCAL SERVER. This means				 * that any local server will be instantiated BEFORE even				 * looking on a remote server. Thus if we have a server name,				 * probably we want to access a remote machine or we would not				 * have bothered specifying it. So it would be wrong to to				 * connect locally. Futher, unless the name passed is a GUID,				 * there has to be something to map the Prog.Id to GUID and				 * unless that has been modified to remove the information				 * about local instantiation CLSCTX_SERVER would force a local				 * instantiation This setting can be overridden below if the				 * user specifies a flags element */				flags = CLSCTX_REMOTE_SERVER;			}			if (FAILURE == zend_hash_find(ht, "Username", 9, (void **) &tmp)) {				user_name = NULL;			} else {				user_name = *tmp;				convert_to_string_ex(&user_name);			}			if (FAILURE == zend_hash_find(ht, "Domain", 7, (void **) &tmp)) {				domain = NULL;			} else {				domain = *tmp;				convert_to_string_ex(&domain);			}			if (FAILURE == zend_hash_find(ht, "Password", 9, (void **) &tmp)) {				password=NULL;			} else {				password = *tmp;				convert_to_string_ex(&password);			}			if (SUCCESS == zend_hash_find(ht, "Flags", 6, (void **) &tmp)) {				convert_to_long_ex(tmp);				flags = (CLSCTX) Z_LVAL_PP(tmp);			}		} else {			if (!INI_INT("com.allow_dcom")) {				php_error(E_WARNING, "%s(): DCOM is disabled", get_active_function_name(TSRMLS_C));				RETURN_NULL();			} else {				flags = CLSCTX_REMOTE_SERVER;				convert_to_string_ex(&server_name);			}		}	}	ALLOC_COM(obj);	convert_to_string_ex(&module_name);	ProgID = php_char_to_OLECHAR(Z_STRVAL_P(module_name), Z_STRLEN_P(module_name), codepage TSRMLS_CC);	/* obtain CLSID */	if (FAILED(CLSIDFromString(ProgID, &clsid))) {		/* Perhaps this is a Moniker? */		IBindCtx *pBindCtx;		IMoniker *pMoniker;		ULONG ulEaten;		/* @todo if (server_name) */		if (!server_name) {			/* @todo shouldn't the bind context be fetched on module startup and kept as a global shared instance ?			 * all calls to BindToObject would deliver the same instance then (as desired)			 * IBindCtx::RegisterObjectBound() should be called then after  mkparsedisplayname()			 *			 * @todo use mkparsedisplaynameex() ?			 */ 			if (SUCCEEDED(hr = CreateBindCtx(0, &pBindCtx))) {				if (SUCCEEDED(hr = MkParseDisplayName(pBindCtx, ProgID, &ulEaten, &pMoniker))) {					hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));					pMoniker->lpVtbl->Release(pMoniker);				}				pBindCtx->lpVtbl->Release(pBindCtx);			}		} else {			hr = MK_E_SYNTAX;		}		efree(ProgID);		if (FAILED(hr)) {			php_COM_destruct(obj TSRMLS_CC);			error_message = php_COM_error_message(hr TSRMLS_CC);  			php_error(E_WARNING, "%s(): Invalid ProgID, GUID string, or Moniker: %s", get_active_function_name(TSRMLS_C), error_message);			LocalFree(error_message);			RETURN_NULL();		}	} else {		efree(ProgID);		/* obtain IDispatch */		if (!server_name) {			hr = CoCreateInstance(&clsid, NULL, flags, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));		} else {			COSERVERINFO server_info;			MULTI_QI pResults;			COAUTHIDENTITY authid;			COAUTHINFO authinfo = {RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, &authid, EOAC_NONE};			server_info.dwReserved1=0;			server_info.dwReserved2=0;			server_info.pwszName = php_char_to_OLECHAR(Z_STRVAL_P(server_name), Z_STRLEN_P(server_name), codepage TSRMLS_CC);			if (user_name) {				/* Z_STRVAL_P(user_name); */				/* Parse Username into domain\username */				authid.User = (WCHAR *) Z_STRVAL_P(user_name);				authid.UserLength = Z_STRLEN_P(user_name);				if (password) {					authid.Password = (USHORT *) Z_STRVAL_P(password);					authid.PasswordLength = Z_STRLEN_P(password);				} else {					authid.Password = (USHORT *) "";					authid.PasswordLength = 0;				}				if (domain) {					authid.Domain = (USHORT *) Z_STRVAL_P(domain);					authid.DomainLength = Z_STRLEN_P(domain);				} else {					authid.Domain = (USHORT *) "";					authid.DomainLength = 0;				}				authid.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;				server_info.pAuthInfo=&authinfo;			} else {				server_info.pAuthInfo=NULL;			}			pResults.pIID = &IID_IDispatch;			pResults.pItf = NULL;			pResults.hr = S_OK;			hr=CoCreateInstanceEx(&clsid, NULL, flags, &server_info, 1, &pResults);			if (SUCCEEDED(hr)) {				hr = pResults.hr;				C_DISPATCH(obj) = (IDispatch *) pResults.pItf;			}			efree(server_info.pwszName);		}		if (FAILED(hr)) {			error_message = php_COM_error_message(hr TSRMLS_CC);			clsid_str = php_string_from_clsid(&clsid TSRMLS_CC);			php_error(E_WARNING, "%s(): Unable to obtain IDispatch interface for CLSID %s: %s", get_active_function_name(TSRMLS_C), clsid_str, error_message);			LocalFree(error_message);			efree(clsid_str);			php_COM_destruct(obj TSRMLS_CC);			RETURN_NULL();		}	}	php_COM_set(obj, &C_DISPATCH(obj), TRUE TSRMLS_CC);	if (INI_INT("com.autoregister_casesensitive")) {		mode |= CONST_CS;	}	if (C_HASTLIB(obj)) {		if (INI_INT("com.autoregister_typelib")) {			unsigned int idx;			/* @todo check if typlib isn't already loaded */			if (C_TYPEINFO_VT(obj)->GetContainingTypeLib(C_TYPEINFO(obj), &pTL, &idx) == S_OK) {				php_COM_load_typelib(pTL, mode TSRMLS_CC);				pTL->lpVtbl->Release(pTL);			}		}	} else {		if (typelib != NULL) {			ITypeLib *pTL;			if ((pTL = php_COM_find_typelib(Z_STRVAL_P(typelib), mode TSRMLS_CC)) != NULL) {				C_HASTLIB(obj) = SUCCEEDED(pTL->lpVtbl->GetTypeInfo(pTL, 0, &C_TYPEINFO(obj)));				/* idx 0 should deliver the ITypeInfo for the IDispatch Interface */				if (INI_INT("com.autoregister_typelib")) {					php_COM_load_typelib(pTL, mode TSRMLS_CC);				}				pTL->lpVtbl->Release(pTL);			}		}	}	RETVAL_COM(obj);}/* }}} */static int do_COM_invoke(comval *obj, WORD dispflags, pval *function_name, VARIANT *var_result, pval **arguments, int arg_count TSRMLS_DC){	DISPID dispid, altdispid;	DISPPARAMS dispparams;	HRESULT hr;	OLECHAR *funcname;	SAFEARRAY *pSA;	SAFEARRAYBOUND rgsabound[1];	VARIANT *variant_args;	char *error_message;	int current_arg, current_variant;	unsigned long count; 	if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "next")) {		/* Grab one argument off the stack, allocate enough		 * VARIANTs		 * Get the IEnumVariant interface and call ->Next();		 */		switch (arg_count) {			case 0:				count = 1;				break;			case 1:				convert_to_long_ex(&arguments[0]);				count = Z_LVAL_P(arguments[0]);				break;			default:				php_error(E_WARNING, "%s(): Wrong argument count to IEnumVariant::Next()", get_active_function_name(TSRMLS_C));				return FAILURE;		}		rgsabound[0].lLbound = 0;		rgsabound[0].cElements = count;		if ((pSA = SafeArrayCreate(VT_VARIANT, 1, rgsabound)) == NULL) {			VariantInit(var_result);			return FAILURE;		} else {			V_ARRAY(var_result) = pSA;			V_VT(var_result) = VT_VARIANT|VT_ARRAY;		}		if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Next(C_ENUMVARIANT(obj), count, pSA->pvData, &count))) {			char *error_message = php_COM_error_message(hr TSRMLS_CC);			php_error(E_WARNING, "%s(): IEnumVariant::Next() failed: %s", get_active_function_name(TSRMLS_C), error_message);			efree(error_message);			VariantClear(var_result);			return FAILURE;		}		if (count != rgsabound[0].cElements) {			rgsabound[0].cElements = count;			if (FAILED(SafeArrayRedim(pSA, rgsabound))) {				char *error_message = php_COM_error_message(hr TSRMLS_CC);				php_error(E_WARNING, "%s(): IEnumVariant::Next() failed: %s", get_active_function_name(TSRMLS_C), error_message);				efree(error_message);				VariantClear(var_result);				return FAILURE;			}		}		/* return a single element if next() was called without count */		if ((arg_count == 0) && (count == 1)) {			long index[] = {0};			SafeArrayGetElement(pSA, index, var_result);			SafeArrayDestroy(pSA);		}		return SUCCESS;	} else if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "all")) {#define FETCH_BLOCKSIZE 10 /* fetch blocks of 10 elements */		count = FETCH_BLOCKSIZE;		rgsabound[0].lLbound = 0;		rgsabound[0].cElements = count;		if ((pSA = SafeArrayCreate(VT_VARIANT, 1, rgsabound)) == NULL) {			VariantInit(var_result);			return FAILURE;		} else {			V_ARRAY(var_result) = pSA;			V_VT(var_result) = VT_VARIANT|VT_ARRAY;		}		/* blah*/	} else if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "reset")) {		if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Reset(C_ENUMVARIANT(obj)))) {			char *error_message = php_COM_error_message(hr TSRMLS_CC);			php_error(E_WARNING,"%s(): IEnumVariant::Next() failed: %s", get_active_function_name(TSRMLS_C), error_message);			efree(error_message);			return FAILURE;		}		return SUCCESS;	} else if (C_HASENUM(obj) && strstr(Z_STRVAL_P(function_name), "skip")) {		unsigned long count;		switch (arg_count) {			case 0:				count = 1;				break;			case 1:				convert_to_long_ex(&arguments[0]);				count = Z_LVAL_P(arguments[0]);				break;			default:				php_error(E_WARNING, "%s(): Wrong argument count to IEnumVariant::Skip()", get_active_function_name(TSRMLS_C));				return FAILURE;		}		if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Skip(C_ENUMVARIANT(obj), count))) {			char *error_message = php_COM_error_message(hr TSRMLS_CC);			php_error(E_WARNING,"%s(): IEnumVariant::Next() failed: %s", get_active_function_name(TSRMLS_C), error_message);			efree(error_message);			return FAILURE;		}		return SUCCESS;	} else {		char *ErrString;		funcname = php_char_to_OLECHAR(Z_STRVAL_P(function_name), Z_STRLEN_P(function_name), codepage TSRMLS_CC);		hr = php_COM_get_ids_of_names(obj, &funcname, &dispid TSRMLS_CC);		if (FAILED(hr)) {			error_message = php_COM_error_message(hr TSRMLS_CC);			php_error(E_WARNING, "%s(): Unable to lookup %s: %s", get_active_function_name(TSRMLS_C), Z_STRVAL_P(function_name), error_message);			LocalFree(error_message);			efree(funcname);			return FAILURE;		}		variant_args = (VARIANT *) emalloc(sizeof(VARIANT) * arg_count);		for (current_arg=0; current_arg<arg_count; current_arg++) {			current_variant = arg_count - current_arg - 1;			php_pval_to_variant(arguments[current_arg], &variant_args[current_variant], codepage TSRMLS_CC);		}		dispparams.rgvarg = variant_args;		dispparams.rgdispidNamedArgs = NULL;		dispparams.cArgs = arg_count;		dispparams.cNamedArgs = 0;		if (dispflags & DISPATCH_PROPERTYPUT) {			/* Make this work for property set-ing */			altdispid = DISPID_PROPERTYPUT;			dispparams.rgdispidNamedArgs = &altdispid;			dispparams.cNamedArgs = 1;		}		hr = php_COM_invoke(obj, dispid, dispflags, &dispparams, var_result, &ErrString TSRMLS_CC);		efree(funcname);		for (current_arg=0;current_arg<arg_count;current_arg++) {			/* don't release IDispatch pointers as they are used afterwards */			if (V_VT(&(variant_args[current_arg])) != VT_DISPATCH) {				/* @todo review this: what happens to an array of IDispatchs or a VARIANT->IDispatch */				VariantClear(&variant_args[current_arg]);			}		}		efree(variant_args);		if (FAILED(hr)) {			error_message = php_COM_error_message(hr TSRMLS_CC);			if (ErrString) {				php_error(E_WARNING, "%s(): Invoke() failed: %s %s", get_active_function_name(TSRMLS_C), error_message, ErrString);				pefree(ErrString, 1);			} else {				php_error(E_WARNING, "%s(): Invoke() failed: %s", get_active_function_name(TSRMLS_C), error_message);			}			LocalFree(error_message);			return FAILURE;		}	}	return SUCCESS;}/* {{{ proto mixed com_invoke_ex(int module, int invokeflags, string handler_name [, mixed arg [, mixed ...]])   Invokes a COM module */PHP_FUNCTION(com_invoke_ex){	pval **arguments;	pval *object, *function_name, *invokeflags;	comval *obj = NULL;	WORD dispflags = 0;	int arg_count = ZEND_NUM_ARGS();	VARIANT *var_result;	if (arg_count<3) {		ZEND_WRONG_PARAM_COUNT();	}	arguments = (pval **) emalloc(sizeof(pval *)*arg_count);	if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) {		RETURN_NULL();	}	object = arguments[0];	function_name = arguments[2];	invokeflags = arguments[1];	/* obtain property/method handler */	convert_to_string_ex(&function_name);	convert_to_long(invokeflags);	dispflags = (WORD)Z_LVAL_P(invokeflags);	/* obtain IDispatch interface */	FETCH_COM_SAFE(object, obj);	ALLOC_VARIANT(var_result);	if (do_COM_invoke(obj, dispflags, function_name, var_result, arguments+3, arg_count-3 TSRMLS_CC)==FAILURE) {		FREE_VARIANT(var_result);		efree(arguments);		RETURN_NULL();	}

⌨️ 快捷键说明

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