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