mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
I am tired of all the bug reports about SSL cerificate verify failures on windows caused by the windows certificate store not having needed intermediate certificates. So use the bundled certificates instead which are the set of certificates trusted by Firefox and curl. Can be turned off via CALIBRE_USE_SYSTEM_CERTIFICATES=1 env var
125 lines
4.5 KiB
C
125 lines
4.5 KiB
C
/*
|
|
* Copyright 2009 Kovid Goyal
|
|
*/
|
|
|
|
#define UNICODE
|
|
#define PY_SSIZE_T_CLEAN
|
|
|
|
#define _WIN32_WINNT 0x0502
|
|
#define WINDOWS_LEAN_AND_MEAN
|
|
|
|
#include <windows.h>
|
|
#include <Python.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <Shellapi.h>
|
|
#include <delayimp.h>
|
|
#include <io.h>
|
|
#include <fcntl.h>
|
|
#include "../run-python.h"
|
|
|
|
static char python_dll[] = PYDLL;
|
|
|
|
|
|
|
|
static wchar_t qt_prefix_dir[MAX_PATH] = {0};
|
|
|
|
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;
|
|
|
|
sz = GetModuleFileNameW(NULL, interpreter_data.exe_path, MAX_PATH);
|
|
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
|
err = _wsplitpath_s(interpreter_data.exe_path, 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(interpreter_data.app_dir, MAX_PATH, _TRUNCATE, L"%ls%ls", drive, buf);
|
|
_snwprintf_s(interpreter_data.resources_path, MAX_PATH, _TRUNCATE, L"%ls%lsapp\\resources", drive, buf);
|
|
_snwprintf_s(interpreter_data.extensions_path, MAX_PATH, _TRUNCATE, L"%ls%lsapp\\bin", drive, buf);
|
|
_snwprintf_s(interpreter_data.executables_path, MAX_PATH, _TRUNCATE, L"%ls%lsapp\\bin", drive, buf);
|
|
}
|
|
|
|
static void
|
|
get_install_locations(void) {
|
|
get_app_dirw();
|
|
_snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%ls\\ossl-modules", interpreter_data.executables_path);
|
|
_wputenv_s(L"OPENSSL_MODULES", qt_prefix_dir);
|
|
// Have to disable sandbox or Qt WebEngine Render Process crashes as of Qt 6.6
|
|
_wputenv_s(L"QTWEBENGINE_DISABLE_SANDBOX", "1");
|
|
_snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%ls\\app", interpreter_data.app_dir);
|
|
_wputenv_s(L"CALIBRE_QT_PREFIX", qt_prefix_dir);
|
|
// Lots of people have trouble with various websites failing to download
|
|
// because of missing intermediate certificates in the windows store
|
|
// so use the Mozilla certificate bundle
|
|
_snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%ls\\mozilla-ca-certs.pem", interpreter_data.resources_path);
|
|
const char *s = getenv("CALIBRE_USE_SYSTEM_CERTIFICATES");
|
|
if (!s || strcmp(s, "1") != 0) _wputenv_s(L"SSL_CERT_FILE", qt_prefix_dir);
|
|
}
|
|
|
|
static void
|
|
load_python_dll() {
|
|
get_install_locations();
|
|
bypy_setup_python(python_dll);
|
|
}
|
|
|
|
const static wchar_t out_of_memory[] = L"Out of memory";
|
|
|
|
|
|
static void
|
|
redirect_out_stream(FILE *stream) {
|
|
FILE *f = NULL;
|
|
errno_t err;
|
|
|
|
err = _wfreopen_s(&f, L"NUL", L"wt", stream);
|
|
if (err != 0) {
|
|
ExitProcess(show_last_error_crt(L"Failed to redirect stdout/stderr to NUL. This indicates a corrupted Windows install.\r\n You should contact Microsoft for assistance and/or follow the steps described here:\r\n http://bytes.com/topic/net/answers/264804-compile-error-null-device-missing"));
|
|
}
|
|
}
|
|
|
|
static void
|
|
null_invalid_parameter_handler(
|
|
const wchar_t * expression,
|
|
const wchar_t * function,
|
|
const wchar_t * file,
|
|
unsigned int line,
|
|
uintptr_t pReserved
|
|
) {
|
|
// The python runtime expects various system calls with invalid parameters
|
|
// 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) {
|
|
int n = wprintf(L"%ls", msg); fflush(stdout);
|
|
return n;
|
|
}
|
|
|
|
__declspec(dllexport) int __cdecl
|
|
execute_python_entrypoint(const wchar_t *basename, const wchar_t *module, const wchar_t *function, int is_gui_app) {
|
|
int ret = 0;
|
|
// Prevent Windows' idiotic error dialog popups when various win32 api functions fail
|
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
|
|
// Disable the invalid parameter handler
|
|
_set_invalid_parameter_handler(null_invalid_parameter_handler);
|
|
detect_tty();
|
|
|
|
if (is_gui_app) {
|
|
// Redirect stdout and stderr to NUL so that python does not fail writing to them
|
|
if (!stdout_is_a_tty) redirect_out_stream(stdout);
|
|
if (!stderr_is_a_tty) redirect_out_stream(stderr);
|
|
}
|
|
GUI_APP = is_gui_app;
|
|
interpreter_data.argv = CommandLineToArgvW(GetCommandLineW(), &interpreter_data.argc);
|
|
if (interpreter_data.argv == NULL) ExitProcess(show_last_error(L"Failed to get command line"));
|
|
interpreter_data.basename = basename; interpreter_data.module = module; interpreter_data.function = function;
|
|
load_python_dll();
|
|
pre_initialize_interpreter(is_gui_app);
|
|
run_interpreter();
|
|
|
|
|
|
/* printf("111111111111 returning: %d\r\n", ret); */
|
|
|
|
return ret;
|
|
}
|