1
2 /* Return the initial module search path. */
3 /* Used by DOS, Windows 3.1, Windows 95/98, Windows NT. */
4
5 /* ----------------------------------------------------------------
6 PATH RULES FOR WINDOWS:
7 This describes how sys.path is formed on Windows. It describes the
8 functionality, not the implementation (ie, the order in which these
9 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.
12
13 * Python always adds an empty entry at the start, which corresponds
14 to the current directory.
15
16 * If the PYTHONPATH env. var. exists, its entries are added next.
17
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
28 to try and locate one of our "landmarks" and deduce our home.
29 - If we DO have a Python Home: The relevant sub-directories (Lib,
30 DLLs, etc) are based on the Python Home
31 - If we DO NOT have a Python Home, the core Python Path is
32 loaded from the registry. This is the main PythonPath key,
33 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_
37 we can assume is a good path), a default path with relative entries is
38 used (eg. .\Lib;.\DLLs, etc)
39
40
41 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
56
57 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
63 * When Python is hosted in another exe (different directory, embedded via
64 COM, etc), the Python Home will not be deduced, so the core path from
65 the registry is used. Other "application paths" in the registry are
66 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
72 * An embedding application can use Py_SetPath() to override all of
73 these automatic path computations.
74
75 * 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.
78
79 ---------------------------------------------------------------- */
80
81
82 #include "Python.h"
83 #include "osdefs.h"
84 #include <wchar.h>
85
86 #ifndef MS_WINDOWS
87 #error getpathp.c should only be built on Windows
88 #endif
89
90 #include <windows.h>
91 #include <Shlwapi.h>
92
93 #ifdef HAVE_SYS_TYPES_H
94 #include <sys/types.h>
95 #endif /* HAVE_SYS_TYPES_H */
96
97 #ifdef HAVE_SYS_STAT_H
98 #include <sys/stat.h>
99 #endif /* HAVE_SYS_STAT_H */
100
101 #include <string.h>
102
103 /* Search in some common locations for the associated Python libraries.
104 *
105 * Py_GetPath() tries to return a sensible Python module search path.
106 *
107 * The approach is an adaptation for Windows of the strategy used in
108 * ../Modules/getpath.c; it uses the Windows Registry as one of its
109 * information sources.
110 *
111 * Py_SetPath() can be used to override this mechanism. Call Py_SetPath
112 * with a semicolon separated path prior to calling Py_Initialize.
113 */
114
115 #ifndef LANDMARK
116 #define LANDMARK L"lib\\os.py"
117 #endif
118
119 static wchar_t prefix[MAXPATHLEN+1];
120 static wchar_t progpath[MAXPATHLEN+1];
121 static wchar_t dllpath[MAXPATHLEN+1];
122 static wchar_t *module_search_path = NULL;
123
124
125 static int
is_sep(wchar_t ch)126 is_sep(wchar_t ch) /* determine if "ch" is a separator character */
127 {
128 #ifdef ALTSEP
129 return ch == SEP || ch == ALTSEP;
130 #else
131 return ch == SEP;
132 #endif
133 }
134
135 /* assumes 'dir' null terminated in bounds. Never writes
136 beyond existing terminator.
137 */
138 static void
reduce(wchar_t * dir)139 reduce(wchar_t *dir)
140 {
141 size_t i = wcsnlen_s(dir, MAXPATHLEN+1);
142 if (i >= MAXPATHLEN+1)
143 Py_FatalError("buffer overflow in getpathp.c's reduce()");
144
145 while (i > 0 && !is_sep(dir[i]))
146 --i;
147 dir[i] = '\0';
148 }
149
150 static int
change_ext(wchar_t * dest,const wchar_t * src,const wchar_t * ext)151 change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext)
152 {
153 size_t src_len = wcsnlen_s(src, MAXPATHLEN+1);
154 size_t i = src_len;
155 if (i >= MAXPATHLEN+1)
156 Py_FatalError("buffer overflow in getpathp.c's reduce()");
157
158 while (i > 0 && src[i] != '.' && !is_sep(src[i]))
159 --i;
160
161 if (i == 0) {
162 dest[0] = '\0';
163 return -1;
164 }
165
166 if (is_sep(src[i]))
167 i = src_len;
168
169 if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) ||
170 wcscat_s(dest, MAXPATHLEN+1, ext)) {
171 dest[0] = '\0';
172 return -1;
173 }
174
175 return 0;
176 }
177
178 static int
exists(wchar_t * filename)179 exists(wchar_t *filename)
180 {
181 return GetFileAttributesW(filename) != 0xFFFFFFFF;
182 }
183
184 /* Assumes 'filename' MAXPATHLEN+1 bytes long -
185 may extend 'filename' by one character.
186 */
187 static int
ismodule(wchar_t * filename,int update_filename)188 ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc/.pyo too */
189 {
190 size_t n;
191
192 if (exists(filename))
193 return 1;
194
195 /* Check for the compiled version of prefix. */
196 n = wcsnlen_s(filename, MAXPATHLEN+1);
197 if (n < MAXPATHLEN) {
198 int exist = 0;
199 filename[n] = Py_OptimizeFlag ? L'o' : L'c';
200 filename[n + 1] = L'\0';
201 exist = exists(filename);
202 if (!update_filename)
203 filename[n] = L'\0';
204 return exist;
205 }
206 return 0;
207 }
208
209 /* Add a path component, by appending stuff to buffer.
210 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
211 NUL-terminated string with no more than MAXPATHLEN characters (not counting
212 the trailing NUL). It's a fatal error if it contains a string longer than
213 that (callers must be careful!). If these requirements are met, it's
214 guaranteed that buffer will still be a NUL-terminated string with no more
215 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
216 stuff as fits will be appended.
217 */
218
219 static int _PathCchCombineEx_Initialized = 0;
220 typedef HRESULT(__stdcall *PPathCchCombineEx)(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags);
221 static PPathCchCombineEx _PathCchCombineEx;
222
223 static void
join(wchar_t * buffer,const wchar_t * stuff)224 join(wchar_t *buffer, const wchar_t *stuff)
225 {
226 if (_PathCchCombineEx_Initialized == 0) {
227 HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
228 if (pathapi)
229 _PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
230 else
231 _PathCchCombineEx = NULL;
232 _PathCchCombineEx_Initialized = 1;
233 }
234
235 if (_PathCchCombineEx) {
236 if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0)))
237 Py_FatalError("buffer overflow in getpathp.c's join()");
238 } else {
239 if (!PathCombineW(buffer, buffer, stuff))
240 Py_FatalError("buffer overflow in getpathp.c's join()");
241 }
242 }
243
244 /* gotlandmark only called by search_for_prefix, which ensures
245 'prefix' is null terminated in bounds. join() ensures
246 'landmark' can not overflow prefix if too long.
247 */
248 static int
gotlandmark(const wchar_t * landmark)249 gotlandmark(const wchar_t *landmark)
250 {
251 int ok;
252 Py_ssize_t n = wcsnlen_s(prefix, MAXPATHLEN);
253
254 join(prefix, landmark);
255 ok = ismodule(prefix, FALSE);
256 prefix[n] = '\0';
257 return ok;
258 }
259
260 /* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
261 assumption provided by only caller, calculate_path() */
262 static int
search_for_prefix(wchar_t * argv0_path,const wchar_t * landmark)263 search_for_prefix(wchar_t *argv0_path, const wchar_t *landmark)
264 {
265 /* Search from argv0_path, until landmark is found */
266 wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
267 do {
268 if (gotlandmark(landmark))
269 return 1;
270 reduce(prefix);
271 } while (prefix[0]);
272 return 0;
273 }
274
275 #ifdef Py_ENABLE_SHARED
276
277 /* a string loaded from the DLL at startup.*/
278 extern const char *PyWin_DLLVersionString;
279
280
281 /* Load a PYTHONPATH value from the registry.
282 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
283
284 Works in both Unicode and 8bit environments. Only uses the
285 Ex family of functions so it also works with Windows CE.
286
287 Returns NULL, or a pointer that should be freed.
288
289 XXX - this code is pretty strange, as it used to also
290 work on Win16, where the buffer sizes werent available
291 in advance. It could be simplied now Win16/Win32s is dead!
292 */
293
294 static wchar_t *
getpythonregpath(HKEY keyBase,int skipcore)295 getpythonregpath(HKEY keyBase, int skipcore)
296 {
297 HKEY newKey = 0;
298 DWORD dataSize = 0;
299 DWORD numKeys = 0;
300 LONG rc;
301 wchar_t *retval = NULL;
302 WCHAR *dataBuf = NULL;
303 static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\";
304 static const WCHAR keySuffix[] = L"\\PythonPath";
305 size_t versionLen, keyBufLen;
306 DWORD index;
307 WCHAR *keyBuf = NULL;
308 WCHAR *keyBufPtr;
309 WCHAR **ppPaths = NULL;
310
311 /* Tried to use sysget("winver") but here is too early :-( */
312 versionLen = strlen(PyWin_DLLVersionString);
313 /* Space for all the chars, plus one \0 */
314 keyBufLen = sizeof(keyPrefix) +
315 sizeof(WCHAR)*(versionLen-1) +
316 sizeof(keySuffix);
317 keyBuf = keyBufPtr = PyMem_RawMalloc(keyBufLen);
318 if (keyBuf==NULL) goto done;
319
320 memcpy_s(keyBufPtr, keyBufLen, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
321 keyBufPtr += Py_ARRAY_LENGTH(keyPrefix) - 1;
322 mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen);
323 keyBufPtr += versionLen;
324 /* NULL comes with this one! */
325 memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
326 /* Open the root Python key */
327 rc=RegOpenKeyExW(keyBase,
328 keyBuf, /* subkey */
329 0, /* reserved */
330 KEY_READ,
331 &newKey);
332 if (rc!=ERROR_SUCCESS) goto done;
333 /* Find out how big our core buffer is, and how many subkeys we have */
334 rc = RegQueryInfoKey(newKey, NULL, NULL, NULL, &numKeys, NULL, NULL,
335 NULL, NULL, &dataSize, NULL, NULL);
336 if (rc!=ERROR_SUCCESS) goto done;
337 if (skipcore) dataSize = 0; /* Only count core ones if we want them! */
338 /* Allocate a temp array of char buffers, so we only need to loop
339 reading the registry once
340 */
341 ppPaths = PyMem_RawMalloc( sizeof(WCHAR *) * numKeys );
342 if (ppPaths==NULL) goto done;
343 memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
344 /* Loop over all subkeys, allocating a temp sub-buffer. */
345 for(index=0;index<numKeys;index++) {
346 WCHAR keyBuf[MAX_PATH+1];
347 HKEY subKey = 0;
348 DWORD reqdSize = MAX_PATH+1;
349 /* Get the sub-key name */
350 DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
351 NULL, NULL, NULL, NULL );
352 if (rc!=ERROR_SUCCESS) goto done;
353 /* Open the sub-key */
354 rc=RegOpenKeyExW(newKey,
355 keyBuf, /* subkey */
356 0, /* reserved */
357 KEY_READ,
358 &subKey);
359 if (rc!=ERROR_SUCCESS) goto done;
360 /* Find the value of the buffer size, malloc, then read it */
361 RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
362 if (reqdSize) {
363 ppPaths[index] = PyMem_RawMalloc(reqdSize);
364 if (ppPaths[index]) {
365 RegQueryValueExW(subKey, NULL, 0, NULL,
366 (LPBYTE)ppPaths[index],
367 &reqdSize);
368 dataSize += reqdSize + 1; /* 1 for the ";" */
369 }
370 }
371 RegCloseKey(subKey);
372 }
373
374 /* return null if no path to return */
375 if (dataSize == 0) goto done;
376
377 /* original datasize from RegQueryInfo doesn't include the \0 */
378 dataBuf = PyMem_RawMalloc((dataSize+1) * sizeof(WCHAR));
379 if (dataBuf) {
380 WCHAR *szCur = dataBuf;
381 /* Copy our collected strings */
382 for (index=0;index<numKeys;index++) {
383 if (index > 0) {
384 *(szCur++) = L';';
385 dataSize--;
386 }
387 if (ppPaths[index]) {
388 Py_ssize_t len = wcslen(ppPaths[index]);
389 wcsncpy(szCur, ppPaths[index], len);
390 szCur += len;
391 assert(dataSize > (DWORD)len);
392 dataSize -= (DWORD)len;
393 }
394 }
395 if (skipcore)
396 *szCur = '\0';
397 else {
398 /* If we have no values, we dont need a ';' */
399 if (numKeys) {
400 *(szCur++) = L';';
401 dataSize--;
402 }
403 /* Now append the core path entries -
404 this will include the NULL
405 */
406 rc = RegQueryValueExW(newKey, NULL, 0, NULL,
407 (LPBYTE)szCur, &dataSize);
408 if (rc != ERROR_SUCCESS) {
409 PyMem_RawFree(dataBuf);
410 goto done;
411 }
412 }
413 /* And set the result - caller must free */
414 retval = dataBuf;
415 }
416 done:
417 /* Loop freeing my temp buffers */
418 if (ppPaths) {
419 for(index=0; index<numKeys; index++)
420 PyMem_RawFree(ppPaths[index]);
421 PyMem_RawFree(ppPaths);
422 }
423 if (newKey)
424 RegCloseKey(newKey);
425 PyMem_RawFree(keyBuf);
426 return retval;
427 }
428 #endif /* Py_ENABLE_SHARED */
429
430 static void
get_progpath(void)431 get_progpath(void)
432 {
433 extern wchar_t *Py_GetProgramName(void);
434 wchar_t *path = _wgetenv(L"PATH");
435 wchar_t *prog = Py_GetProgramName();
436
437 #ifdef Py_ENABLE_SHARED
438 extern HANDLE PyWin_DLLhModule;
439 /* static init of progpath ensures final char remains \0 */
440 if (PyWin_DLLhModule)
441 if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN))
442 dllpath[0] = 0;
443 #else
444 dllpath[0] = 0;
445 #endif
446 if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
447 return;
448 if (prog == NULL || *prog == '\0')
449 prog = L"python";
450
451 /* If there is no slash in the argv0 path, then we have to
452 * assume python is on the user's $PATH, since there's no
453 * other way to find a directory to start the search from. If
454 * $PATH isn't exported, you lose.
455 */
456 #ifdef ALTSEP
457 if (wcschr(prog, SEP) || wcschr(prog, ALTSEP))
458 #else
459 if (wcschr(prog, SEP))
460 #endif
461 wcsncpy(progpath, prog, MAXPATHLEN);
462 else if (path) {
463 while (1) {
464 wchar_t *delim = wcschr(path, DELIM);
465
466 if (delim) {
467 size_t len = delim - path;
468 /* ensure we can't overwrite buffer */
469 len = min(MAXPATHLEN,len);
470 wcsncpy(progpath, path, len);
471 *(progpath + len) = '\0';
472 }
473 else
474 wcsncpy(progpath, path, MAXPATHLEN);
475
476 /* join() is safe for MAXPATHLEN+1 size buffer */
477 join(progpath, prog);
478 if (exists(progpath))
479 break;
480
481 if (!delim) {
482 progpath[0] = '\0';
483 break;
484 }
485 path = delim + 1;
486 }
487 }
488 else
489 progpath[0] = '\0';
490 }
491
492 static int
find_env_config_value(FILE * env_file,const wchar_t * key,wchar_t * value)493 find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
494 {
495 int result = 0; /* meaning not found */
496 char buffer[MAXPATHLEN*2+1]; /* allow extra for key, '=', etc. */
497
498 fseek(env_file, 0, SEEK_SET);
499 while (!feof(env_file)) {
500 char * p = fgets(buffer, MAXPATHLEN*2, env_file);
501 wchar_t tmpbuffer[MAXPATHLEN*2+1];
502 PyObject * decoded;
503 size_t n;
504
505 if (p == NULL)
506 break;
507 n = strlen(p);
508 if (p[n - 1] != '\n') {
509 /* line has overflowed - bail */
510 break;
511 }
512 if (p[0] == '#') /* Comment - skip */
513 continue;
514 decoded = PyUnicode_DecodeUTF8(buffer, n, "surrogateescape");
515 if (decoded != NULL) {
516 Py_ssize_t k;
517 k = PyUnicode_AsWideChar(decoded,
518 tmpbuffer, MAXPATHLEN * 2);
519 Py_DECREF(decoded);
520 if (k >= 0) {
521 wchar_t * context = NULL;
522 wchar_t * tok = wcstok_s(tmpbuffer, L" \t\r\n", &context);
523 if ((tok != NULL) && !wcscmp(tok, key)) {
524 tok = wcstok_s(NULL, L" \t", &context);
525 if ((tok != NULL) && !wcscmp(tok, L"=")) {
526 tok = wcstok_s(NULL, L"\r\n", &context);
527 if (tok != NULL) {
528 wcsncpy(value, tok, MAXPATHLEN);
529 result = 1;
530 break;
531 }
532 }
533 }
534 }
535 }
536 }
537 return result;
538 }
539
540 static int
read_pth_file(const wchar_t * path,wchar_t * prefix,int * isolated,int * nosite)541 read_pth_file(const wchar_t *path, wchar_t *prefix, int *isolated, int *nosite)
542 {
543 FILE *sp_file = _Py_wfopen(path, L"r");
544 if (sp_file == NULL)
545 return -1;
546
547 wcscpy_s(prefix, MAXPATHLEN+1, path);
548 reduce(prefix);
549 *isolated = 1;
550 *nosite = 1;
551
552 size_t bufsiz = MAXPATHLEN;
553 size_t prefixlen = wcslen(prefix);
554
555 wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
556 buf[0] = '\0';
557
558 while (!feof(sp_file)) {
559 char line[MAXPATHLEN + 1];
560 char *p = fgets(line, MAXPATHLEN + 1, sp_file);
561 if (!p)
562 break;
563 if (*p == '\0' || *p == '\r' || *p == '\n' || *p == '#')
564 continue;
565 while (*++p) {
566 if (*p == '\r' || *p == '\n') {
567 *p = '\0';
568 break;
569 }
570 }
571
572 if (strcmp(line, "import site") == 0) {
573 *nosite = 0;
574 continue;
575 } else if (strncmp(line, "import ", 7) == 0) {
576 Py_FatalError("only 'import site' is supported in ._pth file");
577 }
578
579 DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, NULL, 0);
580 wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
581 wn = MultiByteToWideChar(CP_UTF8, 0, line, -1, wline, wn + 1);
582 wline[wn] = '\0';
583
584 size_t usedsiz = wcslen(buf);
585 while (usedsiz + wn + prefixlen + 4 > bufsiz) {
586 bufsiz += MAXPATHLEN;
587 buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t));
588 if (!buf) {
589 PyMem_RawFree(wline);
590 goto error;
591 }
592 }
593
594 if (usedsiz) {
595 wcscat_s(buf, bufsiz, L";");
596 usedsiz += 1;
597 }
598
599 errno_t result;
600 _Py_BEGIN_SUPPRESS_IPH
601 result = wcscat_s(buf, bufsiz, prefix);
602 _Py_END_SUPPRESS_IPH
603 if (result == EINVAL) {
604 Py_FatalError("invalid argument during ._pth processing");
605 } else if (result == ERANGE) {
606 Py_FatalError("buffer overflow during ._pth processing");
607 }
608 wchar_t *b = &buf[usedsiz];
609 join(b, wline);
610
611 PyMem_RawFree(wline);
612 }
613
614 module_search_path = buf;
615
616 fclose(sp_file);
617 return 0;
618
619 error:
620 PyMem_RawFree(buf);
621 fclose(sp_file);
622 return -1;
623 }
624
625
626 static void
calculate_path(void)627 calculate_path(void)
628 {
629 wchar_t argv0_path[MAXPATHLEN+1];
630 wchar_t *buf;
631 size_t bufsz;
632 wchar_t *pythonhome = Py_GetPythonHome();
633 wchar_t *envpath = NULL;
634
635 int skiphome, skipdefault;
636 wchar_t *machinepath = NULL;
637 wchar_t *userpath = NULL;
638 wchar_t zip_path[MAXPATHLEN+1];
639
640 if (!Py_IgnoreEnvironmentFlag) {
641 envpath = _wgetenv(L"PYTHONPATH");
642 }
643
644 get_progpath();
645 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
646 wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
647 reduce(argv0_path);
648
649 /* Search for a sys.path file */
650 {
651 wchar_t spbuffer[MAXPATHLEN+1];
652
653 if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) ||
654 (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) {
655
656 if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) {
657 return;
658 }
659 }
660 }
661
662 /* Search for an environment configuration file, first in the
663 executable's directory and then in the parent directory.
664 If found, open it for use when searching for prefixes.
665 */
666
667 {
668 wchar_t envbuffer[MAXPATHLEN+1];
669 wchar_t tmpbuffer[MAXPATHLEN+1];
670 const wchar_t *env_cfg = L"pyvenv.cfg";
671 FILE * env_file = NULL;
672
673 wcscpy_s(envbuffer, MAXPATHLEN+1, argv0_path);
674 join(envbuffer, env_cfg);
675 env_file = _Py_wfopen(envbuffer, L"r");
676 if (env_file == NULL) {
677 errno = 0;
678 reduce(envbuffer);
679 reduce(envbuffer);
680 join(envbuffer, env_cfg);
681 env_file = _Py_wfopen(envbuffer, L"r");
682 if (env_file == NULL) {
683 errno = 0;
684 }
685 }
686 if (env_file != NULL) {
687 /* Look for a 'home' variable and set argv0_path to it, if found */
688 if (find_env_config_value(env_file, L"home", tmpbuffer)) {
689 wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
690 }
691 fclose(env_file);
692 env_file = NULL;
693 }
694 }
695
696 /* Calculate zip archive path from DLL or exe path */
697 change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip");
698
699 if (pythonhome == NULL || *pythonhome == '\0') {
700 if (zip_path[0] && exists(zip_path)) {
701 wcscpy_s(prefix, MAXPATHLEN+1, zip_path);
702 reduce(prefix);
703 pythonhome = prefix;
704 } else if (search_for_prefix(argv0_path, LANDMARK))
705 pythonhome = prefix;
706 else
707 pythonhome = NULL;
708 }
709 else
710 wcscpy_s(prefix, MAXPATHLEN+1, pythonhome);
711
712 if (envpath && *envpath == '\0')
713 envpath = NULL;
714
715
716 skiphome = pythonhome==NULL ? 0 : 1;
717 #ifdef Py_ENABLE_SHARED
718 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
719 userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
720 #endif
721 /* We only use the default relative PYTHONPATH if we havent
722 anything better to use! */
723 skipdefault = envpath!=NULL || pythonhome!=NULL || \
724 machinepath!=NULL || userpath!=NULL;
725
726 /* We need to construct a path from the following parts.
727 (1) the PYTHONPATH environment variable, if set;
728 (2) for Win32, the zip archive file path;
729 (3) for Win32, the machinepath and userpath, if set;
730 (4) the PYTHONPATH config macro, with the leading "."
731 of each component replaced with pythonhome, if set;
732 (5) the directory containing the executable (argv0_path).
733 The length calculation calculates #4 first.
734 Extra rules:
735 - If PYTHONHOME is set (in any way) item (3) is ignored.
736 - If registry values are used, (4) and (5) are ignored.
737 */
738
739 /* Calculate size of return buffer */
740 if (pythonhome != NULL) {
741 wchar_t *p;
742 bufsz = 1;
743 for (p = PYTHONPATH; *p; p++) {
744 if (*p == DELIM)
745 bufsz++; /* number of DELIM plus one */
746 }
747 bufsz *= wcslen(pythonhome);
748 }
749 else
750 bufsz = 0;
751 bufsz += wcslen(PYTHONPATH) + 1;
752 bufsz += wcslen(argv0_path) + 1;
753 if (userpath)
754 bufsz += wcslen(userpath) + 1;
755 if (machinepath)
756 bufsz += wcslen(machinepath) + 1;
757 bufsz += wcslen(zip_path) + 1;
758 if (envpath != NULL)
759 bufsz += wcslen(envpath) + 1;
760
761 module_search_path = buf = PyMem_RawMalloc(bufsz*sizeof(wchar_t));
762 if (buf == NULL) {
763 /* We can't exit, so print a warning and limp along */
764 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
765 if (envpath) {
766 fprintf(stderr, "Using environment $PYTHONPATH.\n");
767 module_search_path = envpath;
768 }
769 else {
770 fprintf(stderr, "Using default static path.\n");
771 module_search_path = PYTHONPATH;
772 }
773 PyMem_RawFree(machinepath);
774 PyMem_RawFree(userpath);
775 return;
776 }
777
778 if (envpath) {
779 if (wcscpy_s(buf, bufsz - (buf - module_search_path), envpath))
780 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
781 buf = wcschr(buf, L'\0');
782 *buf++ = DELIM;
783 }
784 if (zip_path[0]) {
785 if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
786 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
787 buf = wcschr(buf, L'\0');
788 *buf++ = DELIM;
789 }
790 if (userpath) {
791 if (wcscpy_s(buf, bufsz - (buf - module_search_path), userpath))
792 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
793 buf = wcschr(buf, L'\0');
794 *buf++ = DELIM;
795 PyMem_RawFree(userpath);
796 }
797 if (machinepath) {
798 if (wcscpy_s(buf, bufsz - (buf - module_search_path), machinepath))
799 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
800 buf = wcschr(buf, L'\0');
801 *buf++ = DELIM;
802 PyMem_RawFree(machinepath);
803 }
804 if (pythonhome == NULL) {
805 if (!skipdefault) {
806 if (wcscpy_s(buf, bufsz - (buf - module_search_path), PYTHONPATH))
807 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
808 buf = wcschr(buf, L'\0');
809 *buf++ = DELIM;
810 }
811 } else {
812 wchar_t *p = PYTHONPATH;
813 wchar_t *q;
814 size_t n;
815 for (;;) {
816 q = wcschr(p, DELIM);
817 if (q == NULL)
818 n = wcslen(p);
819 else
820 n = q-p;
821 if (p[0] == '.' && is_sep(p[1])) {
822 if (wcscpy_s(buf, bufsz - (buf - module_search_path), pythonhome))
823 Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
824 buf = wcschr(buf, L'\0');
825 p++;
826 n--;
827 }
828 wcsncpy(buf, p, n);
829 buf += n;
830 *buf++ = DELIM;
831 if (q == NULL)
832 break;
833 p = q+1;
834 }
835 }
836 if (argv0_path) {
837 wcscpy(buf, argv0_path);
838 buf = wcschr(buf, L'\0');
839 *buf++ = DELIM;
840 }
841 *(buf - 1) = L'\0';
842 /* Now to pull one last hack/trick. If sys.prefix is
843 empty, then try and find it somewhere on the paths
844 we calculated. We scan backwards, as our general policy
845 is that Python core directories are at the *end* of
846 sys.path. We assume that our "lib" directory is
847 on the path, and that our 'prefix' directory is
848 the parent of that.
849 */
850 if (*prefix==L'\0') {
851 wchar_t lookBuf[MAXPATHLEN+1];
852 wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
853 while (1) {
854 Py_ssize_t nchars;
855 wchar_t *lookEnd = look;
856 /* 'look' will end up one character before the
857 start of the path in question - even if this
858 is one character before the start of the buffer
859 */
860 while (look >= module_search_path && *look != DELIM)
861 look--;
862 nchars = lookEnd-look;
863 wcsncpy(lookBuf, look+1, nchars);
864 lookBuf[nchars] = L'\0';
865 /* Up one level to the parent */
866 reduce(lookBuf);
867 if (search_for_prefix(lookBuf, LANDMARK)) {
868 break;
869 }
870 /* If we are out of paths to search - give up */
871 if (look < module_search_path)
872 break;
873 look--;
874 }
875 }
876 }
877
878
879 /* External interface */
880
881 void
Py_SetPath(const wchar_t * path)882 Py_SetPath(const wchar_t *path)
883 {
884 if (module_search_path != NULL) {
885 PyMem_RawFree(module_search_path);
886 module_search_path = NULL;
887 }
888 if (path != NULL) {
889 extern wchar_t *Py_GetProgramName(void);
890 wchar_t *prog = Py_GetProgramName();
891 wcsncpy(progpath, prog, MAXPATHLEN);
892 prefix[0] = L'\0';
893 module_search_path = PyMem_RawMalloc((wcslen(path) + 1) * sizeof(wchar_t));
894 if (module_search_path != NULL)
895 wcscpy(module_search_path, path);
896 }
897 }
898
899 wchar_t *
Py_GetPath(void)900 Py_GetPath(void)
901 {
902 if (!module_search_path)
903 calculate_path();
904 return module_search_path;
905 }
906
907 wchar_t *
Py_GetPrefix(void)908 Py_GetPrefix(void)
909 {
910 if (!module_search_path)
911 calculate_path();
912 return prefix;
913 }
914
915 wchar_t *
Py_GetExecPrefix(void)916 Py_GetExecPrefix(void)
917 {
918 return Py_GetPrefix();
919 }
920
921 wchar_t *
Py_GetProgramFullPath(void)922 Py_GetProgramFullPath(void)
923 {
924 if (!module_search_path)
925 calculate_path();
926 return progpath;
927 }
928
929 /* Load python3.dll before loading any extension module that might refer
930 to it. That way, we can be sure that always the python3.dll corresponding
931 to this python DLL is loaded, not a python3.dll that might be on the path
932 by chance.
933 Return whether the DLL was found.
934 */
935 static int python3_checked = 0;
936 static HANDLE hPython3;
937 int
_Py_CheckPython3()938 _Py_CheckPython3()
939 {
940 wchar_t py3path[MAXPATHLEN+1];
941 wchar_t *s;
942 if (python3_checked)
943 return hPython3 != NULL;
944 python3_checked = 1;
945
946 /* If there is a python3.dll next to the python3y.dll,
947 assume this is a build tree; use that DLL */
948 wcscpy(py3path, dllpath);
949 s = wcsrchr(py3path, L'\\');
950 if (!s)
951 s = py3path;
952 wcscpy(s, L"\\python3.dll");
953 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
954 if (hPython3 != NULL)
955 return 1;
956
957 /* Check sys.prefix\DLLs\python3.dll */
958 wcscpy(py3path, Py_GetPrefix());
959 wcscat(py3path, L"\\DLLs\\python3.dll");
960 hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
961 return hPython3 != NULL;
962 }
963