summaryrefslogtreecommitdiff
path: root/ext/rpc/com/com.c
diff options
context:
space:
mode:
authorSterling Hughes <sterling@php.net>2003-06-25 00:28:10 +0000
committerSterling Hughes <sterling@php.net>2003-06-25 00:28:10 +0000
commit09927a7ba242e7d48100bf7cd43824c5528d5792 (patch)
treed47efdc84c7deb6e12e8deaa5dcf321f837a08b5 /ext/rpc/com/com.c
parent211ca9d9e59152438b236fbbf679cac975decc51 (diff)
downloadphp-git-09927a7ba242e7d48100bf7cd43824c5528d5792.tar.gz
moved to pecl by sascha. remove them from head.
discussed with harald, will remain in pecl till he has some more time to work on it.
Diffstat (limited to 'ext/rpc/com/com.c')
-rw-r--r--ext/rpc/com/com.c1362
1 files changed, 0 insertions, 1362 deletions
diff --git a/ext/rpc/com/com.c b/ext/rpc/com/com.c
deleted file mode 100644
index 9f4db552b3..0000000000
--- a/ext/rpc/com/com.c
+++ /dev/null
@@ -1,1362 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 4 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2003 The PHP Group |
- +----------------------------------------------------------------------+
- | This source file is subject to version 3.0 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_0.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: Harald Radi <h.radi@nme.at> |
- +----------------------------------------------------------------------+
- */
-
-#define _WIN32_DCOM
-#define COBJMACROS
-
-#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
-
-#include "../rpc.h"
-#include "../handler.h"
-
-#include "com.h"
-#include "com_wrapper.h"
-#include "conversion.h"
-#include "variant.h"
-#include "ext/standard/php_smart_str.h"
-#include <oleauto.h>
-#include <ocidl.h>
-
-
-static ZEND_FUNCTION(com_indexed_prop_set);
-static ZEND_FUNCTION(com_create_guid);
-
-/* protos */
-static int com_hash(rpc_string, rpc_string *, void *, int, char *, int);
-static int com_name(rpc_string, rpc_string *, void *, int);
-static int com_ctor(rpc_string, void **, int , zval ***);
-static int com_dtor(void *);
-static int com_describe(rpc_string, void *, char **, unsigned char **);
-static int com_call(rpc_string, void *, zval *, int, zval ***);
-static int com_get(rpc_string, zval *, void *);
-static int com_set(rpc_string, zval *, void *);
-static int com_compare(void *, void *);
-static int com_has_property(rpc_string, void *);
-static int com_unset_property(rpc_string, void *);
-static int com_get_properties(HashTable **, void *);
-
-static ZEND_INI_MH(com_typelib_file_change);
-
-/* globals */
-static IBindCtx *pBindCtx;
-static unsigned char arg1and2_force_ref[] = { 2, BYREF_FORCE, BYREF_FORCE };
-
-/* register rpc callback function */
-RPC_REGISTER_HANDLERS_BEGIN(com)
-TRUE, /* poolable */
-HASH_AS_INT_WITH_SIGNATURE,
-com_hash,
-com_name,
-com_ctor,
-com_dtor,
-com_describe,
-com_call,
-com_get,
-com_set,
-com_compare,
-com_has_property,
-com_unset_property,
-com_get_properties
-RPC_REGISTER_HANDLERS_END()
-
-/* register ini settings */
-PHP_INI_BEGIN()
-PHP_INI_ENTRY_EX("com.allow_dcom", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb)
-PHP_INI_ENTRY_EX("com.autoregister_typelib", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb)
-PHP_INI_ENTRY_EX("com.autoregister_verbose", "0", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb)
-PHP_INI_ENTRY_EX("com.autoregister_casesensitive", "1", PHP_INI_SYSTEM, NULL, php_ini_boolean_displayer_cb)
-PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, com_typelib_file_change)
-PHP_INI_END()
-
-/* register userspace functions */
-RPC_FUNCTION_ENTRY_BEGIN(com)
- ZEND_FALIAS(com_invoke, rpc_call, NULL)
- ZEND_FE(com_addref, NULL)
- ZEND_FE(com_release, NULL)
- ZEND_FE(com_next, NULL)
- ZEND_FE(com_all, NULL)
- ZEND_FE(com_reset, NULL)
- 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)
- ZEND_FE(com_indexed_prop_set, NULL)
- ZEND_FE(com_create_guid, NULL)
-RPC_FUNCTION_ENTRY_END()
-
-zend_module_entry com_module_entry = {
- ZE2_STANDARD_MODULE_HEADER,
- "com",
- RPC_FUNCTION_ENTRY(com),
- ZEND_MINIT(com),
- ZEND_MSHUTDOWN(com),
- NULL,
- NULL,
- ZEND_MINFO(com),
- "0.1a",
- STANDARD_MODULE_PROPERTIES
-};
-
-/* register class methods */
-RPC_METHOD_ENTRY_BEGIN(com)
- ZEND_FALIAS(addref, com_addref, NULL)
- ZEND_FALIAS(release, com_release, NULL)
- ZEND_FALIAS(next, com_next, NULL)
- ZEND_FALIAS(all, com_all, NULL)
- ZEND_FALIAS(reset, com_reset, NULL)
- ZEND_FALIAS(skip, com_skip, NULL)
-RPC_METHOD_ENTRY_END()
-
-
-ZEND_MINIT_FUNCTION(com)
-{
- CreateBindCtx(0, &pBindCtx);
- php_variant_init(module_number TSRMLS_CC);
-
- RPC_REGISTER_LAYER(com);
- REGISTER_INI_ENTRIES();
-
- return SUCCESS;
-}
-
-ZEND_MSHUTDOWN_FUNCTION(com)
-{
- php_variant_shutdown(TSRMLS_C);
- pBindCtx->lpVtbl->Release(pBindCtx);
-
- UNREGISTER_INI_ENTRIES();
-
- return SUCCESS;
-}
-
-ZEND_MINFO_FUNCTION(com)
-{
- DISPLAY_INI_ENTRIES();
-}
-
-#ifdef COMPILE_DL_COM
-ZEND_GET_MODULE(com);
-#endif
-
-/* rpc handler functions */
-
-static int com_hash(rpc_string name, rpc_string *hash, void *data, int num_args, char *arg_types, int type)
-{
- switch (type) {
- case CLASS:
- {
- CLSID *clsid = malloc(sizeof(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;
- }
-
- efree(olestr);
- } else {
- 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);
- }
- }
-
- 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;
- }
-
- case METHOD:
- 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.
- * nevertheless dispid is freed by the rpc_string_dtor
- */
- hash->len = 0;
-
- efree(olestr);
-
- return SUCCESS;
- } else {
- free(dispid);
- efree(olestr);
-
- return FAILURE;
- }
- }
- }
-
- return FAILURE;
-}
-
-static int com_name(rpc_string hash, rpc_string *name, void *data, int type)
-{
- if (hash.len != 0) {
- /* not a GUID, perhaps a Moniker */
- name->str = strdup(hash.str);
- name->len = hash.len;
-
- return SUCCESS;
- } else {
- switch (type) {
- case CLASS:
- {
- CLSID clsid;
- OLECHAR *olestr;
-
- 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:
- case PROPERTY:
- /* not used yet */
- break;
- }
- }
-
- return FAILURE;
-}
-
-static int com_ctor(rpc_string class_name, void **data, int num_args, zval **args[])
-{
- zval **server_name = NULL;
- zval **code_page = NULL;
- zval **typelib = NULL;
- zval **user_name=NULL;
- zval **password=NULL;
- zval **domain=NULL;
- int mode = 0;
- comval *obj;
- HRESULT hr;
- CLSCTX flags = CLSCTX_SERVER;
-
- switch (num_args) {
- case 3:
- typelib = args[2];
- convert_to_string_ex(typelib);
- /* break missing intentionally */
- case 2:
- code_page = args[1];
- convert_to_long_ex(code_page);
- /* break missing intentionally */
- case 1:
- server_name = args[0];
- /* break missing intentionally */
- break;
-
- case 0:
- /* nothing to do */
- break;
-
- default:
- /* exception */
- return FAILURE;
- }
-
- if (server_name != NULL) {
- /* What is server name? A String or an array? */
- if (Z_TYPE_PP(server_name) == IS_NULL) {
- server_name = NULL;
- } else if (Z_TYPE_PP(server_name) == IS_ARRAY) {
- zval **tmp;
- /* 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_PP(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);
- }
- }
-
- if (server_name != NULL) {
- if (!INI_INT("com.allow_dcom")) {
- rpc_error(E_WARNING, "DCOM is disabled");
- return FAILURE;
- } else {
- flags = CLSCTX_REMOTE_SERVER;
- convert_to_string_ex(server_name);
- }
- }
- }
-
- ALLOC_COM(obj);
- *data = obj;
-
- if (code_page != NULL) {
- C_CODEPAGE(obj) = Z_LVAL_PP(code_page);
- }
-
- if (class_name.len) {
- /* Perhaps this is a Moniker? */
- IMoniker *pMoniker;
- ULONG ulEaten;
-
- if (server_name) {
- hr = MK_E_SYNTAX;
- } else {
- OLECHAR *olestr = php_char_to_OLECHAR(class_name.str, class_name.len, C_CODEPAGE(obj), FALSE);
-
- if (SUCCEEDED(hr = MkParseDisplayNameEx(pBindCtx, olestr, &ulEaten, &pMoniker))) {
- hr = pMoniker->lpVtbl->BindToObject(pMoniker, pBindCtx, NULL, &IID_IDispatch, (LPVOID *) &C_DISPATCH(obj));
- pMoniker->lpVtbl->Release(pMoniker);
- }
-
- efree(olestr);
- }
-
- if (FAILED(hr)) {
- char *error_message;
-
- php_COM_destruct(obj);
- error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"Invalid ProgID, GUID string, or Moniker: %s", error_message);
- LocalFree(error_message);
-
- return FAILURE;
- }
- } else {
- /* obtain IDispatch */
- if (!server_name) {
- hr = CoCreateInstance((CLSID *) class_name.str, 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_PP(server_name), Z_STRLEN_PP(server_name), C_CODEPAGE(obj), FALSE);
- if (user_name) {
- /* Parse Username into domain\username */
- authid.User = (WCHAR *) Z_STRVAL_PP(user_name);
- authid.UserLength = Z_STRLEN_PP(user_name);
- if (password) {
- authid.Password = (USHORT *) Z_STRVAL_PP(password);
- authid.PasswordLength = Z_STRLEN_PP(password);
- } else {
- authid.Password = (USHORT *) "";
- authid.PasswordLength = 0;
- }
- if (domain) {
- authid.Domain = (USHORT *) Z_STRVAL_PP(domain);
- authid.DomainLength = Z_STRLEN_PP(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 *) class_name.str, 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)) {
- char *error_message, *clsid;
-
- php_COM_destruct(obj);
- error_message = php_COM_error_message(hr);
- clsid = php_COM_string_from_CLSID((CLSID *)class_name.str);
- rpc_error(E_WARNING,"Unable to obtain IDispatch interface for CLSID %s: %s", clsid, error_message);
- LocalFree(error_message);
- efree(clsid);
-
- return FAILURE;
- }
- }
-
- php_COM_set(obj, &C_DISPATCH(obj), TRUE);
-
- if (INI_INT("com.autoregister_casesensitive")) {
- mode |= CONST_CS;
- }
-
- if (C_HASTLIB(obj)) {
- if (INI_INT("com.autoregister_typelib")) {
- ITypeLib *pTL;
- 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);
- pTL->lpVtbl->Release(pTL);
- }
- }
- } else {
- if (typelib != NULL) {
- ITypeLib *pTL;
-
- if ((pTL = php_COM_find_typelib(Z_STRVAL_PP(typelib), mode)) != 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);
- }
- pTL->lpVtbl->Release(pTL);
- }
- }
- }
-
- return SUCCESS;
-}
-
-static int com_dtor(void *data)
-{
- php_COM_destruct((comval *) data);
-
- return SUCCESS;
-}
-
-static inline void vt_type_to_zpp_string(ELEMDESC *elem, smart_str *argtypes_str, unsigned char *argflags)
-{
- int ref = 0;
- int nullable = 0;
- char zppflag = 'z';
- WORD vt, flags;
-
- vt = elem->tdesc.vt;
- flags = elem->paramdesc.wParamFlags;
-
- if (vt == VT_PTR) {
- nullable = 1;
- ref = 0;
- vt = elem->tdesc.lptdesc->vt;
- } else {
- ref = vt & VT_BYREF;
- }
-
- if (vt & VT_ARRAY) {
- zppflag = 'a';
- } else {
- switch(vt & ~(VT_BYREF | VT_ARRAY)) {
- case VT_UI1:
- case VT_UI2:
- case VT_UI4:
- case VT_I1:
- case VT_I2:
- case VT_I4:
- zppflag = 'l';
- break;
-
- case VT_R8:
- case VT_CY:
- case VT_DATE:
- zppflag = 'd';
- break;
-
- case VT_BSTR:
- zppflag = 's';
- break;
-
- case VT_BOOL:
- zppflag = 'b';
- break;
-
- case VT_DISPATCH:
- case VT_UNKNOWN:
- zppflag = 'o';
- break;
-
- case VT_VARIANT:
- default:
- zppflag = 'z';
-
- }
- }
-
- if (ref) {
- smart_str_appendl(argtypes_str, "z/", 2);
- *argflags = BYREF_FORCE;
- } else {
- *argflags = BYREF_NONE;
- if (nullable) {
- smart_str_appendl(argtypes_str, "!", 1);
- }
- }
-}
-
-static int com_describe(rpc_string method_name, void *data, char **arg_types, unsigned char **ref_types)
-{
- rpc_internal *intern;
- comval *obj;
- ITypeInfo *typeinfo;
- FUNCDESC *funcdesc;
- MEMBERID fid;
- OLECHAR *olename;
- int retval = FAILURE, arg_count;
- int i, type_len = 0;
- smart_str argtypes_str = {0};
- unsigned char *func_arg_types;
- TSRMLS_FETCH();
-
- GET_INTERNAL_EX(intern, data);
- obj = (comval*)data;
-
- 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))) {
-
- arg_count = funcdesc->cParams + (funcdesc->cParamsOpt == -1 ? 1 : funcdesc->cParamsOpt);
-
- func_arg_types = (unsigned char*)malloc((1 + arg_count) * sizeof(unsigned char));
-
- func_arg_types[0] = arg_count;
-
- /* required parameters first */
- for (i = 0; i < funcdesc->cParams; i++) {
- ELEMDESC *elem = &funcdesc->lprgelemdescParam[i];
-
- vt_type_to_zpp_string(elem, &argtypes_str, &func_arg_types[i+1]);
- }
-
- if (funcdesc->cParamsOpt == -1) {
- /* needs to be a SAFEARRAY of VARIANTS */
- smart_str_appendl(&argtypes_str, "|z", 2);
- func_arg_types[funcdesc->cParams+1] = BYREF_NONE;
- } else if (funcdesc->cParamsOpt > 0) {
- smart_str_appendl(&argtypes_str, "|", 1);
-
- for (i = funcdesc->cParams; i < funcdesc->cParams + funcdesc->cParamsOpt; i++) {
- ELEMDESC *elem = &funcdesc->lprgelemdescParam[i];
-
- vt_type_to_zpp_string(elem, &argtypes_str, &func_arg_types[i+1]);
- }
- }
-
- *ref_types = func_arg_types;
- smart_str_0(&argtypes_str);
- *arg_types = strdup(argtypes_str.c);
- smart_str_free(&argtypes_str);
-
- retval = SUCCESS;
- ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc);
- }
-
- efree(olename);
-
- return retval;
-}
-
-static int com_call(rpc_string method_name, void *data, zval *return_value, int num_args, zval **args[])
-{
- DISPPARAMS dispparams;
- HRESULT hr;
- OLECHAR *funcname = NULL;
- VARIANT *variant_args;
- VARIANT result;
- int current_arg, current_variant;
- char *ErrString = NULL;
- TSRMLS_FETCH();
-
- /* if the length of the name is 0, we are dealing with a pointer to a dispid */
- assert(method_name.len == 0);
-
- variant_args = num_args ? (VARIANT *) emalloc(sizeof(VARIANT) * num_args) : NULL;
-
- for (current_arg = 0; current_arg < num_args; current_arg++) {
- current_variant = num_args - current_arg - 1;
- php_zval_to_variant(*args[current_arg], &variant_args[current_variant], C_CODEPAGE((comval *) data) TSRMLS_CC);
- }
-
- dispparams.rgvarg = variant_args;
- dispparams.rgdispidNamedArgs = NULL;
- dispparams.cArgs = num_args;
- dispparams.cNamedArgs = 0;
-
- VariantInit(&result);
-
- hr = php_COM_invoke((comval *) data, *(DISPID*)method_name.str, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &dispparams, &result, &ErrString);
-
- for (current_arg=0;current_arg<num_args;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]);
- }
- }
-
- if (variant_args) {
- efree(variant_args);
- variant_args = NULL;
- }
-
- if (FAILED(hr)) {
- char *error_message;
-
- error_message = php_COM_error_message(hr);
- if (ErrString) {
- rpc_error(E_WARNING,"Invoke() failed: %s %s", error_message, ErrString);
- efree(ErrString);
- } else {
- rpc_error(E_WARNING,"Invoke() failed: %s", error_message);
- }
- LocalFree(error_message);
- return FAILURE;
- }
-
- RETVAL_VARIANT(&result, C_CODEPAGE((comval *) data));
-
- return SUCCESS;
-}
-
-static int com_get(rpc_string property_name, zval *return_value, void *data)
-{
- char *ErrString = NULL;
- VARIANT *result;
- DISPPARAMS dispparams;
- HRESULT hr;
-
- result = (VARIANT *) emalloc(sizeof(VARIANT));
- VariantInit(result);
-
- dispparams.cArgs = 0;
- dispparams.cNamedArgs = 0;
-
- if (FAILED(hr = php_COM_invoke((comval *) data, *((DISPID *) property_name.str), DISPATCH_PROPERTYGET, &dispparams, result, &ErrString))) {
- char *error_message;
-
- efree(result);
- error_message = php_COM_error_message(hr);
- if (ErrString != NULL) {
- rpc_error(E_WARNING,"PropGet() failed: %s %s", error_message, ErrString);
- efree(ErrString);
- } else {
- rpc_error(E_WARNING,"PropGet() failed: %s", error_message);
- }
- LocalFree(error_message);
-
- return FAILURE;
- }
-
- if (V_VT(result) == VT_DISPATCH) {
- RETVAL_VARIANT(result, C_CODEPAGE((comval *) data));
- } else {
- comval *foo = (comval *) data;
- php_variant_to_zval(result, return_value, C_CODEPAGE(foo));
- VariantClear(result);
- }
-
- efree(result);
-
- return SUCCESS;
-}
-
-static int com_set(rpc_string property_name, zval *value, void *data)
-{
- HRESULT hr;
- DISPID mydispid = DISPID_PROPERTYPUT;
- DISPPARAMS dispparams;
- VARIANT *var;
- char *error_message, *ErrString = NULL;
- TSRMLS_FETCH();
-
- var = (VARIANT *) emalloc(sizeof(VARIANT));
- VariantInit(var);
-
- php_zval_to_variant(value, var, C_CODEPAGE((comval *) data) TSRMLS_CC);
- dispparams.rgvarg = var;
- dispparams.rgdispidNamedArgs = &mydispid;
- dispparams.cArgs = 1;
- dispparams.cNamedArgs = 1;
-
- if (FAILED(hr = php_COM_invoke((comval *) data, *(DISPID*)property_name.str, DISPATCH_PROPERTYPUT, &dispparams, NULL, &ErrString))) {
- error_message = php_COM_error_message(hr);
- if (ErrString) {
- rpc_error(E_WARNING,"PropPut() failed: %s %s", error_message, ErrString);
- efree(ErrString);
- } else {
- rpc_error(E_WARNING,"PropPut() failed: %s", error_message);
- }
- LocalFree(error_message);
- VariantClear(var);
- efree(var);
-
- return FAILURE;
- }
-
-
- VariantClear(var);
- efree(var);
-
- return SUCCESS;
-}
-
-static int com_compare(void *data1, void *data2)
-{
- return SUCCESS;
-}
-
-static int com_has_property(rpc_string property_name, void *data)
-{
- return SUCCESS;
-}
-
-static int com_unset_property(rpc_string property_name, void *data)
-{
- return SUCCESS;
-}
-
-static int com_get_properties(HashTable **properties, void *data)
-{
- return SUCCESS;
-}
-
-
-/* custom functions */
-
-static ZEND_FUNCTION(com_create_guid)
-{
- GUID retval;
- OLECHAR *guid_string;
-
- if (ZEND_NUM_ARGS() != 0) {
- ZEND_WRONG_PARAM_COUNT();
- }
-
- if (CoCreateGuid(&retval) == S_OK && StringFromCLSID(&retval, &guid_string) == S_OK) {
- Z_TYPE_P(return_value) = IS_STRING;
- Z_STRVAL_P(return_value) = php_OLECHAR_to_char(guid_string, &Z_STRLEN_P(return_value), CP_ACP, 0);
-
- CoTaskMemFree(guid_string);
- } else {
- RETURN_FALSE;
- }
-}
-
-
-
-static ZEND_FUNCTION(com_indexed_prop_set)
-{
- zval *object;
- rpc_internal *intern;
- char *propname;
- long propname_len;
- zval **arguments;
- int arg_count = ZEND_NUM_ARGS();
- DISPPARAMS dispparams;
- DISPID dispid, altdispid;
- VARIANT *variant_args;
- VARIANT result;
- int current_arg, current_variant;
- char *ErrString = NULL;
- OLECHAR *olestr;
-
- if (zend_parse_method_parameters(2 TSRMLS_CC, getThis(), "Os", &object, com_class_entry,
- &propname, &propname_len) != SUCCESS) {
- return;
- }
-
- if (ZEND_NUM_ARGS() < 3) {
- ZEND_WRONG_PARAM_COUNT();
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- arguments = (zval **) emalloc(sizeof(zval *) * ZEND_NUM_ARGS());
- if (zend_get_parameters_array(ht, arg_count, arguments) == FAILURE) {
- RETURN_NULL();
- }
-
- olestr = php_char_to_OLECHAR(propname, propname_len, CP_ACP, FALSE);
-
- if (FAILED(php_COM_get_ids_of_names((comval *) intern->data, olestr, &dispid))) {
- RETURN_NULL();
- }
- variant_args = (VARIANT *) emalloc(sizeof(VARIANT) * (arg_count - 2));
-
- for (current_arg = 2; current_arg < arg_count; current_arg++) {
- current_variant = arg_count - current_arg - 1;
- php_zval_to_variant(arguments[current_arg], &variant_args[current_variant],
- C_CODEPAGE((comval *)intern->data) TSRMLS_CC);
- }
-
- dispparams.rgvarg = variant_args;
- dispparams.rgdispidNamedArgs = NULL;
- dispparams.cArgs = arg_count - 2;
- dispparams.cNamedArgs = 0;
- altdispid = DISPID_PROPERTYPUT;
- dispparams.rgdispidNamedArgs = &altdispid;
- dispparams.cNamedArgs = 1;
-
- VariantInit(&result);
-
- if (php_COM_invoke((comval*)intern->data, dispid, DISPATCH_PROPERTYPUT, &dispparams, &result, &ErrString)==FAILURE) {
- VariantClear(&result);
- RETVAL_NULL();
- } else {
- RETVAL_VARIANT(&result, C_CODEPAGE((comval*)intern->data));
- }
-
- efree(variant_args);
- efree(arguments);
- efree(olestr);
-
-}
-
-/* {{{ proto mixed com_addref(int module)
- Increases the reference counter on a COM object */
-ZEND_FUNCTION(com_addref)
-{
- zval *object;
- rpc_internal *intern;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- RETURN_LONG(php_COM_addref((comval *) intern->data));
-}
-/* }}} */
-
-/* {{{ proto mixed com_release(int module)
- Releases a COM object */
-ZEND_FUNCTION(com_release)
-{
- zval *object;
- rpc_internal *intern;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- RETURN_LONG(php_COM_release((comval *) intern->data));
-}
-/* }}} */
-
-ZEND_FUNCTION(com_next)
-{
- zval *object;
- rpc_internal *intern;
- comval *obj;
- unsigned long count = 1;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &object, com_class_entry, &count) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- obj = (comval *) intern->data;
-
- if (C_HASENUM(obj)) {
- SAFEARRAY *pSA;
- SAFEARRAYBOUND rgsabound[1];
- VARIANT *result;
- HRESULT hr;
-
- /* Grab one argument off the stack, allocate enough
- * VARIANTs
- * Get the IEnumVariant interface and call ->Next();
- */
-
- rgsabound[0].lLbound = 0;
- rgsabound[0].cElements = count;
-
- result = (VARIANT *) emalloc(sizeof(VARIANT));
- VariantInit(result);
-
- if ((pSA = SafeArrayCreate(VT_VARIANT, 1, rgsabound)) == NULL) {
- efree(result);
- /* @todo exception */
-
- RETURN_NULL();
- } else {
- V_ARRAY(result) = pSA;
- V_VT(result) = VT_VARIANT|VT_ARRAY;
- }
-
- if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Next(C_ENUMVARIANT(obj), count, pSA->pvData, &count))) {
- char *error_message;
-
- efree(result);
- error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
- efree(error_message);
-
- RETURN_NULL();
- }
-
- if (count != rgsabound[0].cElements) {
- rgsabound[0].cElements = count;
- if (FAILED(SafeArrayRedim(pSA, rgsabound))) {
- char *error_message;
-
- efree(result);
- error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
- efree(error_message);
-
- RETURN_NULL();
- }
- }
-
- /* return a single element if next() was called without count */
- if ((ZEND_NUM_ARGS() == 0) && (count == 1)) {
- long index[] = {0};
-
- SafeArrayGetElement(pSA, index, result);
- SafeArrayDestroy(pSA);
- }
-
- RETURN_VARIANT(result, C_CODEPAGE(obj));
- }
-
- /* @todo exception */
- RETURN_NULL();
-}
-
-ZEND_FUNCTION(com_all)
-{
-#if 0
- } 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*/
-#endif
-}
-
-ZEND_FUNCTION(com_reset)
-{
- zval *object;
- rpc_internal *intern;
- comval *obj;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- obj = (comval *) intern->data;
-
- if (C_HASENUM(obj)) {
- HRESULT hr;
-
- if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Reset(C_ENUMVARIANT(obj)))) {
- char *error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
- efree(error_message);
-
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
- }
-
- /* @todo exception */
- RETURN_FALSE;
-}
-
-ZEND_FUNCTION(com_skip)
-{
- zval *object;
- rpc_internal *intern;
- comval *obj;
- unsigned long count = 1;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|l", &object, com_class_entry, &count) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- obj = (comval *) intern->data;
-
- if (C_HASENUM(obj)) {
- HRESULT hr;
-
- if (FAILED(hr = C_ENUMVARIANT_VT(obj)->Skip(C_ENUMVARIANT(obj), count))) {
- char *error_message = php_COM_error_message(hr);
- rpc_error(E_WARNING,"IEnumVariant::Next() failed: %s", error_message);
- efree(error_message);
- RETURN_FALSE;
- }
-
- RETURN_TRUE;
- }
-
- /* @todo exception */
- RETURN_FALSE;
-}
-
-/* {{{ proto bool com_isenum(object com_module)
- Grabs an IEnumVariant */
-ZEND_FUNCTION(com_isenum)
-{
- zval *object;
- rpc_internal *intern;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, com_class_entry) != SUCCESS) {
- return;
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- RETURN_BOOL(C_HASENUM((comval *) intern->data));
-}
-/* }}} */
-
-/* {{{ proto bool com_load_typelib(string typelib_name [, int case_insensitive])
- Loads a Typelib */
-ZEND_FUNCTION(com_load_typelib)
-{
- char *typelib;
- int len, cis = FALSE;
- int mode = CONST_CS;
- ITypeLib *pTL;
-
- zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &typelib, &len, &cis);
-
- if (cis) {
- mode &= ~CONST_CS;
- }
-
- pTL = php_COM_find_typelib(typelib, mode);
- if (php_COM_load_typelib(pTL, mode) == SUCCESS) {
- pTL->lpVtbl->Release(pTL);
- RETURN_TRUE;
- } else {
- RETURN_FALSE;
- }
-}
-/* }}} */
-
-/* {{{ proto bool com_print_typeinfo(mixed comobject | string typelib, string dispinterface, bool wantsink)
- Print out a PHP class definition for a dispatchable interface */
-ZEND_FUNCTION(com_print_typeinfo)
-{
- zval *object;
- char *ifacename = NULL;
- char *typelibname = NULL;
- int typeliblen, ifacelen;
- zend_bool wantsink = 0;
- comval *obj = NULL;
- rpc_internal *intern;
- ITypeInfo *typeinfo;
-
- if (FAILURE == zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s/s!b",
- &typelibname, &typeliblen, &ifacename, &ifacelen, &wantsink)) {
- if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O/s!b",
- &object, com_class_entry, &ifacename, &ifacelen, &wantsink)) {
- RETURN_FALSE;
- } else {
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- obj = (comval *) intern->data;
- }
- }
-
- typeinfo = php_COM_locate_typeinfo(typelibname, obj, ifacename, wantsink);
- if (typeinfo) {
- php_COM_process_typeinfo(typeinfo, NULL, 1, NULL);
- typeinfo->lpVtbl->Release(typeinfo);
-
- RETURN_TRUE;
- } else {
- rpc_error(E_WARNING, "Unable to find typeinfo using the parameters supplied");
- }
-
- RETURN_FALSE;
-}
-/* }}} */
-
-/* {{{ proto bool com_event_sink(mixed comobject, object sinkobject [, mixed sinkinterface])
- Connect events from a COM object to a PHP object */
-ZEND_FUNCTION(com_event_sink)
-{
- zval *object, *sinkobject, *sink=NULL;
- char *dispname = NULL, *typelibname = NULL;
- zend_bool gotguid = 0;
- comval *obj;
- rpc_internal *intern;
- ITypeInfo *typeinfo = NULL;
-
- RETVAL_FALSE;
-
- if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Oz|z/", &object, com_class_entry, &sinkobject, &sink)) {
- RETURN_FALSE;
- }
-
- if (sink && Z_TYPE_P(sink) == IS_ARRAY) {
- /* 0 => typelibname, 1 => dispname */
- zval **tmp;
-
- if (zend_hash_index_find(Z_ARRVAL_P(sink), 0, (void**)&tmp) == SUCCESS)
- typelibname = Z_STRVAL_PP(tmp);
- if (zend_hash_index_find(Z_ARRVAL_P(sink), 1, (void**)&tmp) == SUCCESS)
- dispname = Z_STRVAL_PP(tmp);
- } else if (sink != NULL) {
- convert_to_string_ex(&sink);
- dispname = Z_STRVAL_P(sink);
- }
-
- if (GET_INTERNAL_EX(intern, object) != SUCCESS) {
- /* TODO: exception */
- }
-
- obj = (comval *) intern->data;
-
- typeinfo = php_COM_locate_typeinfo(typelibname, obj, dispname, 1);
-
- if (typeinfo) {
- HashTable *id_to_name;
-
- ALLOC_HASHTABLE(id_to_name);
-
- if (php_COM_process_typeinfo(typeinfo, id_to_name, 0, &obj->sinkid)) {
-
- /* Create the COM wrapper for this sink */
- obj->sinkdispatch = php_COM_export_as_sink(sinkobject, &obj->sinkid, id_to_name);
-
- /* Now hook it up to the source */
- php_COM_enable_events(obj, TRUE);
-
- RETVAL_TRUE;
-
- } else {
- FREE_HASHTABLE(id_to_name);
- }
- }
-
- if (typeinfo)
- typeinfo->lpVtbl->Release(typeinfo);
-
-}
-/* }}} */
-
-
-
-/* ini callbacks */
-
-static ZEND_INI_MH(com_typelib_file_change)
-{
- FILE *typelib_file;
- char *typelib_name_buffer;
- char *strtok_buf = NULL;
- int interactive;
- interactive = CG(interactive);
-
- if (!new_value || (typelib_file = VCWD_FOPEN(new_value, "r"))==NULL) {
- return FAILURE;
- }
-
- if (interactive) {
- printf("Loading type libraries...");
- fflush(stdout);
- }
-
- typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
-
- while (fgets(typelib_name_buffer, 1024, typelib_file)) {
- ITypeLib *pTL;
- char *typelib_name;
- char *modifier, *ptr;
- int mode = CONST_CS | CONST_PERSISTENT; /* CONST_PERSISTENT is ok here */
-
- if (typelib_name_buffer[0]==';') {
- continue;
- }
- typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */
- if (typelib_name == NULL) {
- continue;
- }
- typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf);
- modifier = php_strtok_r(NULL, "#", &strtok_buf);
- if (modifier != NULL) {
- if (!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) {
- mode &= ~CONST_CS;
- }
- }
-
- /* Remove leading/training white spaces on search_string */
- while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
- typelib_name ++;
- }
- ptr = typelib_name + strlen(typelib_name) - 1;
- while ((ptr != typelib_name) && isspace(*ptr)) {
- *ptr = '\0';
- ptr--;
- }
-
- if (interactive) {
- printf("\rLoading %-60s\r", typelib_name);
- }
-
- if ((pTL = php_COM_find_typelib(typelib_name, mode)) != NULL) {
- php_COM_load_typelib(pTL, mode);
- pTL->lpVtbl->Release(pTL);
- }
- }
-
- efree(typelib_name_buffer);
- fclose(typelib_file);
-
- if (interactive) {
- printf("\r%70s\r", "");
- }
-
- return SUCCESS;
-} \ No newline at end of file