@@ -164,12 +164,16 @@ _Py_CheckPython3(void) |
164 | 164 | static int python3_checked = 0; |
165 | 165 | static HANDLE hPython3; |
166 | 166 | #define MAXPATHLEN 512 |
167 | | - wchar_t py3path[MAXPATHLEN+1]; |
168 | 167 | if (python3_checked) { |
169 | 168 | return hPython3 != NULL; |
170 | 169 | } |
171 | 170 | python3_checked = 1; |
172 | 171 |
|
| 172 | +#ifndef MS_WINDOWS_DESKTOP |
| 173 | + // LoadPackagedLibrary doesn't accept absolute paths so load dll name from current app dir |
| 174 | + hPython3 = LoadPackagedLibrary(PY3_DLLNAME, 0); |
| 175 | +#else |
| 176 | + wchar_t py3path[MAXPATHLEN + 1]; |
173 | 177 | /* If there is a python3.dll next to the python3y.dll, |
174 | 178 | use that DLL */ |
175 | 179 | if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) { |
@@ -202,6 +206,8 @@ _Py_CheckPython3(void) |
202 | 206 | hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); |
203 | 207 | } |
204 | 208 | } |
| 209 | +#endif |
| 210 | + |
205 | 211 | return hPython3 != NULL; |
206 | 212 | #undef MAXPATHLEN |
207 | 213 | #endif /* PY3_DLLNAME */ |
@@ -272,6 +278,20 @@ _Py_CheckPython3t(void) |
272 | 278 |
|
273 | 279 | #endif /* Py_ENABLE_SHARED */ |
274 | 280 |
|
| 281 | +static wchar_t* _Py_AbsolutePath_To_RelativePath(wchar_t* abs_path) |
| 282 | +{ |
| 283 | + wchar_t* rel_path = NULL; |
| 284 | + wchar_t process_path[512] = { 0 }; |
| 285 | + if (GetModuleFileNameW(NULL, process_path, 512)) |
| 286 | + { |
| 287 | + wchar_t* path = wcsrchr(process_path, L'\\'); |
| 288 | + path[1] = L'\0'; // strip process name |
| 289 | + if (wcsstr(abs_path, process_path)) |
| 290 | + rel_path = &abs_path[wcslen(process_path)]; |
| 291 | + } |
| 292 | + return rel_path; |
| 293 | +} |
| 294 | + |
275 | 295 | dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, |
276 | 296 | const char *shortname, |
277 | 297 | PyObject *pathname, FILE *fp) |
@@ -299,14 +319,24 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, |
299 | 319 | old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); |
300 | 320 | #endif |
301 | 321 |
|
| 322 | + Py_BEGIN_ALLOW_THREADS |
| 323 | +#ifndef MS_WINDOWS_DESKTOP |
| 324 | + // UWP does not allow absolute paths due security restrictions. |
| 325 | + // If path is contained inside process path (sub folder), use the relative path instead. |
| 326 | + wchar_t* rel_path = _Py_AbsolutePath_To_RelativePath(wpathname); |
| 327 | + if (rel_path) |
| 328 | + hDLL = LoadPackagedLibrary(rel_path, 0); |
| 329 | + else |
| 330 | + hDLL = LoadPackagedLibrary(wpathname, 0); |
| 331 | +#else |
302 | 332 | /* bpo-36085: We use LoadLibraryEx with restricted search paths |
303 | 333 | to avoid DLL preloading attacks and enable use of the |
304 | 334 | AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to |
305 | 335 | ensure DLLs adjacent to the PYD are preferred. */ |
306 | | - Py_BEGIN_ALLOW_THREADS |
307 | 336 | hDLL = LoadLibraryExW(wpathname, NULL, |
308 | 337 | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | |
309 | 338 | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); |
| 339 | +#endif |
310 | 340 | Py_END_ALLOW_THREADS |
311 | 341 | PyMem_Free(wpathname); |
312 | 342 |
|
|