1 /******************************************************************** 2 3 import_nt.c 4 5 Win32 specific import code. 6 7 */ 8 9 #include "Python.h" 10 #include "osdefs.h" 11 #include <windows.h> 12 #include "importdl.h" 13 #include "malloc.h" /* for alloca */ 14 15 /* a string loaded from the DLL at startup */ 16 extern const char *PyWin_DLLVersionString; 17 18 FILE *PyWin_FindRegisteredModule(const char *moduleName, 19 struct filedescr **ppFileDesc, 20 char *pathBuf, 21 Py_ssize_t pathLen) 22 { 23 char *moduleKey; 24 const char keyPrefix[] = "Software\\Python\\PythonCore\\"; 25 const char keySuffix[] = "\\Modules\\"; 26 #ifdef _DEBUG 27 /* In debugging builds, we _must_ have the debug version 28 * registered. 29 */ 30 const char debugString[] = "\\Debug"; 31 #else 32 const char debugString[] = ""; 33 #endif 34 struct filedescr *fdp = NULL; 35 FILE *fp; 36 HKEY keyBase = HKEY_CURRENT_USER; 37 int modNameSize; 38 long regStat; 39 40 /* Calculate the size for the sprintf buffer. 41 * Get the size of the chars only, plus 1 NULL. 42 */ 43 size_t bufSize = sizeof(keyPrefix)-1 + 44 strlen(PyWin_DLLVersionString) + 45 sizeof(keySuffix) + 46 strlen(moduleName) + 47 sizeof(debugString) - 1; 48 /* alloca == no free required, but memory only local to fn, 49 * also no heap fragmentation! 50 */ 51 moduleKey = alloca(bufSize); 52 PyOS_snprintf(moduleKey, bufSize, 53 "Software\\Python\\PythonCore\\%s\\Modules\\%s%s", 54 PyWin_DLLVersionString, moduleName, debugString); 55 56 assert(pathLen < INT_MAX); 57 modNameSize = (int)pathLen; 58 regStat = RegQueryValue(keyBase, moduleKey, pathBuf, &modNameSize); 59 if (regStat != ERROR_SUCCESS) { 60 /* No user setting - lookup in machine settings */ 61 keyBase = HKEY_LOCAL_MACHINE; 62 /* be anal - failure may have reset size param */ 63 modNameSize = (int)pathLen; 64 regStat = RegQueryValue(keyBase, moduleKey, 65 pathBuf, &modNameSize); 66 67 if (regStat != ERROR_SUCCESS) 68 return NULL; 69 } 70 /* use the file extension to locate the type entry. */ 71 for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { 72 size_t extLen = strlen(fdp->suffix); 73 assert(modNameSize >= 0); /* else cast to size_t is wrong */ 74 if ((size_t)modNameSize > extLen && 75 strnicmp(pathBuf + ((size_t)modNameSize-extLen-1), 76 fdp->suffix, 77 extLen) == 0) 78 break; 79 } 80 if (fdp->suffix == NULL) 81 return NULL; 82 fp = fopen(pathBuf, fdp->mode); 83 if (fp != NULL) 84 *ppFileDesc = fdp; 85 return fp; 86 } 87