Skip to content

Commit

Permalink
Close phpGH-16718: GH-Add SAPI module folder to DLL search path
Browse files Browse the repository at this point in the history
On Windows, it is customary to put dependency DLLs in the main PHP
folder, i.e. right besides php.exe.  If the SAPI is implemented as
.exe, dependency lookup works fine, since DLLs are always searched in
the folder of the .exe.  However, for Webserver modules, this usually
does not work, since the Webserver's executable likely resides in a
different folder.  While there are obviously solutions to this, the
Windows error messages if a module can't be loaded are confusing, so
users and even popular AMP distributions often choose to put the DLLs
in the folder of the Webserver (e.g. right besides httpd.exe).  That
can easily cause more confusion later, when users update to a newer PHP
version, which requires more recent dependencies.

Thus, to simplify setup and to bring the behavior more in line with CLI
and CGI SAPIs, we add the SAPI module folder to the DLL search path.
We keep that simple, and do not cater to long paths, and silently don't
change the DLL search order in case of unexpected failures.

Since we are using `SetDllDirectory()` for all SAPIs, that effectively
also prevents DLLs being looked up in the current folder, what might
break some scripts, but can also avoid confusion regarding ZTS builds,
where the current directory of the process is not necessarily what is
reported by `getcwd()`.  It is also a small security measure, even
stronger than safe DLL search mode[1].

Note that this certainly does not solve all problems related to DLL
lookup, e.g. that the application folder is still searched first, and
that already loaded DLLs will not be searched and loaded again.  But it
appears to be a sensible improvement, and hopefully prevents others to
put DLLs in folders where they don't belong, in the future.

[1] <https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order>
  • Loading branch information
cmb69 committed Nov 27, 2024
1 parent 17187c4 commit 7b74480
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions main/SAPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,31 @@ static void sapi_globals_dtor(sapi_globals_struct *sapi_globals)
SAPI_API sapi_module_struct sapi_module;


#ifdef PHP_WIN32
static void add_sapi_module_folder_to_dll_search_path(sapi_module_struct *sf)
{
const DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT;
HMODULE module;
wchar_t filename[MAX_PATH];
if (GetModuleHandleEx(flags, (LPCTSTR) sf, &module)) {
DWORD len = GetModuleFileNameW(module, filename, MAX_PATH);
if (len > 0 && len < MAX_PATH) {
wchar_t *slash = wcsrchr(filename, L'\\');
slash[0] = L'\0';
SetDllDirectoryW(filename);
}
}
}
#endif

SAPI_API void sapi_startup(sapi_module_struct *sf)
{
sf->ini_entries = NULL;
sapi_module = *sf;

#ifdef PHP_WIN32
add_sapi_module_folder_to_dll_search_path(sf);
#endif
#ifdef ZTS
ts_allocate_fast_id(&sapi_globals_id, &sapi_globals_offset, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor);
# ifdef PHP_WIN32
Expand Down

0 comments on commit 7b74480

Please sign in to comment.