diff -urN a/configure.ac b/configure.ac --- a/configure.ac 2014-10-11 14:21:34.252124800 +0100 +++ b/configure.ac 2014-10-11 14:21:37.003282200 +0100 @@ -5031,7 +5031,7 @@ case $host in *-*-mingw*) dnl default sys.path calculations for windows platforms - MODULE_GETPATH=PC/getpathp.o + MODULE_GETPATH=Modules/getpath.o ;; esac diff -urN a/Include/fileutils.h b/Include/fileutils.h --- a/Include/fileutils.h 2014-10-11 14:21:35.290184200 +0100 +++ b/Include/fileutils.h 2014-10-11 14:21:37.005282300 +0100 @@ -15,7 +15,7 @@ const wchar_t *text, size_t *error_pos); -#if defined(HAVE_STAT) && !defined(MS_WINDOWS) +#if defined(HAVE_STAT) && (!defined(MS_WINDOWS) || defined(__MINGW32__)) PyAPI_FUNC(int) _Py_wstat( const wchar_t* path, struct stat *buf); diff -urN a/Modules/getpath.c b/Modules/getpath.c --- a/Modules/getpath.c 2014-10-11 14:21:35.080172200 +0100 +++ b/Modules/getpath.c 2014-10-11 14:21:37.006282300 +0100 @@ -10,6 +10,10 @@ #include #endif +#ifdef MS_WINDOWS +#include +#endif + /* Search in some common locations for the associated Python libraries. * * Two directories must be found, the platform independent directory @@ -126,9 +130,17 @@ #define LANDMARK L"os.py" #endif +#ifdef __MINGW32__ +#define wcstok(line, delim, pointer) wcstok(line, delim) +#endif + static wchar_t prefix[MAXPATHLEN+1]; static wchar_t exec_prefix[MAXPATHLEN+1]; static wchar_t progpath[MAXPATHLEN+1]; +#ifdef MS_WINDOWS +static wchar_t dllpath[MAXPATHLEN+1]; +extern HANDLE PyWin_DLLhModule; +#endif static wchar_t *module_search_path = NULL; static void @@ -137,7 +149,7 @@ size_t i = wcslen(dir); while (i > 0 && dir[i] != SEP) --i; - dir[i] = '\0'; + dir[i] = 0; } static int @@ -207,7 +219,11 @@ joinpath(wchar_t *buffer, wchar_t *stuff) { size_t n, k; +#ifdef MS_WINDOWS + if (stuff[0] == SEP || (stuff[0] != 0 && stuff[1] == L':')) +#else if (stuff[0] == SEP) +#endif n = 0; else { n = wcslen(buffer); @@ -228,7 +244,11 @@ static void copy_absolute(wchar_t *path, wchar_t *p, size_t pathlen) { +#ifdef MS_WINDOWS + if (p[0] == SEP || (p[0] != 0 && p[1] == L':')) +#else if (p[0] == SEP) +#endif wcscpy(path, p); else { if (!_Py_wgetcwd(path, pathlen)) { @@ -248,7 +268,11 @@ { wchar_t buffer[MAXPATHLEN+1]; +#ifdef MS_WINDOWS + if (path[0] == SEP || (path[0] != 0 && path[1] == L':')) +#else if (path[0] == SEP) +#endif return; copy_absolute(buffer, path, MAXPATHLEN+1); wcscpy(path, buffer); @@ -455,6 +479,35 @@ return 0; } +#ifdef MS_WINDOWS +/* Calculates dllpath and progpath, replacing \\ with / */ +int GetWindowsModulePaths() +{ + int result = 0; + wchar_t* seps; + result = GetModuleFileNameW(NULL, progpath, MAXPATHLEN); + seps = wcschr(progpath, L'\\'); + while(seps) { + *seps = L'/'; + seps = wcschr(seps, L'\\'); + } + dllpath[0] = 0; +#ifdef Py_ENABLE_SHARED + if (PyWin_DLLhModule) { + if((GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN) > 0)) { + result = 1; + seps = wcschr(dllpath, L'\\'); + while(seps) { + *seps = L'/'; + seps = wcschr(seps, L'\\'); + } + } + } +#endif + return result; +} +#endif /* MS_WINDOWS */ + static void calculate_path(void) { @@ -533,6 +586,10 @@ } } #endif /* __APPLE__ */ +#ifdef MS_WINDOWS + else if(GetWindowsModulePaths()) { + } +#endif /* MS_WINDOWS */ else if (path) { while (1) { wchar_t *delim = wcschr(path, DELIM); @@ -561,7 +618,11 @@ else progpath[0] = '\0'; PyMem_RawFree(path_buffer); +#ifdef MS_WINDOWS + if (progpath[0] != '\0' && progpath[0] != SEP && progpath[1] != L':') +#else if (progpath[0] != SEP && progpath[0] != '\0') +#endif absolutize(progpath); wcsncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; @@ -871,7 +932,43 @@ } -#ifdef __cplusplus +#ifdef MS_WINDOWS +/* Load python3.dll before loading any extension module that might refer + to it. That way, we can be sure that always the python3.dll corresponding + to this python DLL is loaded, not a python3.dll that might be on the path + by chance. + Return whether the DLL was found. +*/ +static int python3_checked = 0; +static HANDLE hPython3; +int +_Py_CheckPython3() +{ + wchar_t py3path[MAXPATHLEN+1]; + wchar_t *s; + if (python3_checked) + return hPython3 != NULL; + python3_checked = 1; + + /* If there is a python3.dll next to the python3y.dll, + assume this is a build tree; use that DLL */ + wcscpy(py3path, dllpath); + s = wcsrchr(py3path, L'\\'); + if (!s) + s = py3path; + wcscpy(s, L"\\python3.dll"); + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (hPython3 != NULL) + return 1; + + /* Check sys.prefix\DLLs\python3.dll */ + wcscpy(py3path, Py_GetPrefix()); + wcscat(py3path, L"\\DLLs\\python3.dll"); + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + return hPython3 != NULL; } #endif +#ifdef __cplusplus +} +#endif diff -urN a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c 2014-10-11 14:21:35.095173000 +0100 +++ b/Modules/posixmodule.c 2014-10-11 14:21:37.010282600 +0100 @@ -1019,7 +1019,7 @@ } /* A helper used by a number of POSIX-only functions */ -#ifndef MS_WINDOWS +#if !defined(MS_WINDOWS) || defined(__MINGW32__) static int _parse_off_t(PyObject* arg, void* addr) { @@ -3689,7 +3689,7 @@ Py_END_ALLOW_THREADS /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { + if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) { Py_DECREF(list); list = path_error(path); goto exit; @@ -3744,7 +3744,7 @@ Py_END_ALLOW_THREADS /* FindNextFile sets error to ERROR_NO_MORE_FILES if it got to the end of the directory. */ - if (!result && GetLastError() != ERROR_NO_MORE_FILES) { + if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) { Py_DECREF(list); list = path_error(path); goto exit; diff -urN a/Python/fileutils.c b/Python/fileutils.c --- a/Python/fileutils.c 2014-10-11 14:21:34.292127100 +0100 +++ b/Python/fileutils.c 2014-10-11 14:21:37.011282600 +0100 @@ -511,7 +511,7 @@ Not sure whether the MS_WINDOWS guards are necessary: perhaps for cygwin/mingw builds? */ -#if defined(HAVE_STAT) && !defined(MS_WINDOWS) +#if defined(HAVE_STAT) && (!defined(MS_WINDOWS) || defined(__MINGW32__)) /* Get file status. Encode the path to the locale encoding. */