blob: 5670fa2ee4e18e58dcc74d085b283f6776101791 [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
Martin v. Löwis790465f2008-04-05 20:41:37 +0000118#define LANDMARK L"lib\\os.py"
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000119#endif
120
Victor Stinner0327bde2017-11-23 17:03:20 +0100121typedef struct {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200122 const wchar_t *path_env; /* PATH environment variable */
123 const wchar_t *home; /* PYTHONHOME environment variable */
Victor Stinner0327bde2017-11-23 17:03:20 +0100124
125 /* Registry key "Software\Python\PythonCore\PythonPath" */
126 wchar_t *machine_path; /* from HKEY_LOCAL_MACHINE */
127 wchar_t *user_path; /* from HKEY_CURRENT_USER */
128
Victor Stinner0327bde2017-11-23 17:03:20 +0100129 wchar_t argv0_path[MAXPATHLEN+1];
130 wchar_t zip_path[MAXPATHLEN+1];
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200131
132 wchar_t *dll_path;
Victor Stinner3f5409a2019-09-23 19:50:27 +0200133
134 const wchar_t *pythonpath_env;
Victor Stinner0327bde2017-11-23 17:03:20 +0100135} PyCalculatePath;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000136
Guido van Rossumeea14491997-08-13 21:30:44 +0000137
Victor Stinner0327bde2017-11-23 17:03:20 +0100138/* determine if "ch" is a separator character */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000139static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100140is_sep(wchar_t ch)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000141{
142#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 return ch == SEP || ch == ALTSEP;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000144#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 return ch == SEP;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000146#endif
147}
148
Victor Stinner0327bde2017-11-23 17:03:20 +0100149
Mark Hammond8bf9e3b2000-10-07 11:10:50 +0000150/* assumes 'dir' null terminated in bounds. Never writes
Victor Stinner0327bde2017-11-23 17:03:20 +0100151 beyond existing terminator. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000152static void
Martin v. Löwis790465f2008-04-05 20:41:37 +0000153reduce(wchar_t *dir)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000154{
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700155 size_t i = wcsnlen_s(dir, MAXPATHLEN+1);
Victor Stinner0327bde2017-11-23 17:03:20 +0100156 if (i >= MAXPATHLEN+1) {
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700157 Py_FatalError("buffer overflow in getpathp.c's reduce()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100158 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 while (i > 0 && !is_sep(dir[i]))
161 --i;
162 dir[i] = '\0';
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000163}
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164
Victor Stinner0327bde2017-11-23 17:03:20 +0100165
Steve Dowered51b262016-09-17 12:54:06 -0700166static int
167change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
168{
169 size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
170 size_t i = src_len;
Victor Stinner0327bde2017-11-23 17:03:20 +0100171 if (i >= MAXPATHLEN+1) {
Steve Dowered51b262016-09-17 12:54:06 -0700172 Py_FatalError("buffer overflow in getpathp.c's reduce()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100173 }
Steve Dowered51b262016-09-17 12:54:06 -0700174
175 while (i > 0 && src[i] != '.' && !is_sep(src[i]))
176 --i;
177
178 if (i == 0) {
179 dest[0] = '\0';
180 return -1;
181 }
182
Victor Stinner0327bde2017-11-23 17:03:20 +0100183 if (is_sep(src[i])) {
Steve Dowered51b262016-09-17 12:54:06 -0700184 i = src_len;
Victor Stinner0327bde2017-11-23 17:03:20 +0100185 }
Steve Dowered51b262016-09-17 12:54:06 -0700186
187 if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
Victor Stinner0327bde2017-11-23 17:03:20 +0100188 wcscat_s(dest, MAXPATHLEN+1, ext))
189 {
Steve Dowered51b262016-09-17 12:54:06 -0700190 dest[0] = '\0';
191 return -1;
192 }
193
194 return 0;
195}
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000196
Victor Stinner0327bde2017-11-23 17:03:20 +0100197
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000198static int
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200199exists(const wchar_t *filename)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000200{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000201 return GetFileAttributesW(filename) != 0xFFFFFFFF;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000202}
203
Victor Stinner0327bde2017-11-23 17:03:20 +0100204
205/* Is module -- check for .pyc too.
206 Assumes 'filename' MAXPATHLEN+1 bytes long -
207 may extend 'filename' by one character. */
Guido van Rossum43ff1141998-08-08 23:40:40 +0000208static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100209ismodule(wchar_t *filename, int update_filename)
Guido van Rossum43ff1141998-08-08 23:40:40 +0000210{
Victor Stinnerccb1f8c2016-03-23 11:31:58 +0100211 size_t n;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700212
Victor Stinner0327bde2017-11-23 17:03:20 +0100213 if (exists(filename)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100215 }
Guido van Rossum43ff1141998-08-08 23:40:40 +0000216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000217 /* Check for the compiled version of prefix. */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700218 n = wcsnlen_s(filename, MAXPATHLEN+1);
219 if (n < MAXPATHLEN) {
220 int exist = 0;
Xiang Zhang0710d752017-03-11 13:02:52 +0800221 filename[n] = L'c';
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700222 filename[n + 1] = L'\0';
223 exist = exists(filename);
Victor Stinner0327bde2017-11-23 17:03:20 +0100224 if (!update_filename) {
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700225 filename[n] = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100226 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700227 return exist;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 }
229 return 0;
Guido van Rossum43ff1141998-08-08 23:40:40 +0000230}
231
Victor Stinner0327bde2017-11-23 17:03:20 +0100232
Tim Peters8484fbf2004-08-07 19:12:27 +0000233/* Add a path component, by appending stuff to buffer.
234 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
235 NUL-terminated string with no more than MAXPATHLEN characters (not counting
236 the trailing NUL). It's a fatal error if it contains a string longer than
237 that (callers must be careful!). If these requirements are met, it's
238 guaranteed that buffer will still be a NUL-terminated string with no more
239 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
240 stuff as fits will be appended.
241*/
Steve Dower4db86bc2016-09-09 09:17:35 -0700242
243static int _PathCchCombineEx_Initialized = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100244typedef HRESULT(__stdcall *PPathCchCombineEx) (PWSTR pszPathOut, size_t cchPathOut,
245 PCWSTR pszPathIn, PCWSTR pszMore,
246 unsigned long dwFlags);
Steve Dower4db86bc2016-09-09 09:17:35 -0700247static PPathCchCombineEx _PathCchCombineEx;
248
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000249static void
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700250join(wchar_t *buffer, const wchar_t *stuff)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000251{
Steve Dower4db86bc2016-09-09 09:17:35 -0700252 if (_PathCchCombineEx_Initialized == 0) {
253 HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
Victor Stinner0327bde2017-11-23 17:03:20 +0100254 if (pathapi) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700255 _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
Victor Stinner0327bde2017-11-23 17:03:20 +0100256 }
257 else {
Steve Dower4db86bc2016-09-09 09:17:35 -0700258 _PathCchCombineEx = NULL;
Victor Stinner0327bde2017-11-23 17:03:20 +0100259 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700260 _PathCchCombineEx_Initialized = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700262
Steve Dower4db86bc2016-09-09 09:17:35 -0700263 if (_PathCchCombineEx) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100264 if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0))) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700265 Py_FatalError("buffer overflow in getpathp.c's join()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100266 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700267 } else {
Victor Stinner0327bde2017-11-23 17:03:20 +0100268 if (!PathCombineW(buffer, buffer, stuff)) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700269 Py_FatalError("buffer overflow in getpathp.c's join()");
Victor Stinner0327bde2017-11-23 17:03:20 +0100270 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700271 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000272}
273
Steve Dower48e8c822018-02-22 10:39:26 -0800274static int _PathCchCanonicalizeEx_Initialized = 0;
275typedef HRESULT(__stdcall *PPathCchCanonicalizeEx) (PWSTR pszPathOut, size_t cchPathOut,
276 PCWSTR pszPathIn, unsigned long dwFlags);
277static PPathCchCanonicalizeEx _PathCchCanonicalizeEx;
278
Victor Stinner331a6a52019-05-27 16:39:22 +0200279static PyStatus canonicalize(wchar_t *buffer, const wchar_t *path)
Steve Dower48e8c822018-02-22 10:39:26 -0800280{
281 if (buffer == NULL) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200282 return _PyStatus_NO_MEMORY();
Steve Dower48e8c822018-02-22 10:39:26 -0800283 }
284
285 if (_PathCchCanonicalizeEx_Initialized == 0) {
286 HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
287 if (pathapi) {
288 _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx");
289 }
290 else {
291 _PathCchCanonicalizeEx = NULL;
292 }
293 _PathCchCanonicalizeEx_Initialized = 1;
294 }
295
296 if (_PathCchCanonicalizeEx) {
297 if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200298 return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()");
Steve Dower48e8c822018-02-22 10:39:26 -0800299 }
300 }
301 else {
302 if (!PathCanonicalizeW(buffer, path)) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200303 return _PyStatus_ERR("buffer overflow in getpathp.c's canonicalize()");
Steve Dower48e8c822018-02-22 10:39:26 -0800304 }
305 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200306 return _PyStatus_OK();
Steve Dower48e8c822018-02-22 10:39:26 -0800307}
308
Victor Stinner0327bde2017-11-23 17:03:20 +0100309
Mark Hammond8bf9e3b2000-10-07 11:10:50 +0000310/* gotlandmark only called by search_for_prefix, which ensures
311 'prefix' is null terminated in bounds. join() ensures
Victor Stinner0327bde2017-11-23 17:03:20 +0100312 'landmark' can not overflow prefix if too long. */
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000313static int
Victor Stinner0327bde2017-11-23 17:03:20 +0100314gotlandmark(wchar_t *prefix, const wchar_t *landmark)
Guido van Rossume02e48b2000-03-29 01:49:47 +0000315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 int ok;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700317 Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN);
Guido van Rossume02e48b2000-03-29 01:49:47 +0000318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 join(prefix, landmark);
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700320 ok = ismodule(prefix, FALSE);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 prefix[n] = '\0';
322 return ok;
Guido van Rossume02e48b2000-03-29 01:49:47 +0000323}
324
Victor Stinner0327bde2017-11-23 17:03:20 +0100325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
Victor Stinner3f5409a2019-09-23 19:50:27 +0200327 assumption provided by only caller, calculate_path() */
Guido van Rossume02e48b2000-03-29 01:49:47 +0000328static int
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200329search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *landmark)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 /* Search from argv0_path, until landmark is found */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700332 wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 do {
Victor Stinner0327bde2017-11-23 17:03:20 +0100334 if (gotlandmark(prefix, landmark)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100336 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000337 reduce(prefix);
338 } while (prefix[0]);
339 return 0;
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000340}
341
Victor Stinner0327bde2017-11-23 17:03:20 +0100342
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000343#ifdef Py_ENABLE_SHARED
Guido van Rossum43ff1141998-08-08 23:40:40 +0000344
Guido van Rossum88716bb2000-03-30 19:45:39 +0000345/* a string loaded from the DLL at startup.*/
346extern const char *PyWin_DLLVersionString;
Guido van Rossum271f9771997-09-29 23:39:31 +0000347
Guido van Rossumeea14491997-08-13 21:30:44 +0000348/* Load a PYTHONPATH value from the registry.
349 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
350
Guido van Rossum88716bb2000-03-30 19:45:39 +0000351 Works in both Unicode and 8bit environments. Only uses the
352 Ex family of functions so it also works with Windows CE.
353
Guido van Rossumeea14491997-08-13 21:30:44 +0000354 Returns NULL, or a pointer that should be freed.
Mark Hammond5edc6272001-02-23 11:38:38 +0000355
356 XXX - this code is pretty strange, as it used to also
357 work on Win16, where the buffer sizes werent available
358 in advance. It could be simplied now Win16/Win32s is dead!
Guido van Rossumeea14491997-08-13 21:30:44 +0000359*/
Martin v. Löwis790465f2008-04-05 20:41:37 +0000360static wchar_t *
Guido van Rossum88716bb2000-03-30 19:45:39 +0000361getpythonregpath(HKEY keyBase, int skipcore)
Guido van Rossumeea14491997-08-13 21:30:44 +0000362{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 HKEY newKey = 0;
364 DWORD dataSize = 0;
365 DWORD numKeys = 0;
366 LONG rc;
367 wchar_t *retval = NULL;
368 WCHAR *dataBuf = NULL;
369 static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\";
370 static const WCHAR keySuffix[] = L"\\PythonPath";
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700371 size_t versionLen, keyBufLen;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000372 DWORD index;
373 WCHAR *keyBuf = NULL;
374 WCHAR *keyBufPtr;
375 WCHAR **ppPaths = NULL;
Guido van Rossum271f9771997-09-29 23:39:31 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 /* Tried to use sysget("winver") but here is too early :-( */
378 versionLen = strlen(PyWin_DLLVersionString);
379 /* Space for all the chars, plus one \0 */
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700380 keyBufLen = sizeof(keyPrefix) +
381 sizeof(WCHAR)*(versionLen-1) +
382 sizeof(keySuffix);
383 keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen);
Victor Stinner0327bde2017-11-23 17:03:20 +0100384 if (keyBuf==NULL) {
385 goto done;
386 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000387
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700388 memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
Victor Stinner63941882011-09-29 00:42:28 +0200389 keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000390 mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen);
391 keyBufPtr += versionLen;
392 /* NULL comes with this one! */
393 memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
394 /* Open the root Python key */
395 rc=RegOpenKeyExW(keyBase,
396 keyBuf, /* subkey */
397 0, /* reserved */
398 KEY_READ,
399 &newKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100400 if (rc!=ERROR_SUCCESS) {
401 goto done;
402 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 /* Find out how big our core buffer is, and how many subkeys we have */
404 rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
405 NULL, NULL, &dataSize, NULL, NULL);
Victor Stinner0327bde2017-11-23 17:03:20 +0100406 if (rc!=ERROR_SUCCESS) {
407 goto done;
408 }
409 if (skipcore) {
410 dataSize = 0; /* Only count core ones if we want them! */
411 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 /* Allocate a temp array of char buffers, so we only need to loop
413 reading the registry once
414 */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200415 ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
Victor Stinner0327bde2017-11-23 17:03:20 +0100416 if (ppPaths==NULL) {
417 goto done;
418 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
420 /* Loop over all subkeys, allocating a temp sub-buffer. */
421 for(index=0;index<numKeys;index++) {
422 WCHAR keyBuf[MAX_PATH+1];
423 HKEY subKey = 0;
424 DWORD reqdSize = MAX_PATH+1;
425 /* Get the sub-key name */
426 DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
427 NULL, NULL, NULL, NULL );
Victor Stinner0327bde2017-11-23 17:03:20 +0100428 if (rc!=ERROR_SUCCESS) {
429 goto done;
430 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 /* Open the sub-key */
432 rc=RegOpenKeyExW(newKey,
433 keyBuf, /* subkey */
434 0, /* reserved */
435 KEY_READ,
436 &subKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100437 if (rc!=ERROR_SUCCESS) {
438 goto done;
439 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 /* Find the value of the buffer size, malloc, then read it */
441 RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
442 if (reqdSize) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200443 ppPaths[index] = PyMem_RawMalloc(reqdSize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 if (ppPaths[index]) {
445 RegQueryValueExW(subKey, NULL, 0, NULL,
446 (LPBYTE)ppPaths[index],
447 &reqdSize);
448 dataSize += reqdSize + 1; /* 1 for the ";" */
449 }
450 }
451 RegCloseKey(subKey);
452 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 /* return null if no path to return */
Victor Stinner0327bde2017-11-23 17:03:20 +0100455 if (dataSize == 0) {
456 goto done;
457 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458
459 /* original datasize from RegQueryInfo doesn't include the \0 */
Victor Stinner1a7425f2013-07-07 16:25:15 +0200460 dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 if (dataBuf) {
462 WCHAR *szCur = dataBuf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 /* Copy our collected strings */
464 for (index=0;index<numKeys;index++) {
465 if (index > 0) {
466 *(szCur++) = L';';
467 dataSize--;
468 }
469 if (ppPaths[index]) {
470 Py_ssize_t len = wcslen(ppPaths[index]);
471 wcsncpy(szCur, ppPaths[index], len);
472 szCur += len;
473 assert(dataSize > (DWORD)len);
474 dataSize -= (DWORD)len;
475 }
476 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100477 if (skipcore) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 *szCur = '\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100479 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 else {
luzpaza5293b42017-11-05 07:37:50 -0600481 /* If we have no values, we don't need a ';' */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 if (numKeys) {
483 *(szCur++) = L';';
484 dataSize--;
485 }
486 /* Now append the core path entries -
487 this will include the NULL
488 */
489 rc = RegQueryValueExW(newKey, NULL, 0, NULL,
490 (LPBYTE)szCur, &dataSize);
Serhiy Storchakae0cb9da2015-12-18 09:54:19 +0200491 if (rc != ERROR_SUCCESS) {
492 PyMem_RawFree(dataBuf);
493 goto done;
494 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 }
496 /* And set the result - caller must free */
497 retval = dataBuf;
498 }
Guido van Rossum88716bb2000-03-30 19:45:39 +0000499done:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 /* Loop freeing my temp buffers */
501 if (ppPaths) {
Victor Stinner1a7425f2013-07-07 16:25:15 +0200502 for(index=0; index<numKeys; index++)
503 PyMem_RawFree(ppPaths[index]);
504 PyMem_RawFree(ppPaths);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100506 if (newKey) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 RegCloseKey(newKey);
Victor Stinner0327bde2017-11-23 17:03:20 +0100508 }
Victor Stinner1a7425f2013-07-07 16:25:15 +0200509 PyMem_RawFree(keyBuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 return retval;
Guido van Rossumeea14491997-08-13 21:30:44 +0000511}
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000512#endif /* Py_ENABLE_SHARED */
Guido van Rossumeea14491997-08-13 21:30:44 +0000513
Victor Stinner0327bde2017-11-23 17:03:20 +0100514
Victor Stinner410759f2019-05-18 04:17:01 +0200515wchar_t*
516_Py_GetDLLPath(void)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000517{
Victor Stinner9316ee42017-11-25 03:17:57 +0100518 wchar_t dll_path[MAXPATHLEN+1];
519 memset(dll_path, 0, sizeof(dll_path));
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000520
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000521#ifdef Py_ENABLE_SHARED
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000522 extern HANDLE PyWin_DLLhModule;
Victor Stinner0327bde2017-11-23 17:03:20 +0100523 if (PyWin_DLLhModule) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100524 if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
525 dll_path[0] = 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100526 }
527 }
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000528#else
Victor Stinner9316ee42017-11-25 03:17:57 +0100529 dll_path[0] = 0;
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000530#endif
Victor Stinner9316ee42017-11-25 03:17:57 +0100531
Victor Stinner410759f2019-05-18 04:17:01 +0200532 return _PyMem_RawWcsdup(dll_path);
Victor Stinner9316ee42017-11-25 03:17:57 +0100533}
534
535
Victor Stinner331a6a52019-05-27 16:39:22 +0200536static PyStatus
Victor Stinnerc5c64252019-09-23 15:59:00 +0200537get_program_full_path(_PyPathConfig *pathconfig)
Victor Stinner9316ee42017-11-25 03:17:57 +0100538{
Victor Stinner3f5409a2019-09-23 19:50:27 +0200539 PyStatus status;
Steve Dower1c3de542018-12-10 08:11:21 -0800540 const wchar_t *pyvenv_launcher;
Victor Stinnerb64de462017-12-01 18:27:09 +0100541 wchar_t program_full_path[MAXPATHLEN+1];
542 memset(program_full_path, 0, sizeof(program_full_path));
Victor Stinner9316ee42017-11-25 03:17:57 +0100543
Steve Dower323e7432019-06-29 14:28:59 -0700544 if (!GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
545 /* GetModuleFileName should never fail when passed NULL */
546 return _PyStatus_ERR("Cannot determine program path");
547 }
548
Steve Dower1c3de542018-12-10 08:11:21 -0800549 /* The launcher may need to force the executable path to a
550 * different environment, so override it here. */
551 pyvenv_launcher = _wgetenv(L"__PYVENV_LAUNCHER__");
552 if (pyvenv_launcher && pyvenv_launcher[0]) {
Steve Dower323e7432019-06-29 14:28:59 -0700553 /* If overridden, preserve the original full path */
Victor Stinner3f5409a2019-09-23 19:50:27 +0200554 if (pathconfig->base_executable == NULL) {
555 pathconfig->base_executable = PyMem_RawMalloc(
556 sizeof(wchar_t) * (MAXPATHLEN + 1));
557 if (pathconfig->base_executable == NULL) {
558 return _PyStatus_NO_MEMORY();
559 }
560
561 status = canonicalize(pathconfig->base_executable,
562 program_full_path);
563 if (_PyStatus_EXCEPTION(status)) {
564 return status;
565 }
Steve Dower323e7432019-06-29 14:28:59 -0700566 }
567
Steve Dower1c3de542018-12-10 08:11:21 -0800568 wcscpy_s(program_full_path, MAXPATHLEN+1, pyvenv_launcher);
Steve Dower323e7432019-06-29 14:28:59 -0700569 /* bpo-35873: Clear the environment variable to avoid it being
570 * inherited by child processes. */
571 _wputenv_s(L"__PYVENV_LAUNCHER__", L"");
Victor Stinner0327bde2017-11-23 17:03:20 +0100572 }
Guido van Rossumeea14491997-08-13 21:30:44 +0000573
Victor Stinner3f5409a2019-09-23 19:50:27 +0200574 if (pathconfig->program_full_path == NULL) {
575 pathconfig->program_full_path = PyMem_RawMalloc(
576 sizeof(wchar_t) * (MAXPATHLEN + 1));
577 if (pathconfig->program_full_path == NULL) {
578 return _PyStatus_NO_MEMORY();
579 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000580
Victor Stinner3f5409a2019-09-23 19:50:27 +0200581 status = canonicalize(pathconfig->program_full_path,
582 program_full_path);
583 if (_PyStatus_EXCEPTION(status)) {
584 return status;
585 }
586 }
587 return _PyStatus_OK();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000588}
589
Victor Stinner0327bde2017-11-23 17:03:20 +0100590
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100591static int
Victor Stinner331a6a52019-05-27 16:39:22 +0200592read_pth_file(_PyPathConfig *pathconfig, wchar_t *prefix, const wchar_t *path)
Steve Dower4db86bc2016-09-09 09:17:35 -0700593{
594 FILE *sp_file = _Py_wfopen(path, L"r");
Victor Stinner0327bde2017-11-23 17:03:20 +0100595 if (sp_file == NULL) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100596 return 0;
Victor Stinner0327bde2017-11-23 17:03:20 +0100597 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700598
Steve Dowered51b262016-09-17 12:54:06 -0700599 wcscpy_s(prefix, MAXPATHLEN+1, path);
600 reduce(prefix);
Victor Stinner331a6a52019-05-27 16:39:22 +0200601 pathconfig->isolated = 1;
602 pathconfig->site_import = 0;
Steve Dowered51b262016-09-17 12:54:06 -0700603
Steve Dower4db86bc2016-09-09 09:17:35 -0700604 size_t bufsiz = MAXPATHLEN;
605 size_t prefixlen = wcslen(prefix);
606
607 wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
Zackery Spytz4c49da02018-12-07 03:11:30 -0700608 if (buf == NULL) {
609 goto error;
610 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700611 buf[0] = '\0';
612
613 while (!feof(sp_file)) {
614 char line[MAXPATHLEN + 1];
615 char *p = fgets(line, MAXPATHLEN + 1, sp_file);
Victor Stinner0327bde2017-11-23 17:03:20 +0100616 if (!p) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700617 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100618 }
619 if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#') {
Steve Dowered51b262016-09-17 12:54:06 -0700620 continue;
Victor Stinner0327bde2017-11-23 17:03:20 +0100621 }
Steve Dowered51b262016-09-17 12:54:06 -0700622 while (*++p) {
623 if (*p == '\r' || *p == '\n') {
624 *p = '\0';
625 break;
626 }
627 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700628
Steve Dowered51b262016-09-17 12:54:06 -0700629 if (strcmp(line, "import site") == 0) {
Victor Stinner331a6a52019-05-27 16:39:22 +0200630 pathconfig->site_import = 1;
Steve Dowered51b262016-09-17 12:54:06 -0700631 continue;
Victor Stinnerf2626ce2018-07-21 03:54:20 +0200632 }
633 else if (strncmp(line, "import ", 7) == 0) {
Steve Dowered51b262016-09-17 12:54:06 -0700634 Py_FatalError("only 'import site' is supported in ._pth file");
635 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700636
Steve Dowered51b262016-09-17 12:54:06 -0700637 DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
Steve Dower4db86bc2016-09-09 09:17:35 -0700638 wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
Zackery Spytz4c49da02018-12-07 03:11:30 -0700639 if (wline == NULL) {
640 goto error;
641 }
Steve Dowered51b262016-09-17 12:54:06 -0700642 wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
Steve Dower4db86bc2016-09-09 09:17:35 -0700643 wline[wn] = '\0';
644
Steve Dowerc6dd4152016-10-27 14:28:07 -0700645 size_t usedsiz = wcslen(buf);
646 while (usedsiz + wn + prefixlen + 4 > bufsiz) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700647 bufsiz += MAXPATHLEN;
Zackery Spytz4c49da02018-12-07 03:11:30 -0700648 wchar_t *tmp = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) *
649 sizeof(wchar_t));
650 if (tmp == NULL) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700651 PyMem_RawFree(wline);
652 goto error;
653 }
Zackery Spytz4c49da02018-12-07 03:11:30 -0700654 buf = tmp;
Steve Dower4db86bc2016-09-09 09:17:35 -0700655 }
656
Steve Dowerc6dd4152016-10-27 14:28:07 -0700657 if (usedsiz) {
Steve Dower4db86bc2016-09-09 09:17:35 -0700658 wcscat_s(buf, bufsiz, L";");
Steve Dowerc6dd4152016-10-27 14:28:07 -0700659 usedsiz += 1;
660 }
Steve Dowered51b262016-09-17 12:54:06 -0700661
Steve Dowerc6dd4152016-10-27 14:28:07 -0700662 errno_t result;
663 _Py_BEGIN_SUPPRESS_IPH
664 result = wcscat_s(buf, bufsiz, prefix);
665 _Py_END_SUPPRESS_IPH
666 if (result == EINVAL) {
667 Py_FatalError("invalid argument during ._pth processing");
668 } else if (result == ERANGE) {
669 Py_FatalError("buffer overflow during ._pth processing");
670 }
671 wchar_t *b = &buf[usedsiz];
Steve Dower4db86bc2016-09-09 09:17:35 -0700672 join(b, wline);
673
674 PyMem_RawFree(wline);
675 }
676
Steve Dower4db86bc2016-09-09 09:17:35 -0700677 fclose(sp_file);
Victor Stinner3f5409a2019-09-23 19:50:27 +0200678 if (pathconfig->module_search_path == NULL) {
679 pathconfig->module_search_path = _PyMem_RawWcsdup(buf);
680 if (pathconfig->module_search_path == NULL) {
681 Py_FatalError("out of memory");
682 }
683 }
684 PyMem_RawFree(buf);
Victor Stinner9316ee42017-11-25 03:17:57 +0100685 return 1;
Steve Dower4db86bc2016-09-09 09:17:35 -0700686
687error:
688 PyMem_RawFree(buf);
689 fclose(sp_file);
Victor Stinner9316ee42017-11-25 03:17:57 +0100690 return 0;
Steve Dower4db86bc2016-09-09 09:17:35 -0700691}
692
693
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200694static PyStatus
Victor Stinner3f5409a2019-09-23 19:50:27 +0200695calculate_init(PyCalculatePath *calculate, const PyConfig *config)
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000696{
Victor Stinner331a6a52019-05-27 16:39:22 +0200697 calculate->home = config->home;
Victor Stinner0327bde2017-11-23 17:03:20 +0100698 calculate->path_env = _wgetenv(L"PATH");
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200699
700 calculate->dll_path = _Py_GetDLLPath();
701 if (calculate->dll_path == NULL) {
702 return _PyStatus_NO_MEMORY();
703 }
704
Victor Stinner3f5409a2019-09-23 19:50:27 +0200705 calculate->pythonpath_env = config->pythonpath_env;
706
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200707 return _PyStatus_OK();
Victor Stinner0327bde2017-11-23 17:03:20 +0100708}
709
710
711static int
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200712get_pth_filename(PyCalculatePath *calculate, wchar_t *filename,
713 const _PyPathConfig *pathconfig)
Victor Stinner0327bde2017-11-23 17:03:20 +0100714{
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200715 if (calculate->dll_path[0]) {
716 if (!change_ext(filename, calculate->dll_path, L"._pth") &&
717 exists(filename))
Victor Stinner31a83932017-12-04 13:39:15 +0100718 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100719 return 1;
720 }
721 }
Victor Stinner331a6a52019-05-27 16:39:22 +0200722 if (pathconfig->program_full_path[0]) {
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200723 if (!change_ext(filename, pathconfig->program_full_path, L"._pth") &&
724 exists(filename))
Victor Stinner31a83932017-12-04 13:39:15 +0100725 {
Victor Stinner0327bde2017-11-23 17:03:20 +0100726 return 1;
727 }
728 }
729 return 0;
730}
731
732
733static int
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200734calculate_pth_file(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
735 wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100736{
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200737 wchar_t filename[MAXPATHLEN+1];
Victor Stinner0327bde2017-11-23 17:03:20 +0100738
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200739 if (!get_pth_filename(calculate, filename, pathconfig)) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100740 return 0;
741 }
742
Victor Stinner9f3dcf82019-09-21 02:13:14 +0200743 return read_pth_file(pathconfig, prefix, filename);
Victor Stinner0327bde2017-11-23 17:03:20 +0100744}
745
746
747/* Search for an environment configuration file, first in the
748 executable's directory and then in the parent directory.
749 If found, open it for use when searching for prefixes.
750*/
751static void
752calculate_pyvenv_file(PyCalculatePath *calculate)
753{
754 wchar_t envbuffer[MAXPATHLEN+1];
755 const wchar_t *env_cfg = L"pyvenv.cfg";
756
757 wcscpy_s(envbuffer, MAXPATHLEN+1, calculate->argv0_path);
758 join(envbuffer, env_cfg);
759
760 FILE *env_file = _Py_wfopen(envbuffer, L"r");
761 if (env_file == NULL) {
762 errno = 0;
Victor Stinner9bee3292017-12-21 16:49:13 +0100763
Victor Stinner0327bde2017-11-23 17:03:20 +0100764 reduce(envbuffer);
765 reduce(envbuffer);
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700766 join(envbuffer, env_cfg);
Victor Stinner9bee3292017-12-21 16:49:13 +0100767
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700768 env_file = _Py_wfopen(envbuffer, L"r");
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100769 if (env_file == NULL) {
770 errno = 0;
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100771 }
772 }
773
Victor Stinner0327bde2017-11-23 17:03:20 +0100774 if (env_file == NULL) {
775 return;
776 }
777
778 /* Look for a 'home' variable and set argv0_path to it, if found */
779 wchar_t tmpbuffer[MAXPATHLEN+1];
Victor Stinner9bee3292017-12-21 16:49:13 +0100780 if (_Py_FindEnvConfigValue(env_file, L"home", tmpbuffer, MAXPATHLEN)) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100781 wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, tmpbuffer);
782 }
783 fclose(env_file);
784}
785
786
Victor Stinner331a6a52019-05-27 16:39:22 +0200787#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")
Victor Stinner9316ee42017-11-25 03:17:57 +0100788
789
Victor Stinner0327bde2017-11-23 17:03:20 +0100790static void
Victor Stinner9316ee42017-11-25 03:17:57 +0100791calculate_home_prefix(PyCalculatePath *calculate, wchar_t *prefix)
Victor Stinner0327bde2017-11-23 17:03:20 +0100792{
Victor Stinner0327bde2017-11-23 17:03:20 +0100793 if (calculate->home == NULL || *calculate->home == '\0') {
794 if (calculate->zip_path[0] && exists(calculate->zip_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100795 wcscpy_s(prefix, MAXPATHLEN+1, calculate->zip_path);
796 reduce(prefix);
797 calculate->home = prefix;
798 }
799 else if (search_for_prefix(prefix, calculate->argv0_path, LANDMARK)) {
800 calculate->home = prefix;
Victor Stinner0327bde2017-11-23 17:03:20 +0100801 }
802 else {
803 calculate->home = NULL;
804 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100806 else {
Victor Stinner9316ee42017-11-25 03:17:57 +0100807 wcscpy_s(prefix, MAXPATHLEN+1, calculate->home);
Victor Stinner0327bde2017-11-23 17:03:20 +0100808 }
Victor Stinner9316ee42017-11-25 03:17:57 +0100809}
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000810
Victor Stinner9316ee42017-11-25 03:17:57 +0100811
Victor Stinner331a6a52019-05-27 16:39:22 +0200812static PyStatus
Victor Stinner3f5409a2019-09-23 19:50:27 +0200813calculate_module_search_path(PyCalculatePath *calculate,
814 _PyPathConfig *pathconfig,
Victor Stinner31a83932017-12-04 13:39:15 +0100815 wchar_t *prefix)
Victor Stinner9316ee42017-11-25 03:17:57 +0100816{
Victor Stinner0327bde2017-11-23 17:03:20 +0100817 int skiphome = calculate->home==NULL ? 0 : 1;
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000818#ifdef Py_ENABLE_SHARED
Victor Stinner0327bde2017-11-23 17:03:20 +0100819 calculate->machine_path = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
820 calculate->user_path = getpythonregpath(HKEY_CURRENT_USER, skiphome);
Martin v. Löwisbc186a82009-02-02 15:32:22 +0000821#endif
luzpaza5293b42017-11-05 07:37:50 -0600822 /* We only use the default relative PYTHONPATH if we haven't
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 anything better to use! */
Victor Stinner3f5409a2019-09-23 19:50:27 +0200824 int skipdefault = (calculate->pythonpath_env != NULL ||
Victor Stinner31a83932017-12-04 13:39:15 +0100825 calculate->home != NULL ||
826 calculate->machine_path != NULL ||
827 calculate->user_path != NULL);
Guido van Rossum43ff1141998-08-08 23:40:40 +0000828
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 /* We need to construct a path from the following parts.
830 (1) the PYTHONPATH environment variable, if set;
831 (2) for Win32, the zip archive file path;
Victor Stinner0327bde2017-11-23 17:03:20 +0100832 (3) for Win32, the machine_path and user_path, if set;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 (4) the PYTHONPATH config macro, with the leading "."
Victor Stinner0327bde2017-11-23 17:03:20 +0100834 of each component replaced with home, if set;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 (5) the directory containing the executable (argv0_path).
836 The length calculation calculates #4 first.
837 Extra rules:
838 - If PYTHONHOME is set (in any way) item (3) is ignored.
839 - If registry values are used, (4) and (5) are ignored.
840 */
Guido van Rossumeea14491997-08-13 21:30:44 +0000841
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 /* Calculate size of return buffer */
Victor Stinner0327bde2017-11-23 17:03:20 +0100843 size_t bufsz = 0;
844 if (calculate->home != NULL) {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200845 const wchar_t *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 bufsz = 1;
847 for (p = PYTHONPATH; *p; p++) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100848 if (*p == DELIM) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000849 bufsz++; /* number of DELIM plus one */
Victor Stinner0327bde2017-11-23 17:03:20 +0100850 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100852 bufsz *= wcslen(calculate->home);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 }
Steve Dowerf64b9d52015-05-23 17:34:50 -0700854 bufsz += wcslen(PYTHONPATH) + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100855 bufsz += wcslen(calculate->argv0_path) + 1;
856 if (calculate->user_path) {
857 bufsz += wcslen(calculate->user_path) + 1;
858 }
859 if (calculate->machine_path) {
860 bufsz += wcslen(calculate->machine_path) + 1;
861 }
862 bufsz += wcslen(calculate->zip_path) + 1;
Victor Stinner3f5409a2019-09-23 19:50:27 +0200863 if (calculate->pythonpath_env != NULL) {
864 bufsz += wcslen(calculate->pythonpath_env) + 1;
Victor Stinner0327bde2017-11-23 17:03:20 +0100865 }
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +0000866
Victor Stinner0327bde2017-11-23 17:03:20 +0100867 wchar_t *buf, *start_buf;
868 buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 if (buf == NULL) {
Victor Stinner3f5409a2019-09-23 19:50:27 +0200870 Py_FatalError("Can't malloc dynamic PYTHONPATH");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000871 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100872 start_buf = buf;
Guido van Rossumeea14491997-08-13 21:30:44 +0000873
Victor Stinner3f5409a2019-09-23 19:50:27 +0200874 if (calculate->pythonpath_env) {
Victor Stinner31a83932017-12-04 13:39:15 +0100875 if (wcscpy_s(buf, bufsz - (buf - start_buf),
Victor Stinner3f5409a2019-09-23 19:50:27 +0200876 calculate->pythonpath_env)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100877 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100878 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 buf = wcschr(buf, L'\0');
880 *buf++ = DELIM;
881 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100882 if (calculate->zip_path[0]) {
883 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100884 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100885 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 buf = wcschr(buf, L'\0');
887 *buf++ = DELIM;
888 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100889 if (calculate->user_path) {
890 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->user_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100891 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100892 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 buf = wcschr(buf, L'\0');
894 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100896 if (calculate->machine_path) {
897 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->machine_path)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100898 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100899 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 buf = wcschr(buf, L'\0');
901 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100903 if (calculate->home == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000904 if (!skipdefault) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100905 if (wcscpy_s(buf, bufsz - (buf - start_buf), PYTHONPATH)) {
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');
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700909 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 }
Steve Dower4db86bc2016-09-09 09:17:35 -0700911 } else {
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200912 const wchar_t *p = PYTHONPATH;
913 const wchar_t *q;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 size_t n;
915 for (;;) {
916 q = wcschr(p, DELIM);
Victor Stinner0327bde2017-11-23 17:03:20 +0100917 if (q == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000918 n = wcslen(p);
Victor Stinner0327bde2017-11-23 17:03:20 +0100919 }
920 else {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 n = q-p;
Victor Stinner0327bde2017-11-23 17:03:20 +0100922 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 if (p[0] == '.' && is_sep(p[1])) {
Victor Stinner0327bde2017-11-23 17:03:20 +0100924 if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->home)) {
Victor Stinner9316ee42017-11-25 03:17:57 +0100925 return INIT_ERR_BUFFER_OVERFLOW();
Victor Stinner0327bde2017-11-23 17:03:20 +0100926 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 buf = wcschr(buf, L'\0');
928 p++;
929 n--;
930 }
931 wcsncpy(buf, p, n);
932 buf += n;
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700933 *buf++ = DELIM;
Victor Stinner0327bde2017-11-23 17:03:20 +0100934 if (q == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100936 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000937 p = q+1;
938 }
939 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100940 if (calculate->argv0_path) {
941 wcscpy(buf, calculate->argv0_path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 buf = wcschr(buf, L'\0');
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700943 *buf++ = DELIM;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 }
Steve Dower4a7fe7e2015-05-22 15:10:10 -0700945 *(buf - 1) = L'\0';
Victor Stinner0327bde2017-11-23 17:03:20 +0100946
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 /* Now to pull one last hack/trick. If sys.prefix is
948 empty, then try and find it somewhere on the paths
949 we calculated. We scan backwards, as our general policy
950 is that Python core directories are at the *end* of
951 sys.path. We assume that our "lib" directory is
952 on the path, and that our 'prefix' directory is
953 the parent of that.
954 */
Victor Stinner9316ee42017-11-25 03:17:57 +0100955 if (prefix[0] == L'\0') {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 wchar_t lookBuf[MAXPATHLEN+1];
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200957 const wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 while (1) {
959 Py_ssize_t nchars;
Serhiy Storchaka4ae06c52017-12-12 13:55:04 +0200960 const wchar_t *lookEnd = look;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 /* 'look' will end up one character before the
962 start of the path in question - even if this
963 is one character before the start of the buffer
964 */
Victor Stinner0327bde2017-11-23 17:03:20 +0100965 while (look >= start_buf && *look != DELIM)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 look--;
967 nchars = lookEnd-look;
968 wcsncpy(lookBuf, look+1, nchars);
969 lookBuf[nchars] = L'\0';
970 /* Up one level to the parent */
971 reduce(lookBuf);
Victor Stinner9316ee42017-11-25 03:17:57 +0100972 if (search_for_prefix(prefix, lookBuf, LANDMARK)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 break;
974 }
975 /* If we are out of paths to search - give up */
Victor Stinner0327bde2017-11-23 17:03:20 +0100976 if (look < start_buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 break;
Victor Stinner0327bde2017-11-23 17:03:20 +0100978 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 look--;
980 }
981 }
Victor Stinner0327bde2017-11-23 17:03:20 +0100982
Victor Stinner331a6a52019-05-27 16:39:22 +0200983 pathconfig->module_search_path = start_buf;
984 return _PyStatus_OK();
Victor Stinner9316ee42017-11-25 03:17:57 +0100985}
986
987
Victor Stinner331a6a52019-05-27 16:39:22 +0200988static PyStatus
Victor Stinner3f5409a2019-09-23 19:50:27 +0200989calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
Victor Stinner9316ee42017-11-25 03:17:57 +0100990{
Victor Stinner331a6a52019-05-27 16:39:22 +0200991 PyStatus status;
Victor Stinner9316ee42017-11-25 03:17:57 +0100992
Victor Stinnerc5c64252019-09-23 15:59:00 +0200993 status = get_program_full_path(pathconfig);
Victor Stinner331a6a52019-05-27 16:39:22 +0200994 if (_PyStatus_EXCEPTION(status)) {
995 return status;
Victor Stinner9316ee42017-11-25 03:17:57 +0100996 }
997
Victor Stinnerb64de462017-12-01 18:27:09 +0100998 /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */
Victor Stinner331a6a52019-05-27 16:39:22 +0200999 wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, pathconfig->program_full_path);
Victor Stinner9316ee42017-11-25 03:17:57 +01001000 reduce(calculate->argv0_path);
1001
1002 wchar_t prefix[MAXPATHLEN+1];
1003 memset(prefix, 0, sizeof(prefix));
1004
1005 /* Search for a sys.path file */
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001006 if (calculate_pth_file(calculate, pathconfig, prefix)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001007 goto done;
1008 }
1009
1010 calculate_pyvenv_file(calculate);
1011
1012 /* Calculate zip archive path from DLL or exe path */
1013 change_ext(calculate->zip_path,
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001014 calculate->dll_path[0] ? calculate->dll_path : pathconfig->program_full_path,
Victor Stinner9316ee42017-11-25 03:17:57 +01001015 L".zip");
1016
1017 calculate_home_prefix(calculate, prefix);
1018
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001019 if (pathconfig->module_search_path == NULL) {
Victor Stinner3f5409a2019-09-23 19:50:27 +02001020 status = calculate_module_search_path(calculate, pathconfig, prefix);
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001021 if (_PyStatus_EXCEPTION(status)) {
1022 return status;
1023 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001024 }
1025
1026done:
Victor Stinner331a6a52019-05-27 16:39:22 +02001027 if (pathconfig->prefix == NULL) {
Victor Stinner3f5409a2019-09-23 19:50:27 +02001028 pathconfig->prefix = _PyMem_RawWcsdup(prefix);
1029 if (pathconfig->prefix == NULL) {
1030 return _PyStatus_NO_MEMORY();
1031 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001032 }
Victor Stinner331a6a52019-05-27 16:39:22 +02001033 if (pathconfig->exec_prefix == NULL) {
Victor Stinner3f5409a2019-09-23 19:50:27 +02001034 pathconfig->exec_prefix = _PyMem_RawWcsdup(prefix);
1035 if (pathconfig->exec_prefix == NULL) {
1036 return _PyStatus_NO_MEMORY();
1037 }
Steve Dower177a41a2018-11-17 20:41:48 -08001038 }
Victor Stinner9316ee42017-11-25 03:17:57 +01001039
Victor Stinner331a6a52019-05-27 16:39:22 +02001040 return _PyStatus_OK();
Guido van Rossum1aa7e3a1997-05-19 14:16:21 +00001041}
1042
1043
Victor Stinner0327bde2017-11-23 17:03:20 +01001044static void
1045calculate_free(PyCalculatePath *calculate)
1046{
1047 PyMem_RawFree(calculate->machine_path);
1048 PyMem_RawFree(calculate->user_path);
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001049 PyMem_RawFree(calculate->dll_path);
Victor Stinner0327bde2017-11-23 17:03:20 +01001050}
1051
Victor Stinner9316ee42017-11-25 03:17:57 +01001052
Victor Stinner3f5409a2019-09-23 19:50:27 +02001053/* Calculate 'pathconfig' attributes:
1054
1055 - base_executable
1056 - program_full_path
1057 - module_search_path
1058 - prefix
1059 - exec_prefix
1060 - isolated
1061 - site_import
1062
1063 If an attribute is already set (non NULL), it is left unchanged. */
Victor Stinner331a6a52019-05-27 16:39:22 +02001064PyStatus
1065_PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
Serhiy Storchaka13badcb2017-12-02 21:36:00 +02001066{
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001067 PyStatus status;
Victor Stinner0327bde2017-11-23 17:03:20 +01001068 PyCalculatePath calculate;
1069 memset(&calculate, 0, sizeof(calculate));
1070
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001071 status = calculate_init(&calculate, config);
Victor Stinner331a6a52019-05-27 16:39:22 +02001072 if (_PyStatus_EXCEPTION(status)) {
Victor Stinner9316ee42017-11-25 03:17:57 +01001073 goto done;
1074 }
1075
Victor Stinner3f5409a2019-09-23 19:50:27 +02001076 status = calculate_path(&calculate, pathconfig);
Victor Stinner0327bde2017-11-23 17:03:20 +01001077
Victor Stinner9316ee42017-11-25 03:17:57 +01001078done:
Victor Stinner0327bde2017-11-23 17:03:20 +01001079 calculate_free(&calculate);
Victor Stinner331a6a52019-05-27 16:39:22 +02001080 return status;
Victor Stinner0327bde2017-11-23 17:03:20 +01001081}
1082
1083
Victor Stinner63941882011-09-29 00:42:28 +02001084/* Load python3.dll before loading any extension module that might refer
1085 to it. That way, we can be sure that always the python3.dll corresponding
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001086 to this python DLL is loaded, not a python3.dll that might be on the path
1087 by chance.
1088 Return whether the DLL was found.
1089*/
1090static int python3_checked = 0;
1091static HANDLE hPython3;
1092int
Victor Stinner31a83932017-12-04 13:39:15 +01001093_Py_CheckPython3(void)
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001094{
1095 wchar_t py3path[MAXPATHLEN+1];
1096 wchar_t *s;
Victor Stinner0327bde2017-11-23 17:03:20 +01001097 if (python3_checked) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001098 return hPython3 != NULL;
Victor Stinner0327bde2017-11-23 17:03:20 +01001099 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001100 python3_checked = 1;
1101
1102 /* If there is a python3.dll next to the python3y.dll,
1103 assume this is a build tree; use that DLL */
Victor Stinner9f3dcf82019-09-21 02:13:14 +02001104 if (_Py_dll_path != NULL) {
1105 wcscpy(py3path, _Py_dll_path);
1106 }
1107 else {
1108 wcscpy(py3path, L"");
1109 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001110 s = wcsrchr(py3path, L'\\');
Victor Stinner0327bde2017-11-23 17:03:20 +01001111 if (!s) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001112 s = py3path;
Victor Stinner0327bde2017-11-23 17:03:20 +01001113 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001114 wcscpy(s, L"\\python3.dll");
1115 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
Victor Stinner0327bde2017-11-23 17:03:20 +01001116 if (hPython3 != NULL) {
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001117 return 1;
Victor Stinner0327bde2017-11-23 17:03:20 +01001118 }
Martin v. Löwis4d0d4712010-12-03 20:14:31 +00001119
1120 /* Check sys.prefix\DLLs\python3.dll */
1121 wcscpy(py3path, Py_GetPrefix());
1122 wcscat(py3path, L"\\DLLs\\python3.dll");
1123 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
1124 return hPython3 != NULL;
1125}