blob: f2c796e94d2e61bb82794772ba3ff497c4b68023 [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
27#define STRINGIZE2(x) #x
28#define STRINGIZE(x) STRINGIZE2(x)
29#ifdef PYD_PLATFORM_TAG
30#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) "-" PYD_PLATFORM_TAG ".pyd"
31#else
32#define PYD_TAGGED_SUFFIX PYD_DEBUG_SUFFIX ".cp" STRINGIZE(PY_MAJOR_VERSION) STRINGIZE(PY_MINOR_VERSION) ".pyd"
33#endif
34
35#define PYD_UNTAGGED_SUFFIX PYD_DEBUG_SUFFIX ".pyd"
36
37const char *_PyImport_DynLoadFiletab[] = {
38 PYD_TAGGED_SUFFIX,
39 PYD_UNTAGGED_SUFFIX,
Brett Cannon2657df42012-05-04 15:20:40 -040040 NULL
Guido van Rossum22a1d361999-12-20 21:18:49 +000041};
42
Mark Hammond1f7838b2000-10-05 10:54:45 +000043/* Case insensitive string compare, to avoid any dependencies on particular
44 C RTL implementations */
45
46static int strcasecmp (char *string1, char *string2)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047{
48 int first, second;
Mark Hammond1f7838b2000-10-05 10:54:45 +000049
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050 do {
51 first = tolower(*string1);
52 second = tolower(*string2);
53 string1++;
54 string2++;
55 } while (first && first == second);
Mark Hammond1f7838b2000-10-05 10:54:45 +000056
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000057 return (first - second);
58}
Mark Hammond1f7838b2000-10-05 10:54:45 +000059
60
61/* Function to return the name of the "python" DLL that the supplied module
62 directly imports. Looks through the list of imported modules and
63 returns the first entry that starts with "python" (case sensitive) and
64 is followed by nothing but numbers until the separator (period).
65
66 Returns a pointer to the import name, or NULL if no matching name was
67 located.
68
69 This function parses through the PE header for the module as loaded in
70 memory by the system loader. The PE header is accessed as documented by
71 Microsoft in the MSDN PE and COFF specification (2/99), and handles
72 both PE32 and PE32+. It only worries about the direct import table and
73 not the delay load import table since it's unlikely an extension is
74 going to be delay loading Python (after all, it's already loaded).
75
76 If any magic values are not found (e.g., the PE header or optional
77 header magic), then this function simply returns NULL. */
78
79#define DWORD_AT(mem) (*(DWORD *)(mem))
80#define WORD_AT(mem) (*(WORD *)(mem))
81
82static char *GetPythonImport (HINSTANCE hModule)
83{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 unsigned char *dllbase, *import_data, *import_name;
85 DWORD pe_offset, opt_offset;
86 WORD opt_magic;
87 int num_dict_off, import_off;
Mark Hammond1f7838b2000-10-05 10:54:45 +000088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 /* Safety check input */
90 if (hModule == NULL) {
91 return NULL;
92 }
Mark Hammond1f7838b2000-10-05 10:54:45 +000093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000094 /* Module instance is also the base load address. First portion of
95 memory is the MS-DOS loader, which holds the offset to the PE
96 header (from the load base) at 0x3C */
97 dllbase = (unsigned char *)hModule;
98 pe_offset = DWORD_AT(dllbase + 0x3C);
Mark Hammond1f7838b2000-10-05 10:54:45 +000099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 /* The PE signature must be "PE\0\0" */
101 if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
102 return NULL;
103 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 /* Following the PE signature is the standard COFF header (20
106 bytes) and then the optional header. The optional header starts
107 with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
108 uses 64-bits for some fields). It might also be 0x107 for a ROM
109 image, but we don't process that here.
Mark Hammond1f7838b2000-10-05 10:54:45 +0000110
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 The optional header ends with a data dictionary that directly
112 points to certain types of data, among them the import entries
113 (in the second table entry). Based on the header type, we
114 determine offsets for the data dictionary count and the entry
115 within the dictionary pointing to the imports. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000116
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 opt_offset = pe_offset + 4 + 20;
118 opt_magic = WORD_AT(dllbase+opt_offset);
119 if (opt_magic == 0x10B) {
120 /* PE32 */
121 num_dict_off = 92;
122 import_off = 104;
123 } else if (opt_magic == 0x20B) {
124 /* PE32+ */
125 num_dict_off = 108;
126 import_off = 120;
127 } else {
128 /* Unsupported */
129 return NULL;
130 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 /* Now if an import table exists, offset to it and walk the list of
133 imports. The import table is an array (ending when an entry has
134 empty values) of structures (20 bytes each), which contains (at
135 offset 12) a relative address (to the module base) at which a
136 string constant holding the import name is located. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
139 /* We have at least 2 tables - the import table is the second
140 one. But still it may be that the table size is zero */
141 if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
142 return NULL;
143 import_data = dllbase + DWORD_AT(dllbase +
144 opt_offset +
145 import_off);
146 while (DWORD_AT(import_data)) {
147 import_name = dllbase + DWORD_AT(import_data+12);
148 if (strlen(import_name) >= 6 &&
149 !strncmp(import_name,"python",6)) {
150 char *pch;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000151
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000152#ifndef _DEBUG
153 /* In a release version, don't claim that python3.dll is
154 a Python DLL. */
155 if (strcmp(import_name, "python3.dll") == 0) {
156 import_data += 20;
157 continue;
158 }
159#endif
160
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000161 /* Ensure python prefix is followed only
162 by numbers to the end of the basename */
163 pch = import_name + 6;
Thomas Heller1df04612004-07-02 08:53:57 +0000164#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000166#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 while (*pch && *pch != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000168#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000169 if (*pch >= '0' && *pch <= '9') {
170 pch++;
171 } else {
172 pch = NULL;
173 break;
174 }
175 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000176
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 if (pch) {
178 /* Found it - return the name */
179 return import_name;
180 }
181 }
182 import_data += 20;
183 }
184 }
185
186 return NULL;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000187}
Mark Hammond1f7838b2000-10-05 10:54:45 +0000188
Nick Coghland5cacbb2015-05-23 22:24:10 +1000189dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
190 const char *shortname,
191 PyObject *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +0000192{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 dl_funcptr p;
194 char funcname[258], *import_python;
Victor Stinner33354472011-11-21 02:01:41 +0100195 wchar_t *wpathname;
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000196
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000197#ifndef _DEBUG
198 _Py_CheckPython3();
199#endif
200
Victor Stinner33354472011-11-21 02:01:41 +0100201 wpathname = PyUnicode_AsUnicode(pathname);
202 if (wpathname == NULL)
203 return NULL;
204
Steve Dower76891542015-05-23 08:59:25 -0700205 PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 {
208 HINSTANCE hDLL = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000209 unsigned int old_mode;
Brian Curtin401f9f32012-05-13 11:19:23 -0500210#if HAVE_SXS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000211 ULONG_PTR cookie = 0;
Brian Curtin401f9f32012-05-13 11:19:23 -0500212#endif
Victor Stinner67002af2011-10-02 20:35:10 +0200213
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 /* Don't display a message box when Python can't load a DLL */
215 old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000216
Brian Curtin401f9f32012-05-13 11:19:23 -0500217#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500218 cookie = _Py_ActivateActCtx();
Brian Curtin401f9f32012-05-13 11:19:23 -0500219#endif
Brian Curtin589f89e2011-06-09 17:55:54 -0500220 /* We use LoadLibraryEx so Windows looks for dependent DLLs
221 in directory of pathname first. */
222 /* XXX This call doesn't exist in Windows CE */
Victor Stinner33354472011-11-21 02:01:41 +0100223 hDLL = LoadLibraryExW(wpathname, NULL,
Brian Curtin589f89e2011-06-09 17:55:54 -0500224 LOAD_WITH_ALTERED_SEARCH_PATH);
Brian Curtin401f9f32012-05-13 11:19:23 -0500225#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500226 _Py_DeactivateActCtx(cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -0500227#endif
Christian Heimesbbffeb62008-01-24 09:42:52 +0000228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 /* restore old error mode settings */
230 SetErrorMode(old_mode);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000231
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000232 if (hDLL==NULL){
233 PyObject *message;
234 unsigned int errorCode;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 /* Get an error string from Win32 error code */
237 wchar_t theInfo[256]; /* Pointer to error text
238 from system */
239 int theLength; /* Length of error text */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 errorCode = GetLastError();
Guido van Rossum22a1d361999-12-20 21:18:49 +0000242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 theLength = FormatMessageW(
244 FORMAT_MESSAGE_FROM_SYSTEM |
245 FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
246 NULL, /* message source */
247 errorCode, /* the message (error) ID */
248 MAKELANGID(LANG_NEUTRAL,
249 SUBLANG_DEFAULT),
250 /* Default language */
251 theInfo, /* the buffer */
Gregory P. Smithb803c6c2013-03-23 16:05:36 -0700252 sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 NULL); /* no additional format args. */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000255 /* Problem: could not get the error message.
256 This should not happen if called correctly. */
257 if (theLength == 0) {
258 message = PyUnicode_FromFormat(
259 "DLL load failed with error code %d",
260 errorCode);
261 } else {
262 /* For some reason a \r\n
263 is appended to the text */
264 if (theLength >= 2 &&
265 theInfo[theLength-2] == '\r' &&
266 theInfo[theLength-1] == '\n') {
267 theLength -= 2;
268 theInfo[theLength] = '\0';
269 }
270 message = PyUnicode_FromString(
271 "DLL load failed: ");
Amaury Forgeot d'Arcd6179e12008-01-03 23:42:13 +0000272
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000273 PyUnicode_AppendAndDel(&message,
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100274 PyUnicode_FromWideChar(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 theInfo,
276 theLength));
277 }
Victor Stinner67002af2011-10-02 20:35:10 +0200278 if (message != NULL) {
Richard Oudkerk409f9022013-06-10 15:38:54 +0100279 PyObject *shortname_obj = PyUnicode_FromString(shortname);
280 PyErr_SetImportError(message, shortname_obj, pathname);
281 Py_XDECREF(shortname_obj);
Brian Curtin09b86d12012-04-17 16:57:09 -0500282 Py_DECREF(message);
Victor Stinner67002af2011-10-02 20:35:10 +0200283 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 return NULL;
285 } else {
286 char buffer[256];
Mark Hammond1f7838b2000-10-05 10:54:45 +0000287
Victor Stinner2d322272011-04-04 23:05:53 +0200288 PyOS_snprintf(buffer, sizeof(buffer),
Thomas Heller1df04612004-07-02 08:53:57 +0000289#ifdef _DEBUG
Victor Stinner2d322272011-04-04 23:05:53 +0200290 "python%d%d_d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000291#else
Victor Stinner2d322272011-04-04 23:05:53 +0200292 "python%d%d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000293#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000294 PY_MAJOR_VERSION,PY_MINOR_VERSION);
295 import_python = GetPythonImport(hDLL);
Mark Hammond1f7838b2000-10-05 10:54:45 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 if (import_python &&
298 strcasecmp(buffer,import_python)) {
Victor Stinner2d322272011-04-04 23:05:53 +0200299 PyErr_Format(PyExc_ImportError,
300 "Module use of %.150s conflicts "
301 "with this version of Python.",
302 import_python);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000303 FreeLibrary(hDLL);
304 return NULL;
305 }
306 }
307 p = GetProcAddress(hDLL, funcname);
308 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000311}