Skip to content

Commit 5172fa4

Browse files
authored
gh-152433: Windows: make dynload_win.c UWP compatible (#152797)
1 parent 9ab9181 commit 5172fa4

2 files changed

Lines changed: 33 additions & 2 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
make ``dynload_win.c`` UWP compatible.

Python/dynload_win.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,16 @@ _Py_CheckPython3(void)
164164
static int python3_checked = 0;
165165
static HANDLE hPython3;
166166
#define MAXPATHLEN 512
167-
wchar_t py3path[MAXPATHLEN+1];
168167
if (python3_checked) {
169168
return hPython3 != NULL;
170169
}
171170
python3_checked = 1;
172171

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];
173177
/* If there is a python3.dll next to the python3y.dll,
174178
use that DLL */
175179
if (PyWin_DLLhModule && GetModuleFileNameW(PyWin_DLLhModule, py3path, MAXPATHLEN)) {
@@ -202,6 +206,8 @@ _Py_CheckPython3(void)
202206
hPython3 = LoadLibraryExW(py3path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
203207
}
204208
}
209+
#endif
210+
205211
return hPython3 != NULL;
206212
#undef MAXPATHLEN
207213
#endif /* PY3_DLLNAME */
@@ -272,6 +278,20 @@ _Py_CheckPython3t(void)
272278

273279
#endif /* Py_ENABLE_SHARED */
274280

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+
275295
dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
276296
const char *shortname,
277297
PyObject *pathname, FILE *fp)
@@ -299,14 +319,24 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
299319
old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
300320
#endif
301321

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
302332
/* bpo-36085: We use LoadLibraryEx with restricted search paths
303333
to avoid DLL preloading attacks and enable use of the
304334
AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to
305335
ensure DLLs adjacent to the PYD are preferred. */
306-
Py_BEGIN_ALLOW_THREADS
307336
hDLL = LoadLibraryExW(wpathname, NULL,
308337
LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
309338
LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
339+
#endif
310340
Py_END_ALLOW_THREADS
311341
PyMem_Free(wpathname);
312342

0 commit comments

Comments
 (0)