blob: 9ed9eea33373d36f9ce4ef9e025641bbd08f4636 [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
Victor Stinner2d322272011-04-04 23:05:53 +0200189dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname,
190 PyObject *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +0000191{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 dl_funcptr p;
193 char funcname[258], *import_python;
Victor Stinner33354472011-11-21 02:01:41 +0100194 wchar_t *wpathname;
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000195
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000196#ifndef _DEBUG
197 _Py_CheckPython3();
198#endif
199
Victor Stinner33354472011-11-21 02:01:41 +0100200 wpathname = PyUnicode_AsUnicode(pathname);
201 if (wpathname == NULL)
202 return NULL;
203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000205
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 {
207 HINSTANCE hDLL = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 unsigned int old_mode;
Brian Curtin401f9f32012-05-13 11:19:23 -0500209#if HAVE_SXS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000210 ULONG_PTR cookie = 0;
Brian Curtin401f9f32012-05-13 11:19:23 -0500211#endif
Victor Stinner67002af2011-10-02 20:35:10 +0200212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 /* Don't display a message box when Python can't load a DLL */
214 old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000215
Brian Curtin401f9f32012-05-13 11:19:23 -0500216#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500217 cookie = _Py_ActivateActCtx();
Brian Curtin401f9f32012-05-13 11:19:23 -0500218#endif
Brian Curtin589f89e2011-06-09 17:55:54 -0500219 /* We use LoadLibraryEx so Windows looks for dependent DLLs
220 in directory of pathname first. */
221 /* XXX This call doesn't exist in Windows CE */
Victor Stinner33354472011-11-21 02:01:41 +0100222 hDLL = LoadLibraryExW(wpathname, NULL,
Brian Curtin589f89e2011-06-09 17:55:54 -0500223 LOAD_WITH_ALTERED_SEARCH_PATH);
Brian Curtin401f9f32012-05-13 11:19:23 -0500224#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500225 _Py_DeactivateActCtx(cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -0500226#endif
Christian Heimesbbffeb62008-01-24 09:42:52 +0000227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 /* restore old error mode settings */
229 SetErrorMode(old_mode);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 if (hDLL==NULL){
232 PyObject *message;
233 unsigned int errorCode;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 /* Get an error string from Win32 error code */
236 wchar_t theInfo[256]; /* Pointer to error text
237 from system */
238 int theLength; /* Length of error text */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 errorCode = GetLastError();
Guido van Rossum22a1d361999-12-20 21:18:49 +0000241
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000242 theLength = FormatMessageW(
243 FORMAT_MESSAGE_FROM_SYSTEM |
244 FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
245 NULL, /* message source */
246 errorCode, /* the message (error) ID */
247 MAKELANGID(LANG_NEUTRAL,
248 SUBLANG_DEFAULT),
249 /* Default language */
250 theInfo, /* the buffer */
Gregory P. Smithb803c6c2013-03-23 16:05:36 -0700251 sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000252 NULL); /* no additional format args. */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000253
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000254 /* Problem: could not get the error message.
255 This should not happen if called correctly. */
256 if (theLength == 0) {
257 message = PyUnicode_FromFormat(
258 "DLL load failed with error code %d",
259 errorCode);
260 } else {
261 /* For some reason a \r\n
262 is appended to the text */
263 if (theLength >= 2 &&
264 theInfo[theLength-2] == '\r' &&
265 theInfo[theLength-1] == '\n') {
266 theLength -= 2;
267 theInfo[theLength] = '\0';
268 }
269 message = PyUnicode_FromString(
270 "DLL load failed: ");
Amaury Forgeot d'Arcd6179e12008-01-03 23:42:13 +0000271
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 PyUnicode_AppendAndDel(&message,
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100273 PyUnicode_FromWideChar(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000274 theInfo,
275 theLength));
276 }
Victor Stinner67002af2011-10-02 20:35:10 +0200277 if (message != NULL) {
Richard Oudkerk409f9022013-06-10 15:38:54 +0100278 PyObject *shortname_obj = PyUnicode_FromString(shortname);
279 PyErr_SetImportError(message, shortname_obj, pathname);
280 Py_XDECREF(shortname_obj);
Brian Curtin09b86d12012-04-17 16:57:09 -0500281 Py_DECREF(message);
Victor Stinner67002af2011-10-02 20:35:10 +0200282 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 return NULL;
284 } else {
285 char buffer[256];
Mark Hammond1f7838b2000-10-05 10:54:45 +0000286
Victor Stinner2d322272011-04-04 23:05:53 +0200287 PyOS_snprintf(buffer, sizeof(buffer),
Thomas Heller1df04612004-07-02 08:53:57 +0000288#ifdef _DEBUG
Victor Stinner2d322272011-04-04 23:05:53 +0200289 "python%d%d_d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000290#else
Victor Stinner2d322272011-04-04 23:05:53 +0200291 "python%d%d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000292#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 PY_MAJOR_VERSION,PY_MINOR_VERSION);
294 import_python = GetPythonImport(hDLL);
Mark Hammond1f7838b2000-10-05 10:54:45 +0000295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 if (import_python &&
297 strcasecmp(buffer,import_python)) {
Victor Stinner2d322272011-04-04 23:05:53 +0200298 PyErr_Format(PyExc_ImportError,
299 "Module use of %.150s conflicts "
300 "with this version of Python.",
301 import_python);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 FreeLibrary(hDLL);
303 return NULL;
304 }
305 }
306 p = GetProcAddress(hDLL, funcname);
307 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000310}