345
346
typedef struct PyMethodDef PyMethodDef;
348
// XXX - all of these are potentially fragile! We load and unload
349
// the Python DLL multiple times - so storing functions pointers
350
// is dangerous (although things *look* OK at present)
351
// Better might be to roll prepare_script_environment() into
352
// LoadPythonDll(), and create a new UnloadPythonDLL() which also
353
// clears the global pointers.
347
354
void *(*g_Py_BuildValue)(char *, ...);
348
355
int (*g_PyArg_ParseTuple)(PyObject *, char *, ...);
356
PyObject * (*g_PyLong_FromVoidPtr)(void *);
350
358
PyObject *g_PyExc_ValueError;
351
359
PyObject *g_PyExc_OSError;
648
658
DECLPROC(hPython, PyObject *, Py_BuildValue, (char *, ...));
649
659
DECLPROC(hPython, int, PyArg_ParseTuple, (PyObject *, char *, ...));
650
660
DECLPROC(hPython, PyObject *, PyErr_Format, (PyObject *, char *));
661
DECLPROC(hPython, PyObject *, PyLong_FromVoidPtr, (void *));
651
662
if (!PyImport_ImportModule || !PyObject_GetAttrString ||
652
663
!PyObject_SetAttrString || !PyCFunction_New)
778
790
hPython = LoadPythonDll(pythondll);
780
set_failure_reason("Can't load Python for pre-install script");
793
wsprintf(reason, "Can't load Python for pre-install script (%d)", GetLastError());
794
set_failure_reason(reason);
783
797
rc = do_run_simple_script(hPython, script);
2073
2087
PropertySheet(&psh);
2090
// subtly different from HasLocalMachinePrivs(), in that after executing
2091
// an 'elevated' process, we expect this to return TRUE - but there is no
2092
// such implication for HasLocalMachinePrivs
2093
BOOL MyIsUserAnAdmin()
2095
typedef BOOL (WINAPI *PFNIsUserAnAdmin)();
2096
static PFNIsUserAnAdmin pfnIsUserAnAdmin = NULL;
2098
// This function isn't guaranteed to be available (and it can't hurt
2099
// to leave the library loaded)
2100
if (0 == (shell32=LoadLibrary("shell32.dll")))
2102
if (0 == (pfnIsUserAnAdmin=(PFNIsUserAnAdmin)GetProcAddress(shell32, "IsUserAnAdmin")))
2104
return (*pfnIsUserAnAdmin)();
2107
// Some magic for Vista's UAC. If there is a target_version, and
2108
// if that target version is installed in the registry under
2109
// HKLM, and we are not current administrator, then
2110
// re-execute ourselves requesting elevation.
2111
// Split into 2 functions - "should we elevate" and "spawn elevated"
2113
// Returns TRUE if we should spawn an elevated child
2118
OSVERSIONINFO winverinfo;
2119
winverinfo.dwOSVersionInfoSize = sizeof(winverinfo);
2120
// If less than XP, then we can't do it (and its not necessary).
2121
if (!GetVersionEx(&winverinfo) || winverinfo.dwMajorVersion < 5)
2123
// no Python version info == we can't know yet.
2124
if (target_version[0] == '\0')
2126
// see how python is current installed
2128
"Software\\Python\\PythonCore\\%s\\InstallPath",
2130
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
2131
key_name, 0, KEY_READ, &hk))
2134
// Python is installed in HKLM - we must elevate.
2138
// Spawn ourself as an elevated application. On failure, a message is
2139
// displayed to the user - but this app will always terminate, even
2143
// interesting failure scenario that has been seen: initial executable
2144
// runs from a network drive - but once elevated, that network share
2145
// isn't seen, and ShellExecute fails with SE_ERR_ACCESSDENIED.
2146
int ret = (int)ShellExecute(0, "runas", modulename, "", NULL,
2150
wsprintf(msg, "Failed to start elevated process (ShellExecute returned %d)", ret);
2151
MessageBox(0, msg, "Setup", MB_OK | MB_ICONERROR);
2076
2155
int DoInstall(void)
2078
2157
char ini_buffer[4096];
2106
2185
install_script, sizeof(install_script),
2188
GetPrivateProfileString("Setup", "user_access_control", "",
2189
user_access_control, sizeof(user_access_control), ini_file);
2191
// See if we need to do the Vista UAC magic.
2192
if (strcmp(user_access_control, "force")==0) {
2193
if (!MyIsUserAnAdmin()) {
2197
// already admin - keep going
2198
} else if (strcmp(user_access_control, "auto")==0) {
2199
// Check if it looks like we need UAC control, based
2200
// on how Python itself was installed.
2201
if (!MyIsUserAnAdmin() && NeedAutoUAC()) {
2206
// display a warning about unknown values - only the developer
2207
// of the extension will see it (until they fix it!)
2208
if (user_access_control[0] && strcmp(user_access_control, "none") != 0) {
2209
MessageBox(GetFocus(), "Bad user_access_control value", "oops", MB_OK);
2110
2214
hwndMain = CreateBackground(title);