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
31 #if SIZEOF_ZEND_LONG == 8
32 #define PHP_DISP_E_DIVBYZERO ((zend_long) (ULONG) DISP_E_DIVBYZERO)
33 #define PHP_DISP_E_OVERFLOW ((zend_long) (ULONG) DISP_E_OVERFLOW)
34 #define PHP_DISP_E_BADINDEX ((zend_long) (ULONG) DISP_E_BADINDEX)
35 #define PHP_DISP_E_PARAMNOTFOUND ((zend_long) (ULONG) DISP_E_PARAMNOTFOUND)
36 #define PHP_MK_E_UNAVAILABLE ((zend_long) (ULONG) MK_E_UNAVAILABLE)
37 #else
38 #define PHP_DISP_E_DIVBYZERO DISP_E_DIVBYZERO
39 #define PHP_DISP_E_OVERFLOW DISP_E_OVERFLOW
40 #define PHP_DISP_E_BADINDEX DISP_E_BADINDEX
41 #define PHP_DISP_E_PARAMNOTFOUND DISP_E_PARAMNOTFOUND
42 #define PHP_MK_E_UNAVAILABLE MK_E_UNAVAILABLE
43 #endif
44
45 #include "com_extension_arginfo.h"
46
47 ZEND_DECLARE_MODULE_GLOBALS(com_dotnet)
48 static PHP_GINIT_FUNCTION(com_dotnet);
49
50 zend_class_entry
51 *php_com_variant_class_entry,
52 *php_com_exception_class_entry,
53 *php_com_saproxy_class_entry;
54
55 /* {{{ com_dotnet_module_entry */
56 zend_module_entry com_dotnet_module_entry = {
57 STANDARD_MODULE_HEADER,
58 "com_dotnet",
59 ext_functions,
60 PHP_MINIT(com_dotnet),
61 PHP_MSHUTDOWN(com_dotnet),
62 PHP_RINIT(com_dotnet),
63 PHP_RSHUTDOWN(com_dotnet),
64 PHP_MINFO(com_dotnet),
65 PHP_COM_DOTNET_VERSION,
66 PHP_MODULE_GLOBALS(com_dotnet),
67 PHP_GINIT(com_dotnet),
68 NULL,
69 NULL,
70 STANDARD_MODULE_PROPERTIES_EX
71 };
72 /* }}} */
73
74 #ifdef COMPILE_DL_COM_DOTNET
75 #ifdef ZTS
76 ZEND_TSRMLS_CACHE_DEFINE()
77 #endif
ZEND_GET_MODULE(com_dotnet)78 ZEND_GET_MODULE(com_dotnet)
79 #endif
80
81 /* {{{ PHP_INI */
82
83 /* com.typelib_file is the path to a file containing a
84 * list of typelibraries to register *persistently*.
85 * lines starting with ; are comments
86 * append #cis to end of typelib name to cause its constants
87 * to be loaded case insensitively */
88 static PHP_INI_MH(OnTypeLibFileUpdate)
89 {
90 FILE *typelib_file;
91 char *typelib_name_buffer;
92 char *strtok_buf = NULL;
93
94 if (NULL == new_value || !new_value->val[0] || (typelib_file = VCWD_FOPEN(new_value->val, "r"))==NULL) {
95 return FAILURE;
96 }
97
98 typelib_name_buffer = (char *) emalloc(sizeof(char)*1024);
99
100 while (fgets(typelib_name_buffer, 1024, typelib_file)) {
101 ITypeLib *pTL;
102 char *typelib_name;
103 char *modifier, *ptr;
104
105 if (typelib_name_buffer[0]==';') {
106 continue;
107 }
108 typelib_name = php_strtok_r(typelib_name_buffer, "\r\n", &strtok_buf); /* get rid of newlines */
109 if (typelib_name == NULL) {
110 continue;
111 }
112 typelib_name = php_strtok_r(typelib_name, "#", &strtok_buf);
113 modifier = php_strtok_r(NULL, "#", &strtok_buf);
114 if (modifier != NULL) {
115 if (!strcmp(modifier, "cis") || !strcmp(modifier, "case_insensitive")) {
116 php_error_docref("com.configuration", E_WARNING, "Declaration of case-insensitive constants is no longer supported; #cis modifier ignored");
117 }
118 }
119
120 /* Remove leading/training white spaces on search_string */
121 while (isspace(*typelib_name)) {/* Ends on '\0' in worst case */
122 typelib_name ++;
123 }
124 ptr = typelib_name + strlen(typelib_name) - 1;
125 while ((ptr != typelib_name) && isspace(*ptr)) {
126 *ptr = '\0';
127 ptr--;
128 }
129
130 if ((pTL = php_com_load_typelib_via_cache(typelib_name, COMG(code_page))) != NULL) {
131 php_com_import_typelib(pTL, CONST_PERSISTENT, COMG(code_page));
132 ITypeLib_Release(pTL);
133 }
134 }
135
136 efree(typelib_name_buffer);
137 fclose(typelib_file);
138
139 return SUCCESS;
140 }
141
ZEND_INI_MH(OnAutoregisterCasesensitive)142 static ZEND_INI_MH(OnAutoregisterCasesensitive)
143 {
144 if (!zend_ini_parse_bool(new_value)) {
145 php_error_docref("com.configuration", E_WARNING, "Declaration of case-insensitive constants is no longer supported");
146 return FAILURE;
147 }
148 return OnUpdateBool(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
149 }
150
151 PHP_INI_BEGIN()
152 STD_PHP_INI_BOOLEAN("com.allow_dcom", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_dcom, zend_com_dotnet_globals, com_dotnet_globals)
153 STD_PHP_INI_BOOLEAN("com.autoregister_verbose", "0", PHP_INI_ALL, OnUpdateBool, autoreg_verbose, zend_com_dotnet_globals, com_dotnet_globals)
154 STD_PHP_INI_BOOLEAN("com.autoregister_typelib", "0", PHP_INI_ALL, OnUpdateBool, autoreg_on, zend_com_dotnet_globals, com_dotnet_globals)
155 STD_PHP_INI_ENTRY("com.autoregister_casesensitive", "1", PHP_INI_ALL, OnAutoregisterCasesensitive, autoreg_case_sensitive, zend_com_dotnet_globals, com_dotnet_globals)
156 STD_PHP_INI_ENTRY("com.code_page", "", PHP_INI_ALL, OnUpdateLong, code_page, zend_com_dotnet_globals, com_dotnet_globals)
157 PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypeLibFileUpdate)
158 PHP_INI_ENTRY("com.dotnet_version", NULL, PHP_INI_SYSTEM, NULL)
PHP_INI_END()159 PHP_INI_END()
160 /* }}} */
161
162 /* {{{ PHP_GINIT_FUNCTION */
163 static PHP_GINIT_FUNCTION(com_dotnet)
164 {
165 #if defined(COMPILE_DL_COM_DOTNET) && defined(ZTS)
166 ZEND_TSRMLS_CACHE_UPDATE();
167 #endif
168 memset(com_dotnet_globals, 0, sizeof(*com_dotnet_globals));
169 com_dotnet_globals->code_page = CP_ACP;
170 }
171 /* }}} */
172
173 /* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(com_dotnet)174 PHP_MINIT_FUNCTION(com_dotnet)
175 {
176 zend_class_entry *tmp;
177
178 php_com_wrapper_minit(INIT_FUNC_ARGS_PASSTHRU);
179 php_com_persist_minit(INIT_FUNC_ARGS_PASSTHRU);
180
181 php_com_exception_class_entry = register_class_com_exception(zend_ce_exception);
182 /* php_com_exception_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
183
184 php_com_saproxy_class_entry = register_class_com_safearray_proxy();
185 /* php_com_saproxy_class_entry->constructor->common.fn_flags |= ZEND_ACC_PROTECTED; */
186 php_com_saproxy_class_entry->default_object_handlers = &php_com_saproxy_handlers;
187 php_com_saproxy_class_entry->get_iterator = php_com_saproxy_iter_get;
188
189 php_com_variant_class_entry = register_class_variant();
190 php_com_variant_class_entry->default_object_handlers = &php_com_object_handlers;
191 php_com_variant_class_entry->create_object = php_com_object_new;
192 php_com_variant_class_entry->get_iterator = php_com_iter_get;
193
194 tmp = register_class_com(php_com_variant_class_entry);
195 tmp->default_object_handlers = &php_com_object_handlers;
196 tmp->create_object = php_com_object_new;
197 tmp->get_iterator = php_com_iter_get;
198
199 #if HAVE_MSCOREE_H
200 tmp = register_class_dotnet(php_com_variant_class_entry);
201 tmp->default_object_handlers = &php_com_object_handlers;
202 tmp->create_object = php_com_object_new;
203 tmp->get_iterator = php_com_iter_get;
204 #endif
205
206 REGISTER_INI_ENTRIES();
207
208 register_com_extension_symbols(module_number);
209
210 PHP_MINIT(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
211
212 return SUCCESS;
213 }
214 /* }}} */
215
216 /* {{{ PHP_MSHUTDOWN_FUNCTION */
PHP_MSHUTDOWN_FUNCTION(com_dotnet)217 PHP_MSHUTDOWN_FUNCTION(com_dotnet)
218 {
219 UNREGISTER_INI_ENTRIES();
220 #if HAVE_MSCOREE_H
221 if (COMG(dotnet_runtime_stuff)) {
222 php_com_dotnet_mshutdown();
223 }
224 #endif
225
226 PHP_MSHUTDOWN(com_typeinfo)(INIT_FUNC_ARGS_PASSTHRU);
227
228 return SUCCESS;
229 }
230 /* }}} */
231
232 /* {{{ PHP_RINIT_FUNCTION */
PHP_RINIT_FUNCTION(com_dotnet)233 PHP_RINIT_FUNCTION(com_dotnet)
234 {
235 COMG(rshutdown_started) = 0;
236 return SUCCESS;
237 }
238 /* }}} */
239
240 /* {{{ PHP_RSHUTDOWN_FUNCTION */
PHP_RSHUTDOWN_FUNCTION(com_dotnet)241 PHP_RSHUTDOWN_FUNCTION(com_dotnet)
242 {
243 #if HAVE_MSCOREE_H
244 if (COMG(dotnet_runtime_stuff)) {
245 php_com_dotnet_rshutdown();
246 }
247 #endif
248 COMG(rshutdown_started) = 1;
249 return SUCCESS;
250 }
251 /* }}} */
252
253 /* {{{ PHP_MINFO_FUNCTION */
PHP_MINFO_FUNCTION(com_dotnet)254 PHP_MINFO_FUNCTION(com_dotnet)
255 {
256 php_info_print_table_start();
257
258 php_info_print_table_row(2, "COM support", "enabled");
259 php_info_print_table_row(2, "DCOM support", COMG(allow_dcom) ? "enabled" : "disabled");
260
261 #if HAVE_MSCOREE_H
262 php_info_print_table_row(2, ".Net support", "enabled");
263 #else
264 php_info_print_table_row(2, ".Net support", "not present in this build");
265 #endif
266
267 php_info_print_table_end();
268
269 DISPLAY_INI_ENTRIES();
270 }
271 /* }}} */
272