diff --git a/bypy/init_env.py b/bypy/init_env.py index 94e7256b6f..193d7bd87e 100644 --- a/bypy/init_env.py +++ b/bypy/init_env.py @@ -28,6 +28,7 @@ dlls = [ # 'WebSockets', # 'WebView', 'Positioning', + 'PositioningQuick', 'Sensors', 'Sql', 'Svg', @@ -178,10 +179,11 @@ def build_c_extensions(ext_dir): def run_tests(path_to_calibre_debug, cwd_on_failure): - if run(path_to_calibre_debug, '--test-build') != 0: + ret = run(path_to_calibre_debug, '--test-build') + if ret != 0: os.chdir(cwd_on_failure) print( - 'running calibre build tests failed with:', path_to_calibre_debug, file=sys.stderr) + 'running calibre build tests failed with return code:', ret, 'and exe:', path_to_calibre_debug, file=sys.stderr) run_shell() raise SystemExit('running calibre build tests failed') diff --git a/bypy/windows/__main__.py b/bypy/windows/__main__.py index 7efce10977..766230ca5d 100644 --- a/bypy/windows/__main__.py +++ b/bypy/windows/__main__.py @@ -103,7 +103,7 @@ class Env(object): self.py_ver = '.'.join(map(str, python_major_minor_version())) self.lib_dir = j(self.app_base, 'Lib') self.pylib = j(self.app_base, 'pylib.zip') - self.dll_dir = j(self.app_base, 'DLLs') + self.dll_dir = j(self.app_base, 'bin') self.portable_base = j(d(self.base), 'Calibre Portable') self.obj_dir = j(build_dir, 'launcher') self.installer_dir = j(build_dir, 'wix') @@ -165,10 +165,11 @@ def freeze(env, ext_dir): printf('Adding Qt...') for x in QT_DLLS: copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) + copybin(os.path.join(QT_PREFIX, 'bin', 'QtWebEngineProcess.exe')) for x in 'libGLESv2 libEGL'.split(): copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll')) plugdir = j(QT_PREFIX, 'plugins') - tdir = j(env.app_base, 'qt_plugins') + tdir = j(env.app_base, 'plugins') for d in QT_PLUGINS: imfd = os.path.join(plugdir, d) tg = os.path.join(tdir, d) @@ -178,6 +179,9 @@ def freeze(env, ext_dir): for f in walk(tdir): if not f.lower().endswith('.dll'): os.remove(f) + for data_file in os.listdir(j(QT_PREFIX, 'resources')): + shutil.copy2(j(QT_PREFIX, 'resources', data_file), j(env.app_base, 'resources')) + shutil.copytree(j(QT_PREFIX, 'translations'), j(env.app_base, 'translations')) printf('Adding python...') @@ -205,6 +209,12 @@ def freeze(env, ext_dir): for x in {x for x in os.listdir(pyqt) if x.endswith('.pyd')}: if x.partition('.')[0] not in PYQT_MODULES and x != 'sip.pyd': os.remove(j(pyqt, x)) + with open(j(pyqt, '__init__.py') , 'r+b') as f: + raw = f.read() + nraw = raw.replace(b'def find_qt():', b'def find_qt():\n return # disabled for calibre') + if nraw == raw: + raise Exception('Failed to patch PyQt to disable dll directory manipulation') + f.seek(0), f.truncate(), f.write(nraw) printf('Adding calibre sources...') for x in glob.glob(j(CALIBRE_DIR, 'src', '*')): @@ -636,8 +646,8 @@ def archive_lib_dir(env): shutil.rmtree(env.lib_dir) -def copy_crt(env): - printf('Copying CRT...') +def copy_crt_and_d3d(env): + printf('Copying CRT and D3D...') plat = ('x64' if is64bit else 'x86') for key, val in worker_env.items(): if 'COMNTOOLS' in key.upper(): @@ -653,17 +663,27 @@ def copy_crt(env): 'ucrt', 'DLLs', plat) if not os.path.exists(sdk_path): raise SystemExit('Windows 10 Universal CRT redistributable not found at: %r' % sdk_path) - for dll in glob.glob(os.path.join(sdk_path, '*.dll')): + d3d_path = os.path.join( + worker_env['WINDOWSSDKDIR'], 'Redist', 'D3D', plat) + if not os.path.exists(d3d_path): + raise SystemExit('Windows 10 D3D redistributable not found at: %r' % d3d_path) + + def copy_dll(dll): shutil.copy2(dll, env.dll_dir) os.chmod(os.path.join(env.dll_dir, b(dll)), stat.S_IRWXU) + + for dll in glob.glob(os.path.join(d3d_path, '*.dll')): + if os.path.basename(dll).lower().startswith('d3dcompiler_'): + copy_dll(dll) + for dll in glob.glob(os.path.join(sdk_path, '*.dll')): + copy_dll(dll) for dll in glob.glob(os.path.join(vc_path, '*.dll')): bname = os.path.basename(dll) if not bname.startswith('vccorlib') and not bname.startswith('concrt'): # Those two DLLs are not required vccorlib is for the CORE CLR # I think concrt is the concurrency runtime for C++ which I believe # nothing in calibre currently uses - shutil.copy(dll, env.dll_dir) - os.chmod(os.path.join(env.dll_dir, bname), stat.S_IRWXU) + copy_dll(dll) def sign_executables(env): @@ -685,7 +705,7 @@ def main(): build_utils(env) freeze(env, ext_dir) embed_manifests(env) - copy_crt(env) + copy_crt_and_d3d(env) archive_lib_dir(env) if not args.skip_tests: run_tests(os.path.join(env.base, 'calibre-debug.exe'), env.base) diff --git a/bypy/windows/main.c b/bypy/windows/main.c index 6a70d5cd1e..6bc83285cd 100644 --- a/bypy/windows/main.c +++ b/bypy/windows/main.c @@ -53,18 +53,22 @@ static int show_last_error(wchar_t *preamble) { } typedef int (__cdecl *ENTRYPROC)(const char*, const char*, const char*, int); +typedef void (__cdecl *SIMPLEPRINT)(const wchar_t*); +typedef BOOL (*SETDEFAULTDIRS)(DWORD); +static ENTRYPROC entrypoint = NULL; +static SIMPLEPRINT simple_print = NULL; +static HMODULE dll = 0; -static ENTRYPROC load_launcher_dll() { - wchar_t buf[MAX_PATH]; // Cannot use a zero initializer for the array as it generates an implicit call to memset() +static void +load_launcher_dll() { + static wchar_t buf[MAX_PATH]; // Cannot use a zero initializer for the array as it generates an implicit call to memset() wchar_t *dll_point = NULL; int i = 0; DWORD sz = 0; - HMODULE dll = 0; - ENTRYPROC entrypoint = NULL; if ((sz = GetModuleFileNameW(NULL, buf, MAX_PATH)) >= MAX_PATH - 30) { show_error(L"Installation directory path too long", L"", 1); - return NULL; + return; } while (sz > 0) { @@ -73,33 +77,36 @@ static ENTRYPROC load_launcher_dll() { } if (dll_point == NULL) { show_error(L"Executable path has no path separators", L"", 1); - return NULL; + return; } - wsprintf(dll_point, L"%s\0\0", L"app\\DLLs"); + wsprintf(dll_point, L"%s\0\0", L"app\\bin"); + // Restrict the directories from which DLLs can be loaded + SETDEFAULTDIRS SetDefaultDllDirectories = (SETDEFAULTDIRS)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories"); + if (SetDefaultDllDirectories) SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); if (SetDllDirectoryW(buf) == 0) { show_last_error(L"Failed to set DLL directory"); - return NULL; + return; } // Have to load ucrtbase manually first, otherwise loading fails on systems where the // Universal CRT is not installed. if (!LoadLibraryW(L"ucrtbase.dll")) { show_last_error(L"Unable to find ucrtbase.dll. You should install all Windows updates on your computer to get this file."); - return NULL; + return; } if (!(dll = LoadLibraryW(L"calibre-launcher.dll"))) { show_last_error(L"Failed to load: calibre-launcher.dll"); - return NULL; + return; } if (!(entrypoint = (ENTRYPROC) GetProcAddress(dll, "execute_python_entrypoint"))) { show_last_error(L"Failed to get the calibre-launcher dll entry point"); - return NULL; + return; } - return entrypoint; + simple_print = (SIMPLEPRINT) GetProcAddress(dll, "simple_print"); } int __stdcall start_here() { int ret = 0; - ENTRYPROC entrypoint = load_launcher_dll(); + load_launcher_dll(); if (entrypoint) { #ifdef GUI_APP // This should really be returning the value set in the WM_QUIT message, but I cannot be bothered figuring out how to get that. @@ -108,6 +115,10 @@ int __stdcall start_here() { ret = entrypoint(BASENAME, MODULE, FUNCTION, 0); #endif } else ret = 1; + if (dll != 0) { + FreeLibrary(dll); + dll = 0; + } ExitProcess(ret); return ret; } diff --git a/bypy/windows/site.py b/bypy/windows/site.py index 0842489aeb..6217c4f026 100644 --- a/bypy/windows/site.py +++ b/bypy/windows/site.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai -__license__ = 'GPL v3' +__license__ = 'GPL v3' __copyright__ = '2009, Kovid Goyal ' __docformat__ = 'restructuredtext en' @@ -9,6 +9,7 @@ import sys import os import imp + class PydImporter(object): __slots__ = ('items', 'description') @@ -19,7 +20,7 @@ class PydImporter(object): def find_module(self, fullname, path=None): if self.items is None: - dlls_dir = os.path.join(sys.app_dir, 'app', 'DLLs') + dlls_dir = os.path.join(sys.app_dir, 'app', 'bin') items = self.items = {} for x in os.listdir(dlls_dir): lx = x.lower() @@ -34,27 +35,34 @@ class PydImporter(object): try: path = self.items[fullname.lower()] except KeyError: - raise ImportError('The native code module %s seems to have disappeared from self.items' % fullname) + raise ImportError( + 'The native code module %s seems to have disappeared from self.items' + % fullname + ) package, name = fullname.rpartition(b'.')[::2] - m = imp.load_module(fullname, None, path, self.description) # This inserts the module into sys.modules itself + m = imp.load_module( + fullname, None, path, self.description + ) # This inserts the module into sys.modules itself m.__loader__ = self m.__package__ = package or None return m + def abs__file__(): """Set all module __file__ attribute to an absolute path""" for m in sys.modules.values(): if hasattr(m, '__loader__'): - continue # don't mess with a PEP 302-supplied __file__ + continue # don't mess with a PEP 302-supplied __file__ try: m.__file__ = os.path.abspath(m.__file__) except AttributeError: continue + def aliasmbcs(): import locale, codecs enc = locale.getdefaultlocale()[1] - if enc.startswith('cp'): # "cp***" ? + if enc.startswith('cp'): # "cp***" ? try: codecs.lookup(enc) except LookupError: @@ -62,21 +70,24 @@ def aliasmbcs(): encodings._cache[enc] = encodings._unknown encodings.aliases.aliases[enc] = 'mbcs' + def add_calibre_vars(): sys.new_app_layout = 1 sys.resources_location = os.path.join(sys.app_dir, 'app', 'resources') - sys.extensions_location = os.path.join(sys.app_dir, 'app', 'DLLs') + sys.extensions_location = os.path.join(sys.app_dir, 'app', 'bin') dv = os.environ.get('CALIBRE_DEVELOP_FROM', None) if dv and os.path.exists(dv): sys.path.insert(0, os.path.abspath(dv)) + def run_entry_point(): bname, mod, func = sys.calibre_basename, sys.calibre_module, sys.calibre_function - sys.argv[0] = bname+'.exe' + sys.argv[0] = bname + '.exe' pmod = __import__(mod, fromlist=[1], level=0) return getattr(pmod, func)() + def main(): sys.frozen = 'windows_exe' sys.setdefaultencoding('utf-8') @@ -86,8 +97,10 @@ def main(): sys.path_importer_cache.clear() import linecache + def fake_getline(filename, lineno, module_globals=None): return '' + linecache.orig_getline = linecache.getline linecache.getline = fake_getline @@ -95,7 +108,7 @@ def main(): add_calibre_vars() - # Needed for pywintypes to be able to load its DLL - sys.path.append(os.path.join(sys.app_dir, 'app', 'DLLs')) + # Needed to bypass meaningless check in pywintypes.py + sys.path.append(os.path.join(sys.app_dir, 'app', 'bin')) return run_entry_point() diff --git a/bypy/windows/util.c b/bypy/windows/util.c index 4379e1696c..57021f57f3 100644 --- a/bypy/windows/util.c +++ b/bypy/windows/util.c @@ -16,6 +16,7 @@ #include #include +#define arraysz(x) (sizeof((x))/sizeof((x)[0])) static int GUI_APP = 0; static char python_dll[] = PYDLL; @@ -25,29 +26,16 @@ void set_gui_app(int yes) { GUI_APP = yes; } int calibre_show_python_error(const wchar_t *preamble, int code); static int _show_error(const wchar_t *preamble, const wchar_t *msg, const int code) { - wchar_t *buf; - char *cbuf; - buf = (wchar_t*)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)* - (wcslen(msg) + wcslen(preamble) + 80)); + static wchar_t buf[4096]; - _snwprintf_s(buf, - LocalSize(buf) / sizeof(wchar_t), _TRUNCATE, - L"%s\r\n %s (Error Code: %d)\r\n", - preamble, msg, code); + fwprintf(stderr, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code); + fflush(stderr); if (GUI_APP) { + _snwprintf_s(buf, arraysz(buf), _TRUNCATE, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code); MessageBeep(MB_ICONERROR); MessageBox(NULL, buf, NULL, MB_OK|MB_ICONERROR); } - else { - cbuf = (char*) calloc(10+(wcslen(buf)*4), sizeof(char)); - if (cbuf) { - if (WideCharToMultiByte(CP_UTF8, 0, buf, -1, cbuf, (int)(10+(wcslen(buf)*4)), NULL, NULL) != 0) printf_s(cbuf); - free(cbuf); - } - } - - LocalFree(buf); return code; } @@ -83,72 +71,72 @@ int show_last_error(wchar_t *preamble) { return ret; } -char* get_app_dir() { - char *buf, *buf2, *buf3; +static char app_dir[MAX_PATH] = {0}; +static wchar_t dll_dir[MAX_PATH] = {0}; +static wchar_t qt_prefix_dir[MAX_PATH] = {0}; +static char program_name[MAX_PATH] = {0}; +static wchar_t w_program_name[MAX_PATH] = {0}; +static wchar_t w_app_dir[MAX_PATH] = {0}; +#if PY_VERSION_MAJOR >= 3 +static wchar_t python_path[MAX_PATH] = {0}; +#else +static char python_path[MAX_PATH] = {0}; +#endif + +static void +get_app_dir(void) { char drive[4] = "\0\0\0"; DWORD sz; errno_t err; + char buf[MAX_PATH] = {0}; - buf = (char*)calloc(MAX_PATH, sizeof(char)); - buf2 = (char*)calloc(MAX_PATH, sizeof(char)); - buf3 = (char*)calloc(MAX_PATH, sizeof(char)); - if (!buf || !buf2 || !buf3) ExitProcess(_show_error(L"Out of memory", L"", 1)); - sz = GetModuleFileNameA(NULL, buf, MAX_PATH); + sz = GetModuleFileNameA(NULL, program_name, MAX_PATH); if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1)); - err = _splitpath_s(buf, drive, 4, buf2, MAX_PATH, NULL, 0, NULL, 0); + err = _splitpath_s(program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0); if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory")); - _snprintf_s(buf3, MAX_PATH, _TRUNCATE, "%s%s", drive, buf2); - free(buf); free(buf2); - return buf3; + _snprintf_s(app_dir, MAX_PATH, _TRUNCATE, "%s%s", drive, buf); } -wchar_t* get_app_dirw() { - wchar_t *buf, *buf2, *buf3; +static void +get_app_dirw(void) { + wchar_t buf[MAX_PATH] = {0}; wchar_t drive[4] = L"\0\0\0"; DWORD sz; errno_t err; - buf = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t)); - buf2 = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t)); - buf3 = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t)); - if (!buf || !buf2 || !buf3) ExitProcess(_show_error(L"Out of memory", L"", 1)); - sz = GetModuleFileNameW(NULL, buf, MAX_PATH); + sz = GetModuleFileNameW(NULL, w_program_name, MAX_PATH); if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1)); - err = _wsplitpath_s(buf, drive, 4, buf2, MAX_PATH, NULL, 0, NULL, 0); + err = _wsplitpath_s(w_program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0); if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory")); - _snwprintf_s(buf3, MAX_PATH, _TRUNCATE, L"%s%s", drive, buf2); - free(buf); free(buf2); - return buf3; + _snwprintf_s(w_app_dir, MAX_PATH, _TRUNCATE, L"%s%s", drive, buf); } +static void +get_install_locations(void) { + get_app_dir(); + get_app_dirw(); + _snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%s\\app", w_app_dir); + _wputenv_s(L"CALIBRE_QT_PREFIX", qt_prefix_dir); + _snwprintf_s(dll_dir, MAX_PATH-1, _TRUNCATE, L"%s\\app\\bin", w_app_dir); +#if PY_VERSION_MAJOR >= 3 + _snwprintf_s(python_path, MAX_PATH-1, _TRUNCATE, L"%s\\app\\pylib.zip", w_app_dir); +#else + _snprintf_s(python_path, MAX_PATH-1, _TRUNCATE, "%s\\app\\pylib.zip", app_dir); +#endif -void load_python_dll() { - char *app_dir, *dll_dir, *qt_plugin_dir; - size_t l; +} - app_dir = get_app_dir(); - l = strlen(app_dir)+25; - dll_dir = (char*) calloc(l, sizeof(char)); - qt_plugin_dir = (char*) calloc(l, sizeof(char)); - if (!dll_dir || !qt_plugin_dir) ExitProcess(_show_error(L"Out of memory", L"", 1)); - _snprintf_s(dll_dir, l, _TRUNCATE, "%s\\app\\DLLs", app_dir); - _snprintf_s(qt_plugin_dir, l, _TRUNCATE, "%s\\app\\qt_plugins", app_dir); - free(app_dir); - - _putenv_s("QT_PLUGIN_PATH", qt_plugin_dir); - - if (!SetDllDirectoryA(dll_dir)) ExitProcess(show_last_error(L"Failed to set DLL directory.")); +static void +load_python_dll() { + get_install_locations(); if (FAILED(__HrLoadAllImportsForDll(python_dll))) ExitProcess(_show_error(L"Failed to delay load the python dll", L"", 1)); } -static char program_name[MAX_PATH]; -static char python_home[MAX_PATH]; +const static wchar_t out_of_memory[] = L"Out of memory"; -static wchar_t out_of_memory[] = L"Out of memory"; - -void setup_stream(const char *name, const char *errors, UINT cp) { +static void +setup_stream(const char *name, const char *errors, UINT cp) { PyObject *stream; - char *buf = (char *)calloc(100, sizeof(char)); - if (!buf) ExitProcess(_show_error(out_of_memory, L"", 1)); + char buf[128] = {0}; if (cp == CP_UTF8) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-8"); else if (cp == CP_UTF7) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-7"); @@ -158,9 +146,6 @@ void setup_stream(const char *name, const char *errors, UINT cp) { if (!PyFile_SetEncodingAndErrors(stream, buf, (char*)errors)) ExitProcess(calibre_show_python_error(L"Failed to set stream encoding", 1)); - - free(buf); - } UINT @@ -187,30 +172,12 @@ setup_streams() { UINT initialize_interpreter(const char *basename, const char *module, const char *function) { - DWORD sz; char *buf, *path; HMODULE dll; + DWORD sz; HMODULE dll; int *flag, i, argc; - wchar_t *app_dir, **wargv; + wchar_t **wargv; PyObject *argv, *v; char *dummy_argv[1] = {""}; - buf = (char*)calloc(MAX_PATH, sizeof(char)); - path = (char*)calloc(MAX_PATH, sizeof(char)); - if (!buf || !path) ExitProcess(_show_error(L"Out of memory", L"", 1)); - - sz = GetModuleFileNameA(NULL, buf, MAX_PATH); - if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1)); - - _snprintf_s(program_name, MAX_PATH, _TRUNCATE, "%s", buf); - free(buf); - - buf = get_app_dir(); - buf[strlen(buf)-1] = '\0'; - - _snprintf_s(python_home, MAX_PATH, _TRUNCATE, "%s", buf); - _snprintf_s(path, MAX_PATH, _TRUNCATE, "%s\\app\\pylib.zip", buf); - free(buf); - - dll = GetModuleHandleA(python_dll); if (!dll) ExitProcess(show_last_error(L"Failed to get python dll handle")); flag = (int*)GetProcAddress(dll, "Py_OptimizeFlag"); @@ -238,8 +205,13 @@ initialize_interpreter(const char *basename, const char *module, const char *fun if (!flag) ExitProcess(_show_error(L"Failed to get debug flag", L"", 1)); //*flag = 1; +#if PY_VERSION_MAJOR >= 3 + Py_SetProgramName(w_program_name); + Py_SetPythonHome(w_app_dir); +#else Py_SetProgramName(program_name); - Py_SetPythonHome(python_home); + Py_SetPythonHome(app_dir); +#endif //printf("Path before Py_Initialize(): %s\r\n\n", Py_GetPath()); Py_Initialize(); @@ -247,11 +219,10 @@ initialize_interpreter(const char *basename, const char *module, const char *fun PySys_SetArgv(1, dummy_argv); //printf("Path after Py_Initialize(): %s\r\n\n", Py_GetPath()); - PySys_SetPath(path); + PySys_SetPath(python_path); //printf("Path set by me: %s\r\n\n", path); PySys_SetObject("gui_app", PyBool_FromLong((long)GUI_APP)); - app_dir = get_app_dirw(); - PySys_SetObject("app_dir", PyUnicode_FromWideChar(app_dir, wcslen(app_dir))); + PySys_SetObject("app_dir", PyUnicode_FromWideChar(w_app_dir, wcslen(w_app_dir))); PySys_SetObject("calibre_basename", PyBytes_FromString(basename)); PySys_SetObject("calibre_module", PyBytes_FromString(module)); @@ -271,22 +242,21 @@ initialize_interpreter(const char *basename, const char *module, const char *fun } -wchar_t* pyobject_to_wchar(PyObject *o) { - PyUnicodeObject *t; +static const wchar_t* +pyobject_to_wchar(PyObject *o) { + PyObject *t = NULL; size_t s; - wchar_t *ans; + static wchar_t ans[4096]; if (!PyUnicode_Check(o)) { - t = (PyUnicodeObject*)PyUnicode_FromEncodedObject(o, NULL, "replace"); + t = PyUnicode_FromEncodedObject(o, NULL, "replace"); if (t == NULL) return NULL; - } else t = (PyUnicodeObject*)o; + } - - s = 2*PyUnicode_GET_SIZE(t) +1; - ans = (wchar_t*)calloc(s, sizeof(wchar_t)); - if (ans == NULL) return NULL; - s = PyUnicode_AsWideChar(t, ans, s-1); - ans[s] = L'\0'; + s = PyUnicode_AsWideChar(t ? t : o, ans, arraysz(ans)-1); + Py_XDECREF(t); + if (s >= 0) ans[s] = 0; + else ans[s] = 0; return ans; } @@ -315,7 +285,7 @@ int handle_sysexit(PyObject *e) { int calibre_show_python_error(const wchar_t *preamble, int code) { PyObject *exc, *val, *tb, *str, **system_exit; HMODULE dll; - int ret, issysexit = 0; wchar_t *i; + int ret, issysexit = 0; const wchar_t *i; if (!PyErr_Occurred()) return code; dll = GetModuleHandleA(python_dll); @@ -340,7 +310,6 @@ int calibre_show_python_error(const wchar_t *preamble, int code) { } i = pyobject_to_wchar(str); ret = _show_error(preamble, (i==NULL)?out_of_memory:i, code); - if (i) free(i); if (tb != NULL) { PyErr_Restore(exc, val, tb); PyErr_Print(); @@ -373,6 +342,10 @@ null_invalid_parameter_handler( // to return errors instead of aborting the program. So get the windows CRT // to do that. } +__declspec(dllexport) int __cdecl +simple_print(const wchar_t *msg) { + wprintf(L"%s", msg); fflush(stdout); +} __declspec(dllexport) int __cdecl execute_python_entrypoint(const char *basename, const char *module, const char *function, int is_gui_app) { @@ -398,51 +371,35 @@ execute_python_entrypoint(const char *basename, const char *module, const char * if (site == NULL) ret = calibre_show_python_error(L"Failed to import site module", 1); else { - Py_XINCREF(site); + Py_INCREF(site); main = PyObject_GetAttrString(site, "main"); if (main == NULL || !PyCallable_Check(main)) ret = calibre_show_python_error(L"site module has no main function", 1); else { - Py_XINCREF(main); + Py_INCREF(main); res = PyObject_CallObject(main, NULL); if (res == NULL) ret = calibre_show_python_error(L"Python function terminated unexpectedly", 1); else { +#if PY_VERSION_MAJOR < 3 + if (PyInt_Check(res)) { + ret = PyInt_AS_LONG(res); + } +#else + if (PyLong_Check(res)) { + ret = PyLong_AsLong(res); + } +#endif + Py_DECREF(res); } } } PyErr_Clear(); Py_Finalize(); if (code_page != CP_UTF8) SetConsoleOutputCP(code_page); + /* printf("111111111111 returning: %d\r\n", ret); */ - //printf("11111 Returning: %d\r\n", ret); return ret; } - - -wchar_t* get_temp_filename(const wchar_t *prefix) { - DWORD dwRetVal; - UINT uRetVal; - - wchar_t *szTempName; - wchar_t lpPathBuffer[MAX_PATH]; - szTempName = (wchar_t *)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)*MAX_PATH); - - dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer); - - if (dwRetVal > MAX_PATH || (dwRetVal == 0)) { - ExitProcess(show_last_error(L"Failed to get temp path.")); - } - - uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files - prefix, // temp file name prefix - 0, // create unique name - szTempName); // buffer for name - - if (uRetVal == 0) { - ExitProcess(show_last_error(L"Failed to get temp file name")); - } - return szTempName; -} diff --git a/setup/win-ci.py b/setup/win-ci.py index b4e17cb16b..347fd174cc 100644 --- a/setup/win-ci.py +++ b/setup/win-ci.py @@ -194,7 +194,7 @@ def sanitize_path(): needed_paths.append(p) executables.remove(x) sw = os.environ['SW'] - paths = r'{0}\private\python\DLLs {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format( + paths = r'{0}\private\python\bin {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format( sw ).split() + needed_paths os.environ['PATH'] = os.pathsep.join(paths)