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

📄 dispatch.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 The PHP Group                                |   +----------------------------------------------------------------------+   | This source file is subject to version 3.01 of the PHP license,      |   | that is bundled with this package in the file LICENSE, and is        |   | available through the world-wide-web at the following url:           |   | http://www.php.net/license/3_01.txt                                  |   | If you did not receive a copy of the PHP license and are unable to   |   | obtain it through the world-wide-web, please send a note to          |   | license@php.net so we can mail you a copy immediately.               |   +----------------------------------------------------------------------+   | Author: Wez Furlong <wez@thebrainroom.com>                           |   +----------------------------------------------------------------------+ *//* $Id: dispatch.c,v 1.3.6.2.4.2 2007/01/01 09:46:40 sebastian Exp $ *//*  * This module is used to export PHP objects to COM and DOTNET by exposing * them as objects implementing IDispatch. * */#include "php.h"#include "php_COM.h"#include "php_VARIANT.h"#include "conversion.h"#include "variant.h"#define COBJMACROS#include <unknwn.h> /* IDispatch */#include <dispex.h> /* IDispatchEx */typedef struct {	/* This first part MUST match the declaration	 * of interface IDispatchEx */	CONST_VTBL struct IDispatchExVtbl *lpVtbl;	/* now the PHP stuff */		THREAD_T engine_thread; /* for sanity checking */	zval *object;			/* the object exported */	LONG refcount;			/* COM reference count */	HashTable *dispid_to_name;	/* keep track of dispid -> name mappings */	HashTable *name_to_dispid;	/* keep track of name -> dispid mappings */	GUID sinkid;	/* iid that we "implement" for event sinking */		int id;} php_dispatchex;static void disp_destructor(php_dispatchex *disp);static void dispatch_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){	php_dispatchex *disp = (php_dispatchex *)rsrc->ptr;	disp_destructor(disp);}static int le_dispatch;int php_COM_dispatch_init(int module_number TSRMLS_DC){	le_dispatch = zend_register_list_destructors_ex(dispatch_dtor, NULL, "COM:Dispatch", module_number);	return le_dispatch;}/* {{{ trace */static inline void trace(char *fmt, ...){	va_list ap;	char buf[4096];	sprintf(buf, "T=%08x ", tsrm_thread_id());	OutputDebugString(buf);		va_start(ap, fmt);	vsnprintf(buf, sizeof(buf), fmt, ap);	OutputDebugString(buf);		va_end(ap);}/* }}} */#define FETCH_DISP(methname)	\	php_dispatchex *disp = (php_dispatchex*)This; \	trace(" PHP:%s %s\n", Z_OBJCE_P(disp->object)->name, methname); \	if (tsrm_thread_id() != disp->engine_thread) \		return E_UNEXPECTED;static HRESULT STDMETHODCALLTYPE disp_queryinterface( 	IDispatchEx *This,	/* [in] */ REFIID riid,	/* [iid_is][out] */ void **ppvObject){	FETCH_DISP("QueryInterface");	if (IsEqualGUID(&IID_IUnknown, riid) ||			IsEqualGUID(&IID_IDispatch, riid) ||			IsEqualGUID(&IID_IDispatchEx, riid) ||			IsEqualGUID(&disp->sinkid, riid)) {		*ppvObject = This;		InterlockedIncrement(&disp->refcount);		return S_OK;	}	*ppvObject = NULL;	return E_NOINTERFACE;}        static ULONG STDMETHODCALLTYPE disp_addref(IDispatchEx *This){	FETCH_DISP("AddRef");	return InterlockedIncrement(&disp->refcount);}        static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This){	ULONG ret;	TSRMLS_FETCH();	FETCH_DISP("Release");	ret = InterlockedDecrement(&disp->refcount);	trace("-- refcount now %d\n", ret);	if (ret == 0) {		/* destroy it */		if (disp->id)			zend_list_delete(disp->id);	}	return ret;}static HRESULT STDMETHODCALLTYPE disp_gettypeinfocount( 	IDispatchEx *This,	/* [out] */ UINT *pctinfo){	FETCH_DISP("GetTypeInfoCount");	*pctinfo = 0;	return S_OK;}        static HRESULT STDMETHODCALLTYPE disp_gettypeinfo( 	IDispatchEx *This,	/* [in] */ UINT iTInfo,	/* [in] */ LCID lcid,	/* [out] */ ITypeInfo **ppTInfo){	FETCH_DISP("GetTypeInfo");		*ppTInfo = NULL;	return DISP_E_BADINDEX;}static HRESULT STDMETHODCALLTYPE disp_getidsofnames( 	IDispatchEx *This,	/* [in] */ REFIID riid,	/* [size_is][in] */ LPOLESTR *rgszNames,	/* [in] */ UINT cNames,	/* [in] */ LCID lcid,	/* [size_is][out] */ DISPID *rgDispId){	UINT i;	HRESULT ret = S_OK;	TSRMLS_FETCH();	FETCH_DISP("GetIDsOfNames");	for (i = 0; i < cNames; i++) {		char *name;		unsigned int namelen;		zval **tmp;				name = php_OLECHAR_to_char(rgszNames[i], &namelen, CP_ACP TSRMLS_CC);				/* Lookup the name in the hash */		if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) {			ret = DISP_E_UNKNOWNNAME;			rgDispId[i] = 0;		} else {			rgDispId[i] = Z_LVAL_PP(tmp);		}		efree(name);	}		return ret;}static HRESULT STDMETHODCALLTYPE disp_invoke( 	IDispatchEx *This,	/* [in] */ DISPID dispIdMember,	/* [in] */ REFIID riid,	/* [in] */ LCID lcid,	/* [in] */ WORD wFlags,	/* [out][in] */ DISPPARAMS *pDispParams,	/* [out] */ VARIANT *pVarResult,	/* [out] */ EXCEPINFO *pExcepInfo,	/* [out] */ UINT *puArgErr){	return This->lpVtbl->InvokeEx(This, dispIdMember,			lcid, wFlags, pDispParams,			pVarResult, pExcepInfo, NULL);}static HRESULT STDMETHODCALLTYPE disp_getdispid( 	IDispatchEx *This,	/* [in] */ BSTR bstrName,	/* [in] */ DWORD grfdex,	/* [out] */ DISPID *pid){	HRESULT ret = DISP_E_UNKNOWNNAME;	char *name;	unsigned int namelen;	zval **tmp;	TSRMLS_FETCH();	FETCH_DISP("GetDispID");	name = php_OLECHAR_to_char(bstrName, &namelen, CP_ACP TSRMLS_CC);	/* Lookup the name in the hash */	if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) {		*pid = Z_LVAL_PP(tmp);		ret = S_OK;	}	efree(name);		return ret;}static HRESULT STDMETHODCALLTYPE disp_invokeex( 	IDispatchEx *This,	/* [in] */ DISPID id,	/* [in] */ LCID lcid,	/* [in] */ WORD wFlags,	/* [in] */ DISPPARAMS *pdp,	/* [out] */ VARIANT *pvarRes,	/* [out] */ EXCEPINFO *pei,	/* [unique][in] */ IServiceProvider *pspCaller){	zval **name;	UINT i;	int codepage = CP_ACP;	zval *retval = NULL;	zval ***params = NULL;	HRESULT ret = DISP_E_MEMBERNOTFOUND;	TSRMLS_FETCH();	FETCH_DISP("InvokeEx");	if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) {		/* TODO: add support for overloaded objects */		trace("-- Invoke: %d %20s flags=%08x args=%d\n", id, Z_STRVAL_PP(name), wFlags, pdp->cArgs);				/* convert args into zvals.		 * Args are in reverse order */		params = (zval ***)emalloc(sizeof(zval **) * pdp->cArgs);		for (i = 0; i < pdp->cArgs; i++) {			VARIANT *arg;			zval *zarg;						arg = &pdp->rgvarg[ pdp->cArgs - 1 - i];			trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg));			ALLOC_INIT_ZVAL(zarg);						if (V_VT(arg) == VT_DISPATCH) {				trace("arg %d is dispatchable\n", i);				if (NULL == php_COM_object_from_dispatch(V_DISPATCH(arg), zarg TSRMLS_CC)) {					trace("failed to convert arg %d to zval\n", i);					ZVAL_NULL(zarg);				}			} else {				/* arg can't be an idispatch, so we don't care for the implicit AddRef() call here */				if (FAILURE == php_variant_to_pval(arg, zarg, codepage TSRMLS_CC)) {					trace("failed to convert arg %d to zval\n", i);					ZVAL_NULL(zarg);				}			}						params[i] = &zarg;		}		trace("arguments processed, prepare to do some work\n");					if (wFlags & DISPATCH_PROPERTYGET) {			trace("trying to get a property\n");			zend_hash_find(Z_OBJPROP_P(disp->object), Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, (void**)&retval);		} else if (wFlags & DISPATCH_PROPERTYPUT) {			trace("trying to set a property\n");			add_property_zval(disp->object, Z_STRVAL_PP(name), *params[0]);		} else if (wFlags & DISPATCH_METHOD) {			trace("Trying to call user function\n");			if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name,					&retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) {				ret = S_OK;			} else {				ret = DISP_E_EXCEPTION;			}		} else {			trace("Don't know how to handle this invocation %08x\n", wFlags);		}			/* release arguments */		for (i = 0; i < pdp->cArgs; i++)

⌨️ 快捷键说明

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