|
118 | 118 |
|
119 | 119 | static wchar_t prefix[MAXPATHLEN+1]; |
120 | 120 | static wchar_t progpath[MAXPATHLEN+1]; |
121 | | -static wchar_t dllpath[MAXPATHLEN+1]; |
122 | 121 | static wchar_t *module_search_path = NULL; |
123 | 122 |
|
124 | 123 |
|
@@ -150,24 +149,37 @@ reduce(wchar_t *dir) |
150 | 149 | static int |
151 | 150 | change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext) |
152 | 151 | { |
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()"); |
| 152 | + if (src && src != dest) { |
| 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 | + } |
157 | 158 |
|
158 | | - while (i > 0 && src[i] != '.' && !is_sep(src[i])) |
159 | | - --i; |
| 159 | + while (i > 0 && src[i] != '.' && !is_sep(src[i])) |
| 160 | + --i; |
160 | 161 |
|
161 | | - if (i == 0) { |
162 | | - dest[0] = '\0'; |
163 | | - return -1; |
164 | | - } |
| 162 | + if (i == 0) { |
| 163 | + dest[0] = '\0'; |
| 164 | + return -1; |
| 165 | + } |
165 | 166 |
|
166 | | - if (is_sep(src[i])) |
167 | | - i = src_len; |
| 167 | + if (is_sep(src[i])) { |
| 168 | + i = src_len; |
| 169 | + } |
| 170 | + |
| 171 | + if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) { |
| 172 | + dest[0] = '\0'; |
| 173 | + return -1; |
| 174 | + } |
| 175 | + } else { |
| 176 | + wchar_t *s = wcsrchr(dest, L'.'); |
| 177 | + if (s) { |
| 178 | + s[0] = '\0'; |
| 179 | + } |
| 180 | + } |
168 | 181 |
|
169 | | - if (wcsncpy_s(dest, MAXPATHLEN+1, src, i) || |
170 | | - wcscat_s(dest, MAXPATHLEN+1, ext)) { |
| 182 | + if (wcscat_s(dest, MAXPATHLEN+1, ext)) { |
171 | 183 | dest[0] = '\0'; |
172 | 184 | return -1; |
173 | 185 | } |
@@ -304,6 +316,20 @@ search_for_prefix(wchar_t *argv0_path, const wchar_t *landmark) |
304 | 316 | return 0; |
305 | 317 | } |
306 | 318 |
|
| 319 | + |
| 320 | +static int |
| 321 | +get_dllpath(wchar_t *dllpath) |
| 322 | +{ |
| 323 | +#ifdef Py_ENABLE_SHARED |
| 324 | + extern HANDLE PyWin_DLLhModule; |
| 325 | + if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) { |
| 326 | + return 0; |
| 327 | + } |
| 328 | +#endif |
| 329 | + return -1; |
| 330 | +} |
| 331 | + |
| 332 | + |
307 | 333 | #ifdef Py_ENABLE_SHARED |
308 | 334 |
|
309 | 335 | /* a string loaded from the DLL at startup.*/ |
@@ -467,15 +493,6 @@ get_progpath(void) |
467 | 493 | wchar_t *path = _wgetenv(L"PATH"); |
468 | 494 | wchar_t *prog = Py_GetProgramName(); |
469 | 495 |
|
470 | | -#ifdef Py_ENABLE_SHARED |
471 | | - extern HANDLE PyWin_DLLhModule; |
472 | | - /* static init of progpath ensures final char remains \0 */ |
473 | | - if (PyWin_DLLhModule) |
474 | | - if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) |
475 | | - dllpath[0] = 0; |
476 | | -#else |
477 | | - dllpath[0] = 0; |
478 | | -#endif |
479 | 496 | if (GetModuleFileNameW(NULL, modulepath, MAXPATHLEN)) { |
480 | 497 | canonicalize(progpath, modulepath); |
481 | 498 | return; |
@@ -693,7 +710,7 @@ calculate_path(void) |
693 | 710 | { |
694 | 711 | wchar_t spbuffer[MAXPATHLEN+1]; |
695 | 712 |
|
696 | | - if ((dllpath[0] && !change_ext(spbuffer, dllpath, L"._pth") && exists(spbuffer)) || |
| 713 | + if ((!get_dllpath(spbuffer) && !change_ext(spbuffer, spbuffer, L"._pth") && exists(spbuffer)) || |
697 | 714 | (progpath[0] && !change_ext(spbuffer, progpath, L"._pth") && exists(spbuffer))) { |
698 | 715 |
|
699 | 716 | if (!read_pth_file(spbuffer, prefix, &Py_IsolatedFlag, &Py_NoSiteFlag)) { |
@@ -737,7 +754,11 @@ calculate_path(void) |
737 | 754 | } |
738 | 755 |
|
739 | 756 | /* Calculate zip archive path from DLL or exe path */ |
740 | | - change_ext(zip_path, dllpath[0] ? dllpath : progpath, L".zip"); |
| 757 | + if (!get_dllpath(zip_path)) { |
| 758 | + change_ext(zip_path, zip_path, L".zip"); |
| 759 | + } else { |
| 760 | + change_ext(zip_path, progpath, L".zip"); |
| 761 | + } |
741 | 762 |
|
742 | 763 | if (pythonhome == NULL || *pythonhome == '\0') { |
743 | 764 | if (zip_path[0] && exists(zip_path)) { |
@@ -919,8 +940,6 @@ calculate_path(void) |
919 | 940 | } |
920 | 941 |
|
921 | 942 |
|
922 | | -/* External interface */ |
923 | | - |
924 | 943 | void |
925 | 944 | Py_SetPath(const wchar_t *path) |
926 | 945 | { |
@@ -981,25 +1000,39 @@ int |
981 | 1000 | _Py_CheckPython3() |
982 | 1001 | { |
983 | 1002 | wchar_t py3path[MAXPATHLEN+1]; |
984 | | - wchar_t *s; |
985 | | - if (python3_checked) |
| 1003 | + if (python3_checked) { |
986 | 1004 | return hPython3 != NULL; |
| 1005 | + } |
987 | 1006 | python3_checked = 1; |
988 | 1007 |
|
989 | 1008 | /* If there is a python3.dll next to the python3y.dll, |
990 | | - assume this is a build tree; use that DLL */ |
991 | | - wcscpy(py3path, dllpath); |
992 | | - s = wcsrchr(py3path, L'\\'); |
993 | | - if (!s) |
994 | | - s = py3path; |
995 | | - wcscpy(s, L"\\python3.dll"); |
996 | | - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
997 | | - if (hPython3 != NULL) |
998 | | - return 1; |
| 1009 | + use that DLL */ |
| 1010 | + if (!get_dllpath(py3path)) { |
| 1011 | + reduce(py3path); |
| 1012 | + join(py3path, PY3_DLLNAME); |
| 1013 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 1014 | + if (hPython3 != NULL) { |
| 1015 | + return 1; |
| 1016 | + } |
| 1017 | + } |
| 1018 | + |
| 1019 | + /* If we can locate python3.dll in our application dir, |
| 1020 | + use that DLL */ |
| 1021 | + wcscpy(py3path, Py_GetPrefix()); |
| 1022 | + if (py3path[0]) { |
| 1023 | + join(py3path, PY3_DLLNAME); |
| 1024 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 1025 | + if (hPython3 != NULL) { |
| 1026 | + return 1; |
| 1027 | + } |
| 1028 | + } |
999 | 1029 |
|
1000 | | - /* Check sys.prefix\DLLs\python3.dll */ |
| 1030 | + /* For back-compat, also search {sys.prefix}\DLLs, though |
| 1031 | + that has not been a normal install layout for a while */ |
1001 | 1032 | wcscpy(py3path, Py_GetPrefix()); |
1002 | | - wcscat(py3path, L"\\DLLs\\python3.dll"); |
1003 | | - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 1033 | + if (py3path[0]) { |
| 1034 | + join(py3path, L"DLLs\\" PY3_DLLNAME); |
| 1035 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 1036 | + } |
1004 | 1037 | return hPython3 != NULL; |
1005 | 1038 | } |
0 commit comments