Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 1 | /******************************************************************** |
| 2 | |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 3 | import_nt.c |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 4 | |
| 5 | Win32 specific import code. |
| 6 | |
| 7 | */ |
| 8 | |
Guido van Rossum | 7688bba | 1997-05-05 21:45:44 +0000 | [diff] [blame] | 9 | #include "Python.h" |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 10 | #include "osdefs.h" |
| 11 | #include <windows.h> |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 12 | #include "importdl.h" |
Tim Peters | db63829 | 2000-07-03 23:51:17 +0000 | [diff] [blame] | 13 | #include "malloc.h" /* for alloca */ |
Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 14 | |
Tim Peters | db63829 | 2000-07-03 23:51:17 +0000 | [diff] [blame] | 15 | /* a string loaded from the DLL at startup */ |
| 16 | extern const char *PyWin_DLLVersionString; |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 17 | |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 18 | /* 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 | */ |
| 30 | FILE * |
| 31 | _PyWin_FindRegisteredModule(PyObject *moduleName, |
| 32 | struct filedescr **ppFileDesc, |
| 33 | PyObject **pPath) |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 34 | { |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 35 | wchar_t pathBuf[MAXPATHLEN+1]; |
| 36 | int pathLen = MAXPATHLEN+1; |
| 37 | PyObject *path, *moduleKey, *suffix; |
Victor Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 38 | wchar_t *wmoduleKey, *wsuffix; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 39 | struct filedescr *fdp; |
| 40 | HKEY keyBase; |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 41 | int modNameSize; |
| 42 | long regStat; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 43 | Py_ssize_t extLen; |
| 44 | FILE *fp; |
Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 45 | |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 46 | 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 Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 56 | wmoduleKey = PyUnicode_AsUnicode(moduleKey); |
| 57 | if (wmoduleKey == NULL) { |
| 58 | Py_DECREF(moduleKey); |
| 59 | return NULL; |
| 60 | } |
Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 61 | |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 62 | keyBase = HKEY_CURRENT_USER; |
| 63 | modNameSize = pathLen; |
Victor Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 64 | regStat = RegQueryValueW(keyBase, wmoduleKey, |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 65 | pathBuf, &modNameSize); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 66 | 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 Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 70 | modNameSize = pathLen; |
Victor Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 71 | regStat = RegQueryValueW(keyBase, wmoduleKey, |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 72 | pathBuf, &modNameSize); |
| 73 | if (regStat != ERROR_SUCCESS) { |
| 74 | Py_DECREF(moduleKey); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 75 | return NULL; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 76 | } |
| 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 Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 83 | } |
| 84 | /* use the file extension to locate the type entry. */ |
| 85 | for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 86 | suffix = PyUnicode_FromString(fdp->suffix); |
| 87 | if (suffix == NULL) |
| 88 | return NULL; |
Victor Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 89 | wsuffix = PyUnicode_AsUnicode(suffix); |
| 90 | if (wsuffix == NULL) { |
| 91 | Py_DECREF(suffix); |
| 92 | return NULL; |
| 93 | } |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 94 | extLen = PyUnicode_GET_SIZE(suffix); |
| 95 | if ((Py_ssize_t)modNameSize > extLen && |
| 96 | _wcsnicmp(pathBuf + ((Py_ssize_t)modNameSize-extLen-1), |
Victor Stinner | 3335447 | 2011-11-21 02:01:41 +0100 | [diff] [blame] | 97 | wsuffix, |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 98 | extLen) == 0) |
| 99 | { |
| 100 | Py_DECREF(suffix); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 101 | break; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 102 | } |
| 103 | Py_DECREF(suffix); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 104 | } |
| 105 | if (fdp->suffix == NULL) |
| 106 | return NULL; |
Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 107 | path = PyUnicode_FromWideChar(pathBuf, wcslen(pathBuf)); |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 108 | if (path == NULL) |
| 109 | return NULL; |
| 110 | fp = _Py_fopen(path, fdp->mode); |
| 111 | if (fp == NULL) { |
| 112 | Py_DECREF(path); |
| 113 | return NULL; |
| 114 | } |
| 115 | *pPath = path; |
| 116 | *ppFileDesc = fdp; |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 117 | return fp; |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 118 | } |