@ -195,6 +195,73 @@ namespace tools
catch ( . . . ) { }
}
file_locker : : file_locker ( const std : : string & filename )
{
# ifdef WIN32
m_fd = INVALID_HANDLE_VALUE ;
std : : wstring filename_wide ;
try
{
filename_wide = string_tools : : utf8_to_utf16 ( filename ) ;
}
catch ( const std : : exception & e )
{
MERROR ( " Failed to convert path \" " < < filename < < " \" to UTF-16: " < < e . what ( ) ) ;
return ;
}
m_fd = CreateFileW ( filename_wide . c_str ( ) , GENERIC_READ , 0 , NULL , OPEN_ALWAYS , FILE_ATTRIBUTE_NORMAL , NULL ) ;
if ( m_fd ! = INVALID_HANDLE_VALUE )
{
OVERLAPPED ov ;
memset ( & ov , 0 , sizeof ( ov ) ) ;
if ( ! LockFileEx ( m_fd , LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK , 0 , 1 , 0 , & ov ) )
{
MERROR ( " Failed to lock " < < filename < < " : " < < std : : error_code ( GetLastError ( ) , std : : system_category ( ) ) ) ;
CloseHandle ( m_fd ) ;
m_fd = INVALID_HANDLE_VALUE ;
}
}
else
{
MERROR ( " Failed to open " < < filename < < " : " < < std : : error_code ( GetLastError ( ) , std : : system_category ( ) ) ) ;
}
# else
m_fd = open ( filename , O_RDONLY | O_CREAT , 0666 ) ;
if ( m_fd ! = - 1 )
{
if ( flock ( m_fd , LOCK_EX | LOCK_NB ) = = - 1 )
{
MERROR ( " Failed to lock " < < filename < < " : " < < std : : strerr ( errno ) ) ;
close ( m_fd ) ;
m_fd = - 1 ;
}
}
else
{
MERROR ( " Failed to open " < < filename < < " : " < < std : : strerr ( errno ) ) ;
}
# endif
}
file_locker : : ~ file_locker ( )
{
if ( locked ( ) )
{
# ifdef WIN32
CloseHandle ( m_fd ) ;
# else
close ( m_fd ) ;
# endif
}
}
bool file_locker : : locked ( ) const
{
# ifdef WIN32
return m_fd ! = INVALID_HANDLE_VALUE ;
# else
return m_fd ! = - 1 ;
# endif
}
# ifdef WIN32
std : : string get_windows_version_display_string ( )
{
@ -451,10 +518,15 @@ std::string get_nix_version_display_string()
if ( SHGetSpecialFolderPathW ( NULL , psz_path , nfolder , iscreate ) )
{
int size_needed = WideCharToMultiByte ( CP_UTF8 , 0 , psz_path , wcslen ( psz_path ) , NULL , 0 , NULL , NULL ) ;
std : : string folder_name ( size_needed , 0 ) ;
WideCharToMultiByte ( CP_UTF8 , 0 , psz_path , wcslen ( psz_path ) , & folder_name [ 0 ] , size_needed , NULL , NULL ) ;
return folder_name ;
try
{
return string_tools : : utf16_to_utf8 ( psz_path ) ;
}
catch ( const std : : exception & e )
{
MERROR ( " utf16_to_utf8 failed: " < < e . what ( ) ) ;
return " " ;
}
}
LOG_ERROR ( " SHGetSpecialFolderPathW() failed, could not obtain requested path. " ) ;
@ -515,18 +587,20 @@ std::string get_nix_version_display_string()
int code ;
# if defined(WIN32)
// Maximizing chances for success
WCHAR wide_replacement_name [ 1000 ] ;
MultiByteToWideChar ( CP_UTF8 , 0 , replacement_name . c_str ( ) , replacement_name . size ( ) + 1 , wide_replacement_name , 1000 ) ;
WCHAR wide_replaced_name [ 1000 ] ;
MultiByteToWideChar ( CP_UTF8 , 0 , replaced_name . c_str ( ) , replaced_name . size ( ) + 1 , wide_replaced_name , 1000 ) ;
DWORD attributes = : : GetFileAttributesW ( wide_replaced_name ) ;
std : : wstring wide_replacement_name ;
try { wide_replacement_name = string_tools : : utf8_to_utf16 ( replacement_name ) ; }
catch ( . . . ) { return std : : error_code ( GetLastError ( ) , std : : system_category ( ) ) ; }
std : : wstring wide_replaced_name ;
try { wide_replaced_name = string_tools : : utf8_to_utf16 ( replaced_name ) ; }
catch ( . . . ) { return std : : error_code ( GetLastError ( ) , std : : system_category ( ) ) ; }
DWORD attributes = : : GetFileAttributesW ( wide_replaced_name . c_str ( ) ) ;
if ( INVALID_FILE_ATTRIBUTES ! = attributes )
{
: : SetFileAttributesW ( wide_replaced_name , attributes & ( ~ FILE_ATTRIBUTE_READONLY ) ) ;
: : SetFileAttributesW ( wide_replaced_name .c_str ( ) , attributes & ( ~ FILE_ATTRIBUTE_READONLY ) ) ;
}
bool ok = 0 ! = : : MoveFileExW ( wide_replacement_name , wide_replaced_name , MOVEFILE_REPLACE_EXISTING ) ;
bool ok = 0 ! = : : MoveFileExW ( wide_replacement_name .c_str ( ) , wide_replaced_name . c_str ( ) , MOVEFILE_REPLACE_EXISTING ) ;
code = ok ? 0 : static_cast < int > ( : : GetLastError ( ) ) ;
# else
bool ok = 0 = = std : : rename ( replacement_name . c_str ( ) , replaced_name . c_str ( ) ) ;