diff -rupN --no-dereference Python-3.10.9/Include/cpython/fileutils.h Python-3.10.9-new/Include/cpython/fileutils.h --- Python-3.10.9/Include/cpython/fileutils.h 2022-12-06 19:31:21.000000000 +0100 +++ Python-3.10.9-new/Include/cpython/fileutils.h 2022-12-08 09:37:03.418024952 +0100 @@ -135,9 +135,7 @@ PyAPI_FUNC(wchar_t*) _Py_wrealpath( size_t resolved_path_len); #endif -#ifndef MS_WINDOWS PyAPI_FUNC(int) _Py_isabs(const wchar_t *path); -#endif PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p); diff -rupN --no-dereference Python-3.10.9/Include/osdefs.h Python-3.10.9-new/Include/osdefs.h --- Python-3.10.9/Include/osdefs.h 2022-12-06 19:31:21.000000000 +0100 +++ Python-3.10.9-new/Include/osdefs.h 2022-12-08 09:37:03.418024952 +0100 @@ -10,7 +10,6 @@ extern "C" { #ifdef MS_WINDOWS #define SEP L'\\' #define ALTSEP L'/' -#define MAXPATHLEN 256 #define DELIM L';' #endif diff -rupN --no-dereference Python-3.10.9/Modules/getpath.c Python-3.10.9-new/Modules/getpath.c --- Python-3.10.9/Modules/getpath.c 2022-12-08 09:36:56.842024805 +0100 +++ Python-3.10.9-new/Modules/getpath.c 2022-12-08 09:37:03.419024952 +0100 @@ -13,6 +13,11 @@ # include <mach-o/dyld.h> #endif +#ifdef MS_WINDOWS +#include <windows.h> +#include <shlwapi.h> +#endif + /* Search in some common locations for the associated Python libraries. * * Two directories must be found, the platform independent directory @@ -148,6 +153,15 @@ typedef struct { static const wchar_t delimiter[2] = {DELIM, '\0'}; static const wchar_t separator[2] = {SEP, '\0'}; +static int +is_sep(wchar_t ch) +{ +#ifdef _WIN32 + return ch == SEP || ch == ALTSEP; +#else + return ch == SEP; +#endif +} /* Get file status. Encode the path to the locale encoding. */ static int @@ -170,7 +184,7 @@ static void reduce(wchar_t *dir) { size_t i = wcslen(dir); - while (i > 0 && dir[i] != SEP) { + while (i > 0 && !is_sep(dir[i])) { --i; } dir[i] = '\0'; @@ -242,7 +256,7 @@ joinpath(wchar_t *path, const wchar_t *p return PATHLEN_ERR(); } - if (n > 0 && path[n-1] != SEP) { + if (n > 0 && !is_sep(path[n-1])) { path[n++] = SEP; } } @@ -334,7 +348,7 @@ copy_absolute(wchar_t *abs_path, const w } return _PyStatus_OK(); } - if (path[0] == '.' && path[1] == SEP) { + if (path[0] == '.' && is_sep(path[1])) { path += 2; } PyStatus status = joinpath(abs_path, path, abs_path_len); @@ -614,7 +628,11 @@ calculate_set_prefix(PyCalculatePath *ca if (prefix == NULL) { return _PyStatus_NO_MEMORY(); } - +#ifdef _WIN32 + wchar_t drive_root[3]; + memset(drive_root, 0, sizeof(drive_root)); + wcsncpy(drive_root, prefix, 3); +#endif reduce(prefix); reduce(prefix); if (prefix[0]) { @@ -625,7 +643,11 @@ calculate_set_prefix(PyCalculatePath *ca /* The prefix is the root directory, but reduce() chopped off the "/". */ +#ifdef _WIN32 + pathconfig->prefix = _PyMem_RawWcsdup(drive_root); +#else pathconfig->prefix = _PyMem_RawWcsdup(separator); +#endif if (pathconfig->prefix == NULL) { return _PyStatus_NO_MEMORY(); } @@ -788,6 +810,27 @@ search_for_exec_prefix(PyCalculatePath * return _PyStatus_OK(); } +#ifdef MS_WINDOWS +wchar_t* +_Py_GetDLLPath(void) +{ + wchar_t dll_path[MAXPATHLEN+1]; + memset(dll_path, 0, sizeof(dll_path)); + +#ifdef Py_ENABLE_SHARED + extern HANDLE PyWin_DLLhModule; + if (PyWin_DLLhModule) { + if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) { + dll_path[0] = 0; + } + } +#else + dll_path[0] = 0; +#endif + + return _PyMem_RawWcsdup(dll_path); +} +#endif /* MS_WINDOWS */ static PyStatus calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig) @@ -845,7 +888,11 @@ calculate_set_exec_prefix(PyCalculatePat if (exec_prefix == NULL) { return _PyStatus_NO_MEMORY(); } - +#ifdef _WIN32 + wchar_t drive_root[3]; + memset(drive_root, 0, sizeof(drive_root)); + wcsncpy(drive_root, exec_prefix, 3); +#endif reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); @@ -859,7 +906,11 @@ calculate_set_exec_prefix(PyCalculatePat /* The exec_prefix is the root directory, but reduce() chopped off the "/". */ +#ifdef _WIN32 + pathconfig->exec_prefix = _PyMem_RawWcsdup(drive_root); +#else pathconfig->exec_prefix = _PyMem_RawWcsdup(separator); +#endif if (pathconfig->exec_prefix == NULL) { return _PyStatus_NO_MEMORY(); } @@ -1191,10 +1242,12 @@ calculate_argv0_path(PyCalculatePath *ca } #endif +#if HAVE_READLINK status = resolve_symlinks(&calculate->argv0_path); if (_PyStatus_EXCEPTION(status)) { return status; } +#endif reduce(calculate->argv0_path); @@ -1364,6 +1417,14 @@ calculate_module_search_path(PyCalculate bufsz += wcslen(calculate->zip_path) + 1; bufsz += wcslen(calculate->exec_prefix) + 1; +#ifdef MS_WINDOWS + if (_Py_isabs(calculate->prefix)) { + bufsz += wcslen(calculate->prefix) + 1; + } + if (_Py_isabs(calculate->argv0_path)) { + bufsz += wcslen(calculate->argv0_path) + 1; + } +#endif /* Allocate the buffer */ wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t)); @@ -1391,7 +1452,7 @@ calculate_module_search_path(PyCalculate if (!_Py_isabs(defpath)) { wcscat(buf, calculate->prefix); - if (prefixsz >= 2 && calculate->prefix[prefixsz - 2] != SEP && + if (prefixsz >= 2 && !is_sep(calculate->prefix[prefixsz - 2]) && defpath[0] != (delim ? DELIM : L'\0')) { /* not empty */ @@ -1412,6 +1473,16 @@ calculate_module_search_path(PyCalculate defpath = delim + 1; } wcscat(buf, delimiter); +#ifdef MS_WINDOWS + if (_Py_isabs(calculate->prefix)) { + wcscat(buf, calculate->prefix); + wcscat(buf, delimiter); + } + if (_Py_isabs(calculate->argv0_path)) { + wcscat(buf, calculate->argv0_path); + wcscat(buf, delimiter); + } +#endif /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, calculate->exec_prefix); diff -rupN --no-dereference Python-3.10.9/Python/fileutils.c Python-3.10.9-new/Python/fileutils.c --- Python-3.10.9/Python/fileutils.c 2022-12-06 19:31:21.000000000 +0100 +++ Python-3.10.9-new/Python/fileutils.c 2022-12-08 09:37:03.419024952 +0100 @@ -1976,13 +1976,21 @@ _Py_wrealpath(const wchar_t *path, #endif -#ifndef MS_WINDOWS int _Py_isabs(const wchar_t *path) { - return (path[0] == SEP); -} +#ifdef MS_WINDOWS + size_t i = wcslen(path); + if (i >= 3) { + if (iswalpha(path[0]) && path[1] == L':' && (path[2] == SEP || path[2] == ALTSEP)) { + return 1; + } + } + return 0; +#else + return path[0] == SEP; #endif +} /* Get an absolute path. diff -rupN --no-dereference Python-3.10.9/Python/pathconfig.c Python-3.10.9-new/Python/pathconfig.c --- Python-3.10.9/Python/pathconfig.c 2022-12-06 19:31:21.000000000 +0100 +++ Python-3.10.9-new/Python/pathconfig.c 2022-12-08 09:37:03.420024952 +0100 @@ -15,6 +15,11 @@ extern "C" { #endif +#ifdef __MINGW32__ +// Include windows.h for MAXPATHLEN instead of overriding it in osdefs.h +#include <windows.h> +#endif + _PyPathConfig _Py_path_config = _PyPathConfig_INIT; @@ -227,7 +232,7 @@ _PyPathConfig_AsDict(void) { wchar_t py3path[MAX_PATH]; - HMODULE hPython3 = GetModuleHandleW(PY3_DLLNAME); + HMODULE hPython3 = GetModuleHandleW("python3"); PyObject *obj; if (hPython3 && GetModuleFileNameW(hPython3, py3path, Py_ARRAY_LENGTH(py3path)))