blob: b9b36dca5e2d437111e0a32da44fda79ef6b676f [file] [log] [blame]
Guido van Rossum6dbd1901996-08-21 15:03:37 +00001/********************************************************************
2
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00003 import_nt.c
Guido van Rossum6dbd1901996-08-21 15:03:37 +00004
5 Win32 specific import code.
6
7*/
8
Guido van Rossum7688bba1997-05-05 21:45:44 +00009#include "Python.h"
Guido van Rossum6dbd1901996-08-21 15:03:37 +000010#include "osdefs.h"
11#include <windows.h>
Guido van Rossum6dbd1901996-08-21 15:03:37 +000012#include "importdl.h"
Tim Petersdb638292000-07-03 23:51:17 +000013#include "malloc.h" /* for alloca */
Guido van Rossum271f9771997-09-29 23:39:31 +000014
Tim Petersdb638292000-07-03 23:51:17 +000015/* a string loaded from the DLL at startup */
16extern const char *PyWin_DLLVersionString;
Guido van Rossum6dbd1901996-08-21 15:03:37 +000017
Victor Stinner4d6c1c42011-03-08 23:49:04 +010018/* Find a module on Windows.
19
20 Read the registry Software\Python\PythonCore\<version>\Modules\<name> (or
21 Software\Python\PythonCore\<version>\Modules\<name>\Debug in debug mode)
22 from HKEY_CURRENT_USER, or HKEY_LOCAL_MACHINE. Find the file descriptor using
23 the file extension. Open the file.
24
25 On success, write the file descriptor into *ppFileDesc, the module path
26 (Unicode object) into *pPath, and return the opened file object. If the
27 module cannot be found (e.g. no registry key or the file doesn't exist),
28 return NULL. On error, raise a Python exception and return NULL.
29 */
30FILE *
31_PyWin_FindRegisteredModule(PyObject *moduleName,
32 struct filedescr **ppFileDesc,
33 PyObject **pPath)
Guido van Rossum6dbd1901996-08-21 15:03:37 +000034{
Victor Stinner4d6c1c42011-03-08 23:49:04 +010035 wchar_t pathBuf[MAXPATHLEN+1];
36 int pathLen = MAXPATHLEN+1;
37 PyObject *path, *moduleKey, *suffix;
Victor Stinner33354472011-11-21 02:01:41 +010038 wchar_t *wmoduleKey, *wsuffix;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010039 struct filedescr *fdp;
40 HKEY keyBase;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 int modNameSize;
42 long regStat;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010043 Py_ssize_t extLen;
44 FILE *fp;
Guido van Rossum271f9771997-09-29 23:39:31 +000045
Victor Stinner4d6c1c42011-03-08 23:49:04 +010046 moduleKey = PyUnicode_FromFormat(
47#ifdef _DEBUG
48 /* In debugging builds, we _must_ have the debug version registered */
49 "Software\\Python\\PythonCore\\%s\\Modules\\%U\\Debug",
50#else
51 "Software\\Python\\PythonCore\\%s\\Modules\\%U",
52#endif
53 PyWin_DLLVersionString, moduleName);
54 if (moduleKey == NULL)
55 return NULL;
Victor Stinner33354472011-11-21 02:01:41 +010056 wmoduleKey = PyUnicode_AsUnicode(moduleKey);
57 if (wmoduleKey == NULL) {
58 Py_DECREF(moduleKey);
59 return NULL;
60 }
Guido van Rossum271f9771997-09-29 23:39:31 +000061
Victor Stinner4d6c1c42011-03-08 23:49:04 +010062 keyBase = HKEY_CURRENT_USER;
63 modNameSize = pathLen;
Victor Stinner33354472011-11-21 02:01:41 +010064 regStat = RegQueryValueW(keyBase, wmoduleKey,
Victor Stinner4d6c1c42011-03-08 23:49:04 +010065 pathBuf, &modNameSize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000066 if (regStat != ERROR_SUCCESS) {
67 /* No user setting - lookup in machine settings */
68 keyBase = HKEY_LOCAL_MACHINE;
69 /* be anal - failure may have reset size param */
Victor Stinner4d6c1c42011-03-08 23:49:04 +010070 modNameSize = pathLen;
Victor Stinner33354472011-11-21 02:01:41 +010071 regStat = RegQueryValueW(keyBase, wmoduleKey,
Victor Stinner4d6c1c42011-03-08 23:49:04 +010072 pathBuf, &modNameSize);
73 if (regStat != ERROR_SUCCESS) {
74 Py_DECREF(moduleKey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 return NULL;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010076 }
77 }
78 Py_DECREF(moduleKey);
79 if (modNameSize < 3) {
80 /* path shorter than "a.o" or negative length (cast to
81 size_t is wrong) */
82 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 }
84 /* use the file extension to locate the type entry. */
85 for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
Victor Stinner4d6c1c42011-03-08 23:49:04 +010086 suffix = PyUnicode_FromString(fdp->suffix);
87 if (suffix == NULL)
88 return NULL;
Victor Stinner9e30aa52011-11-21 02:49:52 +010089 wsuffix = PyUnicode_AsUnicodeAndSize(suffix, &extLen);
Victor Stinner33354472011-11-21 02:01:41 +010090 if (wsuffix == NULL) {
91 Py_DECREF(suffix);
92 return NULL;
93 }
Victor Stinner4d6c1c42011-03-08 23:49:04 +010094 if ((Py_ssize_t)modNameSize > extLen &&
95 _wcsnicmp(pathBuf + ((Py_ssize_t)modNameSize-extLen-1),
Victor Stinner33354472011-11-21 02:01:41 +010096 wsuffix,
Victor Stinner4d6c1c42011-03-08 23:49:04 +010097 extLen) == 0)
98 {
99 Py_DECREF(suffix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 break;
Victor Stinner4d6c1c42011-03-08 23:49:04 +0100101 }
102 Py_DECREF(suffix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000103 }
104 if (fdp->suffix == NULL)
105 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200106 path = PyUnicode_FromWideChar(pathBuf, wcslen(pathBuf));
Victor Stinner4d6c1c42011-03-08 23:49:04 +0100107 if (path == NULL)
108 return NULL;
109 fp = _Py_fopen(path, fdp->mode);
110 if (fp == NULL) {
111 Py_DECREF(path);
112 return NULL;
113 }
114 *pPath = path;
115 *ppFileDesc = fdp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 return fp;
Guido van Rossum6dbd1901996-08-21 15:03:37 +0000117}