blob: ffcf0ee1d7392cb9ad6ccca0441f275a3d5c4ae6 [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"
Guido van Rossume7ba4952007-06-06 23:52:48 +000012#include <windows.h>
Guido van Rossum22a1d361999-12-20 21:18:49 +000013
Mark Hammond9844a1f2009-01-27 23:46:57 +000014// "activation context" magic - see dl_nt.c...
Brian Curtin401f9f32012-05-13 11:19:23 -050015#if HAVE_SXS
Mark Hammond9844a1f2009-01-27 23:46:57 +000016extern ULONG_PTR _Py_ActivateActCtx();
17void _Py_DeactivateActCtx(ULONG_PTR cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -050018#endif
Mark Hammond9844a1f2009-01-27 23:46:57 +000019
Brett Cannon2657df42012-05-04 15:20:40 -040020const char *_PyImport_DynLoadFiletab[] = {
Guido van Rossum22a1d361999-12-20 21:18:49 +000021#ifdef _DEBUG
Brett Cannon2657df42012-05-04 15:20:40 -040022 "_d.pyd",
Guido van Rossum22a1d361999-12-20 21:18:49 +000023#else
Brett Cannon2657df42012-05-04 15:20:40 -040024 ".pyd",
Guido van Rossum22a1d361999-12-20 21:18:49 +000025#endif
Brett Cannon2657df42012-05-04 15:20:40 -040026 NULL
Guido van Rossum22a1d361999-12-20 21:18:49 +000027};
28
29
Mark Hammond1f7838b2000-10-05 10:54:45 +000030/* Case insensitive string compare, to avoid any dependencies on particular
31 C RTL implementations */
32
33static int strcasecmp (char *string1, char *string2)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000034{
35 int first, second;
Mark Hammond1f7838b2000-10-05 10:54:45 +000036
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 do {
38 first = tolower(*string1);
39 second = tolower(*string2);
40 string1++;
41 string2++;
42 } while (first && first == second);
Mark Hammond1f7838b2000-10-05 10:54:45 +000043
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000044 return (first - second);
45}
Mark Hammond1f7838b2000-10-05 10:54:45 +000046
47
48/* Function to return the name of the "python" DLL that the supplied module
49 directly imports. Looks through the list of imported modules and
50 returns the first entry that starts with "python" (case sensitive) and
51 is followed by nothing but numbers until the separator (period).
52
53 Returns a pointer to the import name, or NULL if no matching name was
54 located.
55
56 This function parses through the PE header for the module as loaded in
57 memory by the system loader. The PE header is accessed as documented by
58 Microsoft in the MSDN PE and COFF specification (2/99), and handles
59 both PE32 and PE32+. It only worries about the direct import table and
60 not the delay load import table since it's unlikely an extension is
61 going to be delay loading Python (after all, it's already loaded).
62
63 If any magic values are not found (e.g., the PE header or optional
64 header magic), then this function simply returns NULL. */
65
66#define DWORD_AT(mem) (*(DWORD *)(mem))
67#define WORD_AT(mem) (*(WORD *)(mem))
68
69static char *GetPythonImport (HINSTANCE hModule)
70{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000071 unsigned char *dllbase, *import_data, *import_name;
72 DWORD pe_offset, opt_offset;
73 WORD opt_magic;
74 int num_dict_off, import_off;
Mark Hammond1f7838b2000-10-05 10:54:45 +000075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000076 /* Safety check input */
77 if (hModule == NULL) {
78 return NULL;
79 }
Mark Hammond1f7838b2000-10-05 10:54:45 +000080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000081 /* Module instance is also the base load address. First portion of
82 memory is the MS-DOS loader, which holds the offset to the PE
83 header (from the load base) at 0x3C */
84 dllbase = (unsigned char *)hModule;
85 pe_offset = DWORD_AT(dllbase + 0x3C);
Mark Hammond1f7838b2000-10-05 10:54:45 +000086
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 /* The PE signature must be "PE\0\0" */
88 if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
89 return NULL;
90 }
Mark Hammond1f7838b2000-10-05 10:54:45 +000091
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000092 /* Following the PE signature is the standard COFF header (20
93 bytes) and then the optional header. The optional header starts
94 with a magic value of 0x10B for PE32 or 0x20B for PE32+ (PE32+
95 uses 64-bits for some fields). It might also be 0x107 for a ROM
96 image, but we don't process that here.
Mark Hammond1f7838b2000-10-05 10:54:45 +000097
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 The optional header ends with a data dictionary that directly
99 points to certain types of data, among them the import entries
100 (in the second table entry). Based on the header type, we
101 determine offsets for the data dictionary count and the entry
102 within the dictionary pointing to the imports. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000104 opt_offset = pe_offset + 4 + 20;
105 opt_magic = WORD_AT(dllbase+opt_offset);
106 if (opt_magic == 0x10B) {
107 /* PE32 */
108 num_dict_off = 92;
109 import_off = 104;
110 } else if (opt_magic == 0x20B) {
111 /* PE32+ */
112 num_dict_off = 108;
113 import_off = 120;
114 } else {
115 /* Unsupported */
116 return NULL;
117 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000118
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 /* Now if an import table exists, offset to it and walk the list of
120 imports. The import table is an array (ending when an entry has
121 empty values) of structures (20 bytes each), which contains (at
122 offset 12) a relative address (to the module base) at which a
123 string constant holding the import name is located. */
Mark Hammond1f7838b2000-10-05 10:54:45 +0000124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (DWORD_AT(dllbase + opt_offset + num_dict_off) >= 2) {
126 /* We have at least 2 tables - the import table is the second
127 one. But still it may be that the table size is zero */
128 if (0 == DWORD_AT(dllbase + opt_offset + import_off + sizeof(DWORD)))
129 return NULL;
130 import_data = dllbase + DWORD_AT(dllbase +
131 opt_offset +
132 import_off);
133 while (DWORD_AT(import_data)) {
134 import_name = dllbase + DWORD_AT(import_data+12);
135 if (strlen(import_name) >= 6 &&
136 !strncmp(import_name,"python",6)) {
137 char *pch;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000138
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000139#ifndef _DEBUG
140 /* In a release version, don't claim that python3.dll is
141 a Python DLL. */
142 if (strcmp(import_name, "python3.dll") == 0) {
143 import_data += 20;
144 continue;
145 }
146#endif
147
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 /* Ensure python prefix is followed only
149 by numbers to the end of the basename */
150 pch = import_name + 6;
Thomas Heller1df04612004-07-02 08:53:57 +0000151#ifdef _DEBUG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 while (*pch && pch[0] != '_' && pch[1] != 'd' && pch[2] != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000153#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 while (*pch && *pch != '.') {
Thomas Heller1df04612004-07-02 08:53:57 +0000155#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 if (*pch >= '0' && *pch <= '9') {
157 pch++;
158 } else {
159 pch = NULL;
160 break;
161 }
162 }
Mark Hammond1f7838b2000-10-05 10:54:45 +0000163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 if (pch) {
165 /* Found it - return the name */
166 return import_name;
167 }
168 }
169 import_data += 20;
170 }
171 }
172
173 return NULL;
Mark Hammond1f7838b2000-10-05 10:54:45 +0000174}
Mark Hammond1f7838b2000-10-05 10:54:45 +0000175
Victor Stinner2d322272011-04-04 23:05:53 +0200176dl_funcptr _PyImport_GetDynLoadWindows(const char *shortname,
177 PyObject *pathname, FILE *fp)
Guido van Rossum22a1d361999-12-20 21:18:49 +0000178{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000179 dl_funcptr p;
180 char funcname[258], *import_python;
Victor Stinner33354472011-11-21 02:01:41 +0100181 wchar_t *wpathname;
Guido van Rossum96a8fb71999-12-22 14:09:35 +0000182
Martin v. Löwis4d0d4712010-12-03 20:14:31 +0000183#ifndef _DEBUG
184 _Py_CheckPython3();
185#endif
186
Victor Stinner33354472011-11-21 02:01:41 +0100187 wpathname = PyUnicode_AsUnicode(pathname);
188 if (wpathname == NULL)
189 return NULL;
190
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
Guido van Rossum22a1d361999-12-20 21:18:49 +0000192
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 {
194 HINSTANCE hDLL = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000195 unsigned int old_mode;
Brian Curtin401f9f32012-05-13 11:19:23 -0500196#if HAVE_SXS
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 ULONG_PTR cookie = 0;
Brian Curtin401f9f32012-05-13 11:19:23 -0500198#endif
Victor Stinner67002af2011-10-02 20:35:10 +0200199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 /* Don't display a message box when Python can't load a DLL */
201 old_mode = SetErrorMode(SEM_FAILCRITICALERRORS);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000202
Brian Curtin401f9f32012-05-13 11:19:23 -0500203#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500204 cookie = _Py_ActivateActCtx();
Brian Curtin401f9f32012-05-13 11:19:23 -0500205#endif
Brian Curtin589f89e2011-06-09 17:55:54 -0500206 /* We use LoadLibraryEx so Windows looks for dependent DLLs
207 in directory of pathname first. */
208 /* XXX This call doesn't exist in Windows CE */
Victor Stinner33354472011-11-21 02:01:41 +0100209 hDLL = LoadLibraryExW(wpathname, NULL,
Brian Curtin589f89e2011-06-09 17:55:54 -0500210 LOAD_WITH_ALTERED_SEARCH_PATH);
Brian Curtin401f9f32012-05-13 11:19:23 -0500211#if HAVE_SXS
Brian Curtin589f89e2011-06-09 17:55:54 -0500212 _Py_DeactivateActCtx(cookie);
Brian Curtin401f9f32012-05-13 11:19:23 -0500213#endif
Christian Heimesbbffeb62008-01-24 09:42:52 +0000214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 /* restore old error mode settings */
216 SetErrorMode(old_mode);
Christian Heimesbbffeb62008-01-24 09:42:52 +0000217
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000218 if (hDLL==NULL){
219 PyObject *message;
220 unsigned int errorCode;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000221
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 /* Get an error string from Win32 error code */
223 wchar_t theInfo[256]; /* Pointer to error text
224 from system */
225 int theLength; /* Length of error text */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000226
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 errorCode = GetLastError();
Guido van Rossum22a1d361999-12-20 21:18:49 +0000228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 theLength = FormatMessageW(
230 FORMAT_MESSAGE_FROM_SYSTEM |
231 FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
232 NULL, /* message source */
233 errorCode, /* the message (error) ID */
234 MAKELANGID(LANG_NEUTRAL,
235 SUBLANG_DEFAULT),
236 /* Default language */
237 theInfo, /* the buffer */
Gregory P. Smithb803c6c2013-03-23 16:05:36 -0700238 sizeof(theInfo) / sizeof(wchar_t), /* size in wchars */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 NULL); /* no additional format args. */
Guido van Rossum22a1d361999-12-20 21:18:49 +0000240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 /* Problem: could not get the error message.
242 This should not happen if called correctly. */
243 if (theLength == 0) {
244 message = PyUnicode_FromFormat(
245 "DLL load failed with error code %d",
246 errorCode);
247 } else {
248 /* For some reason a \r\n
249 is appended to the text */
250 if (theLength >= 2 &&
251 theInfo[theLength-2] == '\r' &&
252 theInfo[theLength-1] == '\n') {
253 theLength -= 2;
254 theInfo[theLength] = '\0';
255 }
256 message = PyUnicode_FromString(
257 "DLL load failed: ");
Amaury Forgeot d'Arcd6179e12008-01-03 23:42:13 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 PyUnicode_AppendAndDel(&message,
Victor Stinner9d3b93b2011-11-22 02:27:30 +0100260 PyUnicode_FromWideChar(
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 theInfo,
262 theLength));
263 }
Victor Stinner67002af2011-10-02 20:35:10 +0200264 if (message != NULL) {
Richard Oudkerk409f9022013-06-10 15:38:54 +0100265 PyObject *shortname_obj = PyUnicode_FromString(shortname);
266 PyErr_SetImportError(message, shortname_obj, pathname);
267 Py_XDECREF(shortname_obj);
Brian Curtin09b86d12012-04-17 16:57:09 -0500268 Py_DECREF(message);
Victor Stinner67002af2011-10-02 20:35:10 +0200269 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000270 return NULL;
271 } else {
272 char buffer[256];
Mark Hammond1f7838b2000-10-05 10:54:45 +0000273
Victor Stinner2d322272011-04-04 23:05:53 +0200274 PyOS_snprintf(buffer, sizeof(buffer),
Thomas Heller1df04612004-07-02 08:53:57 +0000275#ifdef _DEBUG
Victor Stinner2d322272011-04-04 23:05:53 +0200276 "python%d%d_d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000277#else
Victor Stinner2d322272011-04-04 23:05:53 +0200278 "python%d%d.dll",
Thomas Heller1df04612004-07-02 08:53:57 +0000279#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 PY_MAJOR_VERSION,PY_MINOR_VERSION);
281 import_python = GetPythonImport(hDLL);
Mark Hammond1f7838b2000-10-05 10:54:45 +0000282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000283 if (import_python &&
284 strcasecmp(buffer,import_python)) {
Victor Stinner2d322272011-04-04 23:05:53 +0200285 PyErr_Format(PyExc_ImportError,
286 "Module use of %.150s conflicts "
287 "with this version of Python.",
288 import_python);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 FreeLibrary(hDLL);
290 return NULL;
291 }
292 }
293 p = GetProcAddress(hDLL, funcname);
294 }
Guido van Rossum22a1d361999-12-20 21:18:49 +0000295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 return p;
Guido van Rossum22a1d361999-12-20 21:18:49 +0000297}