blob: c3720511542370dad2928432df0119af948a37ef [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;
38 struct filedescr *fdp;
39 HKEY keyBase;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 int modNameSize;
41 long regStat;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010042 Py_ssize_t extLen;
43 FILE *fp;
Guido van Rossum271f9771997-09-29 23:39:31 +000044
Victor Stinner4d6c1c42011-03-08 23:49:04 +010045 moduleKey = PyUnicode_FromFormat(
46#ifdef _DEBUG
47 /* In debugging builds, we _must_ have the debug version registered */
48 "Software\\Python\\PythonCore\\%s\\Modules\\%U\\Debug",
49#else
50 "Software\\Python\\PythonCore\\%s\\Modules\\%U",
51#endif
52 PyWin_DLLVersionString, moduleName);
53 if (moduleKey == NULL)
54 return NULL;
Guido van Rossum271f9771997-09-29 23:39:31 +000055
Victor Stinner4d6c1c42011-03-08 23:49:04 +010056 keyBase = HKEY_CURRENT_USER;
57 modNameSize = pathLen;
58 regStat = RegQueryValueW(keyBase, PyUnicode_AS_UNICODE(moduleKey),
59 pathBuf, &modNameSize);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 if (regStat != ERROR_SUCCESS) {
61 /* No user setting - lookup in machine settings */
62 keyBase = HKEY_LOCAL_MACHINE;
63 /* be anal - failure may have reset size param */
Victor Stinner4d6c1c42011-03-08 23:49:04 +010064 modNameSize = pathLen;
65 regStat = RegQueryValueW(keyBase, PyUnicode_AS_UNICODE(moduleKey),
66 pathBuf, &modNameSize);
67 if (regStat != ERROR_SUCCESS) {
68 Py_DECREF(moduleKey);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000069 return NULL;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010070 }
71 }
72 Py_DECREF(moduleKey);
73 if (modNameSize < 3) {
74 /* path shorter than "a.o" or negative length (cast to
75 size_t is wrong) */
76 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 }
78 /* use the file extension to locate the type entry. */
79 for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
Victor Stinner4d6c1c42011-03-08 23:49:04 +010080 suffix = PyUnicode_FromString(fdp->suffix);
81 if (suffix == NULL)
82 return NULL;
83 extLen = PyUnicode_GET_SIZE(suffix);
84 if ((Py_ssize_t)modNameSize > extLen &&
85 _wcsnicmp(pathBuf + ((Py_ssize_t)modNameSize-extLen-1),
86 PyUnicode_AS_UNICODE(suffix),
87 extLen) == 0)
88 {
89 Py_DECREF(suffix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 break;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010091 }
92 Py_DECREF(suffix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000093 }
94 if (fdp->suffix == NULL)
95 return NULL;
Victor Stinner4d6c1c42011-03-08 23:49:04 +010096 path = PyUnicode_FromUnicode(pathBuf, wcslen(pathBuf));
97 if (path == NULL)
98 return NULL;
99 fp = _Py_fopen(path, fdp->mode);
100 if (fp == NULL) {
101 Py_DECREF(path);
102 return NULL;
103 }
104 *pPath = path;
105 *ppFileDesc = fdp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 return fp;
Guido van Rossum6dbd1901996-08-21 15:03:37 +0000107}