diff options
Diffstat (limited to 'Python/dynload_win.c')
-rw-r--r-- | Python/dynload_win.c | 157 |
1 files changed, 66 insertions, 91 deletions
diff --git a/Python/dynload_win.c b/Python/dynload_win.c index 6deba11..4e5555e 100644 --- a/Python/dynload_win.c +++ b/Python/dynload_win.c @@ -9,34 +9,39 @@ #include <ctype.h> #include "importdl.h" -#include "patchlevel.h" #include <windows.h> // "activation context" magic - see dl_nt.c... -#if HAVE_SXS extern ULONG_PTR _Py_ActivateActCtx(); void _Py_DeactivateActCtx(ULONG_PTR cookie); -#endif +const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef _DEBUG -#define PYD_DEBUG_SUFFIX "_d" + {"_d.pyd", "rb", C_EXTENSION}, #else -#define PYD_DEBUG_SUFFIX "" + {".pyd", "rb", C_EXTENSION}, #endif + {0, 0} +}; -#ifdef PYD_PLATFORM_TAG -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd" -#else -#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd" -#endif -#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd" +/* Case insensitive string compare, to avoid any dependencies on particular + C RTL implementations */ + +static int strcasecmp (char *string1, char *string2) +{ + int first, second; + + do { + first = tolower(*string1); + second = tolower(*string2); + string1++; + string2++; + } while (first && first == second); + + return (first - second); +} -const char *_PyImport_DynLoadFiletab[] = { - PYD_TAGGED_SUFFIX, - PYD_UNTAGGED_SUFFIX, - NULL -}; /* Function to return the name of the "python" DLL that the supplied module directly imports. Looks through the list of imported modules and @@ -129,15 +134,6 @@ static char *GetPythonImport (HINSTANCE hModule) !strncmp(import_name,"python",6)) { char *pch; -#ifndef _DEBUG - /* In a release version, don't claim that python3.dll is - a Python DLL. */ - if (strcmp(import_name, "python3.dll") == 0) { - import_data += 20; - continue; - } -#endif - /* Ensure python prefix is followed only by numbers to the end of the basename */ pch = import_name + 6; @@ -166,83 +162,73 @@ static char *GetPythonImport (HINSTANCE hModule) return NULL; } -dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, - const char *shortname, - PyObject *pathname, FILE *fp) + +dl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, + const char *pathname, FILE *fp) { dl_funcptr p; char funcname[258], *import_python; - const wchar_t *wpathname; - -#ifndef _DEBUG - _Py_CheckPython3(); -#endif - - wpathname = _PyUnicode_AsUnicode(pathname); - if (wpathname == NULL) - return NULL; - PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname); + PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname); { HINSTANCE hDLL = NULL; + char pathbuf[260]; + LPTSTR dummy; unsigned int old_mode; -#if HAVE_SXS ULONG_PTR cookie = 0; -#endif + /* We use LoadLibraryEx so Windows looks for dependent DLLs + in directory of pathname first. However, Windows95 + can sometimes not work correctly unless the absolute + path is used. If GetFullPathName() fails, the LoadLibrary + will certainly fail too, so use its error code */ /* Don't display a message box when Python can't load a DLL */ old_mode = SetErrorMode(SEM_FAILCRITICALERRORS); -#if HAVE_SXS - cookie = _Py_ActivateActCtx(); -#endif - /* bpo-36085: We use LoadLibraryEx with restricted search paths - to avoid DLL preloading attacks and enable use of the - AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to - ensure DLLs adjacent to the PYD are preferred. */ - Py_BEGIN_ALLOW_THREADS - hDLL = LoadLibraryExW(wpathname, NULL, - LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR); - Py_END_ALLOW_THREADS -#if HAVE_SXS - _Py_DeactivateActCtx(cookie); -#endif + if (GetFullPathName(pathname, + sizeof(pathbuf), + pathbuf, + &dummy)) { + ULONG_PTR cookie = _Py_ActivateActCtx(); + /* XXX This call doesn't exist in Windows CE */ + hDLL = LoadLibraryEx(pathname, NULL, + LOAD_WITH_ALTERED_SEARCH_PATH); + _Py_DeactivateActCtx(cookie); + } /* restore old error mode settings */ SetErrorMode(old_mode); if (hDLL==NULL){ - PyObject *message; + char errBuf[256]; unsigned int errorCode; /* Get an error string from Win32 error code */ - wchar_t theInfo[256]; /* Pointer to error text + char theInfo[256]; /* Pointer to error text from system */ int theLength; /* Length of error text */ errorCode = GetLastError(); - theLength = FormatMessageW( + theLength = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */ NULL, /* message source */ errorCode, /* the message (error) ID */ - MAKELANGID(LANG_NEUTRAL, - SUBLANG_DEFAULT), - /* Default language */ - theInfo, /* the buffer */ - sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */ + 0, /* default language environment */ + (LPTSTR) theInfo, /* the buffer */ + sizeof(theInfo), /* the buffer size */ NULL); /* no additional format args. */ /* Problem: could not get the error message. This should not happen if called correctly. */ if (theLength == 0) { - message = PyUnicode_FromFormat( - "DLL load failed with error code %u while importing %s", - errorCode, shortname); + PyOS_snprintf(errBuf, sizeof(errBuf), + "DLL load failed with error code %d", + errorCode); } else { + size_t len; /* For some reason a \r\n is appended to the text */ if (theLength >= 2 && @@ -251,48 +237,37 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix, theLength -= 2; theInfo[theLength] = '\0'; } - message = PyUnicode_FromFormat( - "DLL load failed while importing %s: ", shortname); - - PyUnicode_AppendAndDel(&message, - PyUnicode_FromWideChar( - theInfo, - theLength)); - } - if (message != NULL) { - PyObject *shortname_obj = PyUnicode_FromString(shortname); - PyErr_SetImportError(message, shortname_obj, pathname); - Py_XDECREF(shortname_obj); - Py_DECREF(message); + strcpy(errBuf, "DLL load failed: "); + len = strlen(errBuf); + strncpy(errBuf+len, theInfo, + sizeof(errBuf)-len); + errBuf[sizeof(errBuf)-1] = '\0'; } + PyErr_SetString(PyExc_ImportError, errBuf); return NULL; } else { char buffer[256]; - PyOS_snprintf(buffer, sizeof(buffer), #ifdef _DEBUG - "python%d%d_d.dll", + PyOS_snprintf(buffer, sizeof(buffer), "python%d%d_d.dll", #else - "python%d%d.dll", + PyOS_snprintf(buffer, sizeof(buffer), "python%d%d.dll", #endif PY_MAJOR_VERSION,PY_MINOR_VERSION); import_python = GetPythonImport(hDLL); if (import_python && - _stricmp(buffer,import_python)) { - PyErr_Format(PyExc_ImportError, - "Module use of %.150s conflicts " - "with this version of Python.", - import_python); - Py_BEGIN_ALLOW_THREADS + strcasecmp(buffer,import_python)) { + PyOS_snprintf(buffer, sizeof(buffer), + "Module use of %.150s conflicts " + "with this version of Python.", + import_python); + PyErr_SetString(PyExc_ImportError,buffer); FreeLibrary(hDLL); - Py_END_ALLOW_THREADS return NULL; } } - Py_BEGIN_ALLOW_THREADS p = GetProcAddress(hDLL, funcname); - Py_END_ALLOW_THREADS } return p; |