|
93 | 93 |
|
94 | 94 | static wchar_t prefix[MAXPATHLEN+1]; |
95 | 95 | static wchar_t progpath[MAXPATHLEN+1]; |
96 | | -static wchar_t dllpath[MAXPATHLEN+1]; |
97 | 96 | static wchar_t *module_search_path = NULL; |
98 | 97 |
|
99 | 98 |
|
@@ -122,6 +121,46 @@ reduce(wchar_t *dir) |
122 | 121 | dir[i] = '\0'; |
123 | 122 | } |
124 | 123 |
|
| 124 | +static int |
| 125 | +change_ext(wchar_t *dest, const wchar_t *src, const wchar_t *ext) |
| 126 | +{ |
| 127 | + if (src && src != dest) { |
| 128 | + size_t src_len = wcsnlen_s(src, MAXPATHLEN+1); |
| 129 | + size_t i = src_len; |
| 130 | + if (i >= MAXPATHLEN+1) { |
| 131 | + Py_FatalError("buffer overflow in getpathp.c's reduce()"); |
| 132 | + } |
| 133 | + |
| 134 | + while (i > 0 && src[i] != '.' && !is_sep(src[i])) |
| 135 | + --i; |
| 136 | + |
| 137 | + if (i == 0) { |
| 138 | + dest[0] = '\0'; |
| 139 | + return -1; |
| 140 | + } |
| 141 | + |
| 142 | + if (is_sep(src[i])) { |
| 143 | + i = src_len; |
| 144 | + } |
| 145 | + |
| 146 | + if (wcsncpy_s(dest, MAXPATHLEN+1, src, i)) { |
| 147 | + dest[0] = '\0'; |
| 148 | + return -1; |
| 149 | + } |
| 150 | + } else { |
| 151 | + wchar_t *s = wcsrchr(dest, L'.'); |
| 152 | + if (s) { |
| 153 | + s[0] = '\0'; |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + if (wcscat_s(dest, MAXPATHLEN+1, ext)) { |
| 158 | + dest[0] = '\0'; |
| 159 | + return -1; |
| 160 | + } |
| 161 | + |
| 162 | + return 0; |
| 163 | +} |
125 | 164 |
|
126 | 165 | static int |
127 | 166 | exists(wchar_t *filename) |
@@ -214,6 +253,20 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *landmark) |
214 | 253 | return 0; |
215 | 254 | } |
216 | 255 |
|
| 256 | + |
| 257 | +static int |
| 258 | +get_dllpath(wchar_t *dllpath) |
| 259 | +{ |
| 260 | +#ifdef Py_ENABLE_SHARED |
| 261 | + extern HANDLE PyWin_DLLhModule; |
| 262 | + if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) { |
| 263 | + return 0; |
| 264 | + } |
| 265 | +#endif |
| 266 | + return -1; |
| 267 | +} |
| 268 | + |
| 269 | + |
217 | 270 | #ifdef MS_WINDOWS |
218 | 271 | #ifdef Py_ENABLE_SHARED |
219 | 272 |
|
@@ -378,19 +431,8 @@ get_progpath(void) |
378 | 431 | wchar_t *path = _wgetenv(L"PATH"); |
379 | 432 | wchar_t *prog = Py_GetProgramName(); |
380 | 433 |
|
381 | | -#ifdef MS_WINDOWS |
382 | | -#ifdef Py_ENABLE_SHARED |
383 | | - extern HANDLE PyWin_DLLhModule; |
384 | | - /* static init of progpath ensures final char remains \0 */ |
385 | | - if (PyWin_DLLhModule) |
386 | | - if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN)) |
387 | | - dllpath[0] = 0; |
388 | | -#else |
389 | | - dllpath[0] = 0; |
390 | | -#endif |
391 | 434 | if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN)) |
392 | 435 | return; |
393 | | -#endif |
394 | 436 | if (prog == NULL || *prog == '\0') |
395 | 437 | prog = L"python"; |
396 | 438 |
|
@@ -578,14 +620,10 @@ calculate_path(void) |
578 | 620 |
|
579 | 621 | #ifdef MS_WINDOWS |
580 | 622 | /* Calculate zip archive path from DLL or exe path */ |
581 | | - if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath)) |
582 | | - /* exceeded buffer length - ignore zip_path */ |
583 | | - zip_path[0] = '\0'; |
584 | | - else { |
585 | | - wchar_t *dot = wcsrchr(zip_path, '.'); |
586 | | - if (!dot || wcscpy_s(dot, MAXPATHLEN+1 - (dot - zip_path), L".zip")) |
587 | | - /* exceeded buffer length - ignore zip_path */ |
588 | | - zip_path[0] = L'\0'; |
| 623 | + if (!get_dllpath(zip_path)) { |
| 624 | + change_ext(zip_path, zip_path, L".zip"); |
| 625 | + } else { |
| 626 | + change_ext(zip_path, progpath, L".zip"); |
589 | 627 | } |
590 | 628 |
|
591 | 629 | skiphome = pythonhome==NULL ? 0 : 1; |
@@ -768,8 +806,6 @@ calculate_path(void) |
768 | 806 | } |
769 | 807 |
|
770 | 808 |
|
771 | | -/* External interface */ |
772 | | - |
773 | 809 | void |
774 | 810 | Py_SetPath(const wchar_t *path) |
775 | 811 | { |
@@ -830,25 +866,39 @@ int |
830 | 866 | _Py_CheckPython3() |
831 | 867 | { |
832 | 868 | wchar_t py3path[MAXPATHLEN+1]; |
833 | | - wchar_t *s; |
834 | | - if (python3_checked) |
| 869 | + if (python3_checked) { |
835 | 870 | return hPython3 != NULL; |
| 871 | + } |
836 | 872 | python3_checked = 1; |
837 | 873 |
|
838 | 874 | /* If there is a python3.dll next to the python3y.dll, |
839 | | - assume this is a build tree; use that DLL */ |
840 | | - wcscpy(py3path, dllpath); |
841 | | - s = wcsrchr(py3path, L'\\'); |
842 | | - if (!s) |
843 | | - s = py3path; |
844 | | - wcscpy(s, L"\\python3.dll"); |
845 | | - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
846 | | - if (hPython3 != NULL) |
847 | | - return 1; |
| 875 | + use that DLL */ |
| 876 | + if (!get_dllpath(py3path)) { |
| 877 | + reduce(py3path); |
| 878 | + join(py3path, PY3_DLLNAME); |
| 879 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 880 | + if (hPython3 != NULL) { |
| 881 | + return 1; |
| 882 | + } |
| 883 | + } |
848 | 884 |
|
849 | | - /* Check sys.prefix\DLLs\python3.dll */ |
| 885 | + /* If we can locate python3.dll in our application dir, |
| 886 | + use that DLL */ |
850 | 887 | wcscpy(py3path, Py_GetPrefix()); |
851 | | - wcscat(py3path, L"\\DLLs\\python3.dll"); |
852 | | - hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 888 | + if (py3path[0]) { |
| 889 | + join(py3path, PY3_DLLNAME); |
| 890 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 891 | + if (hPython3 != NULL) { |
| 892 | + return 1; |
| 893 | + } |
| 894 | + } |
| 895 | + |
| 896 | + /* For back-compat, also search {sys.prefix}\DLLs, though |
| 897 | + that has not been a normal install layout for a while */ |
| 898 | + wcscpy(py3path, Py_GetPrefix()); |
| 899 | + if (py3path[0]) { |
| 900 | + join(py3path, L"DLLs\\" PY3_DLLNAME); |
| 901 | + hPython3 = LoadLibraryExW(py3path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); |
| 902 | + } |
853 | 903 | return hPython3 != NULL; |
854 | 904 | } |
0 commit comments