blob: d960d15ef536fda3f1f57cd0181fe2e35397317f [file] [log] [blame]
Guido van Rossum6dbd1901996-08-21 15:03:37 +00001#include "Python.h"
2#include "osdefs.h"
3#include <windows.h>
4
Guido van Rossum6dbd1901996-08-21 15:03:37 +00005/* 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/*
16This 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
29BOOL 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*/
47static char *
48getpythonregpath(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 Rossum3db41031996-08-23 18:42:39 +000057 if ((rc=RegOpenKey(keyBase, "Software\\Python\\PythonCore\\" MS_DLL_ID "\\PythonPath",
Guido van Rossum6dbd1901996-08-21 15:03:37 +000058 &newKey))==ERROR_SUCCESS) {
59 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
60 &numEntries, &nameSize, &dataSize, NULL, NULL );
61 }
Guido van Rossum6dbd1901996-08-21 15:03:37 +000062 if (bWin32s && numEntries==0 && dataSize==0) { /* must hardcode for Win32s */
63 numEntries = 1;
64 dataSize = 511;
65 }
66 if (numEntries) {
Guido van Rossumbc2e6311996-10-21 14:40:30 +000067 /* 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 Rossumd08735a1997-01-12 20:14:01 +000092 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 Rossumbc2e6311996-10-21 14:40:30 +0000100 }
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 Rossum6dbd1901996-08-21 15:03:37 +0000104 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 Rossumdb9353e1997-05-05 22:17:45 +0000115 RegCloseKey(newKey);
Guido van Rossum6dbd1901996-08-21 15:03:37 +0000116 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
124char *
125Py_GetPath()
126{
127 char *path = getenv("PYTHONPATH");
128 char *defpath = PYTHONPATH;
129 static char *buf = NULL;
130 char *p;
131 int n;
Guido van Rossumdb9353e1997-05-05 22:17:45 +0000132 extern char *Py_GetProgramName();
Guido van Rossum6dbd1901996-08-21 15:03:37 +0000133
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
186char *
187Py_GetPrefix()
188{
189 return PREFIX;
190}
191
192char *
193Py_GetExecPrefix()
194{
195 return EXEC_PREFIX;
196}
Guido van Rossumc2d14171997-05-22 20:45:28 +0000197
198char *
199Py_GetProgramFullPath()
200{
201 extern char *Py_GetProgramName();
202 return Py_GetProgramName();
203}