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; |
| 38 | struct filedescr *fdp; |
| 39 | HKEY keyBase; |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 40 | int modNameSize; |
| 41 | long regStat; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 42 | Py_ssize_t extLen; |
| 43 | FILE *fp; |
Guido van Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 44 | |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 45 | 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 Rossum | 271f977 | 1997-09-29 23:39:31 +0000 | [diff] [blame] | 55 | |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 56 | keyBase = HKEY_CURRENT_USER; |
| 57 | modNameSize = pathLen; |
| 58 | regStat = RegQueryValueW(keyBase, PyUnicode_AS_UNICODE(moduleKey), |
| 59 | pathBuf, &modNameSize); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 60 | 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 Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 64 | modNameSize = pathLen; |
| 65 | regStat = RegQueryValueW(keyBase, PyUnicode_AS_UNICODE(moduleKey), |
| 66 | pathBuf, &modNameSize); |
| 67 | if (regStat != ERROR_SUCCESS) { |
| 68 | Py_DECREF(moduleKey); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 69 | return NULL; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 70 | } |
| 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 Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 77 | } |
| 78 | /* use the file extension to locate the type entry. */ |
| 79 | for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 80 | 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 Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 90 | break; |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 91 | } |
| 92 | Py_DECREF(suffix); |
Antoine Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 93 | } |
| 94 | if (fdp->suffix == NULL) |
| 95 | return NULL; |
Martin v. Löwis | d63a3b8 | 2011-09-28 07:41:54 +0200 | [diff] [blame] | 96 | path = PyUnicode_FromWideChar(pathBuf, wcslen(pathBuf)); |
Victor Stinner | 4d6c1c4 | 2011-03-08 23:49:04 +0100 | [diff] [blame] | 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 Pitrou | f95a1b3 | 2010-05-09 15:52:27 +0000 | [diff] [blame] | 106 | return fp; |
Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 107 | } |