mirror of https://github.com/python/cpython
194 lines
4.8 KiB
C
194 lines
4.8 KiB
C
#include "Python.h"
|
|
#include "osdefs.h"
|
|
#include <windows.h>
|
|
|
|
/* 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\\" MS_DLL_ID "\\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) {
|
|
/* Loop over all subkeys. */
|
|
/* Win32s doesnt know how many subkeys, so we do
|
|
it twice */
|
|
char keyBuf[MAX_PATH+1];
|
|
int index = 0;
|
|
int off = 0;
|
|
for(index=0;;index++) {
|
|
long reqdSize = 0;
|
|
DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1);
|
|
if (rc) break;
|
|
rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
|
|
if (rc) break;
|
|
if (bWin32s && reqdSize==0) reqdSize = 512;
|
|
dataSize += reqdSize + 1; /* 1 for the ";" */
|
|
}
|
|
dataBuf = malloc(dataSize+1);
|
|
if (dataBuf==NULL) return NULL; /* pretty serious? Raise error? */
|
|
/* Now loop over, grabbing the paths. Subkeys before main library */
|
|
for(index=0;;index++) {
|
|
int adjust;
|
|
long reqdSize = dataSize;
|
|
DWORD rc = RegEnumKey(newKey, index, keyBuf,MAX_PATH+1);
|
|
if (rc) break;
|
|
rc = RegQueryValue(newKey, keyBuf, dataBuf+off, &reqdSize);
|
|
if (rc) break;
|
|
adjust = strlen(dataBuf+off);
|
|
dataSize -= adjust;
|
|
off += adjust;
|
|
dataBuf[off++] = ';';
|
|
dataBuf[off] = '\0';
|
|
dataSize--;
|
|
}
|
|
/* Additionally, win32s doesnt work as expected, so
|
|
the specific strlen() is required for 3.1. */
|
|
rc = RegQueryValue(newKey, "", dataBuf+off, &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;
|
|
}
|