@@ -130,8 +130,6 @@ typedef struct {
130130 wchar_t * machine_path ; /* from HKEY_LOCAL_MACHINE */
131131 wchar_t * user_path ; /* from HKEY_CURRENT_USER */
132132
133- wchar_t * dll_path ;
134-
135133 const wchar_t * pythonpath_env ;
136134} PyCalculatePath ;
137135
@@ -167,27 +165,37 @@ reduce(wchar_t *dir)
167165static int
168166change_ext (wchar_t * dest , const wchar_t * src , const wchar_t * ext )
169167{
170- size_t src_len = wcsnlen_s (src , MAXPATHLEN + 1 );
171- size_t i = src_len ;
172- if (i >= MAXPATHLEN + 1 ) {
173- Py_FatalError ("buffer overflow in getpathp.c's reduce()" );
174- }
168+ if (src && src != dest ) {
169+ size_t src_len = wcsnlen_s (src , MAXPATHLEN + 1 );
170+ size_t i = src_len ;
171+ if (i >= MAXPATHLEN + 1 ) {
172+ Py_FatalError ("buffer overflow in getpathp.c's reduce()" );
173+ }
175174
176- while (i > 0 && src [i ] != '.' && !is_sep (src [i ]))
177- -- i ;
175+ while (i > 0 && src [i ] != '.' && !is_sep (src [i ]))
176+ -- i ;
178177
179- if (i == 0 ) {
180- dest [0 ] = '\0' ;
181- return -1 ;
182- }
178+ if (i == 0 ) {
179+ dest [0 ] = '\0' ;
180+ return -1 ;
181+ }
182+
183+ if (is_sep (src [i ])) {
184+ i = src_len ;
185+ }
183186
184- if (is_sep (src [i ])) {
185- i = src_len ;
187+ if (wcsncpy_s (dest , MAXPATHLEN + 1 , src , i )) {
188+ dest [0 ] = '\0' ;
189+ return -1 ;
190+ }
191+ } else {
192+ wchar_t * s = wcsrchr (dest , L'.' );
193+ if (s ) {
194+ s [0 ] = '\0' ;
195+ }
186196 }
187197
188- if (wcsncpy_s (dest , MAXPATHLEN + 1 , src , i ) ||
189- wcscat_s (dest , MAXPATHLEN + 1 , ext ))
190- {
198+ if (wcscat_s (dest , MAXPATHLEN + 1 , ext )) {
191199 dest [0 ] = '\0' ;
192200 return -1 ;
193201 }
@@ -344,6 +352,19 @@ search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path, const wchar_t *lan
344352}
345353
346354
355+ static int
356+ get_dllpath (wchar_t * dllpath )
357+ {
358+ #ifdef Py_ENABLE_SHARED
359+ extern HANDLE PyWin_DLLhModule ;
360+ if (PyWin_DLLhModule && GetModuleFileNameW (PyWin_DLLhModule , dllpath , MAXPATHLEN )) {
361+ return 0 ;
362+ }
363+ #endif
364+ return -1 ;
365+ }
366+
367+
347368#ifdef Py_ENABLE_SHARED
348369
349370/* a string loaded from the DLL at startup.*/
@@ -516,27 +537,6 @@ getpythonregpath(HKEY keyBase, int skipcore)
516537#endif /* Py_ENABLE_SHARED */
517538
518539
519- wchar_t *
520- _Py_GetDLLPath (void )
521- {
522- wchar_t dll_path [MAXPATHLEN + 1 ];
523- memset (dll_path , 0 , sizeof (dll_path ));
524-
525- #ifdef Py_ENABLE_SHARED
526- extern HANDLE PyWin_DLLhModule ;
527- if (PyWin_DLLhModule ) {
528- if (!GetModuleFileNameW (PyWin_DLLhModule , dll_path , MAXPATHLEN )) {
529- dll_path [0 ] = 0 ;
530- }
531- }
532- #else
533- dll_path [0 ] = 0 ;
534- #endif
535-
536- return _PyMem_RawWcsdup (dll_path );
537- }
538-
539-
540540static PyStatus
541541get_program_full_path (_PyPathConfig * pathconfig )
542542{
@@ -717,19 +717,17 @@ static int
717717get_pth_filename (PyCalculatePath * calculate , wchar_t * filename ,
718718 const _PyPathConfig * pathconfig )
719719{
720- if (calculate -> dll_path [0 ]) {
721- if (!change_ext (filename , calculate -> dll_path , L"._pth" ) &&
722- exists (filename ))
723- {
724- return 1 ;
725- }
720+ if (get_dllpath (filename ) &&
721+ !change_ext (filename , filename , L"._pth" ) &&
722+ exists (filename ))
723+ {
724+ return 1 ;
726725 }
727- if (pathconfig -> program_full_path [0 ]) {
728- if (!change_ext (filename , pathconfig -> program_full_path , L"._pth" ) &&
729- exists (filename ))
730- {
731- return 1 ;
732- }
726+ if (pathconfig -> program_full_path [0 ] &&
727+ !change_ext (filename , pathconfig -> program_full_path , L"._pth" ) &&
728+ exists (filename ))
729+ {
730+ return 1 ;
733731 }
734732 return 0 ;
735733}
@@ -1029,9 +1027,12 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
10291027 wchar_t zip_path [MAXPATHLEN + 1 ];
10301028 memset (zip_path , 0 , sizeof (zip_path ));
10311029
1032- change_ext (zip_path ,
1033- calculate -> dll_path [0 ] ? calculate -> dll_path : pathconfig -> program_full_path ,
1034- L".zip" );
1030+ if (get_dllpath (zip_path ) || change_ext (zip_path , zip_path , L".zip" ))
1031+ {
1032+ if (change_ext (zip_path , pathconfig -> program_full_path , L".zip" )) {
1033+ zip_path [0 ] = L'\0' ;
1034+ }
1035+ }
10351036
10361037 calculate_home_prefix (calculate , argv0_path , zip_path , prefix );
10371038
@@ -1068,11 +1069,6 @@ calculate_init(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
10681069 calculate -> home = pathconfig -> home ;
10691070 calculate -> path_env = _wgetenv (L"PATH" );
10701071
1071- calculate -> dll_path = _Py_GetDLLPath ();
1072- if (calculate -> dll_path == NULL ) {
1073- return _PyStatus_NO_MEMORY ();
1074- }
1075-
10761072 calculate -> pythonpath_env = config -> pythonpath_env ;
10771073
10781074 return _PyStatus_OK ();
@@ -1084,7 +1080,6 @@ calculate_free(PyCalculatePath *calculate)
10841080{
10851081 PyMem_RawFree (calculate -> machine_path );
10861082 PyMem_RawFree (calculate -> user_path );
1087- PyMem_RawFree (calculate -> dll_path );
10881083}
10891084
10901085
@@ -1094,7 +1089,6 @@ calculate_free(PyCalculatePath *calculate)
10941089
10951090 - PyConfig.pythonpath_env: PYTHONPATH environment variable
10961091 - _PyPathConfig.home: Py_SetPythonHome() or PYTHONHOME environment variable
1097- - DLL path: _Py_GetDLLPath()
10981092 - PATH environment variable
10991093 - __PYVENV_LAUNCHER__ environment variable
11001094 - GetModuleFileNameW(NULL): fully qualified path of the executable file of
@@ -1148,33 +1142,35 @@ int
11481142_Py_CheckPython3 (void )
11491143{
11501144 wchar_t py3path [MAXPATHLEN + 1 ];
1151- wchar_t * s ;
11521145 if (python3_checked ) {
11531146 return hPython3 != NULL ;
11541147 }
11551148 python3_checked = 1 ;
11561149
11571150 /* If there is a python3.dll next to the python3y.dll,
1158- assume this is a build tree; use that DLL */
1159- if (_Py_dll_path != NULL ) {
1160- wcscpy (py3path , _Py_dll_path );
1161- }
1162- else {
1163- wcscpy (py3path , L"" );
1164- }
1165- s = wcsrchr (py3path , L'\\' );
1166- if (!s ) {
1167- s = py3path ;
1151+ use that DLL */
1152+ if (!get_dllpath (py3path )) {
1153+ reduce (py3path );
1154+ join (py3path , PY3_DLLNAME );
1155+ hPython3 = LoadLibraryExW (py3path , NULL , LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
1156+ if (hPython3 != NULL ) {
1157+ return 1 ;
1158+ }
11681159 }
1169- wcscpy (s , L"\\python3.dll" );
1170- hPython3 = LoadLibraryExW (py3path , NULL , LOAD_WITH_ALTERED_SEARCH_PATH );
1160+
1161+ /* If we can locate python3.dll in our application dir,
1162+ use that DLL */
1163+ hPython3 = LoadLibraryExW (PY3_DLLNAME , NULL , LOAD_LIBRARY_SEARCH_APPLICATION_DIR );
11711164 if (hPython3 != NULL ) {
11721165 return 1 ;
11731166 }
11741167
1175- /* Check sys.prefix\DLLs\python3.dll */
1168+ /* For back-compat, also search {sys.prefix}\DLLs, though
1169+ that has not been a normal install layout for a while */
11761170 wcscpy (py3path , Py_GetPrefix ());
1177- wcscat (py3path , L"\\DLLs\\python3.dll" );
1178- hPython3 = LoadLibraryExW (py3path , NULL , LOAD_WITH_ALTERED_SEARCH_PATH );
1171+ if (py3path [0 ]) {
1172+ join (py3path , L"DLLs\\" PY3_DLLNAME );
1173+ hPython3 = LoadLibraryExW (py3path , NULL , LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
1174+ }
11791175 return hPython3 != NULL ;
11801176}
0 commit comments