| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 1 | #include "Python.h" | 
|  | 2 | #include "osdefs.h" | 
|  | 3 | #include <windows.h> | 
|  | 4 |  | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 5 | /* PREFIX and EXEC_PREFIX are meaningless on Windows */ | 
|  | 6 |  | 
|  | 7 | #ifndef PREFIX | 
|  | 8 | #define PREFIX "" | 
|  | 9 | #endif | 
|  | 10 |  | 
|  | 11 | #ifndef EXEC_PREFIX | 
|  | 12 | #define EXEC_PREFIX "" | 
|  | 13 | #endif | 
|  | 14 |  | 
|  | 15 | /* | 
|  | 16 | This is a special Win32 version of getpath. | 
|  | 17 |  | 
|  | 18 | * There is no default path.  There is nothing even remotely resembling | 
|  | 19 | a standard location.  Maybe later "Program Files/Python", but not yet. | 
|  | 20 |  | 
|  | 21 | * The Registry is used as the primary store for the Python path. | 
|  | 22 |  | 
|  | 23 | * The environment variable PYTHONPATH _overrides_ the registry.  This should | 
|  | 24 | allow a "standard" Python environment, but allow you to manually setup | 
|  | 25 | another (eg, a beta version). | 
|  | 26 |  | 
|  | 27 | */ | 
|  | 28 |  | 
|  | 29 | BOOL PyWin_IsWin32s() | 
|  | 30 | { | 
|  | 31 | static BOOL bIsWin32s = -1; // flag as "not yet looked" | 
|  | 32 |  | 
|  | 33 | if (bIsWin32s==-1) { | 
|  | 34 | OSVERSIONINFO ver; | 
|  | 35 | ver.dwOSVersionInfoSize = sizeof(ver); | 
|  | 36 | GetVersionEx(&ver); | 
|  | 37 | bIsWin32s = ver.dwPlatformId == VER_PLATFORM_WIN32s; | 
|  | 38 | } | 
|  | 39 | return bIsWin32s; | 
|  | 40 | } | 
|  | 41 |  | 
|  | 42 | /* Load a PYTHONPATH value from the registry | 
|  | 43 | Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER | 
|  | 44 |  | 
|  | 45 | Returns NULL, or a pointer that should be free'd. | 
|  | 46 | */ | 
|  | 47 | static char * | 
|  | 48 | getpythonregpath(HKEY keyBase, BOOL bWin32s) | 
|  | 49 | { | 
|  | 50 | HKEY newKey = 0; | 
|  | 51 | DWORD nameSize = 0; | 
|  | 52 | DWORD dataSize = 0; | 
|  | 53 | DWORD numEntries = 0; | 
|  | 54 | LONG rc; | 
|  | 55 | char *retval = NULL; | 
|  | 56 | char *dataBuf; | 
| Guido van Rossum | 3db4103 | 1996-08-23 18:42:39 +0000 | [diff] [blame] | 57 | if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonCore\\" MS_DLL_ID "\\PythonPath", | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 58 | &newKey))==ERROR_SUCCESS) { | 
|  | 59 | RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL, | 
|  | 60 | &numEntries, &nameSize, &dataSize, NULL, NULL ); | 
|  | 61 | } | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 62 | if (bWin32s && numEntries==0 && dataSize==0) { /* must hardcode for Win32s */ | 
|  | 63 | numEntries = 1; | 
|  | 64 | dataSize = 511; | 
|  | 65 | } | 
|  | 66 | if (numEntries) { | 
| Guido van Rossum | bc2e631 | 1996-10-21 14:40:30 +0000 | [diff] [blame] | 67 | /* Loop over all subkeys. */ | 
|  | 68 | /* Win32s doesnt know how many subkeys, so we do | 
|  | 69 | it twice */ | 
|  | 70 | char keyBuf[MAX_PATH+1]; | 
|  | 71 | int index = 0; | 
|  | 72 | int off = 0; | 
|  | 73 | for(index=0;;index++) { | 
|  | 74 | long reqdSize = 0; | 
|  | 75 | DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1); | 
|  | 76 | if (rc) break; | 
|  | 77 | rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize); | 
|  | 78 | if (rc) break; | 
|  | 79 | if (bWin32s && reqdSize==0) reqdSize = 512; | 
|  | 80 | dataSize += reqdSize + 1; /* 1 for the ";" */ | 
|  | 81 | } | 
|  | 82 | dataBuf = malloc(dataSize+1); | 
|  | 83 | if (dataBuf==NULL) return NULL; /* pretty serious?  Raise error? */ | 
|  | 84 | /* Now loop over, grabbing the paths.  Subkeys before main library */ | 
|  | 85 | for(index=0;;index++) { | 
|  | 86 | int adjust; | 
|  | 87 | long reqdSize = dataSize; | 
|  | 88 | DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1); | 
|  | 89 | if (rc) break; | 
|  | 90 | rc = RegQueryValue(newKey, keyBuf, dataBuf+off, &reqdSize); | 
|  | 91 | if (rc) break; | 
| Guido van Rossum | d08735a | 1997-01-12 20:14:01 +0000 | [diff] [blame] | 92 | if (reqdSize>1) { // If Nothing, or only '\0' copied. | 
|  | 93 | adjust = strlen(dataBuf+off); | 
|  | 94 | dataSize -= adjust; | 
|  | 95 | off += adjust; | 
|  | 96 | dataBuf[off++] = ';'; | 
|  | 97 | dataBuf[off] = '\0'; | 
|  | 98 | dataSize--; | 
|  | 99 | } | 
| Guido van Rossum | bc2e631 | 1996-10-21 14:40:30 +0000 | [diff] [blame] | 100 | } | 
|  | 101 | /* Additionally, win32s doesnt work as expected, so | 
|  | 102 | the specific strlen() is required for 3.1. */ | 
|  | 103 | rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize); | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 104 | if (rc==ERROR_SUCCESS) { | 
|  | 105 | if (strlen(dataBuf)==0) | 
|  | 106 | free(dataBuf); | 
|  | 107 | else | 
|  | 108 | retval = dataBuf; // caller will free | 
|  | 109 | } | 
|  | 110 | else | 
|  | 111 | free(dataBuf); | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | if (newKey) | 
| Guido van Rossum | db9353e | 1997-05-05 22:17:45 +0000 | [diff] [blame] | 115 | RegCloseKey(newKey); | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 116 | return retval; | 
|  | 117 | } | 
|  | 118 | /* Return the initial python search path.  This is called once from | 
|  | 119 | initsys() to initialize sys.path.  The environment variable | 
|  | 120 | PYTHONPATH is fetched and the default path appended.  The default | 
|  | 121 | path may be passed to the preprocessor; if not, a system-dependent | 
|  | 122 | default is used. */ | 
|  | 123 |  | 
|  | 124 | char * | 
|  | 125 | Py_GetPath() | 
|  | 126 | { | 
|  | 127 | char *path = getenv("PYTHONPATH"); | 
|  | 128 | char *defpath = PYTHONPATH; | 
|  | 129 | static char *buf = NULL; | 
|  | 130 | char *p; | 
|  | 131 | int n; | 
| Guido van Rossum | db9353e | 1997-05-05 22:17:45 +0000 | [diff] [blame] | 132 | extern char *Py_GetProgramName(); | 
| Guido van Rossum | 6dbd190 | 1996-08-21 15:03:37 +0000 | [diff] [blame] | 133 |  | 
|  | 134 | if (buf != NULL) { | 
|  | 135 | free(buf); | 
|  | 136 | buf = NULL; | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | if (path == NULL) { | 
|  | 140 | char *machinePath, *userPath; | 
|  | 141 | int machineLen, userLen; | 
|  | 142 | /* lookup the registry */ | 
|  | 143 | BOOL bWin32s = PyWin_IsWin32s(); | 
|  | 144 |  | 
|  | 145 | if (bWin32s) { /* are we running under Windows 3.1 Win32s */ | 
|  | 146 | /* only CLASSES_ROOT is supported */ | 
|  | 147 | machinePath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE); | 
|  | 148 | userPath = NULL; | 
|  | 149 | } else { | 
|  | 150 | machinePath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE); | 
|  | 151 | userPath = getpythonregpath(HKEY_CURRENT_USER, FALSE); | 
|  | 152 | } | 
|  | 153 | if (machinePath==NULL && userPath==NULL) return defpath; | 
|  | 154 | machineLen = machinePath ? strlen(machinePath) : 0; | 
|  | 155 | userLen = userPath ? strlen(userPath) : 0; | 
|  | 156 | n = machineLen + userLen + 1; | 
|  | 157 | // this is a memory leak, as Python never frees it.  Only ever called once, so big deal! | 
|  | 158 | buf = malloc(n); | 
|  | 159 | if (buf == NULL) | 
|  | 160 | Py_FatalError("not enough memory to copy module search path"); | 
|  | 161 | p = buf; | 
|  | 162 | *p = '\0'; | 
|  | 163 | if (machineLen) { | 
|  | 164 | strcpy(p, machinePath); | 
|  | 165 | p += machineLen; | 
|  | 166 | } | 
|  | 167 | if (userLen) { | 
|  | 168 | if (machineLen) | 
|  | 169 | *p++ = DELIM; | 
|  | 170 | strcpy(p, userPath); | 
|  | 171 | } | 
|  | 172 | if (userPath) free(userPath); | 
|  | 173 | if (machinePath) free(machinePath); | 
|  | 174 | } else { | 
|  | 175 |  | 
|  | 176 | buf = malloc(strlen(path)+1); | 
|  | 177 | if (buf == NULL) | 
|  | 178 | Py_FatalError("not enough memory to copy module search path"); | 
|  | 179 | strcpy(buf, path); | 
|  | 180 | } | 
|  | 181 | return buf; | 
|  | 182 | } | 
|  | 183 |  | 
|  | 184 | /* Similar for Makefile variables $prefix and $exec_prefix */ | 
|  | 185 |  | 
|  | 186 | char * | 
|  | 187 | Py_GetPrefix() | 
|  | 188 | { | 
|  | 189 | return PREFIX; | 
|  | 190 | } | 
|  | 191 |  | 
|  | 192 | char * | 
|  | 193 | Py_GetExecPrefix() | 
|  | 194 | { | 
|  | 195 | return EXEC_PREFIX; | 
|  | 196 | } | 
| Guido van Rossum | c2d1417 | 1997-05-22 20:45:28 +0000 | [diff] [blame] | 197 |  | 
|  | 198 | char * | 
|  | 199 | Py_GetProgramFullPath() | 
|  | 200 | { | 
|  | 201 | extern char *Py_GetProgramName(); | 
|  | 202 | return Py_GetProgramName(); | 
|  | 203 | } |