mirror of
				https://github.com/kovidgoyal/calibre.git
				synced 2025-10-31 10:37:00 -04:00 
			
		
		
		
	Ideally someone needs to go through all the code and check that nothing breaks because of this macro, but, I dont have that kind of time
		
			
				
	
	
		
			115 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
		
			3.8 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\\app", interpreter_data.app_dir);
 | |
|     _wputenv_s(L"CALIBRE_QT_PREFIX", 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;
 | |
| }
 |