2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*  file_access_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.                 */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/**************************************************************************/  
						 
					
						
							
								
									
										
										
										
											2018-01-05 00:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef WINDOWS_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "file_access_windows.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-08-24 09:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/config/project_settings.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-08-24 09:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/os/os.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-11-07 19:33:38 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "core/string/print_string.h" 
  
						 
					
						
							
								
									
										
										
										
											2023-09-25 15:14:29 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 13:01:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <share.h>   // _SH_DENYNO
  
						 
					
						
							
								
									
										
										
										
											2018-08-24 09:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <shlwapi.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-23 08:56:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define WIN32_LEAN_AND_MEAN 
  
						 
					
						
							
								
									
										
										
										
											2015-03-15 09:43:13 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <windows.h> 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-08 22:09:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <io.h> 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <sys/stat.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/types.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <tchar.h> 
  
						 
					
						
							
								
									
										
										
										
											2025-04-28 16:05:13 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <cerrno> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <cwchar> 
  
						 
					
						
							
								
									
										
										
										
											2015-03-02 00:54:10 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# ifdef _MSC_VER 
  
						 
					
						
							
								
									
										
										
										
											2024-02-28 14:25:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define S_ISREG(m) ((m) & _S_IFREG) 
  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-02 12:03:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : check_errors ( bool  p_write )  const  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-02 12:03:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									last_error  =  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ferror ( f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_write )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											last_error  =  ERR_FILE_CANT_WRITE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											last_error  =  ERR_FILE_CANT_READ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p_write  & &  feof ( f ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-14 18:03:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										last_error  =  ERR_FILE_EOF ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  FileAccessWindows : : is_path_invalid ( const  String  & p_path )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check for invalid operating system file.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 18:11:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  fname  =  p_path . get_file ( ) . to_lower ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-16 18:52:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  dot  =  fname . find_char ( ' . ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-02-09 18:11:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( dot  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fname  =  fname . substr ( 0 ,  dot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  invalid_files . has ( fname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-05 02:12:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								String  FileAccessWindows : : fix_path ( const  String  & p_path )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  r_path  =  FileAccess : : fix_path ( p_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( r_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 ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 12:15:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r_path  =  String : : utf16 ( ( const  char16_t  * ) current_dir_name . get_data ( ) ) . trim_prefix ( R " ( \\ ? \ ) " ) . replace_char ( ' \\ ' ,  ' / ' ) . path_join ( r_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r_path  =  r_path . simplify_path ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-28 12:15:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r_path  =  r_path . replace_char ( ' / ' ,  ' \\ ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! r_path . is_network_share_path ( )  & &  ! r_path . begins_with ( R " ( \\ ? \ ) " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r_path  =  R " ( \\ ? \ ) "  +  r_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-05 02:12:55 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  r_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-05 13:01:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  FileAccessWindows : : open_internal ( const  String  & p_path ,  int  p_mode_flags )  {  
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_path_invalid ( p_path ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef DEBUG_ENABLED 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p_mode_flags  ! =  READ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											WARN_PRINT ( " The path : "  +  p_path  +  "  is a reserved Windows system pipe, so it can't be used for creating files. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ERR_INVALID_PARAMETER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 11:15:02 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_close ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 11:45:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									path_src  =  p_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  =  fix_path ( p_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  WCHAR  * mode_string ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p_mode_flags  = =  READ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										mode_string  =  L " rb " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( p_mode_flags  = =  WRITE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										mode_string  =  L " wb " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( p_mode_flags  = =  READ_WRITE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-10 15:15:04 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mode_string  =  L " rb+ " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( p_mode_flags  = =  WRITE_READ )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-02 12:03:33 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mode_string  =  L " wb+ " ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  ERR_INVALID_PARAMETER ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-09-11 09:44:53 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( path . ends_with ( " : \\ " )  | |  path . ends_with ( " : " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ERR_FILE_CANT_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  file_attr  =  GetFileAttributesW ( ( LPCWSTR ) ( path . utf16 ( ) . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( file_attr  ! =  INVALID_FILE_ATTRIBUTES  & &  ( file_attr  &  FILE_ATTRIBUTE_DIRECTORY ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ERR_FILE_CANT_OPEN ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-15 17:05:12 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef TOOLS_ENABLED 
  
						 
					
						
							
								
									
										
										
										
											2019-01-09 10:24:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Windows is case insensitive in the default configuration, but other platforms can be sensitive to it
 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-18 14:41:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// To ease cross-platform development, we issue a warning if users try to access
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// a file using the wrong case (which *works* on Windows, but won't on other
 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// platforms), we only check for relative paths, or paths in res:// or user://,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// other paths aren't likely to be portable anyway.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_mode_flags  = =  READ  & &  ( p_path . is_relative_path ( )  | |  get_access_type ( )  ! =  ACCESS_FILESYSTEM ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  base_path  =  p_path ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										String  working_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  proper_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( get_access_type ( )  = =  ACCESS_RESOURCES )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ProjectSettings : : get_singleton ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												working_path  =  ProjectSettings : : get_singleton ( ) - > get_resource_path ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! working_path . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													base_path  =  working_path . path_to_file ( base_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-15 17:05:12 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											proper_path  =  " res:// " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( get_access_type ( )  = =  ACCESS_USERDATA )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											working_path  =  OS : : get_singleton ( ) - > get_user_data_dir ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! working_path . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												base_path  =  working_path . path_to_file ( base_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											proper_path  =  " user:// " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										working_path  =  fix_path ( working_path ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										WIN32_FIND_DATAW  d ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Vector < String >  parts  =  base_path . simplify_path ( ) . split ( " / " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  mismatch  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( const  String  & part  :  parts )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											working_path  =  working_path  +  " \\ "  +  part ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HANDLE  fnd  =  FindFirstFileW ( ( LPCWSTR ) ( working_path . utf16 ( ) . get_data ( ) ) ,  & d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( fnd  = =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mismatch  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  String  fname  =  String : : utf16 ( ( const  char16_t  * ) ( d . cFileName ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-29 12:53:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											FindClose ( fnd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:04:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! mismatch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mismatch  =  ( part  ! =  fname  & &  part . findn ( fname )  = =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											proper_path  =  proper_path . path_join ( fname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mismatch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											WARN_PRINT ( " Case mismatch opening requested file ' "  +  p_path  +  " ', stored as ' "  +  proper_path  +  " ' in the filesystem. This file will not open when exported to other case-sensitive platforms. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-15 17:05:12 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
									
										
										
										
											2018-04-18 14:41:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:01:18 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_backup_save_enabled ( )  & &  p_mode_flags  = =  WRITE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 11:45:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										save_path  =  path ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 14:05:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Create a temporary file in the same directory as the target file.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Note: do not use GetTempFileNameW, it's not long path aware!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										String  tmpfile ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint64_t  id  =  OS : : get_singleton ( ) - > get_ticks_usec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tmpfile  =  path  +  itos ( id + + )  +  " .tmp " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HANDLE  handle  =  CreateFileW ( ( LPCWSTR ) tmpfile . utf16 ( ) . get_data ( ) ,  GENERIC_WRITE ,  0 ,  nullptr ,  CREATE_NEW ,  FILE_ATTRIBUTE_NORMAL ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( handle  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												CloseHandle ( handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( GetLastError ( )  ! =  ERROR_FILE_EXISTS  & &  GetLastError ( )  ! =  ERROR_SHARING_VIOLATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												last_error  =  ERR_FILE_CANT_WRITE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 14:05:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										path  =  tmpfile ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-05-14 13:50:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f  =  _wfsopen ( ( LPCWSTR ) ( path . utf16 ( ) . get_data ( ) ) ,  mode_string ,  is_backup_save_enabled ( )  ?  ( ( p_mode_flags  = =  READ )  ?  _SH_DENYWR  :  _SH_DENYRW )  :  _SH_DENYNO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( f  = =  nullptr )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Fix Windows platform file access
This restores Windows platform file handling back to open files non-exlusively by default, as was the case before October 2018. (See https://github.com/godotengine/godot/commit/b902a2f2a7438810cdcb053568ed5c27089b1e8a)
Back then, while fixing warnings for MSVC, the function used for opening files was changed from _wfopen() to _wfopen_s() as suggsted by the warning C4996. ("This function may be unsafe, consider using _wfopen_s instead.")
This new function
1. did parameter validation and thus avoided some possible security issues due to nil pointers or wrongly terminated strings
2. it also changed the default file sharing for opened files from _SH_DENYNO (which was the implicit default for the previous _wfopen()) to _SH_SECURE.
_SH_DENYNO means every opened file could be opened by other calls (like is the default on other operating systems).
_SH_SECURE means if the file is opened with READ access, others can still read the same file, but if it is opened with WRITE access, others can't open it at all, not even to read.
This led to rarely occuring bugs on Windows, i.e. due to random access by Antivirus processes, or Godot/Windows not closing a file handle fast enough while trying to open it again elsewhere (i.e. project.godot, instead showing the Project manager, or saving shaders/debugging the game).
What this PR does it change the file access to a third method, _wfsopen(). This is still secure, doing parameter validation and thus avoids the warning, but it allows us to actually SET the file sharing parameter. And we set it to _SH_DENYNO, as it was implicitely before the change. (And as it currently is on all non-Windows platforms, where file sharing restrictions don't exist by default.)
Warning C4996 should really have been pointing this out. It should've been _wfsopen() all along. Let's hope this banishes those annoying, rare errors for all eternity.
Fixes #28036.
											 
										 
										
											2021-08-09 11:40:13 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  ( errno )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-20 13:59:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  ENOENT :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												last_error  =  ERR_FILE_NOT_FOUND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												last_error  =  ERR_FILE_CANT_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  last_error ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										last_error  =  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										flags  =  p_mode_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-08-17 13:04:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 11:15:02 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : _close ( )  {  
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fclose ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-09 03:42:46 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! save_path . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-25 18:28:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// This workaround of trying multiple times is added to deal with paranoid Windows
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// antiviruses that love reading just written files even if they are not executable, thus
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// locking the file and preventing renaming from happening.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-12 17:03:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bool  rename_error  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-25 18:28:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  Char16String  & path_utf16  =  path . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  Char16String  & save_path_utf16  =  save_path . utf16 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( int  i  =  0 ;  i  <  1000 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ReplaceFileW ( ( LPCWSTR ) ( save_path_utf16 . get_data ( ) ) ,  ( LPCWSTR ) ( path_utf16 . get_data ( ) ) ,  nullptr ,  REPLACEFILE_IGNORE_MERGE_ERRORS  |  REPLACEFILE_IGNORE_ACL_ERRORS ,  nullptr ,  nullptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rename_error  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-12 17:03:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-25 18:28:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Either the target exists and is locked (temporarily, hopefully)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// or it doesn't exist; let's assume the latter before re-trying.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rename_error  =  MoveFileW ( ( LPCWSTR ) ( path_utf16 . get_data ( ) ) ,  ( LPCWSTR ) ( save_path_utf16 . get_data ( ) ) )  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-12 17:03:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-25 18:28:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! rename_error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-12 17:03:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-25 18:28:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											OS : : get_singleton ( ) - > delay_usec ( 1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-13 10:10:50 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-02 23:50:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rename_error )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-30 18:13:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( close_fail_notify )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												close_fail_notify ( save_path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-02 23:50:41 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-30 18:13:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										save_path  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-17 13:04:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ERR_FAIL_COND_MSG ( rename_error ,  " Safe save failed. This may be a permissions problem, but also may happen because you are running a paranoid antivirus. If this is the case, please switch to Windows Defender or disable the 'safe save' option in editor settings. This makes it work, but increases the risk of file corruption in a crash. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-03-09 11:45:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  FileAccessWindows : : get_path ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  path_src ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								String  FileAccessWindows : : get_path_absolute ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-05-28 12:15:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  path . trim_prefix ( R " ( \\ ? \ ) " ) . replace_char ( ' \\ ' ,  ' / ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-09 11:45:21 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  FileAccessWindows : : is_open ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2020-04-02 01:20:12 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ( f  ! =  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-14 14:29:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : seek ( uint64_t  p_position )  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( _fseeki64 ( f ,  p_position ,  SEEK_SET ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										check_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 10:07:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prev_op  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-14 14:29:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								void  FileAccessWindows : : seek_end ( int64_t  p_position )  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:42:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( _fseeki64 ( f ,  p_position ,  SEEK_END ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										check_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 10:07:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prev_op  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-14 14:29:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint64_t  FileAccessWindows : : get_position ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2025-02-13 11:18:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V_MSG ( f ,  0 ,  " File must be opened before use. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int64_t  aux_position  =  _ftelli64 ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( aux_position  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										check_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  aux_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2020-05-14 14:29:06 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-05-25 07:58:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint64_t  FileAccessWindows : : get_length ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( f ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uint64_t  pos  =  get_position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_fseeki64 ( f ,  0 ,  SEEK_END ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint64_t  size  =  get_position ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_fseeki64 ( f ,  pos ,  SEEK_SET ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  FileAccessWindows : : eof_reached ( )  const  {  
						 
					
						
							
								
									
										
										
										
											2024-12-02 12:03:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  feof ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint64_t  FileAccessWindows : : get_buffer ( uint8_t  * p_dst ,  uint64_t  p_length )  const  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( f ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-20 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! p_dst  & &  p_length  >  0 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 10:07:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( flags  = =  READ_WRITE  | |  flags  = =  WRITE_READ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( prev_op  = =  WRITE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fflush ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev_op  =  READ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-20 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 18:51:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									uint64_t  read  =  fread ( p_dst ,  1 ,  p_length ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									check_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-20 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  read ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Error  FileAccessWindows : : get_error ( )  const  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  last_error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-04-08 22:09:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  FileAccessWindows : : resize ( int64_t  p_length )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V_MSG ( f ,  FAILED ,  " File must be opened before use. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errno_t  res  =  _chsize_s ( _fileno ( f ) ,  p_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  EACCES : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  EBADF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ERR_FILE_CANT_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ENOSPC : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ERR_OUT_OF_MEMORY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  EINVAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ERR_INVALID_PARAMETER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  FAILED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-22 12:56:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : flush ( )  {  
						 
					
						
							
								
									
										
										
										
											2023-09-09 17:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_NULL ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:42:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-22 12:56:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									fflush ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( prev_op  = =  WRITE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 10:07:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										prev_op  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-07-27 13:43:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-22 12:56:02 +07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 21:21:43 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  FileAccessWindows : : store_buffer ( const  uint8_t  * p_src ,  uint64_t  p_length )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_NULL_V ( f ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V ( ! p_src  & &  p_length  >  0 ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:42:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-02 10:07:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( flags  = =  READ_WRITE  | |  flags  = =  WRITE_READ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( prev_op  = =  READ )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( last_error  ! =  ERR_FILE_EOF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												fseek ( f ,  0 ,  SEEK_CUR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										prev_op  =  WRITE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-20 18:07:27 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-02 12:03:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bool  res  =  fwrite ( p_src ,  1 ,  p_length ,  f )  = =  ( size_t ) p_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									check_errors ( true ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-04 13:23:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								bool  FileAccessWindows : : file_exists ( const  String  & p_name )  {  
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_path_invalid ( p_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									String  filename  =  fix_path ( p_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-11 21:21:18 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  file_attr  =  GetFileAttributesW ( ( LPCWSTR ) ( filename . utf16 ( ) . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( file_attr  ! =  INVALID_FILE_ATTRIBUTES )  & &  ! ( file_attr  &  FILE_ATTRIBUTE_DIRECTORY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								uint64_t  FileAccessWindows : : _get_modified_time ( const  String  & p_file )  {  
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( is_path_invalid ( p_file ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-08-31 14:19:28 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( file . ends_with ( " \\ " )  & &  file  ! =  " \\ " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										file  =  file . substr ( 0 ,  file . length ( )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 13:56:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-03-05 11:40:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									HANDLE  handle  =  CreateFileW ( ( LPCWSTR ) ( file . utf16 ( ) . get_data ( ) ) ,  FILE_READ_ATTRIBUTES ,  FILE_SHARE_READ  |  FILE_SHARE_WRITE  |  FILE_SHARE_DELETE ,  nullptr ,  OPEN_EXISTING ,  FILE_FLAG_BACKUP_SEMANTICS ,  nullptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:03:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( handle  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FILETIME  ft_create ,  ft_write ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  status  =  GetFileTime ( handle ,  & ft_create ,  nullptr ,  & ft_write ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( status )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uint64_t  ret  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// If write time is invalid, fallback to creation time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ft_write . dwHighDateTime  = =  0  & &  ft_write . dwLowDateTime  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  ft_create . dwHighDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  < < =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ft_create . dwLowDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  ft_write . dwHighDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  < < =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ft_write . dwLowDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  uint64_t  WINDOWS_TICKS_PER_SECOND  =  10000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  uint64_t  TICKS_TO_UNIX_EPOCH  =  116444736000000000LL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ret  > =  TICKS_TO_UNIX_EPOCH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ( ret  -  TICKS_TO_UNIX_EPOCH )  /  WINDOWS_TICKS_PER_SECOND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-16 14:03:34 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 09:35:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-10-17 10:47:58 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								uint64_t  FileAccessWindows : : _get_access_time ( const  String  & p_file )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_path_invalid ( p_file ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( file . ends_with ( " \\ " )  & &  file  ! =  " \\ " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										file  =  file . substr ( 0 ,  file . length ( )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  handle  =  CreateFileW ( ( LPCWSTR ) ( file . utf16 ( ) . get_data ( ) ) ,  FILE_READ_ATTRIBUTES ,  FILE_SHARE_READ  |  FILE_SHARE_WRITE  |  FILE_SHARE_DELETE ,  nullptr ,  OPEN_EXISTING ,  FILE_FLAG_BACKUP_SEMANTICS ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( handle  ! =  INVALID_HANDLE_VALUE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FILETIME  ft_create ,  ft_access ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  status  =  GetFileTime ( handle ,  & ft_create ,  & ft_access ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( status )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											uint64_t  ret  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// If access time is invalid, fallback to creation time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ft_access . dwHighDateTime  = =  0  & &  ft_access . dwLowDateTime  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  ft_create . dwHighDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  < < =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ft_create . dwLowDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  =  ft_access . dwHighDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  < < =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ret  | =  ft_access . dwLowDateTime ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  uint64_t  WINDOWS_TICKS_PER_SECOND  =  10000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  uint64_t  TICKS_TO_UNIX_EPOCH  =  116444736000000000LL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ret  > =  TICKS_TO_UNIX_EPOCH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  ( ret  -  TICKS_TO_UNIX_EPOCH )  /  WINDOWS_TICKS_PER_SECOND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_V_MSG ( 0 ,  " Failed to get access time for:  "  +  p_file  +  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int64_t  FileAccessWindows : : _get_size ( const  String  & p_file )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( is_path_invalid ( p_file ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( file . ends_with ( " \\ " )  & &  file  ! =  " \\ " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										file  =  file . substr ( 0 ,  file . length ( )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  file_attr  =  GetFileAttributesW ( ( LPCWSTR ) ( file . utf16 ( ) . get_data ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HANDLE  handle  =  CreateFileW ( ( LPCWSTR ) ( file . utf16 ( ) . get_data ( ) ) ,  FILE_READ_ATTRIBUTES ,  FILE_SHARE_READ  |  FILE_SHARE_WRITE  |  FILE_SHARE_DELETE ,  nullptr ,  OPEN_EXISTING ,  FILE_FLAG_BACKUP_SEMANTICS ,  nullptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( handle  ! =  INVALID_HANDLE_VALUE  & &  ! ( file_attr  &  FILE_ATTRIBUTE_DIRECTORY ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										LARGE_INTEGER  fsize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bool  status  =  GetFileSizeEx ( handle ,  & fsize ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										CloseHandle ( handle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( status )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ( int64_t ) fsize . QuadPart ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_V_MSG ( - 1 ,  " Failed to get size for:  "  +  p_file  +  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								BitField < FileAccess : : UnixPermissionFlags >  FileAccessWindows : : _get_unix_permissions ( const  String  & p_file )  {  
						 
					
						
							
								
									
										
										
										
											2019-04-07 15:46:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								Error  FileAccessWindows : : _set_unix_permissions ( const  String  & p_file ,  BitField < FileAccess : : UnixPermissionFlags >  p_permissions )  {  
						 
					
						
							
								
									
										
										
										
											2019-06-03 14:20:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ERR_UNAVAILABLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-07 15:46:52 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  FileAccessWindows : : _get_hidden_attribute ( const  String  & p_file )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  attrib  =  GetFileAttributesW ( ( LPCWSTR ) file . utf16 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( attrib  = =  INVALID_FILE_ATTRIBUTES ,  false ,  " Failed to get attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( attrib  &  FILE_ATTRIBUTE_HIDDEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Error  FileAccessWindows : : _set_hidden_attribute ( const  String  & p_file ,  bool  p_hidden )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  Char16String  & file_utf16  =  file . utf16 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  attrib  =  GetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( attrib  = =  INVALID_FILE_ATTRIBUTES ,  FAILED ,  " Failed to get attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BOOL  ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_hidden )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ok  =  SetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ,  attrib  |  FILE_ATTRIBUTE_HIDDEN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ok  =  SetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ,  attrib  &  ~ FILE_ATTRIBUTE_HIDDEN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( ! ok ,  FAILED ,  " Failed to set attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  FileAccessWindows : : _get_read_only_attribute ( const  String  & p_file )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DWORD  attrib  =  GetFileAttributesW ( ( LPCWSTR ) file . utf16 ( ) . get_data ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( attrib  = =  INVALID_FILE_ATTRIBUTES ,  false ,  " Failed to get attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( attrib  &  FILE_ATTRIBUTE_READONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Error  FileAccessWindows : : _set_read_only_attribute ( const  String  & p_file ,  bool  p_ro )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									String  file  =  fix_path ( p_file ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  Char16String  & file_utf16  =  file . utf16 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									DWORD  attrib  =  GetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( attrib  = =  INVALID_FILE_ATTRIBUTES ,  FAILED ,  " Failed to get attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BOOL  ok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p_ro )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ok  =  SetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ,  attrib  |  FILE_ATTRIBUTE_READONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-05-13 14:14:32 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ok  =  SetFileAttributesW ( ( LPCWSTR ) file_utf16 . get_data ( ) ,  attrib  &  ~ FILE_ATTRIBUTE_READONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-08-08 09:53:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ERR_FAIL_COND_V_MSG ( ! ok ,  FAILED ,  " Failed to set attributes for:  "  +  p_file ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-16 15:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : close ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_close ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								FileAccessWindows : : ~ FileAccessWindows ( )  {  
						 
					
						
							
								
									
										
										
										
											2022-04-12 11:15:02 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_close ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-02-09 22:10:30 -03:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								HashSet < String >  FileAccessWindows : : invalid_files ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  FileAccessWindows : : initialize ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  const  char  * reserved_files [ ] { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" con " ,  " prn " ,  " aux " ,  " nul " ,  " com0 " ,  " com1 " ,  " com2 " ,  " com3 " ,  " com4 " ,  " com5 " ,  " com6 " ,  " com7 " ,  " com8 " ,  " com9 " ,  " lpt0 " ,  " lpt1 " ,  " lpt2 " ,  " lpt3 " ,  " lpt4 " ,  " lpt5 " ,  " lpt6 " ,  " lpt7 " ,  " lpt8 " ,  " lpt9 " ,  nullptr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  reserved_file_index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( reserved_files [ reserved_file_index ]  ! =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										invalid_files . insert ( reserved_files [ reserved_file_index ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reserved_file_index + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-07 12:13:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									_setmaxstdio ( 8192 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									print_verbose ( vformat ( " Maximum number of file handles: %d " ,  _getmaxstdio ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-02-16 15:25:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-11 13:47:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  FileAccessWindows : : finalize ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									invalid_files . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-12 17:01:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif  // WINDOWS_ENABLED