diff options
Diffstat (limited to 'PC/getpath_nt.c')
-rw-r--r-- | PC/getpath_nt.c | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/PC/getpath_nt.c b/PC/getpath_nt.c new file mode 100644 index 0000000..045fc7c --- /dev/null +++ b/PC/getpath_nt.c @@ -0,0 +1,178 @@ +#include "Python.h" +#include "osdefs.h" +#include <windows.h> + +#ifndef WIN32_PATCH_LEVEL +#define WIN32_PATCH_LEVEL "000" +#endif + +/* PREFIX and EXEC_PREFIX are meaningless on Windows */ + +#ifndef PREFIX +#define PREFIX "" +#endif + +#ifndef EXEC_PREFIX +#define EXEC_PREFIX "" +#endif + +/* +This is a special Win32 version of getpath. + +* There is no default path. There is nothing even remotely resembling + a standard location. Maybe later "Program Files/Python", but not yet. + +* The Registry is used as the primary store for the Python path. + +* The environment variable PYTHONPATH _overrides_ the registry. This should + allow a "standard" Python environment, but allow you to manually setup + another (eg, a beta version). + +*/ + +BOOL PyWin_IsWin32s() +{ + static BOOL bIsWin32s = -1; // flag as "not yet looked" + + if (bIsWin32s==-1) { + OSVERSIONINFO ver; + ver.dwOSVersionInfoSize = sizeof(ver); + GetVersionEx(&ver); + bIsWin32s = ver.dwPlatformId == VER_PLATFORM_WIN32s; + } + return bIsWin32s; +} + +/* Load a PYTHONPATH value from the registry + Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER + + Returns NULL, or a pointer that should be free'd. +*/ +static char * +getpythonregpath(HKEY keyBase, BOOL bWin32s) +{ + HKEY newKey = 0; + DWORD nameSize = 0; + DWORD dataSize = 0; + DWORD numEntries = 0; + LONG rc; + char *retval = NULL; + char *dataBuf; + if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonCore\\" WIN32_PATCH_LEVEL "\\PythonPath", + &newKey))==ERROR_SUCCESS) { + RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL, + &numEntries, &nameSize, &dataSize, NULL, NULL ); + } + if (numEntries==0) { + if (newKey) + CloseHandle(newKey); + if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonPath", + &newKey))==ERROR_SUCCESS) { + RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL, + &numEntries, &nameSize, &dataSize, NULL, NULL ); + } + } + if (bWin32s && numEntries==0 && dataSize==0) { /* must hardcode for Win32s */ + numEntries = 1; + dataSize = 511; + } + if (numEntries) { + dataBuf = malloc(dataSize); + // on NT, datasize is unicode - ie, 2xstrlen, + // even when ascii string returned. + // presumably will be 1xstrlen on 95/win3.1 + // Additionally, win32s doesnt work as expected, so + // the specific strlen() is required for 3.1. + rc = RegQueryValue(newKey, "", dataBuf, &dataSize); + if (rc==ERROR_SUCCESS) { + if (strlen(dataBuf)==0) + free(dataBuf); + else + retval = dataBuf; // caller will free + } + else + free(dataBuf); + } + + if (newKey) + CloseHandle(newKey); + return retval; +} +/* Return the initial python search path. This is called once from + initsys() to initialize sys.path. The environment variable + PYTHONPATH is fetched and the default path appended. The default + path may be passed to the preprocessor; if not, a system-dependent + default is used. */ + +char * +Py_GetPath() +{ + char *path = getenv("PYTHONPATH"); + char *defpath = PYTHONPATH; + static char *buf = NULL; + char *p; + int n; + + if (buf != NULL) { + free(buf); + buf = NULL; + } + + if (path == NULL) { + char *machinePath, *userPath; + int machineLen, userLen; + /* lookup the registry */ + BOOL bWin32s = PyWin_IsWin32s(); + + if (bWin32s) { /* are we running under Windows 3.1 Win32s */ + /* only CLASSES_ROOT is supported */ + machinePath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE); + userPath = NULL; + } else { + machinePath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE); + userPath = getpythonregpath(HKEY_CURRENT_USER, FALSE); + } + if (machinePath==NULL && userPath==NULL) return defpath; + machineLen = machinePath ? strlen(machinePath) : 0; + userLen = userPath ? strlen(userPath) : 0; + n = machineLen + userLen + 1; + // this is a memory leak, as Python never frees it. Only ever called once, so big deal! + buf = malloc(n); + if (buf == NULL) + Py_FatalError("not enough memory to copy module search path"); + p = buf; + *p = '\0'; + if (machineLen) { + strcpy(p, machinePath); + p += machineLen; + } + if (userLen) { + if (machineLen) + *p++ = DELIM; + strcpy(p, userPath); + } + if (userPath) free(userPath); + if (machinePath) free(machinePath); + } else { + + buf = malloc(strlen(path)+1); + if (buf == NULL) + Py_FatalError("not enough memory to copy module search path"); + strcpy(buf, path); + } + return buf; +} + +/* Similar for Makefile variables $prefix and $exec_prefix */ + +char * +Py_GetPrefix() +{ + return PREFIX; +} + +char * +Py_GetExecPrefix() +{ + return EXEC_PREFIX; +} |