xref: /PHP-7.1/ext/com_dotnet/com_extension.c (revision ccd4716e)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 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 <intsafe.h>
26 
27 #include "php.h"
28 #include "php_ini.h"
29 #include "ext/standard/info.h"
30 #include "php_com_dotnet.h"
31 #include "php_com_dotnet_internal.h"
32 #include "Zend/zend_exceptions.h"
33 
34 ZEND_DECLARE_MODULE_GLOBALS(com_dotnet)
35 static PHP_GINIT_FUNCTION(com_dotnet);
36 
37 TsHashTable php_com_typelibraries;
38 
39 zend_class_entry
40 	*php_com_variant_class_entry,
41    	*php_com_exception_class_entry,
42 	*php_com_saproxy_class_entry;
43 
44 /* {{{ arginfo */
45 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_set, 0, 0, 2)
46 	ZEND_ARG_INFO(0, variant)
47 	ZEND_ARG_INFO(0, value)
48 ZEND_END_ARG_INFO()
49 
50 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_add, 0, 0, 2)
51 	ZEND_ARG_INFO(0, left)
52 	ZEND_ARG_INFO(0, right)
53 ZEND_END_ARG_INFO()
54 
55 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_cat, 0, 0, 2)
56 	ZEND_ARG_INFO(0, left)
57 	ZEND_ARG_INFO(0, right)
58 ZEND_END_ARG_INFO()
59 
60 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_sub, 0, 0, 2)
61 	ZEND_ARG_INFO(0, left)
62 	ZEND_ARG_INFO(0, right)
63 ZEND_END_ARG_INFO()
64 
65 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_mul, 0, 0, 2)
66 	ZEND_ARG_INFO(0, left)
67 	ZEND_ARG_INFO(0, right)
68 ZEND_END_ARG_INFO()
69 
70 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_and, 0, 0, 2)
71 	ZEND_ARG_INFO(0, left)
72 	ZEND_ARG_INFO(0, right)
73 ZEND_END_ARG_INFO()
74 
75 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_div, 0, 0, 2)
76 	ZEND_ARG_INFO(0, left)
77 	ZEND_ARG_INFO(0, right)
78 ZEND_END_ARG_INFO()
79 
80 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_eqv, 0, 0, 2)
81 	ZEND_ARG_INFO(0, left)
82 	ZEND_ARG_INFO(0, right)
83 ZEND_END_ARG_INFO()
84 
85 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_idiv, 0, 0, 2)
86 	ZEND_ARG_INFO(0, left)
87 	ZEND_ARG_INFO(0, right)
88 ZEND_END_ARG_INFO()
89 
90 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_imp, 0, 0, 2)
91 	ZEND_ARG_INFO(0, left)
92 	ZEND_ARG_INFO(0, right)
93 ZEND_END_ARG_INFO()
94 
95 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_mod, 0, 0, 2)
96 	ZEND_ARG_INFO(0, left)
97 	ZEND_ARG_INFO(0, right)
98 ZEND_END_ARG_INFO()
99 
100 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_or, 0, 0, 2)
101 	ZEND_ARG_INFO(0, left)
102 	ZEND_ARG_INFO(0, right)
103 ZEND_END_ARG_INFO()
104 
105 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_pow, 0, 0, 2)
106 	ZEND_ARG_INFO(0, left)
107 	ZEND_ARG_INFO(0, right)
108 ZEND_END_ARG_INFO()
109 
110 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_xor, 0, 0, 2)
111 	ZEND_ARG_INFO(0, left)
112 	ZEND_ARG_INFO(0, right)
113 ZEND_END_ARG_INFO()
114 
115 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_abs, 0, 0, 1)
116 	ZEND_ARG_INFO(0, left)
117 ZEND_END_ARG_INFO()
118 
119 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_fix, 0, 0, 1)
120 	ZEND_ARG_INFO(0, left)
121 ZEND_END_ARG_INFO()
122 
123 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_int, 0, 0, 1)
124 	ZEND_ARG_INFO(0, left)
125 ZEND_END_ARG_INFO()
126 
127 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_neg, 0, 0, 1)
128 	ZEND_ARG_INFO(0, left)
129 ZEND_END_ARG_INFO()
130 
131 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_not, 0, 0, 1)
132 	ZEND_ARG_INFO(0, left)
133 ZEND_END_ARG_INFO()
134 
135 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_round, 0, 0, 2)
136 	ZEND_ARG_INFO(0, left)
137 	ZEND_ARG_INFO(0, decimals)
138 ZEND_END_ARG_INFO()
139 
140 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_cmp, 0, 0, 2)
141 	ZEND_ARG_INFO(0, left)
142 	ZEND_ARG_INFO(0, right)
143 	ZEND_ARG_INFO(0, lcid)
144 	ZEND_ARG_INFO(0, flags)
145 ZEND_END_ARG_INFO()
146 
147 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_date_to_timestamp, 0, 0, 1)
148 	ZEND_ARG_INFO(0, variant)
149 ZEND_END_ARG_INFO()
150 
151 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_date_from_timestamp, 0, 0, 1)
152 	ZEND_ARG_INFO(0, timestamp)
153 ZEND_END_ARG_INFO()
154 
155 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_get_type, 0, 0, 1)
156 	ZEND_ARG_INFO(0, variant)
157 ZEND_END_ARG_INFO()
158 
159 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_set_type, 0, 0, 2)
160 	ZEND_ARG_INFO(0, variant)
161 	ZEND_ARG_INFO(0, type)
162 ZEND_END_ARG_INFO()
163 
164 ZEND_BEGIN_ARG_INFO_EX(arginfo_variant_cast, 0, 0, 2)
165 	ZEND_ARG_INFO(0, variant)
166 	ZEND_ARG_INFO(0, type)
167 ZEND_END_ARG_INFO()
168 
169 ZEND_BEGIN_ARG_INFO_EX(arginfo_com_get_active_object, 0, 0, 1)
170 	ZEND_ARG_INFO(0, progid)
171 	ZEND_ARG_INFO(0, code_page)
172 ZEND_END_ARG_INFO()
173 
174 ZEND_BEGIN_ARG_INFO(arginfo_com_create_guid, 0)
175 ZEND_END_ARG_INFO()
176 
177 ZEND_BEGIN_ARG_INFO_EX(arginfo_com_event_sink, 0, 0, 2)
178 	ZEND_ARG_INFO(0, comobject)
179 	ZEND_ARG_INFO(0, sinkobject)
180 	ZEND_ARG_INFO(0, sinkinterface)
181 ZEND_END_ARG_INFO()
182 
183 ZEND_BEGIN_ARG_INFO_EX(arginfo_com_print_typeinfo, 0, 0, 1)
184 	ZEND_ARG_INFO(0, comobject)
185 	ZEND_ARG_INFO(0, dispinterface)
186 	ZEND_ARG_INFO(0, wantsink)
187 ZEND_END_ARG_INFO()
188 
189 ZEND_BEGIN_ARG_INFO_EX(arginfo_com_message_pump, 0, 0, 0)
190 	ZEND_ARG_INFO(0, timeoutms)
191 ZEND_END_ARG_INFO()
192 
193 ZEND_BEGIN_ARG_INFO_EX(arginfo_com_load_typelib, 0, 0, 1)
194 	ZEND_ARG_INFO(0, typelib_name)
195 	ZEND_ARG_INFO(0, case_insensitive)
196 ZEND_END_ARG_INFO()
197 /* }}} */
198 
199 const zend_function_entry com_dotnet_functions[] = {
200 	PHP_FE(variant_set, arginfo_variant_set)
201 	PHP_FE(variant_add, arginfo_variant_add)
202 	PHP_FE(variant_cat, arginfo_variant_cat)
203 	PHP_FE(variant_sub, arginfo_variant_sub)
204 	PHP_FE(variant_mul, arginfo_variant_mul)
205 	PHP_FE(variant_and, arginfo_variant_and)
206 	PHP_FE(variant_div, arginfo_variant_div)
207 	PHP_FE(variant_eqv, arginfo_variant_eqv)
208 	PHP_FE(variant_idiv, arginfo_variant_idiv)
209 	PHP_FE(variant_imp, arginfo_variant_imp)
210 	PHP_FE(variant_mod, arginfo_variant_mod)
211 	PHP_FE(variant_or, arginfo_variant_or)
212 	PHP_FE(variant_pow, arginfo_variant_pow)
213 	PHP_FE(variant_xor, arginfo_variant_xor)
214 	PHP_FE(variant_abs, arginfo_variant_abs)
215 	PHP_FE(variant_fix, arginfo_variant_fix)
216 	PHP_FE(variant_int, arginfo_variant_int)
217 	PHP_FE(variant_neg, arginfo_variant_neg)
218 	PHP_FE(variant_not, arginfo_variant_not)
219 	PHP_FE(variant_round, arginfo_variant_round)
220 	PHP_FE(variant_cmp, arginfo_variant_cmp)
221 	PHP_FE(variant_date_to_timestamp, arginfo_variant_date_to_timestamp)
222 	PHP_FE(variant_date_from_timestamp, arginfo_variant_date_from_timestamp)
223 	PHP_FE(variant_get_type, arginfo_variant_get_type)
224 	PHP_FE(variant_set_type, arginfo_variant_set_type)
225 	PHP_FE(variant_cast, arginfo_variant_cast)
226 	/* com_com.c */
227 	PHP_FE(com_create_guid, arginfo_com_create_guid)
228 	PHP_FE(com_event_sink, arginfo_com_event_sink)
229 	PHP_FE(com_print_typeinfo, arginfo_com_print_typeinfo)
230 	PHP_FE(com_message_pump, arginfo_com_message_pump)
231 	PHP_FE(com_load_typelib, arginfo_com_load_typelib)
232 	PHP_FE(com_get_active_object, arginfo_com_get_active_object)
233 	PHP_FE_END
234 };
235 
236 /* {{{ com_dotnet_module_entry
237  */
238 zend_module_entry com_dotnet_module_entry = {
239 	STANDARD_MODULE_HEADER,
240 	"com_dotnet",
241 	com_dotnet_functions,
242 	PHP_MINIT(com_dotnet),
243 	PHP_MSHUTDOWN(com_dotnet),
244 	PHP_RINIT(com_dotnet),
245 	PHP_RSHUTDOWN(com_dotnet),
246 	PHP_MINFO(com_dotnet),
247 	PHP_COM_DOTNET_VERSION,
248 	PHP_MODULE_GLOBALS(com_dotnet),
249 	PHP_GINIT(com_dotnet),
250 	NULL,
251 	NULL,
252 	STANDARD_MODULE_PROPERTIES_EX
253 };
254 /* }}} */
255 
256 #ifdef COMPILE_DL_COM_DOTNET
257 #ifdef ZTS
258 ZEND_TSRMLS_CACHE_DEFINE()
259 #endif
ZEND_GET_MODULE(com_dotnet)260 ZEND_GET_MODULE(com_dotnet)
261 #endif
262 
263 /* {{{ PHP_INI
264  */
265 
266 /* com.typelib_file is the path to a file containing a
267  * list of typelibraries to register *persistently*.
268  * lines starting with ; are comments
269  * append #cis to end of typelib name to cause its constants
270  * to be loaded case insensitively */
271 static PHP_INI_MH(OnTypeLibFileUpdate)
272 {
273 	FILE *typelib_file;
274 	char *typelib_name_buffer;
275 	char *strtok_buf = NULL;
276 	int cached;
277 
278 	if (NULL == new_value || !new_value->val[0] || (typelib_file = VCWD_FOPEN(new_value->val, "r"))==NULL) {
279 		return FAILURE;
280 	}
281 
282 	typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
283 
284 	while (fgets(typelib_name_buffer, 1024, typelib_file)) {
285 		ITypeLib *pTL;
286 		char *typelib_name;
287 		char *modifier, *ptr;
288 		int mode = CONST_CS | CONST_PERSISTENT;	/* CONST_PERSISTENT is ok here */
289 
290 		if (typelib_name_buffer[0]==';') {
291 			continue;
292 		}
293 		typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */
294 		if (typelib_name == NULL) {
295 			continue;
296 		}
297 		typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf);
298 		modifier = php_strtok_r(NULL, "#", &strtok_buf);
299 		if (modifier != NULL) {
300 			if (!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) {
301 				mode &= ~CONST_CS;
302 			}
303 		}
304 
305 		/* Remove leading/training white spaces on search_string */
306 		while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
307 			typelib_name ++;
308 		}
309 		ptr = typelib_name + strlen(typelib_name) - 1;
310 		while ((ptr != typelib_name) && isspace(*ptr)) {
311 			*ptr = '\0';
312 			ptr--;
313 		}
314 
315 		if ((pTL = php_com_load_typelib_via_cache(typelib_name, COMG(code_page), &cached)) != NULL) {
316 			if (!cached) {
317 				php_com_import_typelib(pTL, mode, COMG(code_page));
318 			}
319 			ITypeLib_Release(pTL);
320 		}
321 	}
322 
323 	efree(typelib_name_buffer);
324 	fclose(typelib_file);
325 
326 	return SUCCESS;
327 }
328 
329 PHP_INI_BEGIN()
330     STD_PHP_INI_ENTRY("com.allow_dcom",				"0", PHP_INI_SYSTEM, OnUpdateBool, allow_dcom, zend_com_dotnet_globals, com_dotnet_globals)
331     STD_PHP_INI_ENTRY("com.autoregister_verbose",	"0", PHP_INI_ALL, OnUpdateBool, autoreg_verbose, zend_com_dotnet_globals, com_dotnet_globals)
332     STD_PHP_INI_ENTRY("com.autoregister_typelib",	"0", PHP_INI_ALL, OnUpdateBool, autoreg_on, zend_com_dotnet_globals, com_dotnet_globals)
333     STD_PHP_INI_ENTRY("com.autoregister_casesensitive",	"1", PHP_INI_ALL, OnUpdateBool, autoreg_case_sensitive, zend_com_dotnet_globals, com_dotnet_globals)
334 	STD_PHP_INI_ENTRY("com.code_page", "", PHP_INI_ALL, OnUpdateLong, code_page, zend_com_dotnet_globals, com_dotnet_globals)
335 	PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypeLibFileUpdate)
PHP_INI_END()336 PHP_INI_END()
337 /* }}} */
338 
339 /* {{{ PHP_GINIT_FUNCTION
340  */
341 static PHP_GINIT_FUNCTION(com_dotnet)
342 {
343 #if defined(COMPILE_DL_COM_DOTNET) && defined(ZTS)
344 	ZEND_TSRMLS_CACHE_UPDATE();
345 #endif
346 	memset(com_dotnet_globals, 0, sizeof(*com_dotnet_globals));
347 	com_dotnet_globals->code_page = CP_ACP;
348 }
349 /* }}} */
350 
351 /* {{{ PHP_MINIT_FUNCTION
352  */
PHP_MINIT_FUNCTION(com_dotnet)353 PHP_MINIT_FUNCTION(com_dotnet)
354 {
355 	zend_class_entry ce, *tmp;
356 
357 	php_com_wrapper_minit(INIT_FUNC_ARGS_PASSTHRU);
358 	php_com_persist_minit(INIT_FUNC_ARGS_PASSTHRU);
359 
360 	INIT_CLASS_ENTRY(ce, "com_exception", NULL);
361 	php_com_exception_class_entry = zend_register_internal_class_ex(&ce, zend_ce_exception);
362 	php_com_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;
363 /*	php_com_exception_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
364 
365 	INIT_CLASS_ENTRY(ce, "com_safearray_proxy", NULL);
366 	php_com_saproxy_class_entry = zend_register_internal_class(&ce);
367 	php_com_saproxy_class_entry->ce_flags |= ZEND_ACC_FINAL;
368 /*	php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
369 	php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get;
370 
371 	INIT_CLASS_ENTRY(ce, "variant", NULL);
372 	ce.create_object = php_com_object_new;
373 	php_com_variant_class_entry = zend_register_internal_class(&ce);
374 	php_com_variant_class_entry->get_iterator = php_com_iter_get;
375 
376 	INIT_CLASS_ENTRY(ce, "com", NULL);
377 	ce.create_object = php_com_object_new;
378 	tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry);
379 	tmp->get_iterator = php_com_iter_get;
380 
381 	zend_ts_hash_init(&php_com_typelibraries, 0, NULL, php_com_typelibrary_dtor, 1);
382 
383 #if HAVE_MSCOREE_H
384 	INIT_CLASS_ENTRY(ce, "dotnet", NULL);
385 	ce.create_object = php_com_object_new;
386 	tmp = zend_register_internal_class_ex(&ce, php_com_variant_class_entry);
387 	tmp->get_iterator = php_com_iter_get;
388 #endif
389 
390 	REGISTER_INI_ENTRIES();
391 
392 #define COM_CONST(x) REGISTER_LONG_CONSTANT(#x, x, CONST_CS|CONST_PERSISTENT)
393 
394 #define COM_ERR_CONST(x) { \
395 	zend_long __tmp; \
396 	ULongToIntPtr(x, &__tmp); \
397 	REGISTER_LONG_CONSTANT(#x, __tmp, CONST_CS|CONST_PERSISTENT); \
398 }
399 
400 	COM_CONST(CLSCTX_INPROC_SERVER);
401 	COM_CONST(CLSCTX_INPROC_HANDLER);
402 	COM_CONST(CLSCTX_LOCAL_SERVER);
403 	COM_CONST(CLSCTX_REMOTE_SERVER);
404 	COM_CONST(CLSCTX_SERVER);
405 	COM_CONST(CLSCTX_ALL);
406 
407 #if 0
408 	COM_CONST(DISPATCH_METHOD);
409 	COM_CONST(DISPATCH_PROPERTYGET);
410 	COM_CONST(DISPATCH_PROPERTYPUT);
411 #endif
412 
413 	COM_CONST(VT_NULL);
414 	COM_CONST(VT_EMPTY);
415 	COM_CONST(VT_UI1);
416 	COM_CONST(VT_I1);
417 	COM_CONST(VT_UI2);
418 	COM_CONST(VT_I2);
419 	COM_CONST(VT_UI4);
420 	COM_CONST(VT_I4);
421 	COM_CONST(VT_R4);
422 	COM_CONST(VT_R8);
423 	COM_CONST(VT_BOOL);
424 	COM_CONST(VT_ERROR);
425 	COM_CONST(VT_CY);
426 	COM_CONST(VT_DATE);
427 	COM_CONST(VT_BSTR);
428 	COM_CONST(VT_DECIMAL);
429 	COM_CONST(VT_UNKNOWN);
430 	COM_CONST(VT_DISPATCH);
431 	COM_CONST(VT_VARIANT);
432 	COM_CONST(VT_INT);
433 	COM_CONST(VT_UINT);
434 	COM_CONST(VT_ARRAY);
435 	COM_CONST(VT_BYREF);
436 
437 	COM_CONST(CP_ACP);
438 	COM_CONST(CP_MACCP);
439 	COM_CONST(CP_OEMCP);
440 	COM_CONST(CP_UTF7);
441 	COM_CONST(CP_UTF8);
442 	COM_CONST(CP_SYMBOL);
443 	COM_CONST(CP_THREAD_ACP);
444 
445 	COM_CONST(VARCMP_LT);
446 	COM_CONST(VARCMP_EQ);
447 	COM_CONST(VARCMP_GT);
448 	COM_CONST(VARCMP_NULL);
449 
450 	COM_CONST(NORM_IGNORECASE);
451 	COM_CONST(NORM_IGNORENONSPACE);
452 	COM_CONST(NORM_IGNORESYMBOLS);
453 	COM_CONST(NORM_IGNOREWIDTH);
454 	COM_CONST(NORM_IGNOREKANATYPE);
455 #ifdef NORM_IGNOREKASHIDA
456 	COM_CONST(NORM_IGNOREKASHIDA);
457 #endif
458 	COM_ERR_CONST(DISP_E_DIVBYZERO);
459 	COM_ERR_CONST(DISP_E_OVERFLOW);
460 	COM_ERR_CONST(DISP_E_BADINDEX);
461 	COM_ERR_CONST(MK_E_UNAVAILABLE);
462 
463 #if SIZEOF_ZEND_LONG == 8
464 	COM_CONST(VT_UI8);
465 	COM_CONST(VT_I8);
466 #endif
467 	return SUCCESS;
468 }
469 /* }}} */
470 
471 /* {{{ PHP_MSHUTDOWN_FUNCTION
472  */
PHP_MSHUTDOWN_FUNCTION(com_dotnet)473 PHP_MSHUTDOWN_FUNCTION(com_dotnet)
474 {
475 	UNREGISTER_INI_ENTRIES();
476 #if HAVE_MSCOREE_H
477 	if (COMG(dotnet_runtime_stuff)) {
478 		php_com_dotnet_mshutdown();
479 	}
480 #endif
481 
482 	zend_ts_hash_destroy(&php_com_typelibraries);
483 	return SUCCESS;
484 }
485 /* }}} */
486 
487 /* {{{ PHP_RINIT_FUNCTION
488  */
PHP_RINIT_FUNCTION(com_dotnet)489 PHP_RINIT_FUNCTION(com_dotnet)
490 {
491 	COMG(rshutdown_started) = 0;
492 	return SUCCESS;
493 }
494 /* }}} */
495 
496 /* {{{ PHP_RSHUTDOWN_FUNCTION
497  */
PHP_RSHUTDOWN_FUNCTION(com_dotnet)498 PHP_RSHUTDOWN_FUNCTION(com_dotnet)
499 {
500 #if HAVE_MSCOREE_H
501 	if (COMG(dotnet_runtime_stuff)) {
502 		php_com_dotnet_rshutdown();
503 	}
504 #endif
505 	COMG(rshutdown_started) = 1;
506 	return SUCCESS;
507 }
508 /* }}} */
509 
510 /* {{{ PHP_MINFO_FUNCTION
511  */
PHP_MINFO_FUNCTION(com_dotnet)512 PHP_MINFO_FUNCTION(com_dotnet)
513 {
514 	php_info_print_table_start();
515 
516 	php_info_print_table_header(2, "COM support", "enabled");
517 	php_info_print_table_header(2, "DCOM support", COMG(allow_dcom) ? "enabled" : "disabled");
518 
519 #if HAVE_MSCOREE_H
520 	php_info_print_table_header(2, ".Net support", "enabled");
521 #else
522 	php_info_print_table_header(2, ".Net support", "not present in this build");
523 #endif
524 
525 	php_info_print_table_end();
526 
527 	DISPLAY_INI_ENTRIES();
528 }
529 /* }}} */
530 
531 /*
532  * Local variables:
533  * tab-width: 4
534  * c-basic-offset: 4
535  * End:
536  * vim600: noet sw=4 ts=4 fdm=marker
537  * vim<600: noet sw=4 ts=4
538  */
539