Home | History | Annotate | Download | only in PC
      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