KiCad PCB EDA Suite
Loading...
Searching...
No Matches
msw/app.cpp
Go to the documentation of this file.
1/*
2* This program source code file is part of KiCad, a free EDA CAD application.
3*
4* Copyright (C) 2020 Mark Roszko <[email protected]>
5* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
6*
7* This program is free software: you can redistribute it and/or modify it
8* under the terms of the GNU General Public License as published by the
9* Free Software Foundation, either version 3 of the License, or (at your
10* option) any later version.
11*
12* This program is distributed in the hope that it will be useful, but
13* WITHOUT ANY WARRANTY; without even the implied warranty of
14* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15* General Public License for more details.
16*
17* You should have received a copy of the GNU General Public License along
18* with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21#include <kiplatform/app.h>
22
23#include <wx/log.h>
24#include <wx/string.h>
25#include <wx/window.h>
26
27#include <windows.h>
28#include <strsafe.h>
29#include <config.h>
30#include <VersionHelpers.h>
31#include <iostream>
32#include <cstdio>
33
34#if defined( _MSC_VER )
35#include <werapi.h> // issues on msys2
36#endif
37
38#ifdef _WIN32
39extern "C"
40{
41 // So there exists this malware called Nahimic by A-Volute, which is marketed as an audio enhancement
42 // software. In reality it's an aggressive form of malware that injects itself wildly into every process
43 // on the system for god knows what reason. It even includes a tracking/analytics package, <insert tinfoil hat>
44 // Our problem is this garbage basically bugs out OpenGL (why an audio driver does that, who knows, its made by morons)
45 // And then we get issues reported both in our issue tracker and sentry reports as a result
46 // At least these malware authors were nice to include a dumb "disable" trick where it checks if the exe is exporting
47 // a symbol called NoHotPatch, so here we are.
48 // Hopefully this works and stops the bug reports. Apparently the worst part is this malware aggressively gets reinstalled
49 // by awful low-tier motherboard vendors like MSI, Alienware and others who bundled it into their driver packages
50 // and distributed it over Windows Update
51 // Did I mention they clearly had issues with other apps so instead of fixing their malware, they blacklisted a hundred common
52 // apps and even some games in their own config? Obviously kicad isn't on that blacklist :(
53 // This malware seems to no longer be distributed as Nahimic and replaced with "Sonar" by SteelSeries.
54 // Time will tell if it's the same garbage, I'm not volunteering to install it.
55 __declspec(dllexport) void NoHotPatch()
56 {
57 // this is a intentionally empty function
58 return;
59 }
60}
61#endif
62
64{
65#if defined( _MSC_VER ) && defined( DEBUG )
66 // wxWidgets turns on leak dumping in debug but its "flawed" and will falsely dump
67 // for half a hour _CRTDBG_ALLOC_MEM_DF is the usual default for MSVC.
68 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF );
69#endif
70
71#if defined( DEBUG )
72 // undo wxwidgets trying to hide errors
73 SetErrorMode( 0 );
74#else
75 SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
76#endif
77
78 // remove CWD from the dll search paths
79 // just the smallest of security tweaks as we do load DLLs on demand
80 SetDllDirectory( wxT( "" ) );
81
82 // Moves the CWD to the end of the search list for spawning processes
83 SetSearchPathMode( BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE | BASE_SEARCH_PATH_PERMANENT );
84
85 // In order to support GUI and CLI
86 // Let's attach to console when it's possible, or allocate if requested.
87 AttachConsole( wxGetEnv( wxS( "KICAD_ALLOC_CONSOLE" ), nullptr ) );
88
89 // It may be useful to log up to traces in a console, but in Release builds the log level changes to Info
90 // Also we have to force the active target to stderr or else it goes to the void
91 bool forceLog = wxGetEnv( wxS( "KICAD_FORCE_CONSOLE_TRACE" ), nullptr );
92
93 if( forceLog )
94 {
95 wxLog::EnableLogging( true );
96#ifndef DEBUG
97 wxLog::SetLogLevel( wxLOG_Trace );
98#endif
99 wxLog::SetActiveTarget( new wxLogStderr );
100 }
101
102 return true;
103}
104
105
106bool KIPLATFORM::APP::AttachConsole( bool aTryAlloc )
107{
108 if( ::AttachConsole( ATTACH_PARENT_PROCESS ) || ( aTryAlloc && ::AllocConsole() ) )
109 {
110 #if !defined( __MINGW32__ ) // These redirections create problems on mingw:
111 // Nothing is printed to the console
112
113 if( ::GetStdHandle( STD_INPUT_HANDLE ) != INVALID_HANDLE_VALUE )
114 {
115 freopen( "CONIN$", "r", stdin );
116 setvbuf( stdin, NULL, _IONBF, 0 );
117 }
118
119 if( ::GetStdHandle( STD_OUTPUT_HANDLE ) != INVALID_HANDLE_VALUE )
120 {
121 freopen( "CONOUT$", "w", stdout );
122 setvbuf( stdout, NULL, _IONBF, 0 );
123 }
124
125 if( ::GetStdHandle( STD_ERROR_HANDLE ) != INVALID_HANDLE_VALUE )
126 {
127 freopen( "CONOUT$", "w", stderr );
128 setvbuf( stderr, NULL, _IONBF, 0 );
129 }
130 #endif
131
132 std::ios::sync_with_stdio( true );
133
134 std::wcout.clear();
135 std::cout.clear();
136 std::wcerr.clear();
137 std::cerr.clear();
138 std::wcin.clear();
139 std::cin.clear();
140
141 return true;
142 }
143
144 return false;
145}
146
147
149{
150#if defined( PYTHON_VERSION_MAJOR ) && ( ( PYTHON_VERSION_MAJOR == 3 && PYTHON_VERSION_MINOR >= 8 ) \
151 || PYTHON_VERSION_MAJOR > 3 )
152 // Python 3.8 switched to Windows 8+ API, we do not support Windows 7 and will not
153 // attempt to hack around it. A normal user will never get here because the Python DLL
154 // is missing dependencies - and because it is not dynamically loaded, KiCad will not even
155 // start without patching Python or its WinAPI dependency. This is just to create a nag dialog
156 // for those who run patched Python and prevent them from submitting bug reports.
157 return !IsWindows8OrGreater();
158#else
159 return false;
160#endif
161}
162
163
164bool KIPLATFORM::APP::RegisterApplicationRestart( const wxString& aCommandLine )
165{
166 // Command line arguments with spaces require quotes.
167 wxString restartCmd = wxS( "\"" ) + aCommandLine + wxS( "\"" );
168
169 // Ensure we don't exceed the maximum allowable size
170 if( restartCmd.length() > RESTART_MAX_CMD_LINE - 1 )
171 {
172 return false;
173 }
174
175 HRESULT hr = S_OK;
176
177 hr = ::RegisterApplicationRestart( restartCmd.wc_str(), RESTART_NO_PATCH );
178
179 return SUCCEEDED( hr );
180}
181
182
184{
185 // Note, this isn't required to be used on Windows if you are just closing the program
186 return SUCCEEDED( ::UnregisterApplicationRestart() );
187}
188
189
191{
192 return true;
193}
194
195
196void KIPLATFORM::APP::RemoveShutdownBlockReason( wxWindow* aWindow )
197{
198 // Destroys any block reason that may have existed
199 ShutdownBlockReasonDestroy( aWindow->GetHandle() );
200}
201
202
203void KIPLATFORM::APP::SetShutdownBlockReason( wxWindow* aWindow, const wxString& aReason )
204{
205 // Sets up the pretty message on the shutdown page on why it's being "blocked"
206 // This is used in conjunction with handling WM_QUERYENDSESSION (wxCloseEvent)
207 // ShutdownBlockReasonCreate does not block by itself
208
209 ShutdownBlockReasonDestroy( aWindow->GetHandle() ); // Destroys any existing or nonexisting reason
210
211 ShutdownBlockReasonCreate( aWindow->GetHandle(), aReason.wc_str() );
212}
213
214
216{
217 // Taken from https://devblogs.microsoft.com/oldnewthing/20191108-00/?p=103080
218 MSG msg;
219 PeekMessage( &msg, nullptr, WM_TIMER, WM_TIMER, PM_NOREMOVE );
220}
221
222
223void KIPLATFORM::APP::AddDynamicLibrarySearchPath( const wxString& aPath )
224{
225 SetDllDirectory( aPath.c_str() );
226}
void SetShutdownBlockReason(wxWindow *aWindow, const wxString &aReason)
Sets the block reason why the window/application is preventing OS shutdown.
Definition: gtk/app.cpp:90
bool UnregisterApplicationRestart()
Unregisters the application from automatic restart.
Definition: gtk/app.cpp:72
bool AttachConsole(bool aTryAlloc)
Tries to attach a console window with stdout, stderr and stdin.
Definition: gtk/app.cpp:51
void RemoveShutdownBlockReason(wxWindow *aWindow)
Removes any shutdown block reason set.
Definition: gtk/app.cpp:85
bool RegisterApplicationRestart(const wxString &aCommandLine)
Registers the application for restart with the OS with the given command line string to pass as args.
Definition: gtk/app.cpp:65
bool Init()
Perform application-specific initialization tasks.
Definition: gtk/app.cpp:40
void ForceTimerMessagesToBeCreatedIfNecessary()
Forces wxTimers to fire more promptly on Win32.
Definition: gtk/app.cpp:95
bool IsOperatingSystemUnsupported()
Checks if the Operating System is explicitly unsupported and we want to prevent users from sending bu...
Definition: gtk/app.cpp:58
bool SupportsShutdownBlockReason()
Whether or not the window supports setting a shutdown block reason.
Definition: gtk/app.cpp:79
void AddDynamicLibrarySearchPath(const wxString &aPath)
Inserts a search path for loading dynamic libraries.
Definition: gtk/app.cpp:100