Home | History | Annotate | Download | only in PC
      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