1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Wez Furlong <wez@thebrainroom.com> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id$ */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "php.h"
26 #include "php_ini.h"
27 #include "ext/standard/info.h"
28 #include "php_com_dotnet.h"
29 #include "php_com_dotnet_internal.h"
30 #include "Zend/zend_exceptions.h"
31
php_com_throw_exception(HRESULT code,char * message TSRMLS_DC)32 void php_com_throw_exception(HRESULT code, char *message TSRMLS_DC)
33 {
34 int free_msg = 0;
35 if (message == NULL) {
36 message = php_win_err(code);
37 free_msg = 1;
38 }
39 zend_throw_exception(php_com_exception_class_entry, message, (long)code TSRMLS_CC);
40 if (free_msg) {
41 LocalFree(message);
42 }
43 }
44
php_com_wrap_dispatch(zval * z,IDispatch * disp,int codepage TSRMLS_DC)45 PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp,
46 int codepage TSRMLS_DC)
47 {
48 php_com_dotnet_object *obj;
49
50 obj = emalloc(sizeof(*obj));
51 memset(obj, 0, sizeof(*obj));
52 obj->code_page = codepage;
53 obj->ce = php_com_variant_class_entry;
54 obj->zo.ce = php_com_variant_class_entry;
55
56 VariantInit(&obj->v);
57 V_VT(&obj->v) = VT_DISPATCH;
58 V_DISPATCH(&obj->v) = disp;
59
60 IDispatch_AddRef(V_DISPATCH(&obj->v));
61 IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
62
63 Z_TYPE_P(z) = IS_OBJECT;
64 z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
65 z->value.obj.handlers = &php_com_object_handlers;
66 }
67
php_com_wrap_variant(zval * z,VARIANT * v,int codepage TSRMLS_DC)68 PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v,
69 int codepage TSRMLS_DC)
70 {
71 php_com_dotnet_object *obj;
72
73 obj = emalloc(sizeof(*obj));
74 memset(obj, 0, sizeof(*obj));
75 obj->code_page = codepage;
76 obj->ce = php_com_variant_class_entry;
77 obj->zo.ce = php_com_variant_class_entry;
78
79 VariantInit(&obj->v);
80 VariantCopyInd(&obj->v, v);
81 obj->modified = 0;
82
83 if ((V_VT(&obj->v) == VT_DISPATCH) && (V_DISPATCH(&obj->v) != NULL)) {
84 IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo);
85 }
86
87 Z_TYPE_P(z) = IS_OBJECT;
88
89 z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC);
90 z->value.obj.handlers = &php_com_object_handlers;
91 }
92
93 /* this is a convenience function for fetching a particular
94 * element from a (possibly multi-dimensional) safe array */
php_com_safearray_get_elem(VARIANT * array,VARIANT * dest,LONG dim1 TSRMLS_DC)95 PHP_COM_DOTNET_API int php_com_safearray_get_elem(VARIANT *array, VARIANT *dest, LONG dim1 TSRMLS_DC)
96 {
97 UINT dims;
98 LONG lbound, ubound;
99 LONG indices[1];
100 VARTYPE vt;
101
102 if (!V_ISARRAY(array)) {
103 return 0;
104 }
105
106 dims = SafeArrayGetDim(V_ARRAY(array));
107
108 if (dims != 1) {
109 php_error_docref(NULL TSRMLS_CC, E_WARNING,
110 "Can only handle single dimension variant arrays (this array has %d)", dims);
111 return 0;
112 }
113
114 if (FAILED(SafeArrayGetVartype(V_ARRAY(array), &vt)) || vt == VT_EMPTY) {
115 vt = V_VT(array) & ~VT_ARRAY;
116 }
117
118 /* determine the bounds */
119 SafeArrayGetLBound(V_ARRAY(array), 1, &lbound);
120 SafeArrayGetUBound(V_ARRAY(array), 1, &ubound);
121
122 /* check bounds */
123 if (dim1 < lbound || dim1 > ubound) {
124 php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC);
125 return 0;
126 }
127
128 /* now fetch that element */
129 VariantInit(dest);
130
131 indices[0] = dim1;
132
133 if (vt == VT_VARIANT) {
134 SafeArrayGetElement(V_ARRAY(array), indices, dest);
135 } else {
136 V_VT(dest) = vt;
137 /* store the value into "lVal" member of the variant.
138 * This works because it is a union; since we know the variant
139 * type, we end up with a working variant */
140 SafeArrayGetElement(V_ARRAY(array), indices, &dest->lVal);
141 }
142
143 return 1;
144 }
145