blob: c4c0636dddeb1fc2a9ac8bcf8c67d7cf8494e90e [file] [log] [blame]
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00001
2/* Return the initial module search path. */
Jesus Ceaf1af7052012-10-05 02:48:46 +02003/* Used by DOS, Windows 3.1, Windows 95/98, Windows NT. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00004
Guido van Rossum88716bb2000-03-30 19:45:39 +00005/* ----------------------------------------------------------------
6 PATH RULES FOR WINDOWS:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00007 This describes how sys.path is formed on Windows. It describes the
8 functionality, not the implementation (ie, the order in which these
Steve Dowered51b262016-09-17 12:54:06 -07009 are actually fetched is different). The presence of a python._pth or
10 pythonXY._pth file alongside the program overrides these rules - see
11 below.
Guido van Rossum88716bb2000-03-30 19:45:39 +000012
13 * Python always adds an empty entry at the start, which corresponds
14 to the current directory.
15
Georg Brandl7eb4b7d2005-07-22 21:49:32 +000016 * If the PYTHONPATH env. var. exists, its entries are added next.
Guido van Rossum88716bb2000-03-30 19:45:39 +000017
18 * We look in the registry for "application paths" - that is, sub-keys
19 under the main PythonPath registry key. These are added next (the
20 order of sub-key processing is undefined).
21 HKEY_CURRENT_USER is searched and added first.
22 HKEY_LOCAL_MACHINE is searched and added next.
23 (Note that all known installers only use HKLM, so HKCU is typically
24 empty)
25
26 * We attempt to locate the "Python Home" - if the PYTHONHOME env var
27 is set, we believe it. Otherwise, we use the path of our host .EXE's
Martin Panterfd13c0f2016-09-10 10:45:28 +000028 to try and locate one of our "landmarks" and deduce our home.
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 - If we DO have a Python Home: The relevant sub-directories (Lib,
Zachary Warec4b53af2016-09-09 17:59:49 -070030 DLLs, etc) are based on the Python Home
Guido van Rossum88716bb2000-03-30 19:45:39 +000031 - If we DO NOT have a Python Home, the core Python Path is
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000032 loaded from the registry. This is the main PythonPath key,
Guido van Rossum88716bb2000-03-30 19:45:39 +000033 and both HKLM and HKCU are combined to form the path)
34
35 * Iff - we can not locate the Python Home, have not had a PYTHONPATH
36 specified, and can't locate any Registry entries (ie, we have _nothing_
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 we can assume is a good path), a default path with relative entries is
Zachary Warec4b53af2016-09-09 17:59:49 -070038 used (eg. .\Lib;.\DLLs, etc)
Guido van Rossum88716bb2000-03-30 19:45:39 +000039
40
Steve Dowered51b262016-09-17 12:54:06 -070041 If a '._pth' file exists adjacent to the executable with the same base name
42 (e.g. python._pth adjacent to python.exe) or adjacent to the shared library
43 (e.g. python36._pth adjacent to python36.dll), it is used in preference to
44 the above process. The shared library file takes precedence over the
45 executable. The path file must contain a list of paths to add to sys.path,
46 one per line. Each path is relative to the directory containing the file.
47 Blank lines and comments beginning with '#' are permitted.
48
49 In the presence of this ._pth file, no other paths are added to the search
50 path, the registry finder is not enabled, site.py is not imported and
51 isolated mode is enabled. The site package can be enabled by including a
52 line reading "import site"; no other imports are recognized. Any invalid
53 entry (other than directories that do not exist) will result in immediate
54 termination of the program.
55
Steve Dower4db86bc2016-09-09 09:17:35 -070056
Guido van Rossum88716bb2000-03-30 19:45:39 +000057 The end result of all this is:
58 * When running python.exe, or any other .exe in the main Python directory
59 (either an installed version, or directly from the PCbuild directory),
60 the core path is deduced, and the core paths in the registry are
61 ignored. Other "application paths" in the registry are always read.
62
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000063 * When Python is hosted in another exe (different directory, embedded via
Guido van Rossum88716bb2000-03-30 19:45:39 +000064 COM, etc), the Python Home will not be deduced, so the core path from
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000065 the registry is used. Other "application paths" in the registry are
Guido van Rossum88716bb2000-03-30 19:45:39 +000066 always read.
67
68 * If Python can't find its home and there is no registry (eg, frozen
69 exe, some very strange installation setup) you get a path with
70 some default, but relative, paths.
71
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +000072 * An embedding application can use Py_SetPath() to override all of
Steve Dower4db86bc2016-09-09 09:17:35 -070073 these automatic path computations.
74
Steve Dowered51b262016-09-17 12:54:06 -070075 * An install of Python can fully specify the contents of sys.path using
76 either a 'EXENAME._pth' or 'DLLNAME._pth' file, optionally including
77 "import site" to enable the site module.
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +000078
Guido van Rossum88716bb2000-03-30 19:45:39 +000079 ---------------------------------------------------------------- */
80
81
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000082#include "Python.h"
Victor Stinner331a6a52019-05-27 16:39:22 +020083#include "pycore_initconfig.h"
Victor Stinner621cebe2018-11-12 16:53:38 +010084#include "pycore_pystate.h"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000085#include "osdefs.h"
Martin v. Löwis790465f2008-04-05 20:41:37 +000086#include <wchar.h>
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000087
Steve Dower4db86bc2016-09-09 09:17:35 -070088#ifndef MS_WINDOWS
89#error getpathp.c should only be built on Windows
Guido van Rossum8f1b6511997-08-13 19:55:43 +000090#endif
91
Steve Dower4db86bc2016-09-09 09:17:35 -070092#include <windows.h>
erikjanss6cf82552018-07-25 02:41:46 +020093#include <shlwapi.h>
Steve Dower4db86bc2016-09-09 09:17:35 -070094
Thomas Wouters0e3f5912006-08-11 14:57:12 +000095#ifdef HAVE_SYS_TYPES_H
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +000096#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000097#endif /* HAVE_SYS_TYPES_H */
98
99#ifdef HAVE_SYS_STAT_H
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000100#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000101#endif /* HAVE_SYS_STAT_H */
102
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000103#include <string.h>
104
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000105/* Search in some common locations for the associated Python libraries.
106 *
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000107 * Py_GetPath() tries to return a sensible Python module search path.
108 *
Guido van Rossum42a97441998-02-19 21:00:45 +0000109 * The approach is an adaptation for Windows of the strategy used in
110 * ../Modules/getpath.c; it uses the Windows Registry as one of its
111 * information sources.
Kristján Valur Jónsson3b69db22010-09-27 05:32:54 +0000112 *
113 * Py_SetPath() can be used to override this mechanism. Call Py_SetPath
114 * with a semicolon separated path prior to calling Py_Initialize.
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000115 */
116
117#ifndef LANDMARK
Victor Stinner85ce0a72019-09-24 00:55:48 +0200118# define LANDMARK L"lib\\os.py"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000119#endif
120
Victor Stinner85ce0a72019-09-24 00:55:48 +0200121#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")
122
123
Victor Stinner0327bde2017-11-23 17:03:20 +0100124typedef struct {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200125 const wchar_t *path_env; /* PATH environment variable */
126 const wchar_t *home; /* PYTHONHOME environment variable */
Victor Stinner0327bde2017-11-23 17:03:20 +0100127
Victor Stinner85ce0a72019-09-24 00:55:48 +0200128 /* Registry key "Software\Python\PythonCore\X.Y\PythonPath"
129 where X.Y is the Python version (major.minor) */
Victor Stinner0327bde2017-11-23 17:03:20 +0100130 wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
131 wchar_t *user_path; /* from HKEY_CURRENT_USER */
132
Victor Stinnerc4221672019-09-21 01:02:56 +0200133 wchar_t *dll_path;
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200134
135 const wchar_t *pythonpath_env;
Victor Stinner0327bde2017-11-23 17:03:20 +0100136} PyCalculatePath;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000137
Guido van Rossumeea14491997-08-13 21:30:44 +0000138
Victor Stinner0327bde2017-11-23 17:03:20 +0100139/* determine if "ch" is a separator character */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000140static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100141is_sep(wchar_t ch)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000142{
143#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 return ch == SEP || ch == ALTSEP;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000145#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 return ch == SEP;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000147#endif
148}
149
Victor Stinner0327bde2017-11-23 17:03:20 +0100150
Mark Hammond8bf9e3b2000-10-07 11:10:50 +0000151/* assumes 'dir' null terminated in bounds. Never writes
Victor Stinner0327bde2017-11-23 17:03:20 +0100152 beyond existing terminator. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000153static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000154reduce(wchar_t *dir)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000155{
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700156 size_t i = wcsnlen_s(dir, MAXPATHLEN+1);
Victor Stinner0327bde2017-11-23 17:03:20 +0100157 if (i >= MAXPATHLEN+1) {
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700158 Py_FatalError("buffer overflow in getpathp.c's reduce()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100159 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 while (i > 0 && !is_sep(dir[i]))
162 --i;
163 dir[i] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000164}
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165
Victor Stinner0327bde2017-11-23 17:03:20 +0100166
Steve Dowered51b262016-09-17 12:54:06 -0700167static int
168change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
169{
170 size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
171 size_t i = src_len;
Victor Stinner0327bde2017-11-23 17:03:20 +0100172 if (i >= MAXPATHLEN+1) {
Steve Dowered51b262016-09-17 12:54:06 -0700173 Py_FatalError("buffer overflow in getpathp.c's reduce()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100174 }
Steve Dowered51b262016-09-17 12:54:06 -0700175
176 while (i > 0 && src[i] != '.' && !is_sep(src[i]))
177 --i;
178
179 if (i == 0) {
180 dest[0] = '\0';
181 return -1;
182 }
183
Victor Stinner0327bde2017-11-23 17:03:20 +0100184 if (is_sep(src[i])) {
Steve Dowered51b262016-09-17 12:54:06 -0700185 i = src_len;
Victor Stinner0327bde2017-11-23 17:03:20 +0100186 }
Steve Dowered51b262016-09-17 12:54:06 -0700187
188 if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
Victor Stinner0327bde2017-11-23 17:03:20 +0100189 wcscat_s(dest, MAXPATHLEN+1, ext))
190 {
Steve Dowered51b262016-09-17 12:54:06 -0700191 dest[0] = '\0';
192 return -1;
193 }
194
195 return 0;
196}
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000197
Victor Stinner0327bde2017-11-23 17:03:20 +0100198
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000199static int
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200200exists(const wchar_t *filename)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000202 return GetFileAttributesW(filename) != 0xFFFFFFFF;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000203}
204
Victor Stinner0327bde2017-11-23 17:03:20 +0100205
206/* Is module -- check for .pyc too.
207 Assumes 'filename' MAXPATHLEN+1 bytes long -
208 may extend 'filename' by one character. */
Guido van Rossum43ff1141998-08-08 23:40:40 +0000209static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100210ismodule(wchar_t *filename, int update_filename)
Guido van Rossum43ff1141998-08-08 23:40:40 +0000211{
Victor Stinnerccb1f8c2016-03-23 11:31:58 +0100212 size_t n;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700213
Victor Stinner0327bde2017-11-23 17:03:20 +0100214 if (exists(filename)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100216 }
Guido van Rossum43ff1141998-08-08 23:40:40 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 /* Check for the compiled version of prefix. */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700219 n = wcsnlen_s(filename, MAXPATHLEN+1);
220 if (n < MAXPATHLEN) {
221 int exist = 0;
Xiang Zhang0710d752017-03-11 13:02:52 +0800222 filename[n] = L'c';
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700223 filename[n + 1] = L'\0';
224 exist = exists(filename);
Victor Stinner0327bde2017-11-23 17:03:20 +0100225 if (!update_filename) {
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700226 filename[n] = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100227 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700228 return exist;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 }
230 return 0;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000231}
232
Victor Stinner0327bde2017-11-23 17:03:20 +0100233
Tim Peters8484fbf2004-08-07 19:12:27 +0000234/* Add a path component, by appending stuff to buffer.
235 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
236 NUL-terminated string with no more than MAXPATHLEN characters (not counting
237 the trailing NUL). It's a fatal error if it contains a string longer than
238 that (callers must be careful!). If these requirements are met, it's
239 guaranteed that buffer will still be a NUL-terminated string with no more
240 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
241 stuff as fits will be appended.
242*/
Steve Dower4db86bc2016-09-09 09:17:35 -0700243
244static int _PathCchCombineEx_Initialized = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100245typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut,
246 PCWSTR pszPathIn, PCWSTR pszMore,
247 unsigned long dwFlags);
Steve Dower4db86bc2016-09-09 09:17:35 -0700248static PPathCchCombineEx _PathCchCombineEx;
249
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000250static void
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700251join(wchar_t *buffer, const wchar_t *stuff)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000252{
Steve Dower4db86bc2016-09-09 09:17:35 -0700253 if (_PathCchCombineEx_Initialized == 0) {
254 HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
Victor Stinner0327bde2017-11-23 17:03:20 +0100255 if (pathapi) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700256 _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
Victor Stinner0327bde2017-11-23 17:03:20 +0100257 }
258 else {
Steve Dower4db86bc2016-09-09 09:17:35 -0700259 _PathCchCombineEx = NULL;
Victor Stinner0327bde2017-11-23 17:03:20 +0100260 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700261 _PathCchCombineEx_Initialized = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700263
Steve Dower4db86bc2016-09-09 09:17:35 -0700264 if (_PathCchCombineEx) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100265 if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700266 Py_FatalError("buffer overflow in getpathp.c's join()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100267 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700268 } else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100269 if (!PathCombineW(buffer, buffer, stuff)) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700270 Py_FatalError("buffer overflow in getpathp.c's join()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100271 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700272 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000273}
274
Steve Dower48e8c822018-02-22 10:39:26 -0800275static int _PathCchCanonicalizeEx_Initialized = 0;
276typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cchPathOut,
277 PCWSTR pszPathIn, unsigned long dwFlags);
278static PPathCchCanonicalizeEx _PathCchCanonicalizeEx;
279
Victor Stinner85ce0a72019-09-24 00:55:48 +0200280/* Call PathCchCanonicalizeEx(path): remove navigation elements such as "."
281 and ".." to produce a direct, well-formed path. */
282static PyStatus
283canonicalize(wchar_t *buffer, const wchar_t *path)
Steve Dower48e8c822018-02-22 10:39:26 -0800284{
285 if (buffer == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200286 return _PyStatus_NO_MEMORY();
Steve Dower48e8c822018-02-22 10:39:26 -0800287 }
288
289 if (_PathCchCanonicalizeEx_Initialized == 0) {
290 HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
291 if (pathapi) {
292 _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx");
293 }
294 else {
295 _PathCchCanonicalizeEx = NULL;
296 }
297 _PathCchCanonicalizeEx_Initialized = 1;
298 }
299
300 if (_PathCchCanonicalizeEx) {
301 if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200302 return INIT_ERR_BUFFER_OVERFLOW();
Steve Dower48e8c822018-02-22 10:39:26 -0800303 }
304 }
305 else {
306 if (!PathCanonicalizeW(buffer, path)) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200307 return INIT_ERR_BUFFER_OVERFLOW();
Steve Dower48e8c822018-02-22 10:39:26 -0800308 }
309 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200310 return _PyStatus_OK();
Steve Dower48e8c822018-02-22 10:39:26 -0800311}
312
Victor Stinner0327bde2017-11-23 17:03:20 +0100313
Mark Hammond8bf9e3b2000-10-07 11:10:50 +0000314/* gotlandmark only called by search_for_prefix, which ensures
315 'prefix' is null terminated in bounds. join() ensures
Victor Stinner0327bde2017-11-23 17:03:20 +0100316 'landmark' can not overflow prefix if too long. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000317static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100318gotlandmark(wchar_t *prefix, const wchar_t *landmark)
Guido van Rossume02e48b2000-03-29 01:49:47 +0000319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 int ok;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700321 Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN);
Guido van Rossume02e48b2000-03-29 01:49:47 +0000322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 join(prefix, landmark);
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700324 ok = ismodule(prefix, FALSE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000325 prefix[n] = '\0';
326 return ok;
Guido van Rossume02e48b2000-03-29 01:49:47 +0000327}
328
Victor Stinner0327bde2017-11-23 17:03:20 +0100329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200331 assumption provided by only caller, calculate_path() */
Guido van Rossume02e48b2000-03-29 01:49:47 +0000332static int
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200333search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 /* Search from argv0_path, until landmark is found */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700336 wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 do {
Victor Stinner0327bde2017-11-23 17:03:20 +0100338 if (gotlandmark(prefix, landmark)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100340 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 reduce(prefix);
342 } while (prefix[0]);
343 return 0;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000344}
345
Victor Stinner0327bde2017-11-23 17:03:20 +0100346
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000347#ifdef Py_ENABLE_SHARED
Guido van Rossum43ff1141998-08-08 23:40:40 +0000348
Guido van Rossum88716bb2000-03-30 19:45:39 +0000349/* a string loaded from the DLL at startup.*/
350extern const char *PyWin_DLLVersionString;
Guido van Rossum271f9771997-09-29 23:39:31 +0000351
Guido van Rossumeea14491997-08-13 21:30:44 +0000352/* Load a PYTHONPATH value from the registry.
353 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
354
Guido van Rossum88716bb2000-03-30 19:45:39 +0000355 Works in both Unicode and 8bit environments. Only uses the
356 Ex family of functions so it also works with Windows CE.
357
Guido van Rossumeea14491997-08-13 21:30:44 +0000358 Returns NULL, or a pointer that should be freed.
Mark Hammond5edc6272001-02-23 11:38:38 +0000359
360 XXX - this code is pretty strange, as it used to also
361 work on Win16, where the buffer sizes werent available
362 in advance. It could be simplied now Win16/Win32s is dead!
Guido van Rossumeea14491997-08-13 21:30:44 +0000363*/
Martin v. Löwis790465f2008-04-05 20:41:37 +0000364static wchar_t *
Guido van Rossum88716bb2000-03-30 19:45:39 +0000365getpythonregpath(HKEY keyBase, int skipcore)
Guido van Rossumeea14491997-08-13 21:30:44 +0000366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 HKEY newKey = 0;
368 DWORD dataSize = 0;
369 DWORD numKeys = 0;
370 LONG rc;
371 wchar_t *retval = NULL;
372 WCHAR *dataBuf = NULL;
373 static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\";
374 static const WCHAR keySuffix[] = L"\\PythonPath";
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700375 size_t versionLen, keyBufLen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 DWORD index;
377 WCHAR *keyBuf = NULL;
378 WCHAR *keyBufPtr;
379 WCHAR **ppPaths = NULL;
Guido van Rossum271f9771997-09-29 23:39:31 +0000380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 /* Tried to use sysget("winver") but here is too early :-( */
382 versionLen = strlen(PyWin_DLLVersionString);
383 /* Space for all the chars, plus one \0 */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700384 keyBufLen = sizeof(keyPrefix) +
385 sizeof(WCHAR)*(versionLen-1) +
386 sizeof(keySuffix);
387 keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen);
Victor Stinner0327bde2017-11-23 17:03:20 +0100388 if (keyBuf==NULL) {
389 goto done;
390 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000391
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700392 memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
Victor Stinner63941882011-09-29 00:42:28 +0200393 keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen);
395 keyBufPtr += versionLen;
396 /* NULL comes with this one! */
397 memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
398 /* Open the root Python key */
399 rc=RegOpenKeyExW(keyBase,
400 keyBuf, /* subkey */
401 0, /* reserved */
402 KEY_READ,
403 &newKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100404 if (rc!=ERROR_SUCCESS) {
405 goto done;
406 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000407 /* Find out how big our core buffer is, and how many subkeys we have */
408 rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
409 NULL, NULL, &dataSize, NULL, NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +0100410 if (rc!=ERROR_SUCCESS) {
411 goto done;
412 }
413 if (skipcore) {
414 dataSize = 0; /* Only count core ones if we want them! */
415 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 /* Allocate a temp array of char buffers, so we only need to loop
417 reading the registry once
418 */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200419 ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
Victor Stinner0327bde2017-11-23 17:03:20 +0100420 if (ppPaths==NULL) {
421 goto done;
422 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
424 /* Loop over all subkeys, allocating a temp sub-buffer. */
425 for(index=0;index<numKeys;index++) {
426 WCHAR keyBuf[MAX_PATH+1];
427 HKEY subKey = 0;
428 DWORD reqdSize = MAX_PATH+1;
429 /* Get the sub-key name */
430 DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
431 NULL, NULL, NULL, NULL );
Victor Stinner0327bde2017-11-23 17:03:20 +0100432 if (rc!=ERROR_SUCCESS) {
433 goto done;
434 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 /* Open the sub-key */
436 rc=RegOpenKeyExW(newKey,
437 keyBuf, /* subkey */
438 0, /* reserved */
439 KEY_READ,
440 &subKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100441 if (rc!=ERROR_SUCCESS) {
442 goto done;
443 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 /* Find the value of the buffer size, malloc, then read it */
445 RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
446 if (reqdSize) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200447 ppPaths[index] = PyMem_RawMalloc(reqdSize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 if (ppPaths[index]) {
449 RegQueryValueExW(subKey, NULL, 0, NULL,
450 (LPBYTE)ppPaths[index],
451 &reqdSize);
452 dataSize += reqdSize + 1; /* 1 for the ";" */
453 }
454 }
455 RegCloseKey(subKey);
456 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 /* return null if no path to return */
Victor Stinner0327bde2017-11-23 17:03:20 +0100459 if (dataSize == 0) {
460 goto done;
461 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462
463 /* original datasize from RegQueryInfo doesn't include the \0 */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200464 dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 if (dataBuf) {
466 WCHAR *szCur = dataBuf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 /* Copy our collected strings */
468 for (index=0;index<numKeys;index++) {
469 if (index > 0) {
470 *(szCur++) = L';';
471 dataSize--;
472 }
473 if (ppPaths[index]) {
474 Py_ssize_t len = wcslen(ppPaths[index]);
475 wcsncpy(szCur, ppPaths[index], len);
476 szCur += len;
477 assert(dataSize > (DWORD)len);
478 dataSize -= (DWORD)len;
479 }
480 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100481 if (skipcore) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 *szCur = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100483 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 else {
luzpaza5293b42017-11-05 07:37:50 -0600485 /* If we have no values, we don't need a ';' */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 if (numKeys) {
487 *(szCur++) = L';';
488 dataSize--;
489 }
490 /* Now append the core path entries -
491 this will include the NULL
492 */
493 rc = RegQueryValueExW(newKey, NULL, 0, NULL,
494 (LPBYTE)szCur, &dataSize);
Serhiy Storchakae0cb9da2015-12-18 09:54:19 +0200495 if (rc != ERROR_SUCCESS) {
496 PyMem_RawFree(dataBuf);
497 goto done;
498 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 }
500 /* And set the result - caller must free */
501 retval = dataBuf;
502 }
Guido van Rossum88716bb2000-03-30 19:45:39 +0000503done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 /* Loop freeing my temp buffers */
505 if (ppPaths) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200506 for(index=0; index<numKeys; index++)
507 PyMem_RawFree(ppPaths[index]);
508 PyMem_RawFree(ppPaths);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100510 if (newKey) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 RegCloseKey(newKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100512 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200513 PyMem_RawFree(keyBuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 return retval;
Guido van Rossumeea14491997-08-13 21:30:44 +0000515}
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000516#endif /* Py_ENABLE_SHARED */
Guido van Rossumeea14491997-08-13 21:30:44 +0000517
Victor Stinner0327bde2017-11-23 17:03:20 +0100518
Victor Stinner410759f2019-05-18 04:17:01 +0200519wchar_t*
520_Py_GetDLLPath(void)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000521{
Victor Stinner9316ee42017-11-25 03:17:57 +0100522 wchar_t dll_path[MAXPATHLEN+1];
523 memset(dll_path, 0, sizeof(dll_path));
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000524
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000525#ifdef Py_ENABLE_SHARED
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 extern HANDLE PyWin_DLLhModule;
Victor Stinner0327bde2017-11-23 17:03:20 +0100527 if (PyWin_DLLhModule) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100528 if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
529 dll_path[0] = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100530 }
531 }
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000532#else
Victor Stinner9316ee42017-11-25 03:17:57 +0100533 dll_path[0] = 0;
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000534#endif
Victor Stinner9316ee42017-11-25 03:17:57 +0100535
Victor Stinner410759f2019-05-18 04:17:01 +0200536 return _PyMem_RawWcsdup(dll_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100537}
538
539
Victor Stinner331a6a52019-05-27 16:39:22 +0200540static PyStatus
Victor Stinnerfcdb0272019-09-23 14:45:47 +0200541get_program_full_path(_PyPathConfig *pathconfig)
Victor Stinner9316ee42017-11-25 03:17:57 +0100542{
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200543 PyStatus status;
Steve Dower1c3de542018-12-10 08:11:21 -0800544 const wchar_t *pyvenv_launcher;
Victor Stinnerb64de462017-12-01 18:27:09 +0100545 wchar_t program_full_path[MAXPATHLEN+1];
546 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100547
Steve Dower9048c492019-06-29 10:34:11 -0700548 if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
549 /* GetModuleFileName should never fail when passed NULL */
550 return _PyStatus_ERR("Cannot determine program path");
551 }
552
Steve Dower1c3de542018-12-10 08:11:21 -0800553 /* The launcher may need to force the executable path to a
554 * different environment, so override it here. */
555 pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__");
556 if (pyvenv_launcher && pyvenv_launcher[0]) {
Steve Dower9048c492019-06-29 10:34:11 -0700557 /* If overridden, preserve the original full path */
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200558 if (pathconfig->base_executable == NULL) {
559 pathconfig->base_executable = PyMem_RawMalloc(
560 sizeof(wchar_t) * (MAXPATHLEN + 1));
561 if (pathconfig->base_executable == NULL) {
562 return _PyStatus_NO_MEMORY();
563 }
564
565 status = canonicalize(pathconfig->base_executable,
566 program_full_path);
567 if (_PyStatus_EXCEPTION(status)) {
568 return status;
569 }
Steve Dower9048c492019-06-29 10:34:11 -0700570 }
571
Steve Dower1c3de542018-12-10 08:11:21 -0800572 wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
Steve Dower9048c492019-06-29 10:34:11 -0700573 /* bpo-35873: Clear the environment variable to avoid it being
574 * inherited by child processes. */
575 _wputenv_s(L"__PYVENV_LAUNCHER__", L"");
Victor Stinner0327bde2017-11-23 17:03:20 +0100576 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000577
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200578 if (pathconfig->program_full_path == NULL) {
579 pathconfig->program_full_path = PyMem_RawMalloc(
580 sizeof(wchar_t) * (MAXPATHLEN + 1));
581 if (pathconfig->program_full_path == NULL) {
582 return _PyStatus_NO_MEMORY();
583 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000584
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200585 status = canonicalize(pathconfig->program_full_path,
586 program_full_path);
587 if (_PyStatus_EXCEPTION(status)) {
588 return status;
589 }
590 }
591 return _PyStatus_OK();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000592}
593
Victor Stinner0327bde2017-11-23 17:03:20 +0100594
Victor Stinner85ce0a72019-09-24 00:55:48 +0200595static PyStatus
596read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path,
597 int *found)
Steve Dower4db86bc2016-09-09 09:17:35 -0700598{
Victor Stinner85ce0a72019-09-24 00:55:48 +0200599 PyStatus status;
600 wchar_t *buf = NULL;
601 wchar_t *wline = NULL;
602 FILE *sp_file;
603
604 sp_file = _Py_wfopen(path, L"r");
Victor Stinner0327bde2017-11-23 17:03:20 +0100605 if (sp_file == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200606 return _PyStatus_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100607 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700608
Steve Dowered51b262016-09-17 12:54:06 -0700609 wcscpy_s(prefix, MAXPATHLEN+1, path);
610 reduce(prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200611 pathconfig->isolated = 1;
612 pathconfig->site_import = 0;
Steve Dowered51b262016-09-17 12:54:06 -0700613
Steve Dower4db86bc2016-09-09 09:17:35 -0700614 size_t bufsiz = MAXPATHLEN;
615 size_t prefixlen = wcslen(prefix);
616
Victor Stinner85ce0a72019-09-24 00:55:48 +0200617 buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
Zackery Spytz4c49da02018-12-07 03:11:30 -0700618 if (buf == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200619 status = _PyStatus_NO_MEMORY();
620 goto done;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700621 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700622 buf[0] = '\0';
623
624 while (!feof(sp_file)) {
625 char line[MAXPATHLEN + 1];
Victor Stinner85ce0a72019-09-24 00:55:48 +0200626 char *p = fgets(line, Py_ARRAY_LENGTH(line), sp_file);
Victor Stinner0327bde2017-11-23 17:03:20 +0100627 if (!p) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700628 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100629 }
630 if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') {
Steve Dowered51b262016-09-17 12:54:06 -0700631 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100632 }
Steve Dowered51b262016-09-17 12:54:06 -0700633 while (*++p) {
634 if (*p == '\r' || *p == '\n') {
635 *p = '\0';
636 break;
637 }
638 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700639
Steve Dowered51b262016-09-17 12:54:06 -0700640 if (strcmp(line, "import site") == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200641 pathconfig->site_import = 1;
Steve Dowered51b262016-09-17 12:54:06 -0700642 continue;
Victor Stinnerf2626ce2018-07-21 03:54:20 +0200643 }
644 else if (strncmp(line, "import ", 7) == 0) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200645 status = _PyStatus_ERR("only 'import site' is supported "
646 "in ._pth file");
647 goto done;
Steve Dowered51b262016-09-17 12:54:06 -0700648 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700649
Steve Dowered51b262016-09-17 12:54:06 -0700650 DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
Steve Dower4db86bc2016-09-09 09:17:35 -0700651 wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
Zackery Spytz4c49da02018-12-07 03:11:30 -0700652 if (wline == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200653 status = _PyStatus_NO_MEMORY();
654 goto done;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700655 }
Steve Dowered51b262016-09-17 12:54:06 -0700656 wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
Steve Dower4db86bc2016-09-09 09:17:35 -0700657 wline[wn] = '\0';
658
Steve Dowerc6dd4152016-10-27 14:28:07 -0700659 size_t usedsiz = wcslen(buf);
660 while (usedsiz + wn + prefixlen + 4 > bufsiz) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700661 bufsiz += MAXPATHLEN;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700662 wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) *
663 sizeof(wchar_t));
664 if (tmp == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200665 status = _PyStatus_NO_MEMORY();
666 goto done;
Steve Dower4db86bc2016-09-09 09:17:35 -0700667 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700668 buf = tmp;
Steve Dower4db86bc2016-09-09 09:17:35 -0700669 }
670
Steve Dowerc6dd4152016-10-27 14:28:07 -0700671 if (usedsiz) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700672 wcscat_s(buf, bufsiz, L";");
Steve Dowerc6dd4152016-10-27 14:28:07 -0700673 usedsiz += 1;
674 }
Steve Dowered51b262016-09-17 12:54:06 -0700675
Steve Dowerc6dd4152016-10-27 14:28:07 -0700676 errno_t result;
677 _Py_BEGIN_SUPPRESS_IPH
678 result = wcscat_s(buf, bufsiz, prefix);
679 _Py_END_SUPPRESS_IPH
Victor Stinner85ce0a72019-09-24 00:55:48 +0200680
Steve Dowerc6dd4152016-10-27 14:28:07 -0700681 if (result == EINVAL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200682 status = _PyStatus_ERR("invalid argument during ._pth processing");
683 goto done;
Steve Dowerc6dd4152016-10-27 14:28:07 -0700684 } else if (result == ERANGE) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200685 status = _PyStatus_ERR("buffer overflow during ._pth processing");
686 goto done;
Steve Dowerc6dd4152016-10-27 14:28:07 -0700687 }
Victor Stinner85ce0a72019-09-24 00:55:48 +0200688
Steve Dowerc6dd4152016-10-27 14:28:07 -0700689 wchar_t *b = &buf[usedsiz];
Steve Dower4db86bc2016-09-09 09:17:35 -0700690 join(b, wline);
691
692 PyMem_RawFree(wline);
Victor Stinner85ce0a72019-09-24 00:55:48 +0200693 wline = NULL;
Steve Dower4db86bc2016-09-09 09:17:35 -0700694 }
695
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200696 if (pathconfig->module_search_path == NULL) {
697 pathconfig->module_search_path = _PyMem_RawWcsdup(buf);
698 if (pathconfig->module_search_path == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200699 status = _PyStatus_NO_MEMORY();
700 goto done;
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200701 }
702 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700703
Victor Stinner85ce0a72019-09-24 00:55:48 +0200704 *found = 1;
705 status = _PyStatus_OK();
706 goto done;
707
708done:
Steve Dower4db86bc2016-09-09 09:17:35 -0700709 PyMem_RawFree(buf);
Victor Stinner85ce0a72019-09-24 00:55:48 +0200710 PyMem_RawFree(wline);
Steve Dower4db86bc2016-09-09 09:17:35 -0700711 fclose(sp_file);
Victor Stinner85ce0a72019-09-24 00:55:48 +0200712 return status;
Victor Stinner0327bde2017-11-23 17:03:20 +0100713}
714
715
716static int
Victor Stinnerc4221672019-09-21 01:02:56 +0200717get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
718 const _PyPathConfig *pathconfig)
Victor Stinner0327bde2017-11-23 17:03:20 +0100719{
Victor Stinnerc4221672019-09-21 01:02:56 +0200720 if (calculate->dll_path[0]) {
721 if (!change_ext(filename, calculate->dll_path, L"._pth") &&
722 exists(filename))
Victor Stinner31a83932017-12-04 13:39:15 +0100723 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100724 return 1;
725 }
726 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200727 if (pathconfig->program_full_path[0]) {
Victor Stinnerc4221672019-09-21 01:02:56 +0200728 if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
729 exists(filename))
Victor Stinner31a83932017-12-04 13:39:15 +0100730 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100731 return 1;
732 }
733 }
734 return 0;
735}
736
737
Victor Stinner85ce0a72019-09-24 00:55:48 +0200738static PyStatus
Victor Stinnerc4221672019-09-21 01:02:56 +0200739calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
Victor Stinner85ce0a72019-09-24 00:55:48 +0200740 wchar_t *prefix, int *found)
Victor Stinner0327bde2017-11-23 17:03:20 +0100741{
Victor Stinnerc4221672019-09-21 01:02:56 +0200742 wchar_t filename[MAXPATHLEN+1];
Victor Stinner0327bde2017-11-23 17:03:20 +0100743
Victor Stinnerc4221672019-09-21 01:02:56 +0200744 if (!get_pth_filename(calculate, filename, pathconfig)) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200745 return _PyStatus_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100746 }
747
Victor Stinner85ce0a72019-09-24 00:55:48 +0200748 return read_pth_file(pathconfig, prefix, filename, found);
Victor Stinner0327bde2017-11-23 17:03:20 +0100749}
750
751
752/* Search for an environment configuration file, first in the
753 executable's directory and then in the parent directory.
754 If found, open it for use when searching for prefixes.
755*/
756static void
Victor Stinner85ce0a72019-09-24 00:55:48 +0200757calculate_pyvenv_file(PyCalculatePath *calculate,
758 wchar_t *argv0_path, size_t argv0_path_len)
Victor Stinner0327bde2017-11-23 17:03:20 +0100759{
760 wchar_t envbuffer[MAXPATHLEN+1];
761 const wchar_t *env_cfg = L"pyvenv.cfg";
762
Victor Stinner85ce0a72019-09-24 00:55:48 +0200763 wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path);
Victor Stinner0327bde2017-11-23 17:03:20 +0100764 join(envbuffer, env_cfg);
765
766 FILE *env_file = _Py_wfopen(envbuffer, L"r");
767 if (env_file == NULL) {
768 errno = 0;
Victor Stinner9bee3292017-12-21 16:49:13 +0100769
Victor Stinner0327bde2017-11-23 17:03:20 +0100770 reduce(envbuffer);
771 reduce(envbuffer);
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700772 join(envbuffer, env_cfg);
Victor Stinner9bee3292017-12-21 16:49:13 +0100773
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700774 env_file = _Py_wfopen(envbuffer, L"r");
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100775 if (env_file == NULL) {
776 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100777 }
778 }
779
Victor Stinner0327bde2017-11-23 17:03:20 +0100780 if (env_file == NULL) {
781 return;
782 }
783
784 /* Look for a 'home' variable and set argv0_path to it, if found */
785 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinner9bee3292017-12-21 16:49:13 +0100786 if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, MAXPATHLEN)) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200787 wcscpy_s(argv0_path, argv0_path_len, tmpbuffer);
Victor Stinner0327bde2017-11-23 17:03:20 +0100788 }
789 fclose(env_file);
790}
791
792
793static void
Victor Stinner85ce0a72019-09-24 00:55:48 +0200794calculate_home_prefix(PyCalculatePath *calculate,
795 const wchar_t *argv0_path,
796 const wchar_t *zip_path,
797 wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100798{
Victor Stinner0327bde2017-11-23 17:03:20 +0100799 if (calculate->home == NULL || *calculate->home == '\0') {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200800 if (zip_path[0] && exists(zip_path)) {
801 wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100802 reduce(prefix);
803 calculate->home = prefix;
804 }
Victor Stinner85ce0a72019-09-24 00:55:48 +0200805 else if (search_for_prefix(prefix, argv0_path, LANDMARK)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100806 calculate->home = prefix;
Victor Stinner0327bde2017-11-23 17:03:20 +0100807 }
808 else {
809 calculate->home = NULL;
810 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100812 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100813 wcscpy_s(prefix, MAXPATHLEN+1, calculate->home);
Victor Stinner0327bde2017-11-23 17:03:20 +0100814 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100815}
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000816
Victor Stinner9316ee42017-11-25 03:17:57 +0100817
Victor Stinner331a6a52019-05-27 16:39:22 +0200818static PyStatus
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200819calculate_module_search_path(PyCalculatePath *calculate,
820 _PyPathConfig *pathconfig,
Victor Stinner85ce0a72019-09-24 00:55:48 +0200821 const wchar_t *argv0_path,
822 wchar_t *prefix,
823 const wchar_t *zip_path)
Victor Stinner9316ee42017-11-25 03:17:57 +0100824{
Victor Stinner0327bde2017-11-23 17:03:20 +0100825 int skiphome = calculate->home==NULL ? 0 : 1;
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000826#ifdef Py_ENABLE_SHARED
Victor Stinner0327bde2017-11-23 17:03:20 +0100827 calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
828 calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome);
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000829#endif
luzpaza5293b42017-11-05 07:37:50 -0600830 /* We only use the default relative PYTHONPATH if we haven't
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 anything better to use! */
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200832 int skipdefault = (calculate->pythonpath_env != NULL ||
Victor Stinner31a83932017-12-04 13:39:15 +0100833 calculate->home != NULL ||
834 calculate->machine_path != NULL ||
835 calculate->user_path != NULL);
Guido van Rossum43ff1141998-08-08 23:40:40 +0000836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 /* We need to construct a path from the following parts.
838 (1) the PYTHONPATH environment variable, if set;
839 (2) for Win32, the zip archive file path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100840 (3) for Win32, the machine_path and user_path, if set;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 (4) the PYTHONPATH config macro, with the leading "."
Victor Stinner0327bde2017-11-23 17:03:20 +0100842 of each component replaced with home, if set;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 (5) the directory containing the executable (argv0_path).
844 The length calculation calculates #4 first.
845 Extra rules:
846 - If PYTHONHOME is set (in any way) item (3) is ignored.
847 - If registry values are used, (4) and (5) are ignored.
848 */
Guido van Rossumeea14491997-08-13 21:30:44 +0000849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 /* Calculate size of return buffer */
Victor Stinner0327bde2017-11-23 17:03:20 +0100851 size_t bufsz = 0;
852 if (calculate->home != NULL) {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200853 const wchar_t *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 bufsz = 1;
855 for (p = PYTHONPATH; *p; p++) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100856 if (*p == DELIM) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 bufsz++; /* number of DELIM plus one */
Victor Stinner0327bde2017-11-23 17:03:20 +0100858 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100860 bufsz *= wcslen(calculate->home);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 }
Steve Dowerf64b9d52015-05-23 17:34:50 -0700862 bufsz += wcslen(PYTHONPATH) + 1;
Victor Stinner85ce0a72019-09-24 00:55:48 +0200863 bufsz += wcslen(argv0_path) + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100864 if (calculate->user_path) {
865 bufsz += wcslen(calculate->user_path) + 1;
866 }
867 if (calculate->machine_path) {
868 bufsz += wcslen(calculate->machine_path) + 1;
869 }
Victor Stinner85ce0a72019-09-24 00:55:48 +0200870 bufsz += wcslen(zip_path) + 1;
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200871 if (calculate->pythonpath_env != NULL) {
872 bufsz += wcslen(calculate->pythonpath_env) + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100873 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000874
Victor Stinner0327bde2017-11-23 17:03:20 +0100875 wchar_t *buf, *start_buf;
876 buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if (buf == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +0200878 return _PyStatus_NO_MEMORY();
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100880 start_buf = buf;
Guido van Rossumeea14491997-08-13 21:30:44 +0000881
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200882 if (calculate->pythonpath_env) {
Victor Stinner31a83932017-12-04 13:39:15 +0100883 if (wcscpy_s(buf, bufsz - (buf - start_buf),
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200884 calculate->pythonpath_env)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100885 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100886 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 buf = wcschr(buf, L'\0');
888 *buf++ = DELIM;
889 }
Victor Stinner85ce0a72019-09-24 00:55:48 +0200890 if (zip_path[0]) {
891 if (wcscpy_s(buf, bufsz - (buf - start_buf), zip_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100892 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100893 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 buf = wcschr(buf, L'\0');
895 *buf++ = DELIM;
896 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100897 if (calculate->user_path) {
898 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100899 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100900 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 buf = wcschr(buf, L'\0');
902 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100904 if (calculate->machine_path) {
905 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100906 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100907 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 buf = wcschr(buf, L'\0');
909 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100911 if (calculate->home == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 if (!skipdefault) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100913 if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100914 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100915 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 buf = wcschr(buf, L'\0');
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700917 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700919 } else {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200920 const wchar_t *p = PYTHONPATH;
921 const wchar_t *q;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 size_t n;
923 for (;;) {
924 q = wcschr(p, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100925 if (q == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000926 n = wcslen(p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100927 }
928 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 n = q-p;
Victor Stinner0327bde2017-11-23 17:03:20 +0100930 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 if (p[0] == '.' && is_sep(p[1])) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100932 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100933 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100934 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 buf = wcschr(buf, L'\0');
936 p++;
937 n--;
938 }
939 wcsncpy(buf, p, n);
940 buf += n;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700941 *buf++ = DELIM;
Victor Stinner0327bde2017-11-23 17:03:20 +0100942 if (q == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100944 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 p = q+1;
946 }
947 }
Victor Stinner85ce0a72019-09-24 00:55:48 +0200948 if (argv0_path) {
949 wcscpy(buf, argv0_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 buf = wcschr(buf, L'\0');
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700951 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700953 *(buf - 1) = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 /* Now to pull one last hack/trick. If sys.prefix is
956 empty, then try and find it somewhere on the paths
957 we calculated. We scan backwards, as our general policy
958 is that Python core directories are at the *end* of
959 sys.path. We assume that our "lib" directory is
960 on the path, and that our 'prefix' directory is
961 the parent of that.
962 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100963 if (prefix[0] == L'\0') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 wchar_t lookBuf[MAXPATHLEN+1];
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200965 const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 while (1) {
967 Py_ssize_t nchars;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200968 const wchar_t *lookEnd = look;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 /* 'look' will end up one character before the
970 start of the path in question - even if this
971 is one character before the start of the buffer
972 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100973 while (look >= start_buf && *look != DELIM)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 look--;
975 nchars = lookEnd-look;
976 wcsncpy(lookBuf, look+1, nchars);
977 lookBuf[nchars] = L'\0';
978 /* Up one level to the parent */
979 reduce(lookBuf);
Victor Stinner9316ee42017-11-25 03:17:57 +0100980 if (search_for_prefix(prefix, lookBuf, LANDMARK)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000981 break;
982 }
983 /* If we are out of paths to search - give up */
Victor Stinner0327bde2017-11-23 17:03:20 +0100984 if (look < start_buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100986 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 look--;
988 }
989 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100990
Victor Stinner331a6a52019-05-27 16:39:22 +0200991 pathconfig->module_search_path = start_buf;
992 return _PyStatus_OK();
Victor Stinner9316ee42017-11-25 03:17:57 +0100993}
994
995
Victor Stinner331a6a52019-05-27 16:39:22 +0200996static PyStatus
Victor Stinner9c42f8c2019-09-23 18:47:29 +0200997calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
Victor Stinner9316ee42017-11-25 03:17:57 +0100998{
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 PyStatus status;
Victor Stinner9316ee42017-11-25 03:17:57 +01001000
Victor Stinnerfcdb0272019-09-23 14:45:47 +02001001 status = get_program_full_path(pathconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +02001002 if (_PyStatus_EXCEPTION(status)) {
1003 return status;
Victor Stinner9316ee42017-11-25 03:17:57 +01001004 }
1005
Victor Stinnerb64de462017-12-01 18:27:09 +01001006 /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */
Victor Stinner85ce0a72019-09-24 00:55:48 +02001007 wchar_t argv0_path[MAXPATHLEN+1];
1008 memset(argv0_path, 0, sizeof(argv0_path));
1009
1010 wcscpy_s(argv0_path, MAXPATHLEN+1, pathconfig->program_full_path);
1011 reduce(argv0_path);
Victor Stinner9316ee42017-11-25 03:17:57 +01001012
1013 wchar_t prefix[MAXPATHLEN+1];
1014 memset(prefix, 0, sizeof(prefix));
1015
1016 /* Search for a sys.path file */
Victor Stinner85ce0a72019-09-24 00:55:48 +02001017 int pth_found = 0;
1018 status = calculate_pth_file(calculate, pathconfig, prefix, &pth_found);
1019 if (_PyStatus_EXCEPTION(status)) {
1020 return status;
1021 }
1022 if (pth_found) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001023 goto done;
1024 }
1025
Victor Stinner85ce0a72019-09-24 00:55:48 +02001026 calculate_pyvenv_file(calculate, argv0_path, Py_ARRAY_LENGTH(argv0_path));
Victor Stinner9316ee42017-11-25 03:17:57 +01001027
1028 /* Calculate zip archive path from DLL or exe path */
Victor Stinner85ce0a72019-09-24 00:55:48 +02001029 wchar_t zip_path[MAXPATHLEN+1];
1030 memset(zip_path, 0, sizeof(zip_path));
1031
1032 change_ext(zip_path,
Victor Stinnerc4221672019-09-21 01:02:56 +02001033 calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
Victor Stinner9316ee42017-11-25 03:17:57 +01001034 L".zip");
1035
Victor Stinner85ce0a72019-09-24 00:55:48 +02001036 calculate_home_prefix(calculate, argv0_path, zip_path, prefix);
Victor Stinner9316ee42017-11-25 03:17:57 +01001037
Victor Stinnere2677932019-09-21 01:50:16 +02001038 if (pathconfig->module_search_path == NULL) {
Victor Stinner85ce0a72019-09-24 00:55:48 +02001039 status = calculate_module_search_path(calculate, pathconfig,
1040 argv0_path, prefix, zip_path);
Victor Stinnere2677932019-09-21 01:50:16 +02001041 if (_PyStatus_EXCEPTION(status)) {
1042 return status;
1043 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001044 }
1045
1046done:
Victor Stinner331a6a52019-05-27 16:39:22 +02001047 if (pathconfig->prefix == NULL) {
Victor Stinner9c42f8c2019-09-23 18:47:29 +02001048 pathconfig->prefix = _PyMem_RawWcsdup(prefix);
1049 if (pathconfig->prefix == NULL) {
1050 return _PyStatus_NO_MEMORY();
1051 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001052 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001053 if (pathconfig->exec_prefix == NULL) {
Victor Stinner9c42f8c2019-09-23 18:47:29 +02001054 pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
1055 if (pathconfig->exec_prefix == NULL) {
1056 return _PyStatus_NO_MEMORY();
1057 }
Steve Dower177a41a2018-11-17 20:41:48 -08001058 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001059
Victor Stinner331a6a52019-05-27 16:39:22 +02001060 return _PyStatus_OK();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00001061}
1062
1063
Victor Stinner85ce0a72019-09-24 00:55:48 +02001064static PyStatus
1065calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
1066 const PyConfig *config)
1067{
1068 calculate->home = pathconfig->home;
1069 calculate->path_env = _wgetenv(L"PATH");
1070
1071 calculate->dll_path = _Py_GetDLLPath();
1072 if (calculate->dll_path == NULL) {
1073 return _PyStatus_NO_MEMORY();
1074 }
1075
1076 calculate->pythonpath_env = config->pythonpath_env;
1077
1078 return _PyStatus_OK();
1079}
1080
1081
Victor Stinner0327bde2017-11-23 17:03:20 +01001082static void
1083calculate_free(PyCalculatePath *calculate)
1084{
1085 PyMem_RawFree(calculate->machine_path);
1086 PyMem_RawFree(calculate->user_path);
Victor Stinnerc4221672019-09-21 01:02:56 +02001087 PyMem_RawFree(calculate->dll_path);
Victor Stinner0327bde2017-11-23 17:03:20 +01001088}
1089
Victor Stinner9316ee42017-11-25 03:17:57 +01001090
Victor Stinner85ce0a72019-09-24 00:55:48 +02001091/* Calculate the Python path configuration.
1092
1093 Inputs:
1094
1095 - PyConfig.pythonpath_env: PYTHONPATH environment variable
1096 - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
1097 - DLL path: _Py_GetDLLPath()
1098 - PATH environment variable
1099 - __PYVENV_LAUNCHER__ environment variable
1100 - GetModuleFileNameW(NULL): fully qualified path of the executable file of
1101 the current process
1102 - .pth configuration file
1103 - pyvenv.cfg configuration file
1104 - Registry key "Software\Python\PythonCore\X.Y\PythonPath"
1105 of HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER where X.Y is the Python
1106 version (major.minor).
1107
1108 Outputs, 'pathconfig' fields:
Victor Stinner9c42f8c2019-09-23 18:47:29 +02001109
1110 - base_executable
1111 - program_full_path
1112 - module_search_path
1113 - prefix
1114 - exec_prefix
1115 - isolated
1116 - site_import
1117
Victor Stinner85ce0a72019-09-24 00:55:48 +02001118 If a field is already set (non NULL), it is left unchanged. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001119PyStatus
1120_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
Serhiy Storchaka13badcb2017-12-02 21:36:00 +02001121{
Victor Stinnerc4221672019-09-21 01:02:56 +02001122 PyStatus status;
Victor Stinner0327bde2017-11-23 17:03:20 +01001123 PyCalculatePath calculate;
1124 memset(&calculate, 0, sizeof(calculate));
1125
Victor Stinner85ce0a72019-09-24 00:55:48 +02001126 status = calculate_init(&calculate, pathconfig, config);
Victor Stinner331a6a52019-05-27 16:39:22 +02001127 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001128 goto done;
1129 }
1130
Victor Stinner9c42f8c2019-09-23 18:47:29 +02001131 status = calculate_path(&calculate, pathconfig);
Victor Stinner0327bde2017-11-23 17:03:20 +01001132
Victor Stinner9316ee42017-11-25 03:17:57 +01001133done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001134 calculate_free(&calculate);
Victor Stinner331a6a52019-05-27 16:39:22 +02001135 return status;
Victor Stinner0327bde2017-11-23 17:03:20 +01001136}
1137
1138
Victor Stinner63941882011-09-29 00:42:28 +02001139/* Load python3.dll before loading any extension module that might refer
1140 to it. That way, we can be sure that always the python3.dll corresponding
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001141 to this python DLL is loaded, not a python3.dll that might be on the path
1142 by chance.
1143 Return whether the DLL was found.
1144*/
1145static int python3_checked = 0;
1146static HANDLE hPython3;
1147int
Victor Stinner31a83932017-12-04 13:39:15 +01001148_Py_CheckPython3(void)
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001149{
1150 wchar_t py3path[MAXPATHLEN+1];
1151 wchar_t *s;
Victor Stinner0327bde2017-11-23 17:03:20 +01001152 if (python3_checked) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001153 return hPython3 != NULL;
Victor Stinner0327bde2017-11-23 17:03:20 +01001154 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001155 python3_checked = 1;
1156
1157 /* If there is a python3.dll next to the python3y.dll,
1158 assume this is a build tree; use that DLL */
Victor Stinnerc4221672019-09-21 01:02:56 +02001159 if (_Py_dll_path != NULL) {
1160 wcscpy(py3path, _Py_dll_path);
1161 }
1162 else {
1163 wcscpy(py3path, L"");
1164 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001165 s = wcsrchr(py3path, L'\\');
Victor Stinner0327bde2017-11-23 17:03:20 +01001166 if (!s) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001167 s = py3path;
Victor Stinner0327bde2017-11-23 17:03:20 +01001168 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001169 wcscpy(s, L"\\python3.dll");
1170 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
Victor Stinner0327bde2017-11-23 17:03:20 +01001171 if (hPython3 != NULL) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001172 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +01001173 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001174
1175 /* Check sys.prefix\DLLs\python3.dll */
1176 wcscpy(py3path, Py_GetPrefix());
1177 wcscat(py3path, L"\\DLLs\\python3.dll");
1178 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
1179 return hPython3 != NULL;
1180}