summaryrefslogtreecommitdiffstats
path: root/Python/dynload_win.c
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2021-12-03 00:08:42 (GMT)
committerGitHub <noreply@github.com>2021-12-03 00:08:42 (GMT)
commit99fcf1505218464c489d419d4500f126b6d6dc28 (patch)
treea9d607d854e943b3651248eadbe2f31f8c410021 /Python/dynload_win.c
parent9f2f7e42269db74a89fc8cd74d82a875787f01d7 (diff)
downloadcpython-99fcf1505218464c489d419d4500f126b6d6dc28.zip
cpython-99fcf1505218464c489d419d4500f126b6d6dc28.tar.gz
cpython-99fcf1505218464c489d419d4500f126b6d6dc28.tar.bz2
bpo-45582: Port getpath[p].c to Python (GH-29041)
The getpath.py file is frozen at build time and executed as code over a namespace. It is never imported, nor is it meant to be importable or reusable. However, it should be easier to read, modify, and patch than the previous code. This commit attempts to preserve every previously tested quirk, but these may be changed in the future to better align platforms.
Diffstat (limited to 'Python/dynload_win.c')
-rw-r--r--Python/dynload_win.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
index 5702ab2..854b1e6 100644
--- a/Python/dynload_win.c
+++ b/Python/dynload_win.c
@@ -2,6 +2,9 @@
/* Support for dynamic loading of extension modules */
#include "Python.h"
+#include "pycore_fileutils.h" // _Py_add_relfile()
+#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
#ifdef HAVE_DIRECT_H
#include <direct.h>
@@ -160,6 +163,60 @@ static char *GetPythonImport (HINSTANCE hModule)
return NULL;
}
+/* Load python3.dll before loading any extension module that might refer
+ to it. That way, we can be sure that always the python3.dll corresponding
+ to this python DLL is loaded, not a python3.dll that might be on the path
+ by chance.
+ Return whether the DLL was found.
+*/
+extern HMODULE PyWin_DLLhModule;
+static int
+_Py_CheckPython3(void)
+{
+ static int python3_checked = 0;
+ static HANDLE hPython3;
+ #define MAXPATHLEN 512
+ wchar_t py3path[MAXPATHLEN+1];
+ if (python3_checked) {
+ return hPython3 != NULL;
+ }
+ python3_checked = 1;
+
+ /* If there is a python3.dll next to the python3y.dll,
+ use that DLL */
+ if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) {
+ wchar_t *p = wcsrchr(py3path, L'\\');
+ if (p) {
+ wcscpy(p + 1, PY3_DLLNAME);
+ hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+ if (hPython3 != NULL) {
+ return 1;
+ }
+ }
+ }
+
+ /* If we can locate python3.dll in our application dir,
+ use that DLL */
+ hPython3 = LoadLibraryExW(PY3_DLLNAME, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
+ if (hPython3 != NULL) {
+ return 1;
+ }
+
+ /* For back-compat, also search {sys.prefix}\DLLs, though
+ that has not been a normal install layout for a while */
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
+ assert(config->prefix);
+ if (config->prefix) {
+ wcscpy_s(py3path, MAXPATHLEN, config->prefix);
+ if (py3path[0] && _Py_add_relfile(py3path, L"DLLs\\" PY3_DLLNAME, MAXPATHLEN) >= 0) {
+ hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
+ }
+ }
+ return hPython3 != NULL;
+ #undef MAXPATHLEN
+}
+
dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
const char *shortname,
PyObject *pathname, FILE *fp)