summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-08-05 08:59:41 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-09-21 16:25:31 +0200
commit3e33e1e86d15e262cd9e0224a9604e252f5d9284 (patch)
tree8cb9f1178c8d2d287144c7be3cf7c7037c7bd72a /win32
parent6fa2493789f8f05c7a53eca803227fcfb1bf2573 (diff)
downloadphp-git-3e33e1e86d15e262cd9e0224a9604e252f5d9284.tar.gz
Check linker compatibility directly from HMODULE
Checking the linker compatibility with extranous `ImageLoad()` calls is possible, but unnecessary, since the modules are either already loaded or loaded shortly afterwards, so that we can get the required information directly from the module handles. And actually, doing `ImageLoad()` as well as `LoadLibrary()` leaves a tiny room for a race condition, because both functions will lookup the module in the search path, so there is no *guarantee* that both are dealing with the same module. Dropping the `ImageLoad()` calls also has the advantage to no longer face the issue reported in bug #79557. A very minor additional advantage is that we no longer have to link against Imagehlp.dll. Furthermore, there is no need to check for CRT compatibility multiple times, so we can simplify the signature of `php_win32_crt_compatible`, and at the same time clean up main.c a bit. These changes require to change the signature of the exported `php_win32_image_compatible` and `php_win32_crt_compatible` functions, which now expect a `HMODULE` and nothing, respectively, instead of the module name.
Diffstat (limited to 'win32')
-rw-r--r--win32/build/confutils.js2
-rw-r--r--win32/winutil.c58
-rw-r--r--win32/winutil.h4
3 files changed, 33 insertions, 31 deletions
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index e71757748f..857e50acbe 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -3401,7 +3401,7 @@ function toolset_setup_common_ldlags()
function toolset_setup_common_libs()
{
// urlmon.lib ole32.lib oleaut32.lib uuid.lib gdi32.lib winspool.lib comdlg32.lib
- DEFINE("LIBS", "kernel32.lib ole32.lib user32.lib advapi32.lib shell32.lib ws2_32.lib Dnsapi.lib psapi.lib bcrypt.lib imagehlp.lib");
+ DEFINE("LIBS", "kernel32.lib ole32.lib user32.lib advapi32.lib shell32.lib ws2_32.lib Dnsapi.lib psapi.lib bcrypt.lib");
}
function toolset_setup_build_mode()
diff --git a/win32/winutil.c b/win32/winutil.c
index 40664a9e03..530dc4f0f6 100644
--- a/win32/winutil.c
+++ b/win32/winutil.c
@@ -20,7 +20,6 @@
#include "codepage.h"
#include <bcrypt.h>
#include <lmcons.h>
-#include <imagehlp.h>
PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error)
@@ -436,26 +435,13 @@ PHP_WINUTIL_API char *php_win32_get_username(void)
return uname;
}/*}}}*/
-static zend_always_inline BOOL is_compatible(const char *name, BOOL is_smaller, char *format, char **err)
+static zend_always_inline BOOL is_compatible(HMODULE handle, BOOL is_smaller, char *format, char **err)
{/*{{{*/
- /* work around ImageLoad() issue */
- const char *name_stripped = name;
- if (name[0] == '.' && IS_SLASH(name[1])) {
- name_stripped += 2;
- }
-
- PLOADED_IMAGE img = ImageLoad(name_stripped, NULL);
+ PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) handle;
+ PIMAGE_NT_HEADERS pNTHeader = (PIMAGE_NT_HEADERS)((char *) dosHeader + dosHeader->e_lfanew);
- if (!img) {
- DWORD _err = GetLastError();
- char *err_txt = php_win32_error_to_msg(_err);
- spprintf(err, 0, "Failed to load %s, %s", name, err_txt);
- free(err_txt);
- return FALSE;
- }
-
- DWORD major = img->FileHeader->OptionalHeader.MajorLinkerVersion;
- DWORD minor = img->FileHeader->OptionalHeader.MinorLinkerVersion;
+ DWORD major = pNTHeader->OptionalHeader.MajorLinkerVersion;
+ DWORD minor = pNTHeader->OptionalHeader.MinorLinkerVersion;
#if PHP_LINKER_MAJOR == 14
/* VS 2015, 2017 and 2019 are binary compatible, but only forward compatible.
@@ -474,23 +460,39 @@ static zend_always_inline BOOL is_compatible(const char *name, BOOL is_smaller,
if (PHP_LINKER_MAJOR != major)
#endif
{
- spprintf(err, 0, format, name, major, minor, PHP_LINKER_MAJOR, PHP_LINKER_MINOR);
- ImageUnload(img);
+ char buf[MAX_PATH];
+ if (GetModuleFileName(handle, buf, sizeof(buf)) != 0) {
+ spprintf(err, 0, format, buf, major, minor, PHP_LINKER_MAJOR, PHP_LINKER_MINOR);
+ } else {
+ spprintf(err, 0, "Can't retrieve the module name (error %u)", GetLastError());
+ }
return FALSE;
}
- ImageUnload(img);
return TRUE;
}/*}}}*/
-PHP_WINUTIL_API BOOL php_win32_image_compatible(const char *name, char **err)
+PHP_WINUTIL_API BOOL php_win32_image_compatible(HMODULE handle, char **err)
{/*{{{*/
- return is_compatible(name, TRUE, "Can't load module '%s' as it's linked with %u.%u, but the core is linked with %d.%d", err);
+ return is_compatible(handle, TRUE, "Can't load module '%s' as it's linked with %u.%u, but the core is linked with %d.%d", err);
}/*}}}*/
-/* Expect a CRT name DLL. */
-PHP_WINUTIL_API BOOL php_win32_crt_compatible(const char *name, char **err)
+/* Expect a CRT module handle */
+PHP_WINUTIL_API BOOL php_win32_crt_compatible(char **err)
{/*{{{*/
- return is_compatible(name, FALSE, "'%s' %u.%u is not compatible with this PHP build linked with %d.%d", err);
+#if PHP_LINKER_MAJOR == 14
+ /* Extend for other CRT if needed. */
+# if PHP_DEBUG
+ const char *crt_name = "vcruntime140d.dll";
+# else
+ const char *crt_name = "vcruntime140.dll";
+# endif
+ HMODULE handle = GetModuleHandle(crt_name);
+ if (handle == NULL) {
+ spprintf(err, 0, "Can't get handle of module %s (error %u)", crt_name, GetLastError());
+ return FALSE;
+ }
+ return is_compatible(handle, FALSE, "'%s' %u.%u is not compatible with this PHP build linked with %d.%d", err);
+#endif
+ return TRUE;
}/*}}}*/
-
diff --git a/win32/winutil.h b/win32/winutil.h
index 8acf87e671..cc3f115280 100644
--- a/win32/winutil.h
+++ b/win32/winutil.h
@@ -53,7 +53,7 @@ PHP_WINUTIL_API int php_win32_code_to_errno(unsigned long w32Err);
PHP_WINUTIL_API char *php_win32_get_username(void);
-PHP_WINUTIL_API BOOL php_win32_image_compatible(const char *img, char **err);
-PHP_WINUTIL_API BOOL php_win32_crt_compatible(const char *img, char **err);
+PHP_WINUTIL_API BOOL php_win32_image_compatible(HMODULE handle, char **err);
+PHP_WINUTIL_API BOOL php_win32_crt_compatible(char **err);
#endif