2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  os_windows.cpp                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                         This file is part of:                          */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                             GODOT ENGINE                               */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                        https://godotengine.org                         */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* a copy of this software and associated documentation files (the        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* "Software"), to deal in the Software without restriction, including    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* the following conditions:                                              */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* The above copyright notice and this permission notice shall be         */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* included in all copies or substantial portions of the Software.        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*                                                                        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2015-01-10 17:35:26 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "os_windows.h" 
  
						 
					
						
							
								
									
										
										
										
											2016-12-21 02:29:58 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-08 14:51:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "display_server_windows.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "joypad_windows.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "lang_table.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "windows_terminal_logger.h" 
  
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "windows_utils.h" 
  
						 
					
						
							
								
									
										
										
										
											2023-06-08 14:51:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-27 03:30:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/debugger/engine_debugger.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/debugger/script_debugger.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-09-11 18:13:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/io/marshalls.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "core/version_generated.gen.h" 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "drivers/windows/dir_access_windows.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "drivers/windows/file_access_windows.h" 
  
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "drivers/windows/file_access_windows_pipe.h" 
  
						 
					
						
							
								
									
										
										
										
											2024-11-10 15:52:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "drivers/windows/ip_windows.h" 
  
						 
					
						
							
								
									
										
										
										
											2024-11-08 13:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "drivers/windows/net_socket_winsock.h" 
  
						 
					
						
							
								
									
										
										
										
											2024-12-14 13:15:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "drivers/windows/thread_windows.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-01-16 19:19:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "main/main.h" 
  
						 
					
						
							
								
									
										
										
										
											2017-06-10 10:15:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "servers/audio_server.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-12-03 18:09:47 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "servers/rendering/rendering_server_default.h" 
  
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "servers/text_server.h" 
  
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 15:43:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <avrt.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:33:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <bcrypt.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-02-20 13:00:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <direct.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-04-22 09:42:11 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <knownfolders.h> 
  
						 
					
						
							
								
									
										
										
										
											2016-04-29 13:57:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <process.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <psapi.h> 
  
						 
					
						
							
								
									
										
										
										
											2015-02-12 04:17:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <regstr.h> 
  
						 
					
						
							
								
									
										
										
										
											2017-01-16 19:19:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <shlobj.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <wbemcli.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-13 21:17:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <wincrypt.h> 
  
						 
					
						
							
								
									
										
										
										
											2015-02-12 04:17:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef DEBUG_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma pack(push, before_imagehlp, 8) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <imagehlp.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma pack(pop, before_imagehlp) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-01-17 02:48:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								extern  " C "  {  
						 
					
						
							
								
									
										
										
										
											2018-11-02 23:10:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								__declspec ( dllexport )  DWORD  NvOptimusEnablement  =  1 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								__declspec ( dllexport )  int  AmdPowerXpressRequestHighPerformance  =  1 ;  
						 
					
						
							
								
									
										
										
										
											2024-11-18 12:58:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								__declspec ( dllexport )  void  NoHotPatch ( )  { }  // Disable Nahimic code injection.
  
						 
					
						
							
								
									
										
										
										
											2015-01-17 02:48:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-18 20:46:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Workaround mingw-w64 < 4.0 bug
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef WM_TOUCH 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define WM_TOUCH 576 
  
						 
					
						
							
								
									
										
										
										
											2016-02-04 17:16:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-13 22:32:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifndef WM_POINTERUPDATE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define WM_POINTERUPDATE 0x0245 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-05 18:16:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Missing in MinGW headers before 8.0.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef DWRITE_FONT_WEIGHT_SEMI_LIGHT 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DWRITE_FONT_WEIGHT_SEMI_LIGHT (DWRITE_FONT_WEIGHT)350 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-16 12:07:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if defined(__GNUC__) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Workaround GCC warning from -Wcast-function-type.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define GetProcAddress (void *)GetProcAddress 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  fix_path ( const  String  & p_path )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  path  =  p_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_path . is_relative_path ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Char16String  current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										size_t  str_len  =  GetCurrentDirectoryW ( 0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetCurrentDirectoryW ( current_dir_name . size ( ) ,  ( LPWSTR ) current_dir_name . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										path  =  String : : utf16 ( ( const  char16_t  * ) current_dir_name . get_data ( ) ) . trim_prefix ( R " ( \\ ? \ ) " ) . replace ( " \\ " ,  " / " ) . path_join ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  =  path . simplify_path ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  =  path . replace ( " / " ,  " \\ " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-09-10 10:20:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( path . size ( )  > =  MAX_PATH  & &  ! path . is_network_share_path ( )  & &  ! path . begins_with ( R " ( \\ ? \ ) " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										path  =  R " ( \\ ? \ ) "  +  path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-01 08:42:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  String  format_error_message ( DWORD  id )  {  
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LPWSTR  messageBuffer  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-01 08:42:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									size_t  size  =  FormatMessageW ( FORMAT_MESSAGE_ALLOCATE_BUFFER  |  FORMAT_MESSAGE_FROM_SYSTEM  |  FORMAT_MESSAGE_IGNORE_INSERTS , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											nullptr ,  id ,  MAKELANGID ( LANG_NEUTRAL ,  SUBLANG_DEFAULT ) ,  ( LPWSTR ) & messageBuffer ,  0 ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-01 08:42:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  msg  =  " Error  "  +  itos ( id )  +  " :  "  +  String : : utf16 ( ( const  char16_t  * ) messageBuffer ,  size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-01 08:42:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LocalFree ( messageBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  msg . replace ( " \r " ,  " " ) . replace ( " \n " ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-01 08:42:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-28 08:30:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  RedirectStream ( const  char  * p_file_name ,  const  char  * p_mode ,  FILE  * p_cpp_stream ,  const  DWORD  p_std_handle )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  HANDLE  h_existing  =  GetStdHandle ( p_std_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( h_existing  ! =  INVALID_HANDLE_VALUE )  {  // Redirect only if attached console have a valid handle.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  HANDLE  h_cpp  =  reinterpret_cast < HANDLE > ( _get_osfhandle ( _fileno ( p_cpp_stream ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( h_cpp  = =  INVALID_HANDLE_VALUE )  {  // Redirect only if it's not already redirected to the pipe or file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											FILE  * fp  =  p_cpp_stream ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											freopen_s ( & fp ,  p_file_name ,  p_mode ,  p_cpp_stream ) ;  // Redirect stream.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											setvbuf ( p_cpp_stream ,  nullptr ,  _IONBF ,  0 ) ;  // Disable stream buffering.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  RedirectIOToConsole ( )  {  
						 
					
						
							
								
									
										
										
										
											2024-04-25 12:56:07 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Save current handles.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h_stdin  =  GetStdHandle ( STD_INPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h_stdout  =  GetStdHandle ( STD_OUTPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h_stderr  =  GetStdHandle ( STD_ERROR_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( AttachConsole ( ATTACH_PARENT_PROCESS ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-25 12:56:07 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Restore redirection (Note: if not redirected it's NULL handles not INVALID_HANDLE_VALUE).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( h_stdin  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SetStdHandle ( STD_INPUT_HANDLE ,  h_stdin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( h_stdout  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SetStdHandle ( STD_OUTPUT_HANDLE ,  h_stdout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( h_stderr  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											SetStdHandle ( STD_ERROR_HANDLE ,  h_stderr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Update file handles.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-28 08:30:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RedirectStream ( " CONIN$ " ,  " r " ,  stdin ,  STD_INPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RedirectStream ( " CONOUT$ " ,  " w " ,  stdout ,  STD_OUTPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RedirectStream ( " CONOUT$ " ,  " w " ,  stderr ,  STD_ERROR_HANDLE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-28 13:41:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 10:34:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  OS_Windows : : is_using_con_wrapper ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  String  exe_renames [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" .console.exe " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" _console.exe " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"  console.exe " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" console.exe " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  found_exe  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  found_conwrap_exe  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  exe_name  =  get_executable_path ( ) . to_lower ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  exe_dir  =  exe_name . get_base_dir ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  exe_fname  =  exe_name . get_file ( ) . get_basename ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  pids [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  count  =  GetConsoleProcessList ( & pids [ 0 ] ,  256 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( DWORD  i  =  0 ;  i  <  count ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HANDLE  process  =  OpenProcess ( PROCESS_QUERY_LIMITED_INFORMATION ,  false ,  pids [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( process  ! =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											WCHAR  proc_name [ MAX_PATH ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DWORD  len  =  MAX_PATH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( QueryFullProcessImageNameW ( process ,  0 ,  & proc_name [ 0 ] ,  & len ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  name  =  String : : utf16 ( ( const  char16_t  * ) & proc_name [ 0 ] ,  len ) . replace ( " \\ " ,  " / " ) . to_lower ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( name  = =  exe_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													found_exe  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( int  j  =  0 ;  ! exe_renames [ j ] . is_empty ( ) ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( name  = =  exe_dir . path_join ( exe_fname  +  exe_renames [ j ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														found_conwrap_exe  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( process ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( found_conwrap_exe  & &  found_exe )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! found_exe )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ;  // Unable to read console info, assume true.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  found_conwrap_exe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								BOOL  WINAPI  HandlerRoutine ( _In_  DWORD  dwCtrlType )  {  
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! EngineDebugger : : is_active ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-18 14:17:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( dwCtrlType )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  CTRL_C_EVENT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EngineDebugger : : get_script_debugger ( ) - > set_depth ( - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											EngineDebugger : : get_script_debugger ( ) - > set_lines_left ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  FALSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-18 14:17:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 19:23:48 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : alert ( const  String  & p_alert ,  const  String  & p_title )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MessageBoxW ( nullptr ,  ( LPCWSTR ) ( p_alert . utf16 ( ) . get_data ( ) ) ,  ( LPCWSTR ) ( p_title . utf16 ( ) . get_data ( ) ) ,  MB_OK  |  MB_ICONEXCLAMATION  |  MB_TASKMODAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : initialize_debugging ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SetConsoleCtrlHandler ( HandlerRoutine ,  TRUE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 19:25:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef WINDOWS_DEBUG_OUTPUT_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  _error_handler ( void  * p_self ,  const  char  * p_func ,  const  char  * p_file ,  int  p_line ,  const  char  * p_error ,  const  char  * p_errorexp ,  bool  p_editor_notify ,  ErrorHandlerType  p_type )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  err_str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_errorexp  & &  p_errorexp [ 0 ] )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 15:00:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err_str  =  String : : utf8 ( p_errorexp )  +  " \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 19:25:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-27 15:00:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err_str  =  String : : utf8 ( p_file )  +  " : "  +  itos ( p_line )  +  "  -  "  +  String : : utf8 ( p_error )  +  " \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 19:25:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									OutputDebugStringW ( ( LPCWSTR ) err_str . utf16 ( ) . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : initialize ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									crash_handler . initialize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 19:25:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef WINDOWS_DEBUG_OUTPUT_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_handlers . errfunc  =  _error_handler ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									error_handlers . userdata  =  this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									add_error_handler ( & error_handlers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-14 13:15:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef THREADS_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									init_thread_win ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FileAccess : : make_default < FileAccessWindows > ( FileAccess : : ACCESS_RESOURCES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FileAccess : : make_default < FileAccessWindows > ( FileAccess : : ACCESS_USERDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FileAccess : : make_default < FileAccessWindows > ( FileAccess : : ACCESS_FILESYSTEM ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FileAccess : : make_default < FileAccessWindowsPipe > ( FileAccess : : ACCESS_PIPE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DirAccess : : make_default < DirAccessWindows > ( DirAccess : : ACCESS_RESOURCES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DirAccess : : make_default < DirAccessWindows > ( DirAccess : : ACCESS_USERDATA ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DirAccess : : make_default < DirAccessWindows > ( DirAccess : : ACCESS_FILESYSTEM ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 13:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									NetSocketWinSock : : make_default ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// We need to know how often the clock is updated
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 22:38:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									QueryPerformanceFrequency ( ( LARGE_INTEGER  * ) & ticks_per_second ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									QueryPerformanceCounter ( ( LARGE_INTEGER  * ) & ticks_start ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// set minimum resolution for periodic timers, otherwise Sleep(n) may wait at least as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//  long as the windows scheduler resolution (~16-30ms) even for calls like Sleep(1)
 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 13:27:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									TIMECAPS  time_caps ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( timeGetDevCaps ( & time_caps ,  sizeof ( time_caps ) )  = =  MMSYSERR_NOERROR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delay_resolution  =  time_caps . wPeriodMin  *  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										timeBeginPeriod ( time_caps . wPeriodMin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_PRINT ( " Unable to detect sleep timer resolution. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delay_resolution  =  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										timeBeginPeriod ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 15:04:37 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map  =  memnew ( ( HashMap < ProcessID ,  ProcessInfo > ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-11 15:26:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add current Godot PID to the list of known PIDs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ProcessInfo  current_pi  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PROCESS_INFORMATION  current_pi_pi  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_pi . pi  =  current_pi_pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_pi . pi . hProcess  =  GetCurrentProcess ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									process_map - > insert ( GetCurrentProcessId ( ) ,  current_pi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-10 15:52:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									IPWindows : : make_default ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_loop  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  hr  =  DWriteCreateFactory ( DWRITE_FACTORY_TYPE_SHARED ,  __uuidof ( IDWriteFactory ) ,  reinterpret_cast < IUnknown  * * > ( & dwrite_factory ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( SUCCEEDED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  dwrite_factory - > GetSystemFontCollection ( & font_collection ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( SUCCEEDED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dwrite_init  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hr  =  dwrite_factory - > QueryInterface ( & dwrite_factory2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( SUCCEEDED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												hr  =  dwrite_factory2 - > GetSystemFontFallback ( & system_font_fallback ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( SUCCEEDED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dwrite2_init  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dwrite_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										print_verbose ( " Unable to load IDWriteFactory, system font support is disabled. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! dwrite2_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										print_verbose ( " Unable to load IDWriteFactory2, automatic system font fallback is disabled. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FileAccessWindows : : initialize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : delete_main_loop ( )  {  
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( main_loop )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memdelete ( main_loop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_loop  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : set_main_loop ( MainLoop  * p_main_loop )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									main_loop  =  p_main_loop ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-10 20:38:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : finalize ( )  {  
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dwrite_factory2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dwrite_factory2 - > Release ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dwrite_factory2  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( font_collection )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_collection - > Release ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_collection  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( system_font_fallback )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										system_font_fallback - > Release ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										system_font_fallback  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dwrite_factory )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dwrite_factory - > Release ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dwrite_factory  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef WINMIDI_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									driver_midi . close ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-07-09 21:48:22 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( main_loop )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memdelete ( main_loop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-03 04:18:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_loop  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-03 04:18:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : finalize_core ( )  {  
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ! temp_libraries . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_remove_temp_library ( temp_libraries . last ( ) - > key ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FileAccessWindows : : finalize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									timeEndPeriod ( 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-27 20:51:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memdelete ( process_map ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 13:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									NetSocketWinSock : : cleanup ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 19:25:49 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef WINDOWS_DEBUG_OUTPUT_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									remove_error_handler ( & error_handlers ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-07-09 21:48:22 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:33:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Error  OS_Windows : : get_entropy ( uint8_t  * r_buffer ,  int  p_bytes )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NTSTATUS  status  =  BCryptGenRandom ( nullptr ,  r_buffer ,  p_bytes ,  BCRYPT_USE_SYSTEM_PREFERRED_RNG ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( status ,  FAILED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-07-09 21:48:22 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef DEBUG_ENABLED 
  
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  debug_dynamic_library_check_dependencies ( const  String  & p_path ,  HashSet < String >  & r_checked ,  HashSet < String >  & r_missing )  {  
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( r_checked . has ( p_path ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_checked . insert ( p_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LOADED_IMAGE  loaded_image ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  file  =  CreateFileW ( ( LPCWSTR ) p_path . utf16 ( ) . get_data ( ) ,  GENERIC_READ ,  FILE_SHARE_READ ,  nullptr ,  OPEN_EXISTING ,  0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( file  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HANDLE  file_mapping  =  CreateFileMappingW ( file ,  nullptr ,  PAGE_READONLY  |  SEC_COMMIT ,  0 ,  0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( file_mapping  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											PVOID  mapping  =  MapViewOfFile ( file_mapping ,  FILE_MAP_READ ,  0 ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( mapping )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PIMAGE_DOS_HEADER  dos_header  =  ( PIMAGE_DOS_HEADER ) mapping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PIMAGE_NT_HEADERS  nt_header  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( dos_header - > e_magic  = =  IMAGE_DOS_SIGNATURE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PCHAR  nt_header_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													nt_header_ptr  =  ( ( PCHAR ) mapping )  +  dos_header - > e_lfanew ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													nt_header  =  ( PIMAGE_NT_HEADERS ) nt_header_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( nt_header - > Signature  ! =  IMAGE_NT_SIGNATURE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														nt_header  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( nt_header )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . ModuleName  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . hFile  =  file ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . MappedAddress  =  ( PUCHAR ) mapping ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . FileHeader  =  nt_header ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . Sections  =  ( PIMAGE_SECTION_HEADER ) ( ( LPBYTE ) & nt_header - > OptionalHeader  +  nt_header - > FileHeader . SizeOfOptionalHeader ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . NumberOfSections  =  nt_header - > FileHeader . NumberOfSections ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . SizeOfImage  =  GetFileSize ( file ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . Characteristics  =  nt_header - > FileHeader . Characteristics ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . LastRvaSection  =  loaded_image . Sections ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . fSystemImage  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . fDOSImage  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . Links . Flink  =  & loaded_image . Links ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													loaded_image . Links . Blink  =  & loaded_image . Links ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ULONG  size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													const  IMAGE_IMPORT_DESCRIPTOR  * import_desc  =  ( const  IMAGE_IMPORT_DESCRIPTOR  * ) ImageDirectoryEntryToData ( ( HMODULE ) loaded_image . MappedAddress ,  false ,  IMAGE_DIRECTORY_ENTRY_IMPORT ,  & size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( import_desc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														for  ( ;  import_desc - > Name  & &  import_desc - > FirstThunk ;  import_desc + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															char16_t  full_name_wc [ 32767 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															const  char  * name_cs  =  ( const  char  * ) ImageRvaToVa ( loaded_image . FileHeader ,  loaded_image . MappedAddress ,  import_desc - > Name ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															String  name  =  String ( name_cs ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															if  ( name . begins_with ( " api-ms-win- " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																r_checked . insert ( name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															}  else  if  ( SearchPathW ( nullptr ,  ( LPCWSTR ) name . utf16 ( ) . get_data ( ) ,  nullptr ,  32767 ,  ( LPWSTR ) full_name_wc ,  nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																debug_dynamic_library_check_dependencies ( String : : utf16 ( full_name_wc ) ,  r_checked ,  r_missing ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															}  else  if  ( SearchPathW ( ( LPCWSTR ) ( p_path . get_base_dir ( ) . utf16 ( ) . get_data ( ) ) ,  ( LPCWSTR ) name . utf16 ( ) . get_data ( ) ,  nullptr ,  32767 ,  ( LPWSTR ) full_name_wc ,  nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																debug_dynamic_library_check_dependencies ( String : : utf16 ( full_name_wc ) ,  r_checked ,  r_missing ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																r_missing . insert ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UnmapViewOfFile ( mapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( file_mapping ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : open_dynamic_library ( const  String  & p_path ,  void  * & p_library_handle ,  GDExtensionData  * p_data )  {  
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  path  =  p_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-04 15:42:29 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! FileAccess : : exists ( path ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 12:11:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										//this code exists so gdextension can load .dll files from within the executable path
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-29 19:34:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										path  =  get_executable_path ( ) . get_base_dir ( ) . path_join ( p_path . get_file ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-04 15:42:29 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Path to load from may be different from original if we make copies.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  load_path  =  path ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-04 15:42:29 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-01 19:48:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! FileAccess : : exists ( path ) ,  ERR_FILE_NOT_FOUND ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Here we want a copy to be loaded.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This is so the original file isn't locked and can be updated by a compiler.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_data  ! =  nullptr  & &  p_data - > generate_temp_files )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Copy the file to the same directory as the original with a prefix in the name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// This is so relative path to dependencies are satisfied.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										load_path  =  path . get_base_dir ( ) . path_join ( " ~ "  +  path . get_file ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If there's a left-over copy (possibly from a crash) then delete it first.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( FileAccess : : exists ( load_path ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DirAccess : : remove_absolute ( load_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  copy_err  =  DirAccess : : copy_absolute ( path ,  load_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( copy_err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_PRINT ( " Error copying library:  "  +  path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ERR_CANT_CREATE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										FileAccess : : set_hidden_attribute ( load_path ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Error  pdb_err  =  WindowsUtils : : copy_and_rename_pdb ( load_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( pdb_err  ! =  OK  & &  pdb_err  ! =  ERR_SKIP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											WARN_PRINT ( vformat ( " Failed to rename the PDB file. The original PDB file for '%s' will be loaded. " ,  path ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-06 14:29:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									typedef  DLL_DIRECTORY_COOKIE ( WINAPI  *  PAddDllDirectory ) ( PCWSTR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									typedef  BOOL ( WINAPI  *  PRemoveDllDirectory ) ( DLL_DIRECTORY_COOKIE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PAddDllDirectory  add_dll_directory  =  ( PAddDllDirectory ) GetProcAddress ( GetModuleHandle ( " kernel32.dll " ) ,  " AddDllDirectory " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PRemoveDllDirectory  remove_dll_directory  =  ( PRemoveDllDirectory ) GetProcAddress ( GetModuleHandle ( " kernel32.dll " ) ,  " RemoveDllDirectory " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  has_dll_directory_api  =  ( ( add_dll_directory  ! =  nullptr )  & &  ( remove_dll_directory  ! =  nullptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DLL_DIRECTORY_COOKIE  cookie  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-30 10:00:10 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-28 20:12:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  dll_path  =  fix_path ( load_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  dll_dir  =  fix_path ( ProjectSettings : : get_singleton ( ) - > globalize_path ( load_path . get_base_dir ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_data  ! =  nullptr  & &  p_data - > also_set_library_path  & &  has_dll_directory_api )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-28 20:12:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cookie  =  add_dll_directory ( ( LPCWSTR ) ( dll_dir . utf16 ( ) . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-30 10:00:10 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-28 20:12:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_library_handle  =  ( void  * ) LoadLibraryExW ( ( LPCWSTR ) ( dll_path . utf16 ( ) . get_data ( ) ) ,  nullptr ,  ( p_data  ! =  nullptr  & &  p_data - > also_set_library_path  & &  has_dll_directory_api )  ?  LOAD_LIBRARY_SEARCH_DEFAULT_DIRS  :  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_library_handle )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p_data  ! =  nullptr  & &  p_data - > generate_temp_files )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											DirAccess : : remove_absolute ( load_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef DEBUG_ENABLED 
  
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										DWORD  err_code  =  GetLastError ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashSet < String >  checked_libs ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HashSet < String >  missing_libs ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-28 20:12:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										debug_dynamic_library_check_dependencies ( dll_path ,  checked_libs ,  missing_libs ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! missing_libs . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  missing ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( const  String  & E  :  missing_libs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! missing . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													missing  + =  " ,  " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												missing  + =  E ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-28 17:51:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_V_MSG ( ERR_CANT_OPEN ,  vformat ( " Can't open dynamic library: %s. Missing dependencies: %s. Error: %s. " ,  p_path ,  missing ,  format_error_message ( err_code ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-28 17:51:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_V_MSG ( ERR_CANT_OPEN ,  vformat ( " Can't open dynamic library: %s. Error: %s. " ,  p_path ,  format_error_message ( err_code ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef DEBUG_ENABLED 
  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V_MSG ( p_library_handle ,  ERR_CANT_OPEN ,  vformat ( " Can't open dynamic library: %s. Error: %s. " ,  p_path ,  format_error_message ( GetLastError ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-11-30 10:00:10 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-26 11:48:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( cookie )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-06 14:29:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										remove_dll_directory ( cookie ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-30 10:00:10 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_data  ! =  nullptr  & &  p_data - > r_resolved_path  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* p_data - > r_resolved_path  =  path ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-29 00:51:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-19 07:14:05 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_data  ! =  nullptr  & &  p_data - > generate_temp_files )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-08-04 11:00:56 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Save the copied path so it can be deleted later.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										temp_libraries [ p_library_handle ]  =  load_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-08 02:50:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-03 16:11:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : close_dynamic_library ( void  * p_library_handle )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! FreeLibrary ( ( HMODULE ) p_library_handle ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-08 02:50:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Delete temporary copy of library if it exists.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_remove_temp_library ( p_library_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-08 02:50:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-11 15:33:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : _remove_temp_library ( void  * p_library_handle )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( temp_libraries . has ( p_library_handle ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  path  =  temp_libraries [ p_library_handle ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DirAccess : : remove_absolute ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WindowsUtils : : remove_temp_pdbs ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										temp_libraries . erase ( p_library_handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-08 22:36:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : get_dynamic_library_symbol_handle ( void  * p_library_handle ,  const  String  & p_name ,  void  * & p_symbol_handle ,  bool  p_optional )  {  
						 
					
						
							
								
									
										
										
										
											2017-04-03 16:11:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_symbol_handle  =  ( void  * ) GetProcAddress ( ( HMODULE ) p_library_handle ,  p_name . utf8 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-08 02:50:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_symbol_handle )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-27 09:23:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! p_optional )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-27 11:49:05 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ERR_FAIL_V_MSG ( ERR_CANT_RESOLVE ,  vformat ( " Can't resolve symbol %s, error:  \" %s \" . " ,  p_name ,  format_error_message ( GetLastError ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-27 09:23:21 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ERR_CANT_RESOLVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-08 02:50:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-20 13:36:24 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_name ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  " Windows " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-16 11:14:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_distribution_name ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  get_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_version ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RtlGetVersionPtr  version_ptr  =  ( RtlGetVersionPtr ) GetProcAddress ( GetModuleHandle ( " ntdll.dll " ) ,  " RtlGetVersion " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( version_ptr  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-13 17:16:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RTL_OSVERSIONINFOEXW  fow ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-06 09:30:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ZeroMemory ( & fow ,  sizeof ( fow ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-16 11:14:14 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										fow . dwOSVersionInfoSize  =  sizeof ( fow ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( version_ptr ( & fow )  = =  0x00000000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  vformat ( " %d.%d.%d " ,  ( int64_t ) fow . dwMajorVersion ,  ( int64_t ) fow . dwMinorVersion ,  ( int64_t ) fow . dwBuildNumber ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-13 17:16:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_version_alias ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RtlGetVersionPtr  version_ptr  =  ( RtlGetVersionPtr ) GetProcAddress ( GetModuleHandle ( " ntdll.dll " ) ,  " RtlGetVersion " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( version_ptr  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RTL_OSVERSIONINFOEXW  fow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ZeroMemory ( & fow ,  sizeof ( fow ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fow . dwOSVersionInfoSize  =  sizeof ( fow ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( version_ptr ( & fow )  = =  0x00000000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  windows_string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( fow . wProductType  ! =  VER_NT_WORKSTATION  & &  fow . dwMajorVersion  = =  10  & &  fow . dwBuildNumber  > =  26100 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												windows_string  =  " Server 2025 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( fow . dwMajorVersion  = =  10  & &  fow . dwBuildNumber  > =  20348 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Builds above 20348 correspond to Windows 11 / Windows Server 2022.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Their major version numbers are still 10 though, not 11.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fow . wProductType  ! =  VER_NT_WORKSTATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " Server 2022 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " 11 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( fow . dwMajorVersion  = =  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fow . wProductType  ! =  VER_NT_WORKSTATION  & &  fow . dwBuildNumber  > =  17763 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " Server 2019 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( fow . wProductType  ! =  VER_NT_WORKSTATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														windows_string  + =  " Server 2016 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														windows_string  + =  " 10 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( fow . dwMajorVersion  = =  6  & &  fow . dwMinorVersion  = =  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fow . wProductType  ! =  VER_NT_WORKSTATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  =  " Server 2012 R2 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " 8.1 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( fow . dwMajorVersion  = =  6  & &  fow . dwMinorVersion  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fow . wProductType  ! =  VER_NT_WORKSTATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " Server 2012 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " 8 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( fow . dwMajorVersion  = =  6  & &  fow . dwMinorVersion  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fow . wProductType  ! =  VER_NT_WORKSTATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  =  " Server 2008 R2 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													windows_string  + =  " 7 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												windows_string  + =  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Windows versions older than 7 cannot run Godot.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  vformat ( " %s (build %d) " , windows_string, (int64_t)fow.dwBuildNumber) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Vector < String >  OS_Windows : : get_video_adapter_driver_info ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2023-06-06 23:29:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( RenderingServer : : get_singleton ( )  = =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-27 13:52:38 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 18:21:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  Vector < String >  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! info . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									REFCLSID  clsid  =  CLSID_WbemLocator ;  // Unmarshaler CLSID
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									REFIID  uuid  =  IID_IWbemLocator ;  // Interface UUID
 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									IWbemLocator  * wbemLocator  =  nullptr ;  // to get the services
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									IWbemServices  * wbemServices  =  nullptr ;  // to get the class
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									IEnumWbemClassObject  * iter  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									IWbemClassObject  * pnpSDriverObject [ 1 ] ;  // contains driver name, version, etc.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 18:21:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  driver_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  driver_version ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 23:29:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  String  device_name  =  RenderingServer : : get_singleton ( ) - > get_video_adapter_name ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( device_name . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HRESULT  hr  =  CoCreateInstance ( clsid ,  nullptr ,  CLSCTX_INPROC_SERVER ,  uuid ,  ( LPVOID  * ) & wbemLocator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( hr  ! =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-12 20:17:49 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BSTR  resource_name  =  SysAllocString ( L " root \\ CIMV2 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hr  =  wbemLocator - > ConnectServer ( resource_name ,  nullptr ,  nullptr ,  nullptr ,  0 ,  nullptr ,  nullptr ,  & wbemServices ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-12 20:17:49 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SysFreeString ( resource_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SAFE_RELEASE ( wbemLocator )  // from now on, use `wbemServices`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hr  ! =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SAFE_RELEASE ( wbemServices ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  String  gpu_device_class_query  =  vformat ( " SELECT * FROM Win32_PnPSignedDriver WHERE DeviceName =  \" %s \" " ,  device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BSTR  query  =  SysAllocString ( ( const  WCHAR  * ) gpu_device_class_query . utf16 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BSTR  query_lang  =  SysAllocString ( L " WQL " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hr  =  wbemServices - > ExecQuery ( query_lang ,  query ,  WBEM_FLAG_RETURN_IMMEDIATELY  |  WBEM_FLAG_FORWARD_ONLY ,  nullptr ,  & iter ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SysFreeString ( query_lang ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SysFreeString ( query ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hr  = =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ULONG  resultCount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  iter - > Next ( 5000 ,  1 ,  pnpSDriverObject ,  & resultCount ) ;  // Get exactly 1. Wait max 5 seconds.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( hr  = =  S_OK  & &  resultCount  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VARIANT  dn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VariantInit ( & dn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											BSTR  object_name  =  SysAllocString ( L " DriverName " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hr  =  pnpSDriverObject [ 0 ] - > Get ( object_name ,  0 ,  & dn ,  nullptr ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											SysFreeString ( object_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hr  = =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												String  d_name  =  String ( V_BSTR ( & dn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( d_name . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													object_name  =  SysAllocString ( L " DriverProviderName " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													hr  =  pnpSDriverObject [ 0 ] - > Get ( object_name ,  0 ,  & dn ,  nullptr ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													SysFreeString ( object_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( hr  = =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														driver_name  =  String ( V_BSTR ( & dn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													driver_name  =  d_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												object_name  =  SysAllocString ( L " DriverProviderName " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												hr  =  pnpSDriverObject [ 0 ] - > Get ( object_name ,  0 ,  & dn ,  nullptr ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												SysFreeString ( object_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( hr  = =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													driver_name  =  String ( V_BSTR ( & dn ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VARIANT  dv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											VariantInit ( & dv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											object_name  =  SysAllocString ( L " DriverVersion " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hr  =  pnpSDriverObject [ 0 ] - > Get ( object_name ,  0 ,  & dv ,  nullptr ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 12:39:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											SysFreeString ( object_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hr  = =  S_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												driver_version  =  String ( V_BSTR ( & dv ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( ULONG  i  =  0 ;  i  <  resultCount ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												SAFE_RELEASE ( pnpSDriverObject [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SAFE_RELEASE ( wbemServices ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SAFE_RELEASE ( iter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . push_back ( driver_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . push_back ( driver_version ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 05:21:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  OS_Windows : : get_user_prefers_integrated_gpu ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// On Windows 10, the preferred GPU configured in Windows Settings is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// stored in the registry under the key
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// `HKEY_CURRENT_USER\SOFTWARE\Microsoft\DirectX\UserGpuPreferences`
 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 18:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// with the name being the app ID or EXE path. The value is in the form of
 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 05:21:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// `GpuPreference=1;`, with the value being 1 for integrated GPU and 2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// for discrete GPU. On Windows 11, there may be more flags, separated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// by semicolons.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 18:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If this is a packaged app, use the "application user model ID".
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Otherwise, use the EXE path.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WCHAR  value_name [ 32768 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  is_packaged  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HMODULE  kernel32  =  GetModuleHandleW ( L " kernel32.dll " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( kernel32 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											using  GetCurrentApplicationUserModelIdPtr  =  LONG ( WINAPI  * ) ( UINT32  *  length ,  PWSTR  id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											GetCurrentApplicationUserModelIdPtr  GetCurrentApplicationUserModelId  =  ( GetCurrentApplicationUserModelIdPtr ) GetProcAddress ( kernel32 ,  " GetCurrentApplicationUserModelId " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( GetCurrentApplicationUserModelId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UINT32  length  =  sizeof ( value_name )  /  sizeof ( value_name [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												LONG  result  =  GetCurrentApplicationUserModelId ( & length ,  value_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( result  = =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													is_packaged  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! is_packaged  & &  GetModuleFileNameW ( nullptr ,  value_name ,  sizeof ( value_name )  /  sizeof ( value_name [ 0 ] ) )  > =  sizeof ( value_name )  /  sizeof ( value_name [ 0 ] ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 05:21:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Paths should never be longer than 32767, but just in case.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LPCWSTR  subkey  =  L " SOFTWARE \\ Microsoft \\ DirectX \\ UserGpuPreferences " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HKEY  hkey  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LSTATUS  result  =  RegOpenKeyExW ( HKEY_CURRENT_USER ,  subkey ,  0 ,  KEY_READ ,  & hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( result  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  size  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 18:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									result  =  RegGetValueW ( hkey ,  nullptr ,  value_name ,  RRF_RT_REG_SZ ,  nullptr ,  nullptr ,  & size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 05:21:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( result  ! =  ERROR_SUCCESS  | |  size  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < WCHAR >  buffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buffer . resize ( size  /  sizeof ( WCHAR ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 18:15:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									result  =  RegGetValueW ( hkey ,  nullptr ,  value_name ,  RRF_RT_REG_SZ ,  nullptr ,  ( LPBYTE ) buffer . ptrw ( ) ,  & size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-06 05:21:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( result  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  String  flags  =  String : : utf16 ( ( const  char16_t  * ) buffer . ptr ( ) ,  size  /  sizeof ( WCHAR ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  String  & flag  :  flags . split ( " ; " ,  false ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( flag  = =  " GpuPreference=1 " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-08 13:36:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								OS : : DateTime  OS_Windows : : get_datetime ( bool  p_utc )  const  {  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									SYSTEMTIME  systemtime ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 10:16:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_utc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 03:40:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										GetSystemTime ( & systemtime ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 10:16:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 03:40:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										GetLocalTime ( & systemtime ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 10:16:47 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-07 15:06:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//Get DST information from Windows, but only if p_utc is false.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TIME_ZONE_INFORMATION  info ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  is_daylight  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_utc  & &  GetTimeZoneInformation ( & info )  = =  TIME_ZONE_ID_DAYLIGHT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										is_daylight  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-08 13:36:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DateTime  dt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . year  =  systemtime . wYear ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . month  =  Month ( systemtime . wMonth ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . day  =  systemtime . wDay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . weekday  =  Weekday ( systemtime . wDayOfWeek ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . hour  =  systemtime . wHour ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . minute  =  systemtime . wMinute ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dt . second  =  systemtime . wSecond ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dt . dst  =  is_daylight ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-08 13:36:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  dt ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OS : : TimeZoneInfo  OS_Windows : : get_time_zone_info ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TIME_ZONE_INFORMATION  info ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  is_daylight  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( GetTimeZoneInformation ( & info )  = =  TIME_ZONE_ID_DAYLIGHT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										is_daylight  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Daylight Bias needs to be added to the bias if DST is in effect, or else it will not properly update.
 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-07 16:10:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									TimeZoneInfo  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-11 12:32:23 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_daylight )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret . name  =  info . DaylightName ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret . bias  =  info . Bias  +  info . DaylightBias ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret . name  =  info . StandardName ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret . bias  =  info . Bias  +  info . StandardBias ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 21:41:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Bias value returned by GetTimeZoneInformation is inverted of what we expect
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-12 19:05:16 +05:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For example, on GMT-3 GetTimeZoneInformation return a Bias of 180, so invert the value to get -180
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 06:28:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ret . bias  =  - ret . bias ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-06-06 05:35:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-31 14:19:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								double  OS_Windows : : get_unix_time ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// 1 Windows tick is 100ns
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  uint64_t  WINDOWS_TICKS_PER_SECOND  =  10000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  uint64_t  TICKS_TO_UNIX_EPOCH  =  116444736000000000LL ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-11 14:09:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 10:29:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SYSTEMTIME  st ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetSystemTime ( & st ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-10 18:24:55 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FILETIME  ft ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SystemTimeToFileTime ( & st ,  & ft ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-31 14:19:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uint64_t  ticks_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ticks_time  =  ft . dwHighDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ticks_time  < < =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ticks_time  | =  ft . dwLowDateTime ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-11 14:09:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-31 14:19:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( double ) ( ticks_time  -  TICKS_TO_UNIX_EPOCH )  /  WINDOWS_TICKS_PER_SECOND ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-08-06 10:29:33 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  OS_Windows : : delay_usec ( uint32_t  p_usec )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-11-25 19:43:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_usec  <  1000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Sleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Sleep ( p_usec  /  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-14 14:29:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								uint64_t  OS_Windows : : get_ticks_usec ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  ticks ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 12:20:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// This is the number of clock ticks since start
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-04 22:38:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									QueryPerformanceCounter ( ( LARGE_INTEGER  * ) & ticks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Subtract the ticks at game start to get
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// the ticks since the game started
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ticks  - =  ticks_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 12:20:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Divide by frequency to get the time in seconds
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-22 12:20:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// original calculation shown below is subject to overflow
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// with high ticks_per_second and a number of days since the last reboot.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// time = ticks * 1000000L / ticks_per_second;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// we can prevent this by either using 128 bit math
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// or separating into a calculation for seconds, and the fraction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  seconds  =  ticks  /  ticks_per_second ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// compiler will optimize these two into one divide
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  leftover  =  ticks  %  ticks_per_second ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// remainder
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  time  =  ( leftover  *  1000000L )  /  ticks_per_second ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// seconds
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									time  + =  seconds  *  1000000L ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 16:34:15 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : _quote_command_line_argument ( const  String  & p_text )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  p_text . size ( ) ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										char32_t  c  =  p_text [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 16:34:15 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( c  = =  '   '  | |  c  = =  ' & '  | |  c  = =  ' ( '  | |  c  = =  ' ) '  | |  c  = =  ' [ '  | |  c  = =  ' ] '  | |  c  = =  ' { '  | |  c  = =  ' } '  | |  c  = =  ' ^ '  | |  c  = =  ' = '  | |  c  = =  ' ; '  | |  c  = =  ' ! '  | |  c  = =  ' \' '  | |  c  = =  ' + '  | |  c  = =  ' , '  | |  c  = =  ' ` '  | |  c  = =  ' ~ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  " \" "  +  p_text  +  " \" " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p_text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  _append_to_pipe ( char  * p_bytes ,  int  p_size ,  String  * r_pipe ,  Mutex  * p_pipe_mutex )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Try to convert from default ANSI code page to Unicode.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LocalVector < wchar_t >  wchars ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  total_wchars  =  MultiByteToWideChar ( CP_ACP ,  0 ,  p_bytes ,  p_size ,  nullptr ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( total_wchars  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wchars . resize ( total_wchars ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( MultiByteToWideChar ( CP_ACP ,  0 ,  p_bytes ,  p_size ,  wchars . ptr ( ) ,  total_wchars )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											wchars . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_pipe_mutex )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_pipe_mutex - > lock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( wchars . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Let's hope it's compatible with UTF-8.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( * r_pipe )  + =  String : : utf8 ( p_bytes ,  p_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( * r_pipe )  + =  String ( wchars . ptr ( ) ,  total_wchars ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_pipe_mutex )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_pipe_mutex - > unlock ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Dictionary  OS_Windows : : get_memory_info ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Dictionary  meminfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									meminfo [ " physical " ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									meminfo [ " free " ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									meminfo [ " available " ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									meminfo [ " stack " ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PERFORMANCE_INFORMATION  pref_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pref_info . cb  =  sizeof ( pref_info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetPerformanceInfo ( & pref_info ,  sizeof ( pref_info ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									typedef  void ( WINAPI  *  PGetCurrentThreadStackLimits ) ( PULONG_PTR ,  PULONG_PTR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PGetCurrentThreadStackLimits  GetCurrentThreadStackLimits  =  ( PGetCurrentThreadStackLimits ) GetProcAddress ( GetModuleHandleA ( " kernel32.dll " ) ,  " GetCurrentThreadStackLimits " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ULONG_PTR  LowLimit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ULONG_PTR  HighLimit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( GetCurrentThreadStackLimits )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetCurrentThreadStackLimits ( & LowLimit ,  & HighLimit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pref_info . PhysicalTotal  *  pref_info . PageSize  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:01:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										meminfo [ " physical " ]  =  static_cast < int64_t > ( pref_info . PhysicalTotal  *  pref_info . PageSize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pref_info . PhysicalAvailable  *  pref_info . PageSize  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:01:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										meminfo [ " free " ]  =  static_cast < int64_t > ( pref_info . PhysicalAvailable  *  pref_info . PageSize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pref_info . CommitLimit  *  pref_info . PageSize  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:01:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										meminfo [ " available " ]  =  static_cast < int64_t > ( pref_info . CommitLimit  *  pref_info . PageSize ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( HighLimit  -  LowLimit  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-07 11:01:20 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										meminfo [ " stack " ]  =  static_cast < int64_t > ( HighLimit  -  LowLimit ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 11:46:29 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  meminfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-07-16 14:38:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Dictionary  OS_Windows : : execute_with_pipe ( const  String  & p_path ,  const  List < String >  & p_arguments ,  bool  p_blocking )  {  
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define CLEAN_PIPES               \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_in [ 0 ]  ! =  0 )  {         \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_in [ 0 ] ) ;   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_in [ 1 ]  ! =  0 )  {         \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_in [ 1 ] ) ;   \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_out [ 0 ]  ! =  0 )  {        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_out [ 0 ] ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_out [ 1 ]  ! =  0 )  {        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_out [ 1 ] ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_err [ 0 ]  ! =  0 )  {        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_err [ 0 ] ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( pipe_err [ 1 ]  ! =  0 )  {        \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe_err [ 1 ] ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Dictionary  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  path  =  p_path . is_absolute_path ( )  ?  fix_path ( p_path )  :  p_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  command  =  _quote_command_line_argument ( path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  String  & E  :  p_arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										command  + =  "   "  +  _quote_command_line_argument ( E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create pipes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  pipe_in [ 2 ]  =  {  nullptr ,  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  pipe_out [ 2 ]  =  {  nullptr ,  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  pipe_err [ 2 ]  =  {  nullptr ,  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SECURITY_ATTRIBUTES  sa ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sa . nLength  =  sizeof ( SECURITY_ATTRIBUTES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sa . bInheritHandle  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sa . lpSecurityDescriptor  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! CreatePipe ( & pipe_in [ 0 ] ,  & pipe_in [ 1 ] ,  & sa ,  0 ) ,  ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! CreatePipe ( & pipe_out [ 0 ] ,  & pipe_out [ 1 ] ,  & sa ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CLEAN_PIPES 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V ( ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! CreatePipe ( & pipe_err [ 0 ] ,  & pipe_err [ 1 ] ,  & sa ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CLEAN_PIPES 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V ( ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! SetHandleInformation ( pipe_err [ 0 ] ,  HANDLE_FLAG_INHERIT ,  0 ) ,  ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Create process.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ProcessInfo  pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ZeroMemory ( & pi . si ,  sizeof ( pi . si ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pi . si . StartupInfo . cb  =  sizeof ( pi . si ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ZeroMemory ( & pi . pi ,  sizeof ( pi . pi ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LPSTARTUPINFOW  si_w  =  ( LPSTARTUPINFOW ) & pi . si . StartupInfo ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pi . si . StartupInfo . dwFlags  | =  STARTF_USESTDHANDLES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pi . si . StartupInfo . hStdInput  =  pipe_in [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pi . si . StartupInfo . hStdOutput  =  pipe_out [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pi . si . StartupInfo . hStdError  =  pipe_err [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 15:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SIZE_T  attr_list_size  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									InitializeProcThreadAttributeList ( nullptr ,  1 ,  0 ,  & attr_list_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pi . si . lpAttributeList  =  ( LPPROC_THREAD_ATTRIBUTE_LIST ) alloca ( attr_list_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! InitializeProcThreadAttributeList ( pi . si . lpAttributeList ,  1 ,  0 ,  & attr_list_size ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CLEAN_PIPES 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V ( ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  handles_to_inherit [ ]  =  {  pipe_in [ 0 ] ,  pipe_out [ 1 ] ,  pipe_err [ 1 ]  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! UpdateProcThreadAttribute ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pi . si . lpAttributeList , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												PROC_THREAD_ATTRIBUTE_HANDLE_LIST , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												handles_to_inherit , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sizeof ( handles_to_inherit ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nullptr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CLEAN_PIPES 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V ( ret ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  creation_flags  =  NORMAL_PRIORITY_CLASS  |  CREATE_NO_WINDOW  |  EXTENDED_STARTUPINFO_PRESENT ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Char16String  current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  str_len  =  GetCurrentDirectoryW ( 0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetCurrentDirectoryW ( current_dir_name . size ( ) ,  ( LPWSTR ) current_dir_name . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( current_dir_name . size ( )  > =  MAX_PATH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Char16String  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										str_len  =  GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  nullptr ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_short_dir_name . resize ( str_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  ( LPWSTR ) current_short_dir_name . ptrw ( ) ,  current_short_dir_name . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_dir_name  =  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! CreateProcessW ( nullptr ,  ( LPWSTR ) ( command . utf16 ( ) . ptrw ( ) ) ,  nullptr ,  nullptr ,  true ,  creation_flags ,  nullptr ,  ( LPWSTR ) current_dir_name . ptr ( ) ,  si_w ,  & pi . pi ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CLEAN_PIPES 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_FAIL_V_MSG ( ret ,  " Could not create child process:  "  +  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CloseHandle ( pipe_in [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CloseHandle ( pipe_out [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CloseHandle ( pipe_err [ 1 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ProcessID  pid  =  pi . pi . dwProcessId ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map_mutex . lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map - > insert ( pid ,  pi ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map_mutex . unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Ref < FileAccessWindowsPipe >  main_pipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									main_pipe . instantiate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-16 14:38:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_pipe - > open_existing ( pipe_out [ 0 ] ,  pipe_in [ 1 ] ,  p_blocking ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Ref < FileAccessWindowsPipe >  err_pipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err_pipe . instantiate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-16 14:38:01 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err_pipe - > open_existing ( pipe_err [ 0 ] ,  nullptr ,  p_blocking ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-10-19 14:35:10 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret [ " stdio " ]  =  main_pipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret [ " stderr " ]  =  err_pipe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ret [ " pid " ]  =  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef CLEAN_PIPES 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : execute ( const  String  & p_path ,  const  List < String >  & p_arguments ,  String  * r_pipe ,  int  * r_exitcode ,  bool  read_stderr ,  Mutex  * p_pipe_mutex ,  bool  p_open_console )  {  
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  path  =  p_path . is_absolute_path ( )  ?  fix_path ( p_path )  :  p_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  command  =  _quote_command_line_argument ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  String  & E  :  p_arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										command  + =  "   "  +  _quote_command_line_argument ( E ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 11:17:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ProcessInfo  pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ZeroMemory ( & pi . si ,  sizeof ( pi . si ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pi . si . StartupInfo . cb  =  sizeof ( pi . si ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ZeroMemory ( & pi . pi ,  sizeof ( pi . pi ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LPSTARTUPINFOW  si_w  =  ( LPSTARTUPINFOW ) & pi . si . StartupInfo ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  inherit_handles  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  pipe [ 2 ]  =  {  nullptr ,  nullptr  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( r_pipe )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Create pipe for StdOut and StdErr.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										SECURITY_ATTRIBUTES  sa ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sa . nLength  =  sizeof ( SECURITY_ATTRIBUTES ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sa . bInheritHandle  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sa . lpSecurityDescriptor  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_V ( ! CreatePipe ( & pipe [ 0 ] ,  & pipe [ 1 ] ,  & sa ,  0 ) ,  ERR_CANT_FORK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pi . si . StartupInfo . dwFlags  | =  STARTF_USESTDHANDLES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pi . si . StartupInfo . hStdOutput  =  pipe [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-01 16:51:53 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( read_stderr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pi . si . StartupInfo . hStdError  =  pipe [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 15:49:08 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										SIZE_T  attr_list_size  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										InitializeProcThreadAttributeList ( nullptr ,  1 ,  0 ,  & attr_list_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pi . si . lpAttributeList  =  ( LPPROC_THREAD_ATTRIBUTE_LIST ) alloca ( attr_list_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! InitializeProcThreadAttributeList ( pi . si . lpAttributeList ,  1 ,  0 ,  & attr_list_size ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( pipe [ 0 ] ) ;  // Cleanup pipe handles.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( pipe [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_V ( ERR_CANT_FORK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! UpdateProcThreadAttribute ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pi . si . lpAttributeList , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													PROC_THREAD_ATTRIBUTE_HANDLE_LIST , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													& pipe [ 1 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													sizeof ( HANDLE ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													nullptr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( pipe [ 0 ] ) ;  // Cleanup pipe handles.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CloseHandle ( pipe [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ERR_FAIL_V ( ERR_CANT_FORK ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										inherit_handles  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  creation_flags  =  NORMAL_PRIORITY_CLASS ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( inherit_handles )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										creation_flags  | =  EXTENDED_STARTUPINFO_PRESENT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_open_console )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creation_flags  | =  CREATE_NEW_CONSOLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creation_flags  | =  CREATE_NO_WINDOW ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Char16String  current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  str_len  =  GetCurrentDirectoryW ( 0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetCurrentDirectoryW ( current_dir_name . size ( ) ,  ( LPWSTR ) current_dir_name . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( current_dir_name . size ( )  > =  MAX_PATH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Char16String  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										str_len  =  GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  nullptr ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_short_dir_name . resize ( str_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  ( LPWSTR ) current_short_dir_name . ptrw ( ) ,  current_short_dir_name . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_dir_name  =  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ret  =  CreateProcessW ( nullptr ,  ( LPWSTR ) ( command . utf16 ( ) . ptrw ( ) ) ,  nullptr ,  nullptr ,  inherit_handles ,  creation_flags ,  nullptr ,  ( LPWSTR ) current_dir_name . ptr ( ) ,  si_w ,  & pi . pi ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ret  & &  r_pipe )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe [ 0 ] ) ;  // Cleanup pipe handles.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe [ 1 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( ret  = =  0 ,  ERR_CANT_FORK ,  " Could not create child process:  "  +  command ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( r_pipe )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pipe [ 1 ] ) ;  // Close pipe write handle (only child process is writing).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LocalVector < char >  bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  bytes_in_buffer  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  int  CHUNK_SIZE  =  4096 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										DWORD  read  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( ; ; )  {  // Read StdOut and StdErr from pipe.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bytes . resize ( bytes_in_buffer  +  CHUNK_SIZE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  bool  success  =  ReadFile ( pipe [ 0 ] ,  bytes . ptr ( )  +  bytes_in_buffer ,  CHUNK_SIZE ,  & read ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! success  | |  read  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Assume that all possible encodings are ASCII-compatible.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Break at newline to allow receiving long output in portions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  newline_index  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( int  i  =  read  -  1 ;  i  > =  0 ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( bytes [ bytes_in_buffer  +  i ]  = =  ' \n ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													newline_index  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-07 15:46:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( newline_index  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bytes_in_buffer  + =  read ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-07 15:46:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  int  bytes_to_convert  =  bytes_in_buffer  +  ( newline_index  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_append_to_pipe ( bytes . ptr ( ) ,  bytes_to_convert ,  r_pipe ,  p_pipe_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bytes_in_buffer  =  read  -  ( newline_index  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memmove ( bytes . ptr ( ) ,  bytes . ptr ( )  +  bytes_to_convert ,  bytes_in_buffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bytes_in_buffer  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_append_to_pipe ( bytes . ptr ( ) ,  bytes_in_buffer ,  r_pipe ,  p_pipe_mutex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-10 18:27:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CloseHandle ( pipe [ 0 ] ) ;  // Close pipe read handle.
 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-27 09:54:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WaitForSingleObject ( pi . pi . hProcess ,  INFINITE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( r_exitcode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DWORD  ret2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetExitCodeProcess ( pi . pi . hProcess ,  & ret2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_exitcode  =  ret2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CloseHandle ( pi . pi . hProcess ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CloseHandle ( pi . pi . hThread ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( r_pipe )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DeleteProcThreadAttributeList ( pi . si . lpAttributeList ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : create_process ( const  String  & p_path ,  const  List < String >  & p_arguments ,  ProcessID  * r_child_id ,  bool  p_open_console )  {  
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  path  =  p_path . is_absolute_path ( )  ?  fix_path ( p_path )  :  p_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  command  =  _quote_command_line_argument ( path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-15 23:45:57 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( const  String  & E  :  p_arguments )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										command  + =  "   "  +  _quote_command_line_argument ( E ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 16:34:15 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ProcessInfo  pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ZeroMemory ( & pi . si ,  sizeof ( pi . si ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pi . si . StartupInfo . cb  =  sizeof ( pi . si . StartupInfo ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ZeroMemory ( & pi . pi ,  sizeof ( pi . pi ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 18:37:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									LPSTARTUPINFOW  si_w  =  ( LPSTARTUPINFOW ) & pi . si . StartupInfo ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  creation_flags  =  NORMAL_PRIORITY_CLASS ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_open_console )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creation_flags  | =  CREATE_NEW_CONSOLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-16 15:00:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-27 03:11:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creation_flags  | =  CREATE_NO_WINDOW ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-14 14:43:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-25 21:54:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Char16String  current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  str_len  =  GetCurrentDirectoryW ( 0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetCurrentDirectoryW ( current_dir_name . size ( ) ,  ( LPWSTR ) current_dir_name . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( current_dir_name . size ( )  > =  MAX_PATH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Char16String  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										str_len  =  GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  nullptr ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_short_dir_name . resize ( str_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										GetShortPathNameW ( ( LPCWSTR ) current_dir_name . ptr ( ) ,  ( LPWSTR ) current_short_dir_name . ptrw ( ) ,  current_short_dir_name . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_dir_name  =  current_short_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ret  =  CreateProcessW ( nullptr ,  ( LPWSTR ) ( command . utf16 ( ) . ptrw ( ) ) ,  nullptr ,  nullptr ,  false ,  creation_flags ,  nullptr ,  ( LPWSTR ) current_dir_name . ptr ( ) ,  si_w ,  & pi . pi ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( ret  = =  0 ,  ERR_CANT_FORK ,  " Could not create child process:  "  +  command ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ProcessID  pid  =  pi . pi . dwProcessId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( r_child_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_child_id  =  pid ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-19 16:34:15 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map_mutex . lock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map - > insert ( pid ,  pi ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									process_map_mutex . unlock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 18:49:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 17:32:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : kill ( const  ProcessID  & p_pid )  {  
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ret  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MutexLock  lock ( process_map_mutex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( process_map - > has ( p_pid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  PROCESS_INFORMATION  pi  =  ( * process_map ) [ p_pid ] . pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										process_map - > erase ( p_pid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ret  =  TerminateProcess ( pi . hProcess ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										CloseHandle ( pi . hProcess ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( pi . hThread ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HANDLE  hProcess  =  OpenProcess ( PROCESS_TERMINATE ,  false ,  ( DWORD ) p_pid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( hProcess  ! =  nullptr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ret  =  TerminateProcess ( hProcess ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-12 14:41:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											CloseHandle ( hProcess ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-27 17:32:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ret  ! =  0  ?  OK  :  FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-07 17:17:31 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  OS_Windows : : get_process_id ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2016-04-29 13:57:57 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  _getpid ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-12 20:36:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  OS_Windows : : is_process_running ( const  ProcessID  & p_pid )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MutexLock  lock ( process_map_mutex ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-12 20:36:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! process_map - > has ( p_pid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  ProcessInfo  & info  =  ( * process_map ) [ p_pid ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! info . is_running )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-12 20:36:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  PROCESS_INFORMATION  & pi  =  info . pi ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-12 20:36:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  dw_exit_code  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! GetExitCodeProcess ( pi . hProcess ,  & dw_exit_code ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dw_exit_code  ! =  STILL_ACTIVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										info . is_running  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										info . exit_code  =  dw_exit_code ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-12 20:36:23 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-07 20:19:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  OS_Windows : : get_process_exit_code ( const  ProcessID  & p_pid )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MutexLock  lock ( process_map_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! process_map - > has ( p_pid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  ProcessInfo  & info  =  ( * process_map ) [ p_pid ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! info . is_running )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  info . exit_code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  PROCESS_INFORMATION  & pi  =  info . pi ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  dw_exit_code  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! GetExitCodeProcess ( pi . hProcess ,  & dw_exit_code ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dw_exit_code  = =  STILL_ACTIVE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . is_running  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									info . exit_code  =  dw_exit_code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  dw_exit_code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								Error  OS_Windows : : set_cwd ( const  String  & p_cwd )  {  
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( _wchdir ( ( LPCWSTR ) ( p_cwd . utf16 ( ) . get_data ( ) ) )  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  ERR_CANT_OPEN ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Vector < String >  OS_Windows : : get_system_fonts ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! dwrite_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Vector < String >  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HashSet < String >  font_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UINT32  family_count  =  font_collection - > GetFontFamilyCount ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( UINT32  i  =  0 ;  i  <  family_count ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ComAutoreleaseRef < IDWriteFontFamily >  family ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										HRESULT  hr  =  font_collection - > GetFontFamily ( i ,  & family . reference ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_CONTINUE ( FAILED ( hr )  | |  family . is_null ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ComAutoreleaseRef < IDWriteLocalizedStrings >  family_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  family - > GetFamilyNames ( & family_names . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_CONTINUE ( FAILED ( hr )  | |  family_names . is_null ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UINT32  index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BOOL  exists  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UINT32  length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Char16String  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  family_names - > FindLocaleName ( L " en-us " ,  & index ,  & exists ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_CONTINUE ( FAILED ( hr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  family_names - > GetStringLength ( index ,  & length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_CONTINUE ( FAILED ( hr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										name . resize ( length  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  family_names - > GetString ( index ,  ( WCHAR  * ) name . ptrw ( ) ,  length  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_CONTINUE ( FAILED ( hr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_names . insert ( String : : utf16 ( name . ptr ( ) ,  length ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( const  String  & E  :  font_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret . push_back ( E ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# if defined(__GNUC__) && !defined(__clang__) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma GCC diagnostic push 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma GCC diagnostic ignored "-Wnon-virtual-dtor" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  FallbackTextAnalysisSource  :  public  IDWriteTextAnalysisSource  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LONG  _cRef  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  rtl  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  locale ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									IDWriteNumberSubstitution  * n_sub  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								public :  
						 
					
						
							
								
									
										
										
										
											2023-01-30 16:59:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HRESULT  STDMETHODCALLTYPE  QueryInterface ( REFIID  riid ,  VOID  * * ppvInterface )  override  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( IID_IUnknown  = =  riid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AddRef ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* ppvInterface  =  ( IUnknown  * ) this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( __uuidof ( IMMNotificationClient )  = =  riid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AddRef ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* ppvInterface  =  ( IMMNotificationClient  * ) this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* ppvInterface  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  E_NOINTERFACE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 16:59:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ULONG  STDMETHODCALLTYPE  AddRef ( )  override  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  InterlockedIncrement ( & _cRef ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-30 16:59:38 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ULONG  STDMETHODCALLTYPE  Release ( )  override  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ULONG  ulRef  =  InterlockedDecrement ( & _cRef ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( 0  = =  ulRef )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delete  this ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ulRef ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  STDMETHODCALLTYPE  GetTextAtPosition ( UINT32  p_text_position ,  WCHAR  const  * * r_text_string ,  UINT32  * r_text_length )  override  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_text_position  > =  ( UINT32 ) string . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r_text_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r_text_length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_text_string  =  reinterpret_cast < const  wchar_t  * > ( string . get_data ( ) )  +  p_text_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_text_length  =  string . length ( )  -  p_text_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  STDMETHODCALLTYPE  GetTextBeforePosition ( UINT32  p_text_position ,  WCHAR  const  * * r_text_string ,  UINT32  * r_text_length )  override  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_text_position  <  1  | |  p_text_position  > =  ( UINT32 ) string . length ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r_text_string  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* r_text_length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_text_string  =  reinterpret_cast < const  wchar_t  * > ( string . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_text_length  =  p_text_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWRITE_READING_DIRECTION  STDMETHODCALLTYPE  GetParagraphReadingDirection ( )  override  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ( rtl )  ?  DWRITE_READING_DIRECTION_RIGHT_TO_LEFT  :  DWRITE_READING_DIRECTION_LEFT_TO_RIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  STDMETHODCALLTYPE  GetLocaleName ( UINT32  p_text_position ,  UINT32  * r_text_length ,  WCHAR  const  * * r_locale_name )  override  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_locale_name  =  reinterpret_cast < const  wchar_t  * > ( locale . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  STDMETHODCALLTYPE  GetNumberSubstitution ( UINT32  p_text_position ,  UINT32  * r_text_length ,  IDWriteNumberSubstitution  * * r_number_substitution )  override  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* r_number_substitution  =  n_sub ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  S_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FallbackTextAnalysisSource ( const  Char16String  & p_text ,  const  Char16String  & p_locale ,  bool  p_rtl ,  IDWriteNumberSubstitution  * p_nsub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										_cRef  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										string  =  p_text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										locale  =  p_locale ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										n_sub  =  p_nsub ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtl  =  p_rtl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									virtual  ~ FallbackTextAnalysisSource ( )  { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# if defined(__GNUC__) && !defined(__clang__) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma GCC diagnostic pop 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : _get_default_fontname ( const  String  & p_font_name )  const  {  
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  font_name  =  p_font_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( font_name . to_lower ( )  = =  " sans-serif " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_name  =  " Arial " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( font_name . to_lower ( )  = =  " serif " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_name  =  " Times New Roman " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( font_name . to_lower ( )  = =  " monospace " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_name  =  " Courier New " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( font_name . to_lower ( )  = =  " cursive " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_name  =  " Comic Sans MS " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( font_name . to_lower ( )  = =  " fantasy " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										font_name  =  " Gabriola " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  font_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								DWRITE_FONT_WEIGHT  OS_Windows : : _weight_to_dw ( int  p_weight )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_weight  <  150 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_THIN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  250 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_EXTRA_LIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  325 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_LIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  375 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_SEMI_LIGHT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  450 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_NORMAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  550 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_MEDIUM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  650 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_DEMI_BOLD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  750 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_BOLD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  850 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_EXTRA_BOLD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_weight  <  925 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_BLACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_WEIGHT_EXTRA_BLACK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								DWRITE_FONT_STRETCH  OS_Windows : : _stretch_to_dw ( int  p_stretch )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_stretch  <  56 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_ULTRA_CONDENSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  69 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_EXTRA_CONDENSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  81 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_CONDENSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  93 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_SEMI_CONDENSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  106 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_NORMAL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  137 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_SEMI_EXPANDED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  144 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_EXPANDED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p_stretch  <  162 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_EXTRA_EXPANDED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  DWRITE_FONT_STRETCH_ULTRA_EXPANDED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Vector < String >  OS_Windows : : get_system_font_path_for_text ( const  String  & p_font_name ,  const  String  & p_text ,  const  String  & p_locale ,  const  String  & p_script ,  int  p_weight ,  int  p_stretch ,  bool  p_italic )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-11-05 14:21:44 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// This may be called before TextServerManager has been created, which would cause a crash downstream if we do not check here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dwrite2_init  | |  ! TextServerManager : : get_singleton ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  font_name  =  _get_default_fontname ( p_font_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  rtl  =  TS - > is_locale_right_to_left ( p_locale ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  text  =  p_text . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  locale  =  p_locale . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteNumberSubstitution >  number_substitution ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HRESULT  hr  =  dwrite_factory - > CreateNumberSubstitution ( DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE ,  reinterpret_cast < const  wchar_t  * > ( locale . get_data ( ) ) ,  true ,  & number_substitution . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( FAILED ( hr )  | |  number_substitution . is_null ( ) ,  Vector < String > ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FallbackTextAnalysisSource  fs  =  FallbackTextAnalysisSource ( text ,  locale ,  rtl ,  number_substitution . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UINT32  mapped_length  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FLOAT  scale  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteFont >  dwrite_font ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  system_font_fallback - > MapCharacters ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& fs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( UINT32 ) text . length ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											font_collection , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reinterpret_cast < const  wchar_t  * > ( font_name . utf16 ( ) . get_data ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_weight_to_dw ( p_weight ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p_italic  ?  DWRITE_FONT_STYLE_ITALIC  :  DWRITE_FONT_STYLE_NORMAL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_stretch_to_dw ( p_stretch ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& mapped_length , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& dwrite_font . reference , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											& scale ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  dwrite_font . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteFontFace >  dwrite_face ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_font - > CreateFontFace ( & dwrite_face . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  dwrite_face . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UINT32  number_of_files  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_face - > GetFiles ( & number_of_files ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < ComAutoreleaseRef < IDWriteFontFile > >  files ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									files . resize ( number_of_files ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_face - > GetFiles ( & number_of_files ,  ( IDWriteFontFile  * * ) files . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  Vector < String > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < String >  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( UINT32  i  =  0 ;  i  <  number_of_files ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										void  const  * reference_key  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UINT32  reference_key_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ComAutoreleaseRef < IDWriteLocalFontFileLoader >  loader ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  files . write [ i ] - > GetLoader ( ( IDWriteFontFileLoader  * * ) & loader . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( FAILED ( hr )  | |  loader . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  files . write [ i ] - > GetReferenceKey ( & reference_key ,  & reference_key_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										WCHAR  file_path [ 32767 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  loader - > GetFilePathFromKey ( reference_key ,  reference_key_size ,  & file_path [ 0 ] ,  32767 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-27 23:19:43 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  fpath  =  String : : utf16 ( ( const  char16_t  * ) & file_path [ 0 ] ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WIN32_FIND_DATAW  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HANDLE  fnd  =  FindFirstFileW ( ( LPCWSTR ) & file_path [ 0 ] ,  & d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( fnd  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  fname  =  String : : utf16 ( ( const  char16_t  * ) d . cFileName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! fname . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fpath  =  fpath . get_base_dir ( ) . path_join ( fname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											FindClose ( fnd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret . push_back ( fpath ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_system_font_path ( const  String  & p_font_name ,  int  p_weight ,  int  p_stretch ,  bool  p_italic )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dwrite_init )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  font_name  =  _get_default_fontname ( p_font_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UINT32  index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BOOL  exists  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HRESULT  hr  =  font_collection - > FindFamilyName ( ( const  WCHAR  * ) font_name . utf16 ( ) . get_data ( ) ,  & index ,  & exists ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-12 14:08:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  ! exists )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteFontFamily >  family ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  font_collection - > GetFontFamily ( index ,  & family . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  family . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteFont >  dwrite_font ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hr  =  family - > GetFirstMatchingFont ( _weight_to_dw ( p_weight ) ,  _stretch_to_dw ( p_stretch ) ,  p_italic  ?  DWRITE_FONT_STYLE_ITALIC  :  DWRITE_FONT_STYLE_NORMAL ,  & dwrite_font . reference ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  dwrite_font . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ComAutoreleaseRef < IDWriteFontFace >  dwrite_face ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_font - > CreateFontFace ( & dwrite_face . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr )  | |  dwrite_face . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UINT32  number_of_files  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_face - > GetFiles ( & number_of_files ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < ComAutoreleaseRef < IDWriteFontFile > >  files ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									files . resize ( number_of_files ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hr  =  dwrite_face - > GetFiles ( & number_of_files ,  ( IDWriteFontFile  * * ) files . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( UINT32  i  =  0 ;  i  <  number_of_files ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										void  const  * reference_key  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UINT32  reference_key_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ComAutoreleaseRef < IDWriteLocalFontFileLoader >  loader ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  files . write [ i ] - > GetLoader ( ( IDWriteFontFileLoader  * * ) & loader . reference ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( FAILED ( hr )  | |  loader . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  files . write [ i ] - > GetReferenceKey ( & reference_key ,  & reference_key_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										WCHAR  file_path [ 32767 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hr  =  loader - > GetFilePathFromKey ( reference_key ,  reference_key_size ,  & file_path [ 0 ] ,  32767 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( FAILED ( hr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-12-27 23:19:43 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  fpath  =  String : : utf16 ( ( const  char16_t  * ) & file_path [ 0 ] ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-17 09:39:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WIN32_FIND_DATAW  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HANDLE  fnd  =  FindFirstFileW ( ( LPCWSTR ) & file_path [ 0 ] ,  & d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( fnd  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											String  fname  =  String : : utf16 ( ( const  char16_t  * ) d . cFileName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! fname . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fpath  =  fpath . get_base_dir ( ) . path_join ( fname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											FindClose ( fnd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fpath ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-08 15:38:30 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-15 02:01:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_executable_path ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WCHAR  bufname [ 4096 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									GetModuleFileNameW ( nullptr ,  bufname ,  4096 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-22 11:17:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  s  =  String : : utf16 ( ( const  char16_t  * ) bufname ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-15 02:01:39 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  OS_Windows : : has_environment ( const  String  & p_var )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-09-03 16:02:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  GetEnvironmentVariableW ( ( LPCWSTR ) ( p_var . utf16 ( ) . get_data ( ) ) ,  nullptr ,  0 )  >  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_environment ( const  String  & p_var )  const  {  
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									WCHAR  wval [ 0x7fff ] ;  // MSDN says 32767 char is the maximum
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  wlen  =  GetEnvironmentVariableW ( ( LPCWSTR ) ( p_var . utf16 ( ) . get_data ( ) ) ,  wval ,  0x7fff ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-04 13:12:05 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( wlen  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  String : : utf16 ( ( const  char16_t  * ) wval ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-04 13:12:05 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-13 18:03:28 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-05-04 13:12:05 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:26:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : set_environment ( const  String  & p_var ,  const  String  & p_value )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-12-05 17:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_MSG ( p_var . is_empty ( )  | |  p_var . contains_char ( ' = ' ) ,  vformat ( " Invalid environment variable name '%s', cannot be empty or include '='. " ,  p_var ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:26:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Char16String  var  =  p_var . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  value  =  p_value . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_MSG ( var . length ( )  +  value . length ( )  +  2  >  32767 ,  vformat ( " Invalid definition for environment variable '%s', cannot exceed 32767 characters. " ,  p_var ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SetEnvironmentVariableW ( ( LPCWSTR ) ( var . get_data ( ) ) ,  ( LPCWSTR ) ( value . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  OS_Windows : : unset_environment ( const  String  & p_var )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-12-05 17:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_MSG ( p_var . is_empty ( )  | |  p_var . contains_char ( ' = ' ) ,  vformat ( " Invalid environment variable name '%s', cannot be empty or include '='. " ,  p_var ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 14:26:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SetEnvironmentVariableW ( ( LPCWSTR ) ( p_var . utf16 ( ) . get_data ( ) ) ,  nullptr ) ;  // Null to delete.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-29 22:59:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 10:34:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_stdin_string ( int64_t  p_buffer_size )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( get_stdin_type ( )  = =  STD_HANDLE_INVALID )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < uint8_t >  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data . resize ( p_buffer_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-29 21:06:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 10:34:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ReadFile ( GetStdHandle ( STD_INPUT_HANDLE ) ,  data . ptrw ( ) ,  data . size ( ) ,  & count ,  nullptr ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-22 16:26:25 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  String : : utf8 ( ( const  char  * ) data . ptr ( ) ,  count ) . replace ( " \r \n " ,  " \n " ) . rstrip ( " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  String ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-26 10:34:35 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								PackedByteArray  OS_Windows : : get_stdin_buffer ( int64_t  p_buffer_size )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Vector < uint8_t >  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									data . resize ( p_buffer_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ReadFile ( GetStdHandle ( STD_INPUT_HANDLE ) ,  data . ptrw ( ) ,  data . size ( ) ,  & count ,  nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  PackedByteArray ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OS_Windows : : StdHandleType  OS_Windows : : get_stdin_type ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h  =  GetStdHandle ( STD_INPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( h  = =  0  | |  h  = =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_INVALID ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  ftype  =  GetFileType ( h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_UNKNOWN  & &  GetLastError ( )  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ftype  & =  ~ ( FILE_TYPE_REMOTE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_DISK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_FILE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ftype  = =  FILE_TYPE_PIPE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_PIPE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DWORD  conmode  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BOOL  res  =  GetConsoleMode ( h ,  & conmode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! res  & &  ( GetLastError ( )  = =  ERROR_INVALID_HANDLE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_UNKNOWN ;  // Unknown character device.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef WINDOWS_SUBSYSTEM_CONSOLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! is_using_con_wrapper ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  STD_HANDLE_INVALID ;  // Window app can't read stdin input without werapper.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_CONSOLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OS_Windows : : StdHandleType  OS_Windows : : get_stdout_type ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h  =  GetStdHandle ( STD_OUTPUT_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( h  = =  0  | |  h  = =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_INVALID ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  ftype  =  GetFileType ( h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_UNKNOWN  & &  GetLastError ( )  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ftype  & =  ~ ( FILE_TYPE_REMOTE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_DISK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_FILE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ftype  = =  FILE_TYPE_PIPE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_PIPE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DWORD  conmode  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BOOL  res  =  GetConsoleMode ( h ,  & conmode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! res  & &  ( GetLastError ( )  = =  ERROR_INVALID_HANDLE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_UNKNOWN ;  // Unknown character device.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_CONSOLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								OS_Windows : : StdHandleType  OS_Windows : : get_stderr_type ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  h  =  GetStdHandle ( STD_ERROR_HANDLE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( h  = =  0  | |  h  = =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_INVALID ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  ftype  =  GetFileType ( h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_UNKNOWN  & &  GetLastError ( )  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ftype  & =  ~ ( FILE_TYPE_REMOTE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ftype  = =  FILE_TYPE_DISK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_FILE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ftype  = =  FILE_TYPE_PIPE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  STD_HANDLE_PIPE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DWORD  conmode  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BOOL  res  =  GetConsoleMode ( h ,  & conmode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! res  & &  ( GetLastError ( )  = =  ERROR_INVALID_HANDLE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_UNKNOWN ;  // Unknown character device.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  STD_HANDLE_CONSOLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-01-08 22:36:19 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : shell_open ( const  String  & p_uri )  {  
						 
					
						
							
								
									
										
										
										
											2021-09-19 11:29:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									INT_PTR  ret  =  ( INT_PTR ) ShellExecuteW ( nullptr ,  nullptr ,  ( LPCWSTR ) ( p_uri . utf16 ( ) . get_data ( ) ) ,  nullptr ,  nullptr ,  SW_SHOWNORMAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ret  >  32 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( ret )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_FILE_NOT_FOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_DLLNOTFOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_PATH_NOT_FOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_BAD_PATH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_BAD_FORMAT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_CORRUPT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_ACCESSDENIED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_UNAUTHORIZED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_OOM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_OUT_OF_MEMORY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-04-18 11:43:54 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 11:33:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : shell_show_in_file_manager ( String  p_path ,  bool  p_open_folder )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bool  open_folder  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( DirAccess : : dir_exists_absolute ( p_path )  & &  p_open_folder )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										open_folder  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-02 22:25:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p_path . is_quoted ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p_path  =  p_path . quote ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 11:33:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p_path  =  fix_path ( p_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-07 11:33:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									INT_PTR  ret  =  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( open_folder )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  ( INT_PTR ) ShellExecuteW ( nullptr ,  nullptr ,  L " explorer.exe " ,  LPCWSTR ( p_path . utf16 ( ) . get_data ( ) ) ,  nullptr ,  SW_SHOWNORMAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ret  =  ( INT_PTR ) ShellExecuteW ( nullptr ,  nullptr ,  L " explorer.exe " ,  LPCWSTR ( ( String ( " /select, " )  +  p_path ) . utf16 ( ) . get_data ( ) ) ,  nullptr ,  SW_SHOWNORMAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ret  >  32 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( ret )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_FILE_NOT_FOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_DLLNOTFOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_PATH_NOT_FOUND : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_BAD_PATH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ERROR_BAD_FORMAT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_FILE_CORRUPT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_ACCESSDENIED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_UNAUTHORIZED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  SE_ERR_OOM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ERR_OUT_OF_MEMORY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_locale ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  _WinLocale  * wl  =  & _win_locales [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LANGID  langid  =  GetUserDefaultUILanguage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  neutral ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 23:42:11 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  lang  =  PRIMARYLANGID ( langid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  sublang  =  SUBLANGID ( langid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( wl - > locale )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( wl - > main_lang  = =  lang  & &  wl - > sublang  = =  SUBLANG_NEUTRAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											neutral  =  wl - > locale ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( lang  = =  wl - > main_lang  & &  sublang  = =  wl - > sublang )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 23:42:11 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  String ( wl - > locale ) . replace ( " - " ,  " _ " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										wl + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! neutral . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-25 23:42:11 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  String ( neutral ) . replace ( " - " ,  " _ " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " en " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-11 22:08:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_model_name ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HKEY  hkey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( RegOpenKeyExW ( HKEY_LOCAL_MACHINE ,  L " Hardware \\ Description \\ System \\ BIOS " ,  0 ,  KEY_QUERY_VALUE ,  & hkey )  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  OS : : get_model_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  sys_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  board_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WCHAR  buffer [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  buffer_len  =  256 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  vtype  =  REG_SZ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( RegQueryValueExW ( hkey ,  L " SystemProductName " ,  nullptr ,  & vtype ,  ( LPBYTE ) buffer ,  & buffer_len )  = =  ERROR_SUCCESS  & &  buffer_len  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sys_name  =  String : : utf16 ( ( const  char16_t  * ) buffer ,  buffer_len ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buffer_len  =  256 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( RegQueryValueExW ( hkey ,  L " BaseBoardProduct " ,  nullptr ,  & vtype ,  ( LPBYTE ) buffer ,  & buffer_len )  = =  ERROR_SUCCESS  & &  buffer_len  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										board_name  =  String : : utf16 ( ( const  char16_t  * ) buffer ,  buffer_len ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! sys_name . is_empty ( )  & &  sys_name . to_lower ( )  ! =  " system product name " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  sys_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! board_name . is_empty ( )  & &  board_name . to_lower ( )  ! =  " base board product " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  board_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OS : : get_model_name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 01:50:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_processor_name ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  String  id  =  " Hardware \\ Description \\ System \\ CentralProcessor \\ 0 " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HKEY  hkey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( RegOpenKeyExW ( HKEY_LOCAL_MACHINE ,  ( LPCWSTR ) ( id . utf16 ( ) . get_data ( ) ) ,  0 ,  KEY_QUERY_VALUE ,  & hkey )  ! =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V_MSG ( " " ,  String ( " Couldn't get the CPU model name. Returning an empty string. " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WCHAR  buffer [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  buffer_len  =  256 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  vtype  =  REG_SZ ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-03-12 09:40:40 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( RegQueryValueExW ( hkey ,  L " ProcessorNameString " ,  nullptr ,  & vtype ,  ( LPBYTE ) buffer ,  & buffer_len )  = =  ERROR_SUCCESS )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-27 01:50:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  String : : utf16 ( ( const  char16_t  * ) buffer ,  buffer_len ) . strip_edges ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RegCloseKey ( hkey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_V_MSG ( " " ,  String ( " Couldn't get the CPU model name. Returning an empty string. " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  OS_Windows : : run ( )  {  
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! main_loop )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-22 09:50:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_loop - > initialize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 20:29:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										DisplayServer : : get_singleton ( ) - > process_events ( ) ;  // get rid of pending events
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( Main : : iteration ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-22 09:50:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									main_loop - > finalize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								MainLoop  * OS_Windows : : get_main_loop ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  main_loop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 11:28:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint64_t  OS_Windows : : get_embedded_pck_offset ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Ref < FileAccess >  f  =  FileAccess : : open ( get_executable_path ( ) ,  FileAccess : : READ ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( f . is_null ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Process header.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( 0x3c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint32_t  pe_pos  =  f - > get_32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( pe_pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint32_t  magic  =  f - > get_32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( magic  ! =  0x00004550 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  num_sections ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64_t  header_pos  =  f - > get_position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( header_pos  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										num_sections  =  f - > get_16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( header_pos  +  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint16_t  opt_header_size  =  f - > get_16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Skip rest of header + optional header to go to the section headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( f - > get_position ( )  +  2  +  opt_header_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int64_t  section_table_pos  =  f - > get_position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Search for the "pck" section.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int64_t  off  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( int  i  =  0 ;  i  <  num_sections ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int64_t  section_header_pos  =  section_table_pos  +  i  *  40 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > seek ( section_header_pos ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint8_t  section_name [ 9 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > get_buffer ( section_name ,  8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										section_name [ 8 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcmp ( ( char  * ) section_name ,  " pck " )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f - > seek ( section_header_pos  +  20 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											off  =  f - > get_32 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  off ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_config_path ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2021-05-21 12:48:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( has_environment ( " APPDATA " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 23:41:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  get_environment ( " APPDATA " ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 12:48:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  " . " ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_data_path ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2021-05-21 12:48:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  get_config_path ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_cache_path ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2021-02-22 22:54:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  String  cache_path_cache ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cache_path_cache . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-07 19:00:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( has_environment ( " LOCALAPPDATA " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 22:54:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cache_path_cache  =  get_environment ( " LOCALAPPDATA " ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( cache_path_cache . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-21 15:02:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cache_path_cache  =  get_temp_path ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-07 19:02:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-05-21 12:48:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-22 22:54:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  cache_path_cache ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-10-21 15:02:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_temp_path ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  String  temp_path_cache ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( temp_path_cache . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Vector < WCHAR >  temp_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// The maximum possible size is MAX_PATH+1 (261) + terminating null character.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											temp_path . resize ( MAX_PATH  +  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											DWORD  temp_path_length  =  GetTempPathW ( temp_path . size ( ) ,  temp_path . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( temp_path_length  >  0  & &  temp_path_length  <  temp_path . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												temp_path_cache  =  String : : utf16 ( ( const  char16_t  * ) temp_path . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Let's try to get the long path instead of the short path (with tildes ~).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												DWORD  temp_path_long_length  =  GetLongPathNameW ( temp_path . ptr ( ) ,  temp_path . ptrw ( ) ,  temp_path . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( temp_path_long_length  >  0  & &  temp_path_long_length  <  temp_path . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													temp_path_cache  =  String : : utf16 ( ( const  char16_t  * ) temp_path . ptr ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( temp_path_cache . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											temp_path_cache  =  get_config_path ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-26 15:14:45 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  temp_path_cache . replace ( " \\ " ,  " / " ) . trim_suffix ( " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-21 15:02:08 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Get properly capitalized engine name for system paths
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  OS_Windows : : get_godot_dir_name ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2017-11-19 21:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  String ( VERSION_SHORT_NAME ) . capitalize ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Add initial support for the XDG Base Directory spec
Spec version 0.7 from https://standards.freedesktop.org/basedir-spec/basedir-spec-0.7.html
(latest as of this commit).
Three virtual methods are added to OS for the various XDG paths we will use:
- OS::get_data_path gives XDG_DATA_HOME, or if missing:
  ~/.local/share on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_config_path gives XDG_CONFIG_HOME, or if missing:
  ~/.config on X11, ~/Library/Application Support/ on macOS and %APPDATA% on Windows
- OS::get_cache_path gives XDG_CACHE_HOME, or if missing:
  ~/.cache on X11, ~/Library/Caches on macOS and %APPDATA% on Windows
So for Windows there are no changes, for Linux we follow the full split spec
and for macOS stuff will move from ~/.godot to ~/Library/Application Support/Godot.
Support for system-wide installation of templates on Unix was removed for now,
as it's a bit hackish and I don't think anyone uses it.
user:// will still be OS::get_data_path() + "/godot/app_userdata/$name" by
default, but when using the application/config/use_shared_user_dir option
it will now use XDG_DATA_HOME/$name, e.g. ~/.local/share/MyGame.
For now everything still goes in EditorSettings::get_settings_dir(), but
this will be changed in a later commit to make use of the new splitting
where relevant.
Part of #3513.
											 
										 
										
											2017-11-17 17:11:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-10 18:39:31 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_system_dir ( SystemDir  p_dir ,  bool  p_shared_storage )  const  {  
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									KNOWNFOLDERID  id ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p_dir )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_DESKTOP :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Desktop ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_DCIM :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Pictures ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_DOCUMENTS :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Documents ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_DOWNLOADS :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Downloads ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_MOVIES :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Videos ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_MUSIC :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Music ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_PICTURES :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Pictures ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  SYSTEM_DIR_RINGTONES :  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											id  =  FOLDERID_Music ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									PWSTR  szPath ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HRESULT  res  =  SHGetKnownFolderPath ( id ,  0 ,  nullptr ,  & szPath ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( res  ! =  S_OK ,  String ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 23:41:17 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  path  =  String : : utf16 ( ( const  char16_t  * ) szPath ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-18 02:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CoTaskMemFree ( szPath ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  path ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-02 14:02:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-30 21:13:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_user_data_dir ( const  String  & p_user_dir )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  get_data_path ( ) . path_join ( p_user_dir ) . replace ( " \\ " ,  " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-20 21:40:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_unique_id ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2022-05-21 18:41:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HW_PROFILE_INFOA  HwProfInfo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! GetCurrentHwProfileA ( & HwProfInfo ) ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  String ( ( HwProfInfo . szHwProfileGuid ) ,  HW_PROFILE_GUIDLEN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-20 21:40:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-19 17:00:46 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  OS_Windows : : _check_internal_feature_support ( const  String  & p_feature )  {  
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:12:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_feature  = =  " system_fonts " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 15:04:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  dwrite_init ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-31 19:12:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_feature  = =  " pc " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 18:07:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-06-05 19:14:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-07 22:01:49 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : disable_crash_handler ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									crash_handler . disable ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  OS_Windows : : is_disable_crash_handler ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  crash_handler . is_disabled ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  OS_Windows : : move_to_trash ( const  String  & p_path )  {  
						 
					
						
							
								
									
										
										
										
											2018-08-14 11:49:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									SHFILEOPSTRUCTW  sf ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  utf16  =  p_path . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									WCHAR  * from  =  new  WCHAR [ utf16 . length ( )  +  2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									wcscpy_s ( from ,  utf16 . length ( )  +  1 ,  ( LPCWSTR ) ( utf16 . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									from [ utf16 . length ( )  +  1 ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 01:30:22 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . hwnd  =  main_window ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . wFunc  =  FO_DELETE ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 01:30:22 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . pFrom  =  from ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . pTo  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . fFlags  =  FOF_ALLOWUNDO  |  FOF_NOCONFIRMATION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sf . fAnyOperationsAborted  =  FALSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sf . hNameMappings  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sf . lpszProgressTitle  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-14 11:49:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ret  =  SHFileOperationW ( & sf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 01:30:22 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									delete [ ]  from ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-06 17:03:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ERR_PRINT ( " SHFileOperation error:  "  +  itos ( ret ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-25 10:15:11 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 21:17:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  OS_Windows : : get_system_ca_certificates ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HCERTSTORE  cert_store  =  CertOpenSystemStoreA ( 0 ,  " ROOT " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V_MSG ( cert_store ,  " " ,  " Failed to read the root certificate store. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 21:17:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-14 14:38:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FILETIME  curr_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetSystemTimeAsFileTime ( & curr_time ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 21:17:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  certs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PCCERT_CONTEXT  curr  =  CertEnumCertificatesInStore ( cert_store ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( curr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-14 14:38:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										FILETIME  ft ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DWORD  size  =  sizeof ( ft ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Check if the certificate is disallowed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( CertGetCertificateContextProperty ( curr ,  CERT_DISALLOWED_FILETIME_PROP_ID ,  & ft ,  & size )  & &  CompareFileTime ( & curr_time ,  & ft )  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											curr  =  CertEnumCertificatesInStore ( cert_store ,  curr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Encode and add to certificate list.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-13 21:17:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bool  success  =  CryptBinaryToStringA ( curr - > pbCertEncoded ,  curr - > cbCertEncoded ,  CRYPT_STRING_BASE64HEADER  |  CRYPT_STRING_NOCR ,  nullptr ,  & size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_CONTINUE ( ! success ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										PackedByteArray  pba ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pba . resize ( size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CryptBinaryToStringA ( curr - > pbCertEncoded ,  curr - > cbCertEncoded ,  CRYPT_STRING_BASE64HEADER  |  CRYPT_STRING_NOCR ,  ( char  * ) pba . ptrw ( ) ,  & size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										certs  + =  String ( ( char  * ) pba . ptr ( ) ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										curr  =  CertEnumCertificatesInStore ( cert_store ,  curr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CertCloseStore ( cert_store ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  certs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 13:27:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  OS_Windows : : add_frame_delay ( bool  p_can_draw )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  uint32_t  frame_delay  =  Engine : : get_singleton ( ) - > get_frame_delay ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frame_delay )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add fixed frame delay to decrease CPU/GPU usage. This doesn't take
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// the actual frame time into account.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Due to the high fluctuation of the actual sleep duration, it's not recommended
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// to use this as a FPS limiter.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										delay_usec ( frame_delay  *  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add a dynamic frame delay to decrease CPU/GPU usage. This takes the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// previous frame time into account for a smoother result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  dynamic_delay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_in_low_processor_usage_mode ( )  | |  ! p_can_draw )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dynamic_delay  =  get_low_processor_usage_mode_sleep_usec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  int  max_fps  =  Engine : : get_singleton ( ) - > get_max_fps ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( max_fps  >  0  & &  ! Engine : : get_singleton ( ) - > is_editor_hint ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Override the low processor usage mode sleep delay if the target FPS is lower.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dynamic_delay  =  MAX ( dynamic_delay ,  ( uint64_t ) ( 1000000  /  max_fps ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( dynamic_delay  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										target_ticks  + =  dynamic_delay ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint64_t  current_ticks  =  get_ticks_usec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-30 02:30:05 -08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( target_ticks  >  current_ticks  +  delay_resolution )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uint64_t  delay_time  =  target_ticks  -  current_ticks  -  delay_resolution ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Make sure we always sleep for a multiple of delay_resolution to avoid overshooting.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Refer to: https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep#remarks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											delay_time  =  ( delay_time  /  delay_resolution )  *  delay_resolution ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( delay_time  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												delay_usec ( delay_time ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-28 13:27:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Busy wait for the remainder of time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( get_ticks_usec ( )  <  target_ticks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											YieldProcessor ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										current_ticks  =  get_ticks_usec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										target_ticks  =  MIN ( MAX ( target_ticks ,  current_ticks  -  dynamic_delay ) ,  current_ticks  +  dynamic_delay ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								OS_Windows : : OS_Windows ( HINSTANCE  _hInstance )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hInstance  =  _hInstance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reset CWD to ensure long path is used.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  str_len  =  GetCurrentDirectoryW ( 0 ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetCurrentDirectoryW ( current_dir_name . size ( ) ,  ( LPWSTR ) current_dir_name . ptrw ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Char16String  new_current_dir_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									str_len  =  GetLongPathNameW ( ( LPCWSTR ) current_dir_name . get_data ( ) ,  nullptr ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									new_current_dir_name . resize ( str_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetLongPathNameW ( ( LPCWSTR ) current_dir_name . get_data ( ) ,  ( LPWSTR ) new_current_dir_name . ptrw ( ) ,  new_current_dir_name . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SetCurrentDirectoryW ( ( LPCWSTR ) new_current_dir_name . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-25 12:56:07 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifndef WINDOWS_SUBSYSTEM_CONSOLE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RedirectIOToConsole ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SetConsoleOutputCP ( CP_UTF8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SetConsoleCP ( CP_UTF8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-20 12:14:16 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CoInitializeEx ( nullptr ,  COINIT_APARTMENTTHREADED ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-10 10:38:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-08-27 14:01:34 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef WASAPI_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AudioDriverManager : : add_driver ( & driver_wasapi ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2016-10-17 13:40:45 -02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef XAUDIO2_ENABLED 
  
						 
					
						
							
								
									
										
										
										
											2017-01-16 19:19:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AudioDriverManager : : add_driver ( & driver_xaudio2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-17 13:40:45 -02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2017-09-22 12:56:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-09 12:56:48 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DisplayServerWindows : : register_windows_driver ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 12:50:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Enable ANSI escape code support on Windows 10 v1607 (Anniversary Update) and later.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// This lets the engine and projects use ANSI escape codes to color text just like on macOS and Linux.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// NOTE: The engine does not use ANSI escape codes to color error/warning messages; it uses Windows API calls instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Therefore, error/warning messages are still colored on Windows versions older than 10.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-11 10:09:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HANDLE  stdoutHandle  =  GetStdHandle ( STD_OUTPUT_HANDLE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-07-28 00:29:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  outMode  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									GetConsoleMode ( stdoutHandle ,  & outMode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									outMode  | =  ENABLE_PROCESSED_OUTPUT  |  ENABLE_VIRTUAL_TERMINAL_PROCESSING ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-05 12:50:20 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! SetConsoleMode ( stdoutHandle ,  outMode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Windows 8.1 or below, or Windows 10 prior to Anniversary Update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										print_verbose ( " Can't set the ENABLE_VIRTUAL_TERMINAL_PROCESSING Windows console mode. `print_rich()` will not work as expected. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-21 16:35:01 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Vector < Logger  * >  loggers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									loggers . push_back ( memnew ( WindowsTerminalLogger ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_set_logger ( memnew ( CompositeLogger ( loggers ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-09 00:00:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								OS_Windows : : ~ OS_Windows ( )  {  
						 
					
						
							
								
									
										
										
										
											2023-04-10 10:38:25 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CoUninitialize ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}