mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-10-21 08:51:27 +00:00
python-3.6.zip added from Github
README.cosmo contains the necessary links.
This commit is contained in:
parent
75fc601ff5
commit
0c4c56ff39
4219 changed files with 1968626 additions and 0 deletions
259
third_party/python/PC/_findvs.cpp
vendored
Normal file
259
third_party/python/PC/_findvs.cpp
vendored
Normal file
|
@ -0,0 +1,259 @@
|
|||
//
|
||||
// Helper library for location Visual Studio installations
|
||||
// using the COM-based query API.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// Licensed to PSF under a contributor agreement
|
||||
//
|
||||
|
||||
// Version history
|
||||
// 2017-05: Initial contribution (Steve Dower)
|
||||
|
||||
#include <Windows.h>
|
||||
#include <Strsafe.h>
|
||||
#include "external\include\Setup.Configuration.h"
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
static PyObject *error_from_hr(HRESULT hr)
|
||||
{
|
||||
if (FAILED(hr))
|
||||
PyErr_Format(PyExc_OSError, "Error %08x", hr);
|
||||
assert(PyErr_Occurred());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static PyObject *get_install_name(ISetupInstance2 *inst)
|
||||
{
|
||||
HRESULT hr;
|
||||
BSTR name;
|
||||
PyObject *str = nullptr;
|
||||
if (FAILED(hr = inst->GetDisplayName(LOCALE_USER_DEFAULT, &name)))
|
||||
goto error;
|
||||
str = PyUnicode_FromWideChar(name, SysStringLen(name));
|
||||
SysFreeString(name);
|
||||
return str;
|
||||
error:
|
||||
|
||||
return error_from_hr(hr);
|
||||
}
|
||||
|
||||
static PyObject *get_install_version(ISetupInstance *inst)
|
||||
{
|
||||
HRESULT hr;
|
||||
BSTR ver;
|
||||
PyObject *str = nullptr;
|
||||
if (FAILED(hr = inst->GetInstallationVersion(&ver)))
|
||||
goto error;
|
||||
str = PyUnicode_FromWideChar(ver, SysStringLen(ver));
|
||||
SysFreeString(ver);
|
||||
return str;
|
||||
error:
|
||||
|
||||
return error_from_hr(hr);
|
||||
}
|
||||
|
||||
static PyObject *get_install_path(ISetupInstance *inst)
|
||||
{
|
||||
HRESULT hr;
|
||||
BSTR path;
|
||||
PyObject *str = nullptr;
|
||||
if (FAILED(hr = inst->GetInstallationPath(&path)))
|
||||
goto error;
|
||||
str = PyUnicode_FromWideChar(path, SysStringLen(path));
|
||||
SysFreeString(path);
|
||||
return str;
|
||||
error:
|
||||
|
||||
return error_from_hr(hr);
|
||||
}
|
||||
|
||||
static PyObject *get_installed_packages(ISetupInstance2 *inst)
|
||||
{
|
||||
HRESULT hr;
|
||||
PyObject *res = nullptr;
|
||||
LPSAFEARRAY sa_packages = nullptr;
|
||||
LONG ub = 0;
|
||||
IUnknown **packages = nullptr;
|
||||
PyObject *str = nullptr;
|
||||
|
||||
if (FAILED(hr = inst->GetPackages(&sa_packages)) ||
|
||||
FAILED(hr = SafeArrayAccessData(sa_packages, (void**)&packages)) ||
|
||||
FAILED(SafeArrayGetUBound(sa_packages, 1, &ub)) ||
|
||||
!(res = PyList_New(0)))
|
||||
goto error;
|
||||
|
||||
for (LONG i = 0; i < ub; ++i) {
|
||||
ISetupPackageReference *package = nullptr;
|
||||
BSTR id = nullptr;
|
||||
PyObject *str = nullptr;
|
||||
|
||||
if (FAILED(hr = packages[i]->QueryInterface(&package)) ||
|
||||
FAILED(hr = package->GetId(&id)))
|
||||
goto iter_error;
|
||||
|
||||
str = PyUnicode_FromWideChar(id, SysStringLen(id));
|
||||
SysFreeString(id);
|
||||
|
||||
if (!str || PyList_Append(res, str) < 0)
|
||||
goto iter_error;
|
||||
|
||||
Py_CLEAR(str);
|
||||
package->Release();
|
||||
continue;
|
||||
|
||||
iter_error:
|
||||
if (package) package->Release();
|
||||
Py_XDECREF(str);
|
||||
|
||||
goto error;
|
||||
}
|
||||
|
||||
SafeArrayUnaccessData(sa_packages);
|
||||
SafeArrayDestroy(sa_packages);
|
||||
|
||||
return res;
|
||||
error:
|
||||
if (sa_packages && packages) SafeArrayUnaccessData(sa_packages);
|
||||
if (sa_packages) SafeArrayDestroy(sa_packages);
|
||||
Py_XDECREF(res);
|
||||
|
||||
return error_from_hr(hr);
|
||||
}
|
||||
|
||||
static PyObject *find_all_instances()
|
||||
{
|
||||
ISetupConfiguration *sc = nullptr;
|
||||
ISetupConfiguration2 *sc2 = nullptr;
|
||||
IEnumSetupInstances *enm = nullptr;
|
||||
ISetupInstance *inst = nullptr;
|
||||
ISetupInstance2 *inst2 = nullptr;
|
||||
PyObject *res = nullptr;
|
||||
ULONG fetched;
|
||||
HRESULT hr;
|
||||
|
||||
if (!(res = PyList_New(0)))
|
||||
goto error;
|
||||
|
||||
if (FAILED(hr = CoCreateInstance(
|
||||
__uuidof(SetupConfiguration),
|
||||
NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(ISetupConfiguration),
|
||||
(LPVOID*)&sc
|
||||
)) && hr != REGDB_E_CLASSNOTREG)
|
||||
goto error;
|
||||
|
||||
// If the class is not registered, there are no VS instances installed
|
||||
if (hr == REGDB_E_CLASSNOTREG)
|
||||
return res;
|
||||
|
||||
if (FAILED(hr = sc->QueryInterface(&sc2)) ||
|
||||
FAILED(hr = sc2->EnumAllInstances(&enm)))
|
||||
goto error;
|
||||
|
||||
while (SUCCEEDED(enm->Next(1, &inst, &fetched)) && fetched) {
|
||||
PyObject *name = nullptr;
|
||||
PyObject *version = nullptr;
|
||||
PyObject *path = nullptr;
|
||||
PyObject *packages = nullptr;
|
||||
PyObject *tuple = nullptr;
|
||||
|
||||
if (FAILED(hr = inst->QueryInterface(&inst2)) ||
|
||||
!(name = get_install_name(inst2)) ||
|
||||
!(version = get_install_version(inst)) ||
|
||||
!(path = get_install_path(inst)) ||
|
||||
!(packages = get_installed_packages(inst2)) ||
|
||||
!(tuple = PyTuple_Pack(4, name, version, path, packages)) ||
|
||||
PyList_Append(res, tuple) < 0)
|
||||
goto iter_error;
|
||||
|
||||
Py_DECREF(tuple);
|
||||
Py_DECREF(packages);
|
||||
Py_DECREF(path);
|
||||
Py_DECREF(version);
|
||||
Py_DECREF(name);
|
||||
continue;
|
||||
iter_error:
|
||||
if (inst2) inst2->Release();
|
||||
Py_XDECREF(tuple);
|
||||
Py_XDECREF(packages);
|
||||
Py_XDECREF(path);
|
||||
Py_XDECREF(version);
|
||||
Py_XDECREF(name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
enm->Release();
|
||||
sc2->Release();
|
||||
sc->Release();
|
||||
return res;
|
||||
|
||||
error:
|
||||
if (enm) enm->Release();
|
||||
if (sc2) sc2->Release();
|
||||
if (sc) sc->Release();
|
||||
Py_XDECREF(res);
|
||||
|
||||
return error_from_hr(hr);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(findvs_findall_doc, "findall()\
|
||||
\
|
||||
Finds all installed versions of Visual Studio.\
|
||||
\
|
||||
This function will initialize COM temporarily. To avoid impact on other parts\
|
||||
of your application, use a new thread to make this call.");
|
||||
|
||||
static PyObject *findvs_findall(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
|
||||
if (hr == RPC_E_CHANGED_MODE)
|
||||
hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
if (FAILED(hr))
|
||||
return error_from_hr(hr);
|
||||
PyObject *res = find_all_instances();
|
||||
CoUninitialize();
|
||||
return res;
|
||||
}
|
||||
|
||||
// List of functions to add to findvs in exec_findvs().
|
||||
static PyMethodDef findvs_functions[] = {
|
||||
{ "findall", (PyCFunction)findvs_findall, METH_VARARGS | METH_KEYWORDS, findvs_findall_doc },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
// Initialize findvs. May be called multiple times, so avoid
|
||||
// using static state.
|
||||
static int exec_findvs(PyObject *module)
|
||||
{
|
||||
PyModule_AddFunctions(module, findvs_functions);
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(findvs_doc, "The _distutils_findvs helper module");
|
||||
|
||||
static PyModuleDef_Slot findvs_slots[] = {
|
||||
{ Py_mod_exec, exec_findvs },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static PyModuleDef findvs_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_distutils_findvs",
|
||||
findvs_doc,
|
||||
0, // m_size
|
||||
NULL, // m_methods
|
||||
findvs_slots,
|
||||
NULL, // m_traverse
|
||||
NULL, // m_clear
|
||||
NULL, // m_free
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
PyMODINIT_FUNC PyInit__distutils_findvs(void)
|
||||
{
|
||||
return PyModuleDef_Init(&findvs_def);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue