blob: 457d47f5eed50a8f658e9ed5627584d61f5b94cd [file] [log] [blame]
Guido van Rossum22a1d361999-12-20 21:18:49 +00001
2/* Support for dynamic loading of extension modules */
3
Christian Heimesfaf2f632008-01-06 16:59:19 +00004#include "Python.h"
5
Thomas Wouters0e3f5912006-08-11 14:57:12 +00006#ifdef HAVE_DIRECT_H
Guido van Rossum22a1d361999-12-20 21:18:49 +00007#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +00008#endif
Mark Hammond1f7838b2000-10-05 10:54:45 +00009#include <ctype.h>
Guido van Rossum22a1d361999-12-20 21:18:49 +000010
Guido van Rossum22a1d361999-12-20 21:18:49 +000011#include "importdl.h"
Steve Dower03a144b2014-12-15 20:45:23 -080012#include "patchlevel.h"
Guido van Rossume7ba4952007-06-06 23:52:48 +000013#include <windows.h>
Guido van Rossum22a1d361999-12-20 21:18:49 +000014
Mark Hammond9844a1f2009-01-27 23:46:57 +000015// "activation context" magic - see dl_nt.c...
Brian Curtin401f9f32012-05-13 11:19:23 -050016#if HAVE_SXS
Mark Hammond9844a1f2009-01-27 23:46:57 +000017extern ULONG_PTR _Py_ActivateActCtx();
18void _Py_DeactivateActCtx(ULONG_PTR cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -050019#endif
Mark Hammond9844a1f2009-01-27 23:46:57 +000020
Guido van Rossum22a1d361999-12-20 21:18:49 +000021#ifdef _DEBUG
Steve Dower03a144b2014-12-15 20:45:23 -080022#define PYD_DEBUG_SUFFIX "_d"
Guido van Rossum22a1d361999-12-20 21:18:49 +000023#else
Steve Dower03a144b2014-12-15 20:45:23 -080024#define PYD_DEBUG_SUFFIX ""
Guido van Rossum22a1d361999-12-20 21:18:49 +000025#endif
Steve Dower03a144b2014-12-15 20:45:23 -080026
Steve Dower03a144b2014-12-15 20:45:23 -080027#ifdef PYD_PLATFORM_TAG
Serhiy Storchaka12b25382015-11-05 17:43:42 +020028#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd"
Steve Dower03a144b2014-12-15 20:45:23 -080029#else
Serhiy Storchaka12b25382015-11-05 17:43:42 +020030#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" Py_STRINGIFY(PY_MAJOR_VERSION) Py_STRINGIFY(PY_MINOR_VERSION) ".pyd"
Steve Dower03a144b2014-12-15 20:45:23 -080031#endif
32
33#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
34
35const char *_PyImport_DynLoadFiletab[] = {
36 PYD_TAGGED_SUFFIX,
37 PYD_UNTAGGED_SUFFIX,
Brett Cannon2657df42012-05-04 15:20:40 -040038 NULL
Guido van Rossum22a1d361999-12-20 21:18:49 +000039};
40
Mark Hammond1f7838b2000-10-05 10:54:45 +000041/* Case insensitive string compare, to avoid any dependencies on particular
42 C RTL implementations */
43
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020044static int strcasecmp (const char *string1, const char *string2)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045{
46 int first, second;
Mark Hammond1f7838b2000-10-05 10:54:45 +000047
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 do {
49 first = tolower(*string1);
50 second = tolower(*string2);
51 string1++;
52 string2++;
53 } while (first && first == second);
Mark Hammond1f7838b2000-10-05 10:54:45 +000054
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000055 return (first - second);
56}
Mark Hammond1f7838b2000-10-05 10:54:45 +000057
58
59/* Function to return the name of the "python" DLL that the supplied module
60 directly imports. Looks through the list of imported modules and
61 returns the first entry that starts with "python" (case sensitive) and
62 is followed by nothing but numbers until the separator (period).
63
64 Returns a pointer to the import name, or NULL if no matching name was
65 located.
66
67 This function parses through the PE header for the module as loaded in
68 memory by the system loader. The PE header is accessed as documented by
69 Microsoft in the MSDN PE and COFF specification (2/99), and handles
70 both PE32 and PE32+. It only worries about the direct import table and
71 not the delay load import table since it's unlikely an extension is
72 going to be delay loading Python (after all, it's already loaded).
73
74 If any magic values are not found (e.g., the PE header or optional
75 header magic), then this function simply returns NULL. */
76
77#define DWORD_AT(mem) (*(DWORD *)(mem))
78#define WORD_AT(mem) (*(WORD *)(mem))
79
80static char *GetPythonImport (HINSTANCE hModule)
81{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 unsigned char *dllbase, *import_data, *import_name;
83 DWORD pe_offset, opt_offset;
84 WORD opt_magic;
85 int num_dict_off, import_off;
Mark Hammond1f7838b2000-10-05 10:54:45 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 /* Safety check input */
88 if (hModule == NULL) {
89 return NULL;
90 }
Mark Hammond1f7838b2000-10-05 10:54:45 +000091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 /* Module instance is also the base load address. First portion of
93 memory is the MS-DOS loader, which holds the offset to the PE
94 header (from the load base) at 0x3C */
95 dllbase = (unsigned char *)hModule;
96 pe_offset = DWORD_AT(dllbase + 0x3C);
Mark Hammond1f7838b2000-10-05 10:54:45 +000097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 /* The PE signature must be "PE\0\0" */
99 if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
100 return NULL;
101 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000102
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 /* Following the PE signature is the standard COFF header (20
104 bytes) and then the optional header. The optional header starts
105 with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
106 uses 64-bits for some fields). It might also be 0x107 for a ROM
107 image, but we don't process that here.
Mark Hammond1f7838b2000-10-05 10:54:45 +0000108
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 The optional header ends with a data dictionary that directly
110 points to certain types of data, among them the import entries
111 (in the second table entry). Based on the header type, we
112 determine offsets for the data dictionary count and the entry
113 within the dictionary pointing to the imports. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 opt_offset = pe_offset + 4 + 20;
116 opt_magic = WORD_AT(dllbase+opt_offset);
117 if (opt_magic == 0x10B) {
118 /* PE32 */
119 num_dict_off = 92;
120 import_off = 104;
121 } else if (opt_magic == 0x20B) {
122 /* PE32+ */
123 num_dict_off = 108;
124 import_off = 120;
125 } else {
126 /* Unsupported */
127 return NULL;
128 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000129
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 /* Now if an import table exists, offset to it and walk the list of
131 imports. The import table is an array (ending when an entry has
132 empty values) of structures (20 bytes each), which contains (at
133 offset 12) a relative address (to the module base) at which a
134 string constant holding the import name is located. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
137 /* We have at least 2 tables - the import table is the second
138 one. But still it may be that the table size is zero */
139 if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
140 return NULL;
141 import_data = dllbase + DWORD_AT(dllbase +
142 opt_offset +
143 import_off);
144 while (DWORD_AT(import_data)) {
145 import_name = dllbase + DWORD_AT(import_data+12);
146 if (strlen(import_name) >= 6 &&
147 !strncmp(import_name,"python",6)) {
148 char *pch;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000149
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000150#ifndef _DEBUG
151 /* In a release version, don't claim that python3.dll is
152 a Python DLL. */
153 if (strcmp(import_name, "python3.dll") == 0) {
154 import_data += 20;
155 continue;
156 }
157#endif
158
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 /* Ensure python prefix is followed only
160 by numbers to the end of the basename */
161 pch = import_name + 6;
Thomas Heller1df04612004-07-02 08:53:57 +0000162#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000164#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 while (*pch && *pch != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000166#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 if (*pch >= '0' && *pch <= '9') {
168 pch++;
169 } else {
170 pch = NULL;
171 break;
172 }
173 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000174
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000175 if (pch) {
176 /* Found it - return the name */
177 return import_name;
178 }
179 }
180 import_data += 20;
181 }
182 }
183
184 return NULL;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000185}
Mark Hammond1f7838b2000-10-05 10:54:45 +0000186
Nick Coghland5cacbb2015-05-23 22:24:10 +1000187dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
188 const char *shortname,
189 PyObject *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +0000190{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 dl_funcptr p;
192 char funcname[258], *import_python;
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300193 const wchar_t *wpathname;
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000194
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000195#ifndef _DEBUG
196 _Py_CheckPython3();
197#endif
198
Serhiy Storchakaf7eae0a2017-06-28 08:30:06 +0300199 wpathname = _PyUnicode_AsUnicode(pathname);
Victor Stinner33354472011-11-21 02:01:41 +0100200 if (wpathname == NULL)
201 return NULL;
202
Steve Dower76891542015-05-23 08:59:25 -0700203 PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 {
206 HINSTANCE hDLL = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 unsigned int old_mode;
Brian Curtin401f9f32012-05-13 11:19:23 -0500208#if HAVE_SXS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 ULONG_PTR cookie = 0;
Brian Curtin401f9f32012-05-13 11:19:23 -0500210#endif
Victor Stinner67002af2011-10-02 20:35:10 +0200211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 /* Don't display a message box when Python can't load a DLL */
213 old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000214
Brian Curtin401f9f32012-05-13 11:19:23 -0500215#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500216 cookie = _Py_ActivateActCtx();
Brian Curtin401f9f32012-05-13 11:19:23 -0500217#endif
Steve Dower2438cdf2019-03-29 16:37:16 -0700218 /* bpo-36085: We use LoadLibraryEx with restricted search paths
219 to avoid DLL preloading attacks and enable use of the
220 AddDllDirectory function. We add SEARCH_DLL_LOAD_DIR to
221 ensure DLLs adjacent to the PYD are preferred. */
Tony Roberts4860f012019-02-02 18:16:42 +0100222 Py_BEGIN_ALLOW_THREADS
Victor Stinner33354472011-11-21 02:01:41 +0100223 hDLL = LoadLibraryExW(wpathname, NULL,
Steve Dower2438cdf2019-03-29 16:37:16 -0700224 LOAD_LIBRARY_SEARCH_DEFAULT_DIRS |
225 LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR);
Tony Roberts4860f012019-02-02 18:16:42 +0100226 Py_END_ALLOW_THREADS
Brian Curtin401f9f32012-05-13 11:19:23 -0500227#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500228 _Py_DeactivateActCtx(cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -0500229#endif
Christian Heimesbbffeb62008-01-24 09:42:52 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 /* restore old error mode settings */
232 SetErrorMode(old_mode);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000233
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000234 if (hDLL==NULL){
235 PyObject *message;
236 unsigned int errorCode;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000237
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 /* Get an error string from Win32 error code */
239 wchar_t theInfo[256]; /* Pointer to error text
240 from system */
241 int theLength; /* Length of error text */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 errorCode = GetLastError();
Guido van Rossum22a1d361999-12-20 21:18:49 +0000244
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000245 theLength = FormatMessageW(
246 FORMAT_MESSAGE_FROM_SYSTEM |
247 FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
248 NULL, /* message source */
249 errorCode, /* the message (error) ID */
250 MAKELANGID(LANG_NEUTRAL,
251 SUBLANG_DEFAULT),
252 /* Default language */
253 theInfo, /* the buffer */
Gregory P. Smithb803c6c2013-03-23 16:05:36 -0700254 sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 NULL); /* no additional format args. */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 /* Problem: could not get the error message.
258 This should not happen if called correctly. */
259 if (theLength == 0) {
260 message = PyUnicode_FromFormat(
Serhiy Storchakad53fe5f2019-03-13 22:59:55 +0200261 "DLL load failed with error code %u",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 errorCode);
263 } else {
264 /* For some reason a \r\n
265 is appended to the text */
266 if (theLength >= 2 &&
267 theInfo[theLength-2] == '\r' &&
268 theInfo[theLength-1] == '\n') {
269 theLength -= 2;
270 theInfo[theLength] = '\0';
271 }
272 message = PyUnicode_FromString(
273 "DLL load failed: ");
Amaury Forgeot d'Arcd6179e12008-01-03 23:42:13 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 PyUnicode_AppendAndDel(&message,
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100276 PyUnicode_FromWideChar(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 theInfo,
278 theLength));
279 }
Victor Stinner67002af2011-10-02 20:35:10 +0200280 if (message != NULL) {
Richard Oudkerk409f9022013-06-10 15:38:54 +0100281 PyObject *shortname_obj = PyUnicode_FromString(shortname);
282 PyErr_SetImportError(message, shortname_obj, pathname);
283 Py_XDECREF(shortname_obj);
Brian Curtin09b86d12012-04-17 16:57:09 -0500284 Py_DECREF(message);
Victor Stinner67002af2011-10-02 20:35:10 +0200285 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000286 return NULL;
287 } else {
288 char buffer[256];
Mark Hammond1f7838b2000-10-05 10:54:45 +0000289
Victor Stinner2d322272011-04-04 23:05:53 +0200290 PyOS_snprintf(buffer, sizeof(buffer),
Thomas Heller1df04612004-07-02 08:53:57 +0000291#ifdef _DEBUG
Victor Stinner2d322272011-04-04 23:05:53 +0200292 "python%d%d_d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000293#else
Victor Stinner2d322272011-04-04 23:05:53 +0200294 "python%d%d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000295#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 PY_MAJOR_VERSION,PY_MINOR_VERSION);
297 import_python = GetPythonImport(hDLL);
Mark Hammond1f7838b2000-10-05 10:54:45 +0000298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000299 if (import_python &&
300 strcasecmp(buffer,import_python)) {
Victor Stinner2d322272011-04-04 23:05:53 +0200301 PyErr_Format(PyExc_ImportError,
302 "Module use of %.150s conflicts "
303 "with this version of Python.",
304 import_python);
Tony Roberts4860f012019-02-02 18:16:42 +0100305 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 FreeLibrary(hDLL);
Tony Roberts4860f012019-02-02 18:16:42 +0100307 Py_END_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 return NULL;
309 }
310 }
Tony Roberts4860f012019-02-02 18:16:42 +0100311 Py_BEGIN_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 p = GetProcAddress(hDLL, funcname);
Tony Roberts4860f012019-02-02 18:16:42 +0100313 Py_END_ALLOW_THREADS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000317}