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 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 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 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 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 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 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 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 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 * 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 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 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 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 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 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 * 900 Py_GetPath(void) 901 { 902 if (!module_search_path) 903 calculate_path(); 904 return module_search_path; 905 } 906 907 wchar_t * 908 Py_GetPrefix(void) 909 { 910 if (!module_search_path) 911 calculate_path(); 912 return prefix; 913 } 914 915 wchar_t * 916 Py_GetExecPrefix(void) 917 { 918 return Py_GetPrefix(); 919 } 920 921 wchar_t * 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 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