|
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