mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			174 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			174 lines
		
	
	
	
		
			4.3 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 (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;
 | 
						|
}
 |