mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 18:28:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			196 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
	
		
			4.9 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;
 | |
| 			if (reqdSize>1) { // If Nothing, or only '\0' copied.
 | |
| 				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)
 | |
| 		RegCloseKey(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;
 | |
| 	extern char *Py_GetProgramName();
 | |
| 
 | |
| 	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;
 | |
| }
 | 
