1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Wez Furlong <wez@thebrainroom.com> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20
21 #include <intsafe.h>
22
23 #include "php.h"
24 #include "php_ini.h"
25 #include "ext/standard/info.h"
26 #include "php_com_dotnet.h"
27 #include "php_com_dotnet_internal.h"
28 #include "Zend/zend_exceptions.h"
29 #include "Zend/zend_interfaces.h"
30 #include "com_extension_arginfo.h"
31
32 ZEND_DECLARE_MODULE_GLOBALS(com_dotnet)
33 static PHP_GINIT_FUNCTION(com_dotnet);
34
35 zend_class_entry
36 *php_com_variant_class_entry,
37 *php_com_exception_class_entry,
38 *php_com_saproxy_class_entry;
39
40 /* {{{ com_dotnet_module_entry */
41 zend_module_entry com_dotnet_module_entry = {
42 STANDARD_MODULE_HEADER,
43 "com_dotnet",
44 ext_functions,
45 PHP_MINIT(com_dotnet),
46 PHP_MSHUTDOWN(com_dotnet),
47 PHP_RINIT(com_dotnet),
48 PHP_RSHUTDOWN(com_dotnet),
49 PHP_MINFO(com_dotnet),
50 PHP_COM_DOTNET_VERSION,
51 PHP_MODULE_GLOBALS(com_dotnet),
52 PHP_GINIT(com_dotnet),
53 NULL,
54 NULL,
55 STANDARD_MODULE_PROPERTIES_EX
56 };
57 /* }}} */
58
59 #ifdef COMPILE_DL_COM_DOTNET
60 #ifdef ZTS
61 ZEND_TSRMLS_CACHE_DEFINE()
62 #endif
ZEND_GET_MODULE(com_dotnet)63 ZEND_GET_MODULE(com_dotnet)
64 #endif
65
66 /* {{{ PHP_INI */
67
68 /* com.typelib_file is the path to a file containing a
69 * list of typelibraries to register *persistently*.
70 * lines starting with ; are comments
71 * append #cis to end of typelib name to cause its constants
72 * to be loaded case insensitively */
73 static PHP_INI_MH(OnTypeLibFileUpdate)
74 {
75 FILE *typelib_file;
76 char *typelib_name_buffer;
77 char *strtok_buf = NULL;
78
79 if (NULL == new_value || !new_value->val[0] || (typelib_file = VCWD_FOPEN(new_value->val, "r"))==NULL) {
80 return FAILURE;
81 }
82
83 typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
84
85 while (fgets(typelib_name_buffer, 1024, typelib_file)) {
86 ITypeLib *pTL;
87 char *typelib_name;
88 char *modifier, *ptr;
89 int mode = CONST_CS | CONST_PERSISTENT; /* CONST_PERSISTENT is ok here */
90
91 if (typelib_name_buffer[0]==';') {
92 continue;
93 }
94 typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */
95 if (typelib_name == NULL) {
96 continue;
97 }
98 typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf);
99 modifier = php_strtok_r(NULL, "#", &strtok_buf);
100 if (modifier != NULL) {
101 if (!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) {
102 php_error_docref("com.configuration", E_WARNING, "Declaration of case-insensitive constants is no longer supported; #cis modifier ignored");
103 }
104 }
105
106 /* Remove leading/training white spaces on search_string */
107 while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
108 typelib_name ++;
109 }
110 ptr = typelib_name + strlen(typelib_name) - 1;
111 while ((ptr != typelib_name) && isspace(*ptr)) {
112 *ptr = '\0';
113 ptr--;
114 }
115
116 if ((pTL = php_com_load_typelib_via_cache(typelib_name, COMG(code_page))) != NULL) {
117 php_com_import_typelib(pTL, mode, COMG(code_page));
118 ITypeLib_Release(pTL);
119 }
120 }
121
122 efree(typelib_name_buffer);
123 fclose(typelib_file);
124
125 return SUCCESS;
126 }
127
ZEND_INI_MH(OnAutoregisterCasesensitive)128 static ZEND_INI_MH(OnAutoregisterCasesensitive)
129 {
130 if (!zend_ini_parse_bool(new_value)) {
131 php_error_docref("com.configuration", E_WARNING, "Declaration of case-insensitive constants is no longer supported");
132 return FAILURE;
133 }
134 return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
135 }
136
137 PHP_INI_BEGIN()
138 STD_PHP_INI_BOOLEAN("com.allow_dcom", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_dcom, zend_com_dotnet_globals, com_dotnet_globals)
139 STD_PHP_INI_BOOLEAN("com.autoregister_verbose", "0", PHP_INI_ALL, OnUpdateBool, autoreg_verbose, zend_com_dotnet_globals, com_dotnet_globals)
140 STD_PHP_INI_BOOLEAN("com.autoregister_typelib", "0", PHP_INI_ALL, OnUpdateBool, autoreg_on, zend_com_dotnet_globals, com_dotnet_globals)
141 STD_PHP_INI_ENTRY("com.autoregister_casesensitive", "1", PHP_INI_ALL, OnAutoregisterCasesensitive, autoreg_case_sensitive, zend_com_dotnet_globals, com_dotnet_globals)
142 STD_PHP_INI_ENTRY("com.code_page", "", PHP_INI_ALL, OnUpdateLong, code_page, zend_com_dotnet_globals, com_dotnet_globals)
143 PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypeLibFileUpdate)
144 PHP_INI_ENTRY("com.dotnet_version", NULL, PHP_INI_SYSTEM, NULL)
PHP_INI_END()145 PHP_INI_END()
146 /* }}} */
147
148 /* {{{ PHP_GINIT_FUNCTION */
149 static PHP_GINIT_FUNCTION(com_dotnet)
150 {
151 #if defined(COMPILE_DL_COM_DOTNET) && defined(ZTS)
152 ZEND_TSRMLS_CACHE_UPDATE();
153 #endif
154 memset(com_dotnet_globals, 0, sizeof(*com_dotnet_globals));
155 com_dotnet_globals->code_page = CP_ACP;
156 }
157 /* }}} */
158
159 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(com_dotnet)160 PHP_MINIT_FUNCTION(com_dotnet)
161 {
162 zend_class_entry *tmp;
163
164 php_com_wrapper_minit(INIT_FUNC_ARGS_PASSTHRU);
165 php_com_persist_minit(INIT_FUNC_ARGS_PASSTHRU);
166
167 php_com_exception_class_entry = register_class_com_exception(zend_ce_exception);
168 /* php_com_exception_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
169
170 php_com_saproxy_class_entry = register_class_com_safearray_proxy();
171 /* php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
172 php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get;
173
174 php_com_variant_class_entry = register_class_variant();
175 php_com_variant_class_entry->create_object = php_com_object_new;
176 php_com_variant_class_entry->get_iterator = php_com_iter_get;
177
178 tmp = register_class_com(php_com_variant_class_entry);
179 tmp->create_object = php_com_object_new;
180 tmp->get_iterator = php_com_iter_get;
181
182 #if HAVE_MSCOREE_H
183 tmp = register_class_dotnet(php_com_variant_class_entry);
184 tmp->create_object = php_com_object_new;
185 tmp->get_iterator = php_com_iter_get;
186 #endif
187
188 REGISTER_INI_ENTRIES();
189
190 #define COM_CONST(x) REGISTER_LONG_CONSTANT(#x, x, CONST_CS|CONST_PERSISTENT)
191
192 #if SIZEOF_ZEND_LONG == 8
193 # define COM_ERR_CONST(x) REGISTER_LONG_CONSTANT(#x, (zend_long) (ULONG) (x), CONST_CS|CONST_PERSISTENT)
194 #else
195 # define COM_ERR_CONST COM_CONST
196 #endif
197
198 COM_CONST(CLSCTX_INPROC_SERVER);
199 COM_CONST(CLSCTX_INPROC_HANDLER);
200 COM_CONST(CLSCTX_LOCAL_SERVER);
201 COM_CONST(CLSCTX_REMOTE_SERVER);
202 COM_CONST(CLSCTX_SERVER);
203 COM_CONST(CLSCTX_ALL);
204
205 #if 0
206 COM_CONST(DISPATCH_METHOD);
207 COM_CONST(DISPATCH_PROPERTYGET);
208 COM_CONST(DISPATCH_PROPERTYPUT);
209 #endif
210
211 COM_CONST(VT_NULL);
212 COM_CONST(VT_EMPTY);
213 COM_CONST(VT_UI1);
214 COM_CONST(VT_I1);
215 COM_CONST(VT_UI2);
216 COM_CONST(VT_I2);
217 COM_CONST(VT_UI4);
218 COM_CONST(VT_I4);
219 COM_CONST(VT_R4);
220 COM_CONST(VT_R8);
221 COM_CONST(VT_BOOL);
222 COM_CONST(VT_ERROR);
223 COM_CONST(VT_CY);
224 COM_CONST(VT_DATE);
225 COM_CONST(VT_BSTR);
226 COM_CONST(VT_DECIMAL);
227 COM_CONST(VT_UNKNOWN);
228 COM_CONST(VT_DISPATCH);
229 COM_CONST(VT_VARIANT);
230 COM_CONST(VT_INT);
231 COM_CONST(VT_UINT);
232 COM_CONST(VT_ARRAY);
233 COM_CONST(VT_BYREF);
234
235 COM_CONST(CP_ACP);
236 COM_CONST(CP_MACCP);
237 COM_CONST(CP_OEMCP);
238 COM_CONST(CP_UTF7);
239 COM_CONST(CP_UTF8);
240 COM_CONST(CP_SYMBOL);
241 COM_CONST(CP_THREAD_ACP);
242
243 COM_CONST(VARCMP_LT);
244 COM_CONST(VARCMP_EQ);
245 COM_CONST(VARCMP_GT);
246 COM_CONST(VARCMP_NULL);
247 COM_CONST(LOCALE_SYSTEM_DEFAULT);
248
249 COM_CONST(NORM_IGNORECASE);
250 COM_CONST(NORM_IGNORENONSPACE);
251 COM_CONST(NORM_IGNORESYMBOLS);
252 COM_CONST(NORM_IGNOREWIDTH);
253 COM_CONST(NORM_IGNOREKANATYPE);
254 #ifdef NORM_IGNOREKASHIDA
255 COM_CONST(NORM_IGNOREKASHIDA);
256 #endif
257 COM_ERR_CONST(DISP_E_DIVBYZERO);
258 COM_ERR_CONST(DISP_E_OVERFLOW);
259 COM_ERR_CONST(DISP_E_BADINDEX);
260 COM_ERR_CONST(MK_E_UNAVAILABLE);
261
262 #if SIZEOF_ZEND_LONG == 8
263 COM_CONST(VT_UI8);
264 COM_CONST(VT_I8);
265 #endif
266
267 PHP_MINIT(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
268
269 return SUCCESS;
270 }
271 /* }}} */
272
273 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(com_dotnet)274 PHP_MSHUTDOWN_FUNCTION(com_dotnet)
275 {
276 UNREGISTER_INI_ENTRIES();
277 #if HAVE_MSCOREE_H
278 if (COMG(dotnet_runtime_stuff)) {
279 php_com_dotnet_mshutdown();
280 }
281 #endif
282
283 PHP_MSHUTDOWN(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
284
285 return SUCCESS;
286 }
287 /* }}} */
288
289 /* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(com_dotnet)290 PHP_RINIT_FUNCTION(com_dotnet)
291 {
292 COMG(rshutdown_started) = 0;
293 return SUCCESS;
294 }
295 /* }}} */
296
297 /* {{{ PHP_RSHUTDOWN_FUNCTION */
PHP_RSHUTDOWN_FUNCTION(com_dotnet)298 PHP_RSHUTDOWN_FUNCTION(com_dotnet)
299 {
300 #if HAVE_MSCOREE_H
301 if (COMG(dotnet_runtime_stuff)) {
302 php_com_dotnet_rshutdown();
303 }
304 #endif
305 COMG(rshutdown_started) = 1;
306 return SUCCESS;
307 }
308 /* }}} */
309
310 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(com_dotnet)311 PHP_MINFO_FUNCTION(com_dotnet)
312 {
313 php_info_print_table_start();
314
315 php_info_print_table_header(2, "COM support", "enabled");
316 php_info_print_table_header(2, "DCOM support", COMG(allow_dcom) ? "enabled" : "disabled");
317
318 #if HAVE_MSCOREE_H
319 php_info_print_table_header(2, ".Net support", "enabled");
320 #else
321 php_info_print_table_header(2, ".Net support", "not present in this build");
322 #endif
323
324 php_info_print_table_end();
325
326 DISPLAY_INI_ENTRIES();
327 }
328 /* }}} */
329