summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-08-06 18:57:18 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-08-22 12:42:34 +0200
commite6044d4455d7fbaced7f3a6ac28172d963017e51 (patch)
tree31a91bbbc78709a3c339680231188a2558846b5e
parent969a432fd8b34a0ec4e48e903370f0659aef6b04 (diff)
downloadphp-git-e6044d4455d7fbaced7f3a6ac28172d963017e51.tar.gz
Fix #55847: DOTNET .NET 4.0 GAC new location
If we do not specify the exact version of the .NET framework to use, the default CLR is loaded, which is typically CLR 2, which is very old. Therefore, we introduce a `PHP_INI_SYSTEM` setting, which allows users to choose the desired .NET framework version. The value of the setting are the first three parts of the framework's version number, separated by dots, and prefixed with "v", e.g. "v4.0.30319". If the value of the INI setting is `NULL` (the default) or an empty string, the default CLR is used. Internally, we switch from the most generic `CoCreateInstance()` to `CorBindToRuntime()` which is implemented in mscoree.dll. To avoid the hard dependency to that library, we load dynamically. So this fix is supposed to be fully backwards compatible. Closes GH-5949
-rw-r--r--NEWS3
-rw-r--r--UPGRADING4
-rw-r--r--ext/com_dotnet/com_dotnet.c44
-rw-r--r--ext/com_dotnet/com_extension.c1
-rw-r--r--php.ini-development4
-rw-r--r--php.ini-production4
6 files changed, 56 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 65395d8f2b..8d81c0cd5c 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ PHP NEWS
. Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing).
(Andy Postnikov)
+- COM:
+ . Fixed bug #55847 (DOTNET .NET 4.0 GAC new location). (cmb)
+
- DOM:
. Fixed bug #79968 (DOMChildNode API crash on unattached nodes). (Benjamin)
diff --git a/UPGRADING b/UPGRADING
index 9cb89cf969..2412b60865 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -1048,6 +1048,10 @@ PHP 8.0 UPGRADE NOTES
. New INI directive to set the maximum string length in an argument of a
stringified stack strace.
+- com.dotnet_version
+ . New INI directive to choose the version of the .NET framework to use for
+ dotnet objects.
+
========================================
12. Windows Support
========================================
diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c
index 6bd492ef1d..1b0ba2220c 100644
--- a/ext/com_dotnet/com_dotnet.c
+++ b/ext/com_dotnet/com_dotnet.c
@@ -117,6 +117,44 @@ struct dotnet_runtime_stuff {
DISPID create_instance;
};
+/* We link dynamically to mscoree.dll to avoid the hard dependency on .NET
+ * framework, which is only required if a dotnet instance is to be created.
+ */
+static HRESULT dotnet_bind_runtime(LPVOID FAR *ppv)
+{
+ HRESULT hr;
+ HMODULE mscoree;
+ typedef HRESULT (STDAPICALLTYPE *cbtr_t)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
+ cbtr_t CorBindToRuntime;
+ OLECHAR *oleversion;
+ char *version;
+
+ mscoree = LoadLibraryA("mscoree.dll");
+ if (mscoree == NULL) {
+ return S_FALSE;
+ }
+
+ CorBindToRuntime = (cbtr_t) GetProcAddress(mscoree, "CorBindToRuntime");
+ if (CorBindToRuntime == NULL) {
+ FreeLibrary(mscoree);
+ return S_FALSE;
+ }
+
+ version = INI_STR("com.dotnet_version");
+ if (version == NULL || *version == '\0') {
+ oleversion = NULL;
+ } else {
+ oleversion = php_com_string_to_olestring(version, strlen(version), COMG(code_page));
+ }
+
+ hr = CorBindToRuntime(oleversion, NULL, &CLSID_CorRuntimeHost, &IID_ICorRuntimeHost, ppv);
+
+ efree(oleversion);
+ FreeLibrary(mscoree);
+
+ return hr;
+}
+
static HRESULT dotnet_init(char **p_where)
{
HRESULT hr;
@@ -130,10 +168,8 @@ static HRESULT dotnet_init(char **p_where)
}
memset(stuff, 0, sizeof(*stuff));
- where = "CoCreateInstance";
- hr = CoCreateInstance(&CLSID_CorRuntimeHost, NULL, CLSCTX_ALL,
- &IID_ICorRuntimeHost, (LPVOID*)&stuff->dotnet_host);
-
+ where = "dotnet_bind_runtime";
+ hr = dotnet_bind_runtime((LPVOID*)&stuff->dotnet_host);
if (FAILED(hr))
goto out;
diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c
index 0535509412..5e2c1f69de 100644
--- a/ext/com_dotnet/com_extension.c
+++ b/ext/com_dotnet/com_extension.c
@@ -141,6 +141,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("com.autoregister_casesensitive", "1", PHP_INI_ALL, OnAutoregisterCasesensitive, autoreg_case_sensitive, zend_com_dotnet_globals, com_dotnet_globals)
STD_PHP_INI_ENTRY("com.code_page", "", PHP_INI_ALL, OnUpdateLong, code_page, zend_com_dotnet_globals, com_dotnet_globals)
PHP_INI_ENTRY("com.typelib_file", "", PHP_INI_SYSTEM, OnTypeLibFileUpdate)
+ PHP_INI_ENTRY("com.dotnet_version", NULL, PHP_INI_SYSTEM, NULL)
PHP_INI_END()
/* }}} */
diff --git a/php.ini-development b/php.ini-development
index b352f5056f..54006830a2 100644
--- a/php.ini-development
+++ b/php.ini-development
@@ -1614,6 +1614,10 @@ zend.assertions = 1
; Default: system ANSI code page
;com.code_page=
+; The version of the .NET framework to use. The value of the setting are the first three parts
+; of the framework's version number, separated by dots, and prefixed with "v", e.g. "v4.0.30319".
+;com.dotnet_version=
+
[mbstring]
; language for internal character representation.
; This affects mb_send_mail() and mbstring.detect_order.
diff --git a/php.ini-production b/php.ini-production
index 61960ef807..47a5c5e13b 100644
--- a/php.ini-production
+++ b/php.ini-production
@@ -1618,6 +1618,10 @@ zend.assertions = -1
; Default: system ANSI code page
;com.code_page=
+; The version of the .NET framework to use. The value of the setting are the first three parts
+; of the framework's version number, separated by dots, and prefixed with "v", e.g. "v4.0.30319".
+;com.dotnet_version=
+
[mbstring]
; language for internal character representation.
; This affects mb_send_mail() and mbstring.detect_order.