|
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 } |