comparison liboctave/system/file-ops.cc @ 27496:def608acdfa9

Canonicalize case of file path on Windows file systems (bug #56267). * file-ops.cc (canonicalize_file_name): Call GetLongPathNameW to get actual letter case of file name and path.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 21 Sep 2019 18:09:29 +0200
parents 84ff9953faa1
children b442ec6dda5c
comparison
equal deleted inserted replaced
27495:910737d41605 27496:def608acdfa9
29 #include <cstdlib> 29 #include <cstdlib>
30 #include <cstring> 30 #include <cstring>
31 31
32 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)) 32 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
33 # include <algorithm> 33 # include <algorithm>
34 #endif
35 #if defined (OCTAVE_USE_WINDOWS_API)
36 # include <windows.h>
34 #endif 37 #endif
35 38
36 #include <vector> 39 #include <vector>
37 40
38 #include "areadlink-wrapper.h" 41 #include "areadlink-wrapper.h"
702 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)) 705 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
703 // Canonical Windows file separator is backslash. 706 // Canonical Windows file separator is backslash.
704 std::replace (retval.begin (), retval.end (), '/', '\\'); 707 std::replace (retval.begin (), retval.end (), '/', '\\');
705 #endif 708 #endif
706 709
710 #if defined (OCTAVE_USE_WINDOWS_API)
711 // Get a more canonical name wrt case and full names
712 std::wstring w_tmp = L"\\\\?\\" + u8_to_wstring (retval);
713 wchar_t w_long[32767] = L"";
714 int w_len = GetLongPathNameW (w_tmp.c_str (), w_long, 32767);
715 if (w_len > 4)
716 retval = u8_from_wstring (std::wstring (w_long+4, w_len-4));
717 if (retval[1] == ':')
718 retval[0] = toupper (retval[0]);
719 #endif
720
707 if (retval.empty ()) 721 if (retval.empty ())
708 msg = std::strerror (errno); 722 msg = std::strerror (errno);
709 723
710 return retval; 724 return retval;
711 } 725 }